diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/.env b/samples/TeamsSDK/Archived/app-auth/nodejs/.env new file mode 100644 index 0000000000..97a8710caf --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/.env @@ -0,0 +1,9 @@ +MicrosoftAppId= +MicrosoftAppPassword= +TenantId= +AppType= +ConnectionName= +FaceBookAppId= +FaceBookAppPassword= +FBConnectionName= +ApplicationBaseUrl= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/.gitignore b/samples/TeamsSDK/Archived/app-auth/nodejs/.gitignore new file mode 100644 index 0000000000..4d29575de8 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/README.md b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/README.md new file mode 100644 index 0000000000..a57803a527 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/README.md @@ -0,0 +1,32 @@ +# Create and facebook app. + +1. Open [Meta for Developers](https://developers.facebook.com/) and login with your facebook credentials. + +2. One the dashboard page go to `My Apps` section. +![Meta Dashboard](meta-dashboard.png) + +3. Once the developer page opens, click on `Create App`. +![Create App](create-app-page.png) + +4. Enter `App name` +![App Name](app-name.png) + +5. Choose the `Use case` if it aligns with your specific requirement; otherwise, select `Other` and click next. +![Use Case](app-use-case.png) + +6. Choose the `app type` if it aligns with your specific requirement; otherwise, select `Consumer` and click next. +![Use Case](app-type-creation.png) + +7. On the basic information page `App name` will be the name of your app and `App contact email` will be your email linked with facebook, click on Create app. +![Basic Information](app-registration.png) + +8. Once the app is created navigate to basic details in App settings section of the app. You will be able to see App ID `FacebookAppId` and App Secret `FacebookAppPassword` which needs to be fill inside appsettings.json file. +![App Information](app-details.png) + +9. Now on your app dashboard page, click on `Customize adding a Facebook Login button` and left hand menu click on `Settings`. +![Add Product](dashboard-page.png) + +10. Scroll in the bottom and find the `Valid OAuth Redirect URIs` add the below valid domains inside the valid domain area. (Note here base-url refers to your app's base url. For eg when using ngrok if our url is `https://1234.ngrok-free.app` then base-url will be `1234.ngrok-free.app`). +`https:///`, `https:///fb-auth`, `https://token.botframework.com/.auth/web/redirect` and click on save changes. + +![Valid Domains](valid-domains.png) \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-details.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-details.png new file mode 100644 index 0000000000..17374a0a2d Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-details.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-name.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-name.png new file mode 100644 index 0000000000..8017b4ed2d Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-name.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-registration.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-registration.png new file mode 100644 index 0000000000..f7a060b213 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-registration.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-type-creation.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-type-creation.png new file mode 100644 index 0000000000..4977e32910 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-type-creation.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-use-case.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-use-case.png new file mode 100644 index 0000000000..0fee805106 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/app-use-case.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/create-app-page.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/create-app-page.png new file mode 100644 index 0000000000..f69eb6eaac Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/create-app-page.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/dashboard-page.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/dashboard-page.png new file mode 100644 index 0000000000..28a23a13d9 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/dashboard-page.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/meta-dashboard.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/meta-dashboard.png new file mode 100644 index 0000000000..6a430637bc Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/meta-dashboard.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/products-page.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/products-page.png new file mode 100644 index 0000000000..1c7b86b75f Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/products-page.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/valid-domains.png b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/valid-domains.png new file mode 100644 index 0000000000..975f5d0fd1 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/FacebookDocumentation/valid-domains.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/AppOffice.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/AppOffice.png new file mode 100644 index 0000000000..9f02d1b944 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/AppOutlook.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/AppOutlook.png new file mode 100644 index 0000000000..9165fc55eb Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOffice.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOffice.png new file mode 100644 index 0000000000..f24b92b827 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeLogin.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeLogin.png new file mode 100644 index 0000000000..285f40e52d Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeLogin.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeLoginV2.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeLoginV2.png new file mode 100644 index 0000000000..548945c8a5 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeLoginV2.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeSSOAuth.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeSSOAuth.png new file mode 100644 index 0000000000..9c8570d67b Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeSSOAuth.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeSilentAuth.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeSilentAuth.png new file mode 100644 index 0000000000..335d0ddfcb Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOfficeSilentAuth.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlook.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlook.png new file mode 100644 index 0000000000..e5f319b75a Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookLogin.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookLogin.png new file mode 100644 index 0000000000..49c5dc7314 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookLogin.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookLoginV2.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookLoginV2.png new file mode 100644 index 0000000000..376224d381 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookLoginV2.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookSSOAuth.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookSSOAuth.png new file mode 100644 index 0000000000..27a47d583d Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookSSOAuth.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookSilentAuth.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookSilentAuth.png new file mode 100644 index 0000000000..d8d9c6887e Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/InstallOutlookSilentAuth.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabAzureADLoginV1.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabAzureADLoginV1.png new file mode 100644 index 0000000000..d9117f3c2b Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabAzureADLoginV1.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabAzureADLoginV2.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabAzureADLoginV2.png new file mode 100644 index 0000000000..2b2164183c Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabAzureADLoginV2.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabSilentAuth.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabSilentAuth.png new file mode 100644 index 0000000000..2d3affab07 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabSilentAuth.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabSso.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabSso.png new file mode 100644 index 0000000000..e50a5ca9c2 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/TabSso.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/app-auth-tab.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/app-auth-tab.png new file mode 100644 index 0000000000..1a43a81df5 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/app-auth-tab.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/app-auth.gif b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/app-auth.gif new file mode 100644 index 0000000000..1d8c4bd2d6 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/app-auth.gif differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/login-card.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/login-card.png new file mode 100644 index 0000000000..d78441cb25 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/login-card.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/sso-bot.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/sso-bot.png new file mode 100644 index 0000000000..ef252f52b2 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/sso-bot.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tab-silent.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tab-silent.png new file mode 100644 index 0000000000..f17f52caf3 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tab-silent.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tab-sso.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tab-sso.png new file mode 100644 index 0000000000..80c9729618 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tab-sso.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tabv1.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tabv1.png new file mode 100644 index 0000000000..aea1786351 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tabv1.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tabv2.png b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tabv2.png new file mode 100644 index 0000000000..600c834a90 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/Images/tabv2.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/README.md b/samples/TeamsSDK/Archived/app-auth/nodejs/README.md new file mode 100644 index 0000000000..342b81eaec --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/README.md @@ -0,0 +1,289 @@ +--- +page_type: sample +products: + - office + - office-teams + - office-365 +languages: + - typescript + - javascript + - html +description: 'This sample showcases how to implement authentication in Microsoft Teams using both a bot and a tab, supporting Teams SSO with MSAL.js 2.0.' +urlFragment: microsoft-teams-auth +extensions: + contentType: samples + createdDate: "02/08/2018 05:06:47 PM" +urlFragment: officedev-microsoft-teams-samples-app-auth-nodejs +--- + +# Microsoft Teams Authentication Sample + +This sample showcases how to implement authentication in Microsoft Teams using both a bot and a tab. It demonstrates Single Sign-On (SSO) functionality, allowing seamless user experiences across Microsoft services. + +## Included Features +* Teams SSO (Using bots and tabs) +* Bots +* MSAL.js 2.0 support + +## Interaction with App +![app-auth-sample](Images/app-auth.gif) + +## Getting started + +1. Install some sort of tunnelling service. Eg. [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution +2. Begin your tunnelling service to get an https endpoint. For this example ngrok is used. Start an ngrok tunnel with the following command (you'll need the https endpoint for the bot registration):
+ + ```bash + ngrok http 3978 --host-header=localhost + ``` + Alternatively, you can also use the `dev tunnels`. Please follow this documentation: [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) link and host the tunnel with anonymous user access as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +### Setup for code + + - Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + - In a terminal, navigate to `samples/app-auth/nodejs` + + - Install modules + + ```bash + npm install + npm start + ``` + +3. Register a bot with Azure Bot Service, following the instructions [here](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration?view=azure-bot-service-3.0). +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/en-us/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) +- While registering the bot, use `https:///api/messages` as the messaging endpoint. + > NOTE: When you create your bot you will create an App ID and App password - make sure you keep these for later. + +> **IMPORTANT**: Do not use the legacy Bot Framework portal, nor App Studio, to create the bot. Your bot MUST be registered with +> Azure Bot Service to use the authentication functionality provided by Azure Bot Service. + +4. Create an app manifest. Navigate to the file, appManifest/manifest.json - Change: + 1. <> (there are 3) change to your registered bot's app ID + 2. <> (there are 5) change to your https endpoint from ngrok excluding the "https://" part + **Note:** If you want to test your app across multi hub like: Outlook/Office.com, please update the `manifest.json` in the `app-auth\nodejs\appManifestHub` folder with the required values. + 3. Zip up the contents of the `appManifest` folder to create a `manifest.zip` or `appManifestHub` folder into a `appManifestHub.zip`. (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +## Setup + +To be able to use an identity provider, first you have to register your application. + +### Changing app settings + +- Environment variable overrides are defined in `app-auth\nodejs\.env`. You can set these environment variables when running node. + +The instructions below assume that you're using environment variables to configure the app, and will specify the name of the variable to set. + +### [Using Azure AD](#using-azure-ad) + +Registering a bot with the Microsoft Bot Framework automatically creates a corresponding Azure AD application with the same name and ID. + +1. Go to the [Application Registration Portal](https://aka.ms/appregistrations) and sign in with the same account that you used to register your bot. +2. Find your application in the list and click on the name to edit. +3. Navigate to **Authentication** under **Manage** and add the following redirect URLs: + - `https://token.botframework.com/.auth/web/redirect` + - Add this URL as *Single-page application* `https:///silent-end` + +4. Additionally, under the **Implicit grant** subsection select **Access tokens** and **ID tokens** + +5. Click on **Expose an API** under **Manage**. Select the Set link to generate the Application ID URI in the form of api://{AppID}. Insert your fully qualified domain name (with a forward slash "/" appended to the end) between the double forward slashes and the GUID. The entire ID should have the form of: api:///{AppID} +6. Select the **Add a scope** button. In the panel that opens, enter `access_as_user` as the **Scope name**. +7. Set Who can consent? to Admins and users + +8. Fill in the fields for configuring the admin and user consent prompts with values that are appropriate for the `access_as_user` scope. Suggestions: + - **Admin consent title:** Teams can access the user’s profile + - **Admin consent description**: Allows Teams to call the app’s web APIs as the current user. + - **User consent title**: Teams can access your user profile and make requests on your behalf + - **User consent description:** Enable Teams to call this app’s APIs with the same rights that you have +9. Ensure that **State** is set to **Enabled** + +10. Select **Add scope** + - Note: The domain part of the **Scope name** displayed just below the text field should automatically match the **Application ID** URI set in the previous step, with `/access_as_user` appended to the end; for example: + - `api:////access_as_user` + - If you are facing any issue in your app, please uncomment [this] line( https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/app-auth/nodejs/src/AuthBot.ts#L119) and put your debugger for local debug. + +11. In the **Authorized client applications** section, you identify the applications that you want to authorize to your app’s web application. Each of the following IDs needs to be entered: + - `1fec8e78-bce4-4aaf-ab1b-5451cc387264` (Teams mobile/desktop application) + - `5e3ce6c0-2b1f-4285-8d4b-75ee78787346` (Teams web application) +**Note** If you want to test or extend your Teams apps across Office and Outlook, kindly add below client application identifiers while doing Azure AD app registration in your tenant: + * `4765445b-32c6-49b0-83e6-1d93765276ca` (Office web) + * `0ec893e0-5785-4de6-99da-4ed124e5296c` (Office desktop) + * `bc59ab01-8403-45c6-8796-ac3ef710b3e3` (Outlook web) + * `d3590ed6-52b3-4102-aeff-aad2292ab01c` (Outlook desktop) + +12. Navigate to **API Permissions**, and make sure to add the following delegated permissions: + - User.Read + - email + - offline_access + - openid + - profile +13. Scroll to the bottom of the page and click on "Add Permissions". + +14. The bot uses `MICROSOFT_APP_ID` and `MICROSOFT_APP_PASSWORD`, so these should already be set. + +### Setup Facebook authentication +15. To test facebook auth flow [create a facebookapp](FacebookDocumentation/README.md) and get client id and secret for facebook app. + Now go to your bot channel registartion -> configuration -> Add OAuth connection string + - Provide connection Name : for eg `facebookconnection`. You'll use this name in your bot in the appsettings.json file. + - Select service provider ad `facebook` + - Add clientid and secret of your facebook app that was created using Step 16. + - For scopes, add `email public_profile` + +### Update your Microsoft Teams application manifest + +15. Add new properties to your Microsoft Teams app manifest: + + - **WebApplicationInfo** - The parent of the following elements. + - **Id** - The client ID of the application. This is an application ID that you obtain as part of registering the application with Azure AD 1.0 endpoint. + - **Resource** - The domain and subdomain of your application. This is the same URI (including the `api://` protocol) that you used when registering the app in Microsoft Entra ID. The domain part of this URI should match the domain, including any subdomains, used in the URLs in the section of your Teams application manifest. + + ```json + "webApplicationInfo": { + "id": "<<>", + "resource": "api://<>/<<>" + } + ``` + +17. Add permissions and update validDomains to allow token endpoint used by bot framework. Teams will only show the sign-in popup if its from a whitelisted domain. + + ```json + "permissions": [ + "identity" + ], + "validDomains": [ + "<>", + "token.botframework.com" + ], + ``` + +Notes: +- The resource for an Microsoft Entra ID app will usually just be the root of its site URL and the appID (e.g. api://subdomain.example.com/6789/c6c1f32b-5e55-4997-881a-753cc1d563b7). We also use this value to ensure your request is coming from the same domain. Therefore make sure that your contentURL for your tab uses the same domains as your resource property. +- You need to be using manifest version 1.5 or higher for these fields to be used. +- Scopes aren’t supported in the manifest and instead should be specified in the API Permissions section in the Azure portal +- If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/app-auth/nodejs/src/AuthBot.ts#L119) line and put your debugger for local debug. + +### Add the Azure AD OAuth connection to the bot + +1. Navigate to your Azure bot's service page on the [Azure Portal](https://ms.portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.BotService%2FbotServices). +2. Click **Settings**. +3. Under **OAuth Connection Settings** near the bottom of the page, click **Add Setting**. +4. Fill in the form as follows: + + 1. For **Name**, enter a name for your connection (e.g., "AzureADv2") + 2. For **Service Provider**, select **Azure Active Directory v2**. Once you select this, the Azure AD-specific fields will be displayed. + 3. For **Client id**, enter your bot's client ID. + 4. For **Client secret**, enter your bot's client secret. + 5. For **Tenant ID**, enter `common`. + 6. For **Scopes**, enter `User.Read`. + +5. Click **Save**. +6. Set the environment variable `AZUREAD_CONNECTIONNAME` to the name that you chose for this OAuth connection. + +### Testing the OAuth connections + +Before proceeding, it's wise to test the OAuth connections that you have configured with the Azure Bot Service. + +1. Open the [Azure Bot](https://ms.portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.BotService%2FbotServices) blade on the Azure Portal. +2. Navigate to your Azure Bot resource. +3. Click **Settings**. +4. Under **OAuth Connection Settings** near the bottom of the page, click on the connection. +5. Click on **Test connection**. +6. Sign in and authorize your app when prompted. + +If the connection was configured correctly, you will be taken to a page with the access token that your bot would have received. + + +## Running the sample + +Tab authentication + +![tab azure ad login page](Images/app-auth-tab.png) + +![tab azure ad login v1](Images/tabv1.png) + +![tab azure ad login v2](Images/tabv2.png) + +![tab silent auth](Images/tab-silent.png) + +![tab SSO](Images/tab-sso.png) + +Bot authentication + +![Bot SSO](Images/login-card.png) + +![Bot Microsoft Entra ID login](Images/sso-bot.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**On the side bar, select More Apps. Your uploaded app title appears among your installed apps** + +![InstallOutlook](Images/InstallOutlook.png) + +**Select your app icon to launch and preview your app running in Outlook on the web** + +![AppOutlook](Images/AppOutlook.png) + +![InstallOutlookLogin](Images/InstallOutlookLogin.png) + +![InstallOutlookLoginV2](Images/InstallOutlookLoginV2.png) + +![InstallOutlookSilentAuth](Images/InstallOutlookSilentAuth.png) + +![InstallOutlookSSOAuth](Images/InstallOutlookSSOAuth.png) + +**Note:** Similarly, you can test your application in the Outlook desktop app as well. + +## Office on the web + +- To preview your app running in Office on the web. + +- Log into office.com with test tenant credentials + +**Select the Apps icon on the side bar. Your uploaded app title appears among your installed apps** + +![InstallOffice](Images/InstallOffice.png) + +**Select your app icon to launch your app in Office on the web** + +![AppOffice](Images/AppOffice.png) + +![InstallOfficeLogin](Images/InstallOfficeLogin.png) + +![InstallOfficeLoginV2](Images/InstallOfficeLoginV2.png) + +![InstallOfficeSilentAuth](Images/InstallOfficeSilentAuth.png) + +![InstallOfficeSSOAuth](Images/InstallOfficeSSOAuth.png) + +**Note:** Similarly, you can test your application in the Office 365 desktop app as well. + +## Security notes + +- The verification code mechanism prevents a potential ["man in the middle" attack](https://hueniverse.com/explaining-the-oauth-session-fixation-attack-aa759250a0e7) by requiring evidence that the user who authorized the bot in the browser is the same person as the user who is chatting with the bot. **Don't** remove the need for a verification code without understanding what it is protecting against, and weighing the risk against your use case and threat model. +- Don't use the `signin/verifyState` message to pass sensitive data (e.g., access tokens) directly to your bot in plaintext. The `state` value should not be usable without additional information that's available only to your bot. +- The Teams app sends the `signin/verifyState` invoke message in a way that's equivalent to the user typing a message to your bot. This means that although the user information in the message is not falsifiable, a malicious user **can** tamper with the payload, or send additional invoke messages that were not initiated by your app. +- Store your users’ access tokens in such a way that they are encrypted at rest, especially if you are also storing refresh tokens. Consider, based on your use case and threat model, how often to rotate the encryption key. (The sample uses an in-memory store for simplicity; do not do this in your production app!) +- If you are using OAuth, remember that the `state` parameter in the authentication request must contain a unique session token to prevent request forgery attacks. The sample uses a randomly-generated GUID. + +## Mobile clients + +As of April 2019, Microsoft Teams mobile clients support the `signin` action protocol (that is, mobile clients work the same way as the desktop/web clients). It does require an updated version of the [Microsoft Teams JavaScript library](https://www.npmjs.com/package/@microsoft/teams-js) (1.4.1 or later). The way it used to work is described [here](fallbackUrl.md). + +## Further reading + +- [Extend Teams apps across Microsoft 365](https://learn.microsoft.com/en-us/microsoftteams/platform/m365-apps/overview) + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/color.png b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/manifest.json b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/manifest.json new file mode 100644 index 0000000000..d7e363e298 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/manifest.json @@ -0,0 +1,87 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "{{Microsoft-App-Id}}", + "webApplicationInfo": { + "id": "{{Microsoft-App-Id}}", + "resource": "api://{Base_URL_Domain}/botid-{{Microsoft-App-Id}}", + "applicationPermissions": [] + }, + "developer": { + "name": "Microsoft", + "websiteUrl": "https://example.azurewebsites.net", + "privacyUrl": "https://example.azurewebsites.net/privacy", + "termsOfUseUrl": "https://example.azurewebsites.net/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "App auth", + "full": "App authentication sample" + }, + "description": { + "short": "Sample app for Microsoft Teams authentication using bot and tab methods.", + "full": "This sample showcases how to implement single-tenant authentication in Microsoft Teams using both a bot and a tab, supporting Teams SSO." + }, + "staticTabs": [ + { + "contentUrl": "https://{Base_URL_Domain}/AuthTab", + "entityId": "Auth", + "name": "Auth", + "scopes": [ + "personal" + ] + }, + { + "contentUrl": "https://{Base_URL_Domain}/silent-tab?loginHint={loginHint}&userObjectId={userObjectId}&tenantId={tid}", + "entityId": "silentAuth", + "name": "Silent Auth", + "scopes": [ + "personal" + ] + } + ], + "bots": [ + { + "botId": "{{Microsoft-App-Id}}", + "scopes": [ + "personal" + ], + "commandLists": [ + { + "scopes": [ + "personal" + ], + "commands": [ + { + "title": "sso", + "description": "Sign in with Azure AD SSO" + }, + { + "title": "facebooklogin", + "description": "Sign in with Facebook" + }, + { + "title": "logout", + "description": "Sign out" + } + ] + } + ], + "isNotificationOnly": false, + "supportsFiles": true + } + ], + "accentColor": "#60A18E", + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "{Base_URL_Domain}", + "token.botframework.com" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/outline.png b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/color.png b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/color.png new file mode 100644 index 0000000000..caefd6c369 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/color.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/manifest.json b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/manifest.json new file mode 100644 index 0000000000..3e14786a35 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/manifest.json @@ -0,0 +1,87 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "{{Microsoft-App-Id}}", + "webApplicationInfo": { + "id": "{{Microsoft-App-Id}}", + "resource": "api://{Base_URL_Domain}/botid-{{Microsoft-App-Id}}", + "applicationPermissions": [] + }, + "developer": { + "name": "Microsoft", + "websiteUrl": "https://example.azurewebsites.net", + "privacyUrl": "https://example.azurewebsites.net/privacy", + "termsOfUseUrl": "https://example.azurewebsites.net/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "App auth", + "full": "App authentication sample" + }, + "description": { + "short": "Authentication sample for Microsoft Teams", + "full": "This sample showcases how to implement single-tenant authentication in Microsoft Teams" + }, + "staticTabs": [ + { + "contentUrl": "https://{Base_URL_Domain}/AuthTab", + "entityId": "Auth", + "name": "Auth", + "scopes": [ + "personal" + ] + }, + { + "contentUrl": "https://{Base_URL_Domain}/silent-tab?loginHint={loginHint}&userObjectId={userObjectId}&tenantId={tid}", + "entityId": "silentAuth", + "name": "Silent Auth", + "scopes": [ + "personal" + ] + } + ], + "bots": [ + { + "botId": "{{Microsoft-App-Id}}", + "scopes": [ + "personal" + ], + "commandLists": [ + { + "scopes": [ + "personal" + ], + "commands": [ + { + "title": "sso", + "description": "Sign in with Azure AD SSO" + }, + { + "title": "facebooklogin", + "description": "Sign in with Facebook" + }, + { + "title": "logout", + "description": "Sign out" + } + ] + } + ], + "isNotificationOnly": false, + "supportsFiles": true + } + ], + "accentColor": "#60A18E", + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "{Base_URL_Domain}", + "token.botframework.com" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/outline.png b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-auth/nodejs/appManifestHub/outline.png differ diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/assets/sample.json b/samples/TeamsSDK/Archived/app-auth/nodejs/assets/sample.json new file mode 100644 index 0000000000..1fa940e7a0 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-app-complete-auth-nodejs", + "source": "officeDev", + "title": "Authentication complete sample", + "shortDescription": "Sample app showcasing Microsoft Teams authentication using bots and tabs with MSAL.js 2.0 for seamless SSO experience.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/app-complete-auth/nodejs", + "longDescription": [ + "This sample showcases how to implement authentication in Microsoft Teams using both a bot and a tab, supporting Teams SSO with MSAL.js 2.0." + ], + "creationDateTime": "2022-02-16", + "updateDateTime": "2024-10-10", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab,bot,msgext" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/app-complete-auth/nodejs/Images/app-complete-auth.gif", + "alt": "Solution UX showing authentication complete sample" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/bots/dialogBot.js b/samples/TeamsSDK/Archived/app-auth/nodejs/bots/dialogBot.js new file mode 100644 index 0000000000..0fd389fce2 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/bots/dialogBot.js @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { TeamsActivityHandler } = require('botbuilder'); +class DialogBot extends TeamsActivityHandler { + /** + * + * @param {ConversationState} conversationState + * @param {UserState} userState + * @param {Dialog} dialog + */ + constructor(conversationState, userState, dialog) { + super(); + this.baseUrl = process.env.ApplicationBaseUrl; + + if (!conversationState) { + throw new Error('[DialogBot]: Missing parameter. conversationState is required'); + } + + if (!userState) { + throw new Error('[DialogBot]: Missing parameter. userState is required'); + } + + if (!dialog) { + throw new Error('[DialogBot]: Missing parameter. dialog is required'); + } + + this.conversationState = conversationState; + this.userState = userState; + this.dialog = dialog; + this.dialogState = this.conversationState.createProperty('DialogState'); + + this.onMessage(async (context, next) => { + console.log('Running dialog with Message Activity.'); + await this.dialog.run(context, this.dialogState); + await next(); + }); + } + + /** + * Override the ActivityHandler.run() method to save state changes after the bot logic completes. + */ + async run(context) { + await super.run(context); + + // Save any state changes. The load happened during the execution of the Dialog. + await this.conversationState.saveChanges(context, false); + await this.userState.saveChanges(context, false); + } +} + +module.exports.DialogBot = DialogBot; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/bots/teamsBot.js b/samples/TeamsSDK/Archived/app-auth/nodejs/bots/teamsBot.js new file mode 100644 index 0000000000..c2c75f5e66 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/bots/teamsBot.js @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { DialogBot } = require('./dialogBot'); +const { tokenExchangeOperationName } = require('botbuilder'); +const { SsoOAuthHelpler } = require('../SsoOAuthHelpler'); +const axios = require('axios') + +class TeamsBot extends DialogBot { + /** + * + * @param {ConversationState} conversationState + * @param {UserState} userState + * @param {Dialog} dialog + */ + constructor(conversationState, userState, dialog) { + super(conversationState, userState, dialog); + this._ssoOAuthHelper = new SsoOAuthHelpler(process.env.ConnectionName, conversationState); + this.connectionName = process.env.ConnectionName; + this.fbconnectionName = process.env.FBConnectionName; + this.baseUrl = process.env.ApplicationBaseUrl; + this.isSignedIn = false; + this.onMembersAdded(async (context, next) => { + const membersAdded = context.activity.membersAdded; + for (let member = 0; member < membersAdded.length; member++) { + if (membersAdded[member].id !== context.activity.recipient.id) { + await context.sendActivity("Hello and welcome! Please type 'sso' for Azure AD authentication or 'facebooklogin' for Facebook login."); + } + } + await next(); + }); + } + + // Handle token exchange + async handleTeamsSigninTokenExchange(context, query) { + console.log('Running dialog with signin/tokenExchange from an Invoke Activity.'); + await this.dialog.run(context, this.dialogState); + } + + // Verify signin state from invoke activity + async handleTeamsSigninVerifyState(context, query) { + console.log('Running dialog with signin/verifystate from an Invoke Activity.'); + await this.dialog.run(context, this.dialogState); + } +} + +module.exports.TeamsBot = TeamsBot; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/build.js b/samples/TeamsSDK/Archived/app-auth/nodejs/build.js new file mode 100644 index 0000000000..a59684a045 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/build.js @@ -0,0 +1,14 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js' +}) + .then((r) => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/botSSOAuthDialog.js b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/botSSOAuthDialog.js new file mode 100644 index 0000000000..895dd7d294 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/botSSOAuthDialog.js @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { WaterfallDialog,TextPrompt} = require('botbuilder-dialogs'); +const { CardFactory,MessageFactory,InputHints} = require('botbuilder'); + +const { LogoutDialog } = require('./logoutDialog'); +const { SsoOAuthPrompt } = require('./ssoOAuthPrompt'); +const { SimpleGraphClient } = require('../simpleGraphClient'); +const SSOAUTH = 'SsoAuth'; +const OAUTH_PROMPT = 'OAuthPrompt'; +const TEXT_PROMPT = 'textPrompt'; +var token; + +class BotSSOAuthDialog extends LogoutDialog { + constructor(id) { + super(id, process.env.connectionName); + + this.addDialog(new SsoOAuthPrompt(OAUTH_PROMPT, { + connectionName: process.env.connectionName, + text: 'Please Sign In', + title: 'Sign In', + timeout: 300000 + })); + + this.addDialog(new TextPrompt(TEXT_PROMPT)); + this.addDialog(new WaterfallDialog(SSOAUTH, [ + this.promptStep.bind(this), + this.loginStep.bind(this), + this.userInfoStep.bind(this) + ])); + + this.initialDialogId = SSOAUTH; + } + + async promptStep(stepContext) { + return await stepContext.beginDialog(OAUTH_PROMPT); + } + + async loginStep(stepContext) { + // Get the token from the previous step. Note that we could also have gotten the + // token directly from the prompt itself. There is an example of this in the next method. + if (stepContext.context._activity.text.trim() == "sso") { + const tokenResponse = stepContext.result; + + if (!tokenResponse || !tokenResponse.token) { + await stepContext.context.sendActivity('Login was not successful please try again.'); + } + else { + token = tokenResponse.token; + await stepContext.context.sendActivity('Login successful.'); + return await this.userInfoStep(stepContext); + } + + await stepContext.context.sendActivity("Please type 'sso' to begin authentication"); + + return await stepContext.endDialog(); + } + } + + async userInfoStep(stepContext) { + const client = new SimpleGraphClient(token); + const myDetails = await client.getMeAsync(); + + if (myDetails != null) { + let userImage = "https://static2.sharepointonline.com/files/fabric/assets/1x/person.png"; // Default Microsoft image + + try { + // Attempt to get the user profile image + const photoResponse = await client.getUserPhoto(); + const buffer = await photoResponse.arrayBuffer(); + const imageString = Buffer.from(buffer).toString('base64'); + userImage = "data:image/png;base64," + imageString; + } catch (error) { + // If no image is found or an error occurs, log the error and use default + console.log('Unable to fetch user photo:', error.message); + } + + const userCard = CardFactory.adaptiveCard(this.getAdaptiveCardUserDetails(myDetails, userImage)); + await stepContext.context.sendActivity({ attachments: [userCard] }); + } + + return await stepContext.endDialog(); + } + + getAdaptiveCardUserDetails = (myDetails, userImage) => ({ + $schema: 'http://adaptivecards.io/schemas/adaptive-card.json', + body: [ + { + type: "TextBlock", + size: "Medium", + weight: "Bolder", + text: "User profile details are" + }, + { + type: "Image", + size: "Medium", + url: userImage + }, + { + type: "TextBlock", + size: "Medium", + weight: "Bolder", + wrap: true, + text: `Hello! ${myDetails.displayName}` + }, + { + type: "TextBlock", + size: "Medium", + weight: "Bolder", + text: `Job title: ${myDetails.jobDetails ? myDetails.jobDetails : "Unknown"}` + }, + { + type: "TextBlock", + size: "Medium", + weight: "Bolder", + text: `Email: ${myDetails.userPrincipalName}` + } + ], + type: 'AdaptiveCard', + version: '1.4' + }); +} + +exports.BotSSOAuthDialog = BotSSOAuthDialog; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/logoutDialog.js b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/logoutDialog.js new file mode 100644 index 0000000000..01104d1675 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/logoutDialog.js @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { BotFrameworkAdapter, ActivityTypes } = require('botbuilder'); +const { ComponentDialog } = require('botbuilder-dialogs'); + +class LogoutDialog extends ComponentDialog { + constructor(id, connectionName) { + super(id); + this.connectionName = connectionName; + } + + async onBeginDialog(innerDc, options) { + const result = await this.interrupt(innerDc); + if (result) { + return result; + } + + return await super.onBeginDialog(innerDc, options); + } + + async onContinueDialog(innerDc) { + const result = await this.interrupt(innerDc); + if (result) { + return result; + } + + return await super.onContinueDialog(innerDc); + } + + async interrupt(innerDc) { + if (innerDc.context.activity.type === ActivityTypes.Message) { + const text = innerDc.context.activity.text.toLowerCase().trim(); + + if (text === 'logout') { + try { + const userTokenClient = innerDc.context.turnState.get(innerDc.context.adapter.UserTokenClientKey); + const { activity } = innerDc.context; + + await userTokenClient.signOutUser(activity.from.id, this.connectionName, activity.channelId); + await innerDc.context.sendActivity('You have been signed out.'); + + return await innerDc.cancelAllDialogs(); + } catch (error) { + console.error('Error during logout:', error.message); + await innerDc.context.sendActivity('An error occurred during sign out.'); + } + } + } + } +} + +module.exports.LogoutDialog = LogoutDialog; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/mainDialog.js b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/mainDialog.js new file mode 100644 index 0000000000..492a7cd25b --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/mainDialog.js @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { DialogSet, DialogTurnStatus, WaterfallDialog,ComponentDialog } = require('botbuilder-dialogs'); +const { CardFactory,ActionTypes} = require('botbuilder'); +const MAIN_DIALOG = 'MainDialog'; +const MAIN_WATERFALL_DIALOG = 'MainWaterfallDialog'; + +const { SimpleFacebookAuthDialog } = require('./simpleFacebookAuthDialog'); +const { BotSSOAuthDialog } = require('./botSSOAuthDialog'); +const FACEBOOKAUTH = 'FacebookAuth'; +const SSOAUTH = 'SsoAuth'; + +class MainDialog extends ComponentDialog { + constructor() { + super(MAIN_DIALOG, process.env.connectionName); + this.baseUrl = process.env.ApplicationBaseUrl; + + this.addDialog(new SimpleFacebookAuthDialog(FACEBOOKAUTH)); + this.addDialog(new BotSSOAuthDialog(SSOAUTH)); + this.addDialog(new WaterfallDialog(MAIN_WATERFALL_DIALOG, [ + this.promptStep.bind(this) + ])); + + this.initialDialogId = MAIN_WATERFALL_DIALOG; + } + + /** + * The run method handles the incoming activity (in the form of a DialogContext) and passes it through the dialog system. + * If no dialog is active, it will start the default dialog. + * @param {*} dialogContext + */ + async run(context, accessor) { + const dialogSet = new DialogSet(accessor); + dialogSet.add(this); + const dialogContext = await dialogSet.createContext(context); + const results = await dialogContext.continueDialog(); + + if (results.status === DialogTurnStatus.empty) { + await dialogContext.beginDialog(this.id); + } + } + + async promptStep(stepContext) { + try { + const userInput = stepContext.context._activity.text.trim().toLowerCase(); + + if (userInput === "sso") { + return await stepContext.beginDialog(SSOAUTH); + } else if (userInput === "facebooklogin") { + return await stepContext.beginDialog(FACEBOOKAUTH); + } else if (userInput === "logout") { + return await stepContext.beginDialog(FACEBOOKAUTH); + } else { + const buttons = [ + { type: ActionTypes.ImBack, title: 'AAD SSO authentication', value: 'sso' }, + { type: ActionTypes.ImBack, title: 'Facebook login (OAuth 2)', value: 'facebooklogin' } + ]; + const card = CardFactory.heroCard('Login options', undefined, buttons, { text: "Select a login option" }); + await stepContext.context.sendActivity({ attachments: [card] }); + + return await stepContext.endDialog(); + } + } catch (err) { + console.error('Error in promptStep:', err); + await stepContext.context.sendActivity('An error occurred. Please try again.'); + return await stepContext.endDialog(); + } + } +} + +module.exports.MainDialog = MainDialog; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/simpleFacebookAuthDialog.js b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/simpleFacebookAuthDialog.js new file mode 100644 index 0000000000..81e2bba78a --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/simpleFacebookAuthDialog.js @@ -0,0 +1,100 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { OAuthPrompt, WaterfallDialog,TextPrompt} = require('botbuilder-dialogs'); +const { CardFactory,MessageFactory,InputHints} = require('botbuilder'); + +const { LogoutDialog } = require('./logoutDialog'); +const axios = require('axios') +const FACEBOOKAUTH = 'FacebookAuth'; +const OAUTH_PROMPT = 'OAuthPrompt'; +const TEXT_PROMPT = 'textPrompt'; +var token; + +class SimpleFacebookAuthDialog extends LogoutDialog { + constructor(id) { + super(id, process.env.FBConnectionName); + + this.addDialog(new OAuthPrompt(OAUTH_PROMPT, { + connectionName: process.env.FBConnectionName, + text: 'Login to facebook', + title: 'Log In', + timeout: 300000 + })); + + this.addDialog(new TextPrompt(TEXT_PROMPT)); + + this.addDialog(new WaterfallDialog(FACEBOOKAUTH, [ + this.promptStep.bind(this), + this.loginStep.bind(this), + this.userInfoStep.bind(this) + ])); + + this.initialDialogId = FACEBOOKAUTH; + } + + async promptStep(stepContext) { + return await stepContext.beginDialog(OAUTH_PROMPT); + } + + async loginStep(stepContext) { + const tokenResponse = stepContext.result; + + if (tokenResponse) { + token = tokenResponse.token; + await stepContext.context.sendActivity('Login successful.'); + return await this.userInfoStep(stepContext); + } + + await stepContext.context.sendActivity('Login was not successful. Please try again.'); + return await stepContext.endDialog(); + } + + async userInfoStep(stepContext) { + try { + const facebookProfile = await this.getFacebookUserData(token); + + const profileCard = CardFactory.adaptiveCard({ + version: '1.0.0', + type: 'AdaptiveCard', + body: [ + { + type: "Image", + size: "Medium", + url: facebookProfile.picture.data.url + }, + { + type: 'TextBlock', + text: `Hello: ${facebookProfile.name}` + } + ] + }); + + await stepContext.context.sendActivity({ attachments: [profileCard] }); + } catch (error) { + console.error('Error retrieving Facebook profile:', error.message); + await stepContext.context.sendActivity('Unable to retrieve profile information.'); + } + + return await stepContext.endDialog(); + } + + async getFacebookUserData(accessToken) { + try { + const { data } = await axios({ + url: 'https://graph.facebook.com/v2.6/me', + method: 'get', + params: { + fields: ['name', 'picture'].join(','), + access_token: accessToken + } + }); + return data; + } catch (error) { + console.error('Error fetching Facebook user data:', error.message); + throw error; + } + } +} + +exports.SimpleFacebookAuthDialog = SimpleFacebookAuthDialog; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/ssoOauthPrompt.js b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/ssoOauthPrompt.js new file mode 100644 index 0000000000..7fd0aba14e --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/dialogs/ssoOauthPrompt.js @@ -0,0 +1,58 @@ +const { OAuthPrompt } = require('botbuilder-dialogs'); +const { StatusCodes, ActivityTypes } = require('botbuilder'); + +/** + * Response body returned for a token exchange invoke activity. + */ +class TokenExchangeInvokeResponse { + constructor(id, connectionName, failureDetail) { + this.id = id; + this.connectionName = connectionName; + this.failureDetail = failureDetail; + } +} + +class SsoOAuthPrompt extends OAuthPrompt { + async continueDialog(dialogContext) { + // If the token was successfully exchanged already, it should be cached in TurnState along with the TokenExchangeInvokeRequest + const cachedTokenResponse = dialogContext.context.turnState.tokenResponse; + + if (cachedTokenResponse) { + const tokenExchangeRequest = dialogContext.context.turnState.tokenExchangeInvokeRequest; + if (!tokenExchangeRequest) { + throw new Error('TokenResponse is present in TurnState, but TokenExchangeInvokeRequest is missing.'); + } + + // PromptRecognizerResult + let result = {}; + + // TokenExchangeInvokeResponse + const exchangeResponse = new TokenExchangeInvokeResponse(tokenExchangeRequest.id, this.settings.connectionName, this.failureDetail); + + await dialogContext.context.sendActivity( + { + type: ActivityTypes.InvokeResponse, + value: + { + status: StatusCodes.OK, + body: exchangeResponse + } + }); + + result.succeeded = true; + // TokenResponse + result.value = + { + channelId: cachedTokenResponse.channelId, + connectionName: this.settings.connectionName, + token: cachedTokenResponse.token + }; + + return await dialogContext.endDialog(result.value); + } + + return await super.continueDialog(dialogContext); + } +} + +exports.SsoOAuthPrompt = SsoOAuthPrompt; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/index.js b/samples/TeamsSDK/Archived/app-auth/nodejs/index.js new file mode 100644 index 0000000000..44904dc2ec --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/index.js @@ -0,0 +1,190 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// index.js is used to setup and configure your bot + +// Import required packages +const path = require('path'); +const express = require('express'); +const cors = require('cors'); +const { SimpleGraphClient } = require('./simpleGraphClient'); +const msal = require('@azure/msal-node'); +const axios = require('axios') +const jwt = require('jsonwebtoken'); + +// Read botFilePath and botFileSecret from .env file. +const ENV_FILE = path.join(__dirname, '.env'); +require('dotenv').config({ path: ENV_FILE }); +const PORT = process.env.PORT || 3978; +const server = express(); +let multer = require('multer'); +let upload = multer({ storage: multer.memoryStorage() }); + +server.use(cors()); +server.use(express.json()); +server.use(express.urlencoded({ + extended: true +})); +server.engine('html', require('ejs').renderFile); +server.set('view engine', 'ejs'); +server.set('views', __dirname); + +// Import required bot services. +// See https://aka.ms/bot-services to learn more about the different parts of a bot. +const { CloudAdapter, + ConfigurationServiceClientCredentialFactory, + createBotFrameworkAuthenticationFromConfiguration, BotFrameworkAdapter, ConversationState, MemoryStorage, UserState } = require('botbuilder'); +const { TeamsBot } = require('./bots/teamsBot'); +const { MainDialog } = require('./dialogs/mainDialog'); + +const credentialsFactory = new ConfigurationServiceClientCredentialFactory({ + MicrosoftAppId: process.env.MicrosoftAppId, + MicrosoftAppPassword: process.env.MicrosoftAppPassword, + MicrosoftAppType: process.env.AppType, + MicrosoftAppTenantId: process.env.TenantId +}); + +const botFrameworkAuthentication = createBotFrameworkAuthenticationFromConfiguration(null, credentialsFactory); + +// Create adapter. +// See https://aka.ms/about-bot-adapter to learn more about adapters. +const adapter = new CloudAdapter(botFrameworkAuthentication); + +adapter.onTurnError = async (context, error) => { + // This check writes out errors to console log .vs. app insights. + // NOTE: In production environment, you should consider logging this to Azure + // application insights. See https://aka.ms/bottelemetry for telemetry + // configuration instructions. + console.error(`\n [onTurnError] unhandled error: ${error}`); + + // Send a trace activity, which will be displayed in Bot Framework Emulator + await context.sendTraceActivity( + 'OnTurnError Trace', + `${error}`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); + + // Uncomment below commented line for local debugging. + // await context.sendActivity(`Sorry, it looks like something went wrong. Exception Caught: ${error}`); + + // Note: Since this Messaging Extension does not have the messageTeamMembers permission + // in the manifest, the bot will not be allowed to message users. +}; + +// Define the state store for your bot. +// See https://aka.ms/about-bot-state to learn more about using MemoryStorage. +// A bot requires a state storage system to persist the dialog and user state between messages. +const memoryStorage = new MemoryStorage(); + +// Create conversation and user state with in-memory storage provider. +const conversationState = new ConversationState(memoryStorage); +const userState = new UserState(memoryStorage); + +// Create the main dialog. +const dialog = new MainDialog(); +// Create the bot that will handle incoming messages. +const bot = new TeamsBot(conversationState, userState, dialog); + +// Create HTTP server. +server.listen(PORT, () => { + console.log(`Server listening on http://localhost:${PORT}`); +}); + +// Endpoint to fetch Auth tab page +server.get('/AuthTab', (req, res) => { + const clientId = process.env.FaceBookAppId; + res.render('./views/AuthTab', { clientId: clientId }); +}); + +// Auth flow start - initiates AAD authentication +server.get('/auth-start', (req, res) => { + const clientId = process.env.MicrosoftAppId; + res.render('./views/auth-start', { clientId: JSON.stringify(clientId) }); +}); + +// Auth flow completion - returns authentication results +server.get('/auth-end', (req, res) => { + const clientId = process.env.MicrosoftAppId; + res.render('./views/auth-end', { clientId: JSON.stringify(clientId) }); +}); + +// Silent authentication tab +server.get('/silent-tab', (req, res) => { + const clientId = process.env.MicrosoftAppId; + res.render('./views/silent-tab', { clientId: JSON.stringify(clientId) }); +}); + +// Silent auth flow start +server.get('/silent-start', (req, res) => { + const clientId = process.env.MicrosoftAppId; + res.render('./views/silent-start', { clientId: JSON.stringify(clientId) }); +}); + +// Silent auth flow completion +server.get('/silent-end', (req, res) => { + const clientId = process.env.MicrosoftAppId; + res.render('./views/silent-end', { clientId: JSON.stringify(clientId) }); +}); + +// Listen for incoming requests. +server.post('/api/messages', async (req, res) => { + // Route received a request to adapter for processing + await adapter.process(req, res, (context) => bot.run(context)); +}); + +// On-behalf-of token exchange +server.post('/getProfileOnBehalfOf', async function (req, res) { + try { + const tid = process.env.TenantId; + const token = req.body.idToken; + const scopes = ["https://graph.microsoft.com/User.Read", "openid"]; + + // Creating MSAL client + const msalClient = new msal.ConfidentialClientApplication({ + auth: { + clientId: process.env.MicrosoftAppId, + clientSecret: process.env.MicrosoftAppPassword + } + }); + + const result = await msalClient.acquireTokenOnBehalfOf({ + authority: `https://login.microsoftonline.com/${tid}`, + oboAssertion: token, + scopes: scopes, + skipCache: true + }); + + const client = new SimpleGraphClient(result.accessToken); + const myDetails = await client.getMeAsync(); + res.json(myDetails); + } catch (error) { + console.error('Error in /getProfileOnBehalfOf:', error); + res.status(500).json({ error: error.message || 'Failed to get profile' }); + } +}); + +// Listen for decoded token endpoint +server.post('/decodedToken', async (req, res) => { + try { + const idToken = req.body.idToken; + const decodedToken = jwt.decode(idToken, { complete: true }); + res.json(decodedToken.payload); + } catch (error) { + console.error('Error in /decodedToken:', error); + res.status(400).json({ error: error.message || 'Failed to decode token' }); + } +}); + +// Listen for user details endpoint +server.post('/GetUserDetails', async (req, res) => { + try { + const accessToken = req.body.accessToken; + const client = new SimpleGraphClient(accessToken); + const myDetails = await client.getMeAsync(); + res.json(myDetails); + } catch (error) { + console.error('Error in /GetUserDetails:', error); + res.status(500).json({ error: error.message || 'Failed to get user details' }); + } +}); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/package-lock.json b/samples/TeamsSDK/Archived/app-auth/nodejs/package-lock.json new file mode 100644 index 0000000000..fb5aa91ec8 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/package-lock.json @@ -0,0 +1,6088 @@ +{ + "name": "teams-bot", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "teams-bot", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@azure/msal-node": "^1.6.0", + "@microsoft/microsoft-graph-client": "^3.0.4", + "axios": "^0.21.4", + "body-parser": "^1.19.1", + "botbuilder": "^4.18.0", + "botbuilder-dialogs": "^4.18.0", + "cors": "^2.8.5", + "dotenv": "^8.6.0", + "ejs": "^3.1.6", + "express": "^4.17.2", + "html-entities": "^2.3.2", + "isomorphic-fetch": "^3.0.0", + "jsonwebtoken": "^9.0.2", + "multer": "^1.4.4", + "restify": "~8.5.1" + }, + "devDependencies": { + "esbuild": "^0.18.1", + "eslint": "^7.32.0", + "eslint-config-standard": "^14.1.1", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.3.1", + "eslint-plugin-standard": "^4.0.1", + "nodemon": "^2.0.15" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@azure/abort-controller": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.5.0.tgz", + "integrity": "sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-util": "^1.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.7.3.tgz", + "integrity": "sha512-kleJ1iUTxcO32Y06dH9Pfi9K4U+Tlb111WXEnbt7R/ne+NLRwppZiTGJuTD5VVoxTMK5NTbEtm5t2vcdNCFe2g==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.12.1.tgz", + "integrity": "sha512-SsyWQ+T5MFQRX+M8H/66AlaI6HyCbQStGfFngx2fuiW+vKI2DkhtOvbYodPyf9fOe/ARLWWc3ohX54lQ5Kmaog==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.3.0", + "@azure/logger": "^1.0.0", + "form-data": "^4.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.4.0.tgz", + "integrity": "sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-2.1.0.tgz", + "integrity": "sha512-BPDz1sK7Ul9t0l9YKLEa8PHqWU4iCfhGJ+ELJl6c8CP3TpJt2urNCbm0ZHsthmxRsYoMPbz2Dvzj30zXZVmAFw==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.4.0", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^2.26.0", + "@azure/msal-common": "^7.0.0", + "@azure/msal-node": "^1.10.0", + "events": "^3.0.0", + "jws": "^4.0.0", + "open": "^8.0.0", + "stoppable": "^1.1.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/msal-common": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-7.6.0.tgz", + "integrity": "sha512-XqfbglUTVLdkHQ8F9UQJtKseRr3sSnr9ysboxtoswvaMVaEfvyLtMoHv9XdKUfOc0qKGzNgRFd9yRjIWVepl6Q==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz", + "integrity": "sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/ms-rest-js": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.7.0.tgz", + "integrity": "sha512-ngbzWbqF+NmztDOpLBVDxYM+XLcUj7nKhxGbSU9WtIsXfRB//cf2ZbAG5HkOrhU9/wd/ORRB6lM/d69RKVjiyA==", + "dependencies": { + "@azure/core-auth": "^1.1.4", + "abort-controller": "^3.0.0", + "form-data": "^2.5.0", + "node-fetch": "^2.6.7", + "tslib": "^1.10.0", + "tunnel": "0.0.6", + "uuid": "^8.3.2", + "xml2js": "^0.5.0" + } + }, + "node_modules/@azure/ms-rest-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@azure/msal-browser": { + "version": "2.38.2", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-2.38.2.tgz", + "integrity": "sha512-71BeIn2we6LIgMplwCSaMq5zAwmalyJR3jFcVOZxNVfQ1saBRwOD+P77nLs5vrRCedVKTq8RMFhIOdpMLNno0A==", + "dependencies": { + "@azure/msal-common": "13.3.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-13.3.0.tgz", + "integrity": "sha512-/VFWTicjcJbrGp3yQP7A24xU95NiDMe23vxIU1U6qdRPFsprMDNUohMudclnd+WSHE4/McqkZs/nUU3sAKkVjg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.18.3.tgz", + "integrity": "sha512-lI1OsxNbS/gxRD4548Wyj22Dk8kS7eGMwD9GlBZvQmFV8FJUXoXySL1BiNzDsHUE96/DS/DHmA+F73p1Dkcktg==", + "dependencies": { + "@azure/msal-common": "13.3.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": "10 || 12 || 14 || 16 || 18" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", + "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/runtime": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@microsoft/microsoft-graph-client": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@microsoft/microsoft-graph-client/-/microsoft-graph-client-3.0.6.tgz", + "integrity": "sha512-corwIFZ+yzOguEWfzhWycOBqekBzaTH0ymf060D0ONdloICcGfNVNv4LIrhbNUeB3jxsotnTY931crPDTqKM0g==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependenciesMeta": { + "@azure/identity": { + "optional": true + }, + "@azure/msal-browser": { + "optional": true + }, + "buffer": { + "optional": true + }, + "stream-browserify": { + "optional": true + } + } + }, + "node_modules/@microsoft/recognizers-text": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text/-/recognizers-text-1.1.4.tgz", + "integrity": "sha512-hlSVXcaX5i8JcjuUJpVxmy2Z/GxvFXarF0KVySCFop57wNEnrLWMHe4I4DjP866G19VyIKRw+vPA32pkGhZgTg==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@microsoft/recognizers-text-choice": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-choice/-/recognizers-text-choice-1.1.4.tgz", + "integrity": "sha512-4CddwFe4RVhZeJgW65ocBrEdeukBMghK8pgI0K0Qy2eA5ysPZQpeZ7BGSDz5QMQei5LPY+QaAQ3CHU+ORHoO7A==", + "dependencies": { + "@microsoft/recognizers-text": "~1.1.4", + "grapheme-splitter": "^1.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@microsoft/recognizers-text-date-time": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-date-time/-/recognizers-text-date-time-1.1.4.tgz", + "integrity": "sha512-leMnjN+KYNwNvRD5T4G0ORUzkjlek/BBZDvQIjAujtyrd/pkViUnuouWIPkFT/dbSOxXML8et54CSk2KfHiWIA==", + "dependencies": { + "@microsoft/recognizers-text": "~1.1.4", + "@microsoft/recognizers-text-number": "~1.1.4", + "@microsoft/recognizers-text-number-with-unit": "~1.1.4", + "lodash.isequal": "^4.5.0", + "lodash.tonumber": "^4.0.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@microsoft/recognizers-text-number": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-number/-/recognizers-text-number-1.1.4.tgz", + "integrity": "sha512-6EmlR+HR+eJBIX7sQby1vs6LJB64wxLowHaGpIU9OCXFvZ5Nb0QT8qh10rC40v3Mtrz4DpScXfSXr9tWkIO5MQ==", + "dependencies": { + "@microsoft/recognizers-text": "~1.1.4", + "bignumber.js": "^7.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.sortby": "^4.7.0", + "lodash.trimend": "^4.5.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@microsoft/recognizers-text-number-with-unit": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-number-with-unit/-/recognizers-text-number-with-unit-1.1.4.tgz", + "integrity": "sha512-zl+CfmfWK0x/x+iSgaBAevKTYO0F4+z7SYHAHztaaaGuX8FERw2jmUjSgVetm5KA3EveyCx0XYGU1mRNY8p7Eg==", + "dependencies": { + "@microsoft/recognizers-text": "~1.1.4", + "@microsoft/recognizers-text-number": "~1.1.4", + "lodash.escaperegexp": "^4.1.2", + "lodash.last": "^3.0.0", + "lodash.max": "^4.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@microsoft/recognizers-text-sequence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-sequence/-/recognizers-text-sequence-1.1.4.tgz", + "integrity": "sha512-rb5j8/aE7HSOdIxaVfCGFrj0wWPpSq0CuykFg/A/iJNPP+FnAU71bgP5HexrwQcpCsDinauisX7u0DKIChrHRA==", + "dependencies": { + "@microsoft/recognizers-text": "~1.1.4", + "grapheme-splitter": "^1.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@microsoft/recognizers-text-suite": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-suite/-/recognizers-text-suite-1.1.4.tgz", + "integrity": "sha512-hNIaR4M2G0nNeI9WZxt9C0KYh/1vhjeKzX5Ds8XDdT0pxF7zwCSo19WNcPjrVK6aCOeZTw/ULofsAjdu9gSkcA==", + "dependencies": { + "@microsoft/recognizers-text": "~1.1.4", + "@microsoft/recognizers-text-choice": "~1.1.4", + "@microsoft/recognizers-text-date-time": "~1.1.4", + "@microsoft/recognizers-text-number": "~1.1.4", + "@microsoft/recognizers-text-number-with-unit": "~1.1.4", + "@microsoft/recognizers-text-sequence": "~1.1.4" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@netflix/nerror": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@netflix/nerror/-/nerror-1.1.3.tgz", + "integrity": "sha512-b+MGNyP9/LXkapreJzNUzcvuzZslj/RGgdVVJ16P2wSlYatfLycPObImqVJSmNAdyeShvNeM/pl3sVZsObFueg==", + "dependencies": { + "assert-plus": "^1.0.0", + "extsprintf": "^1.4.0", + "lodash": "^4.17.15" + } + }, + "node_modules/@netflix/nerror/node_modules/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "node_modules/@types/ws": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", + "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/adal-node": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.2.3.tgz", + "integrity": "sha512-gMKr8RuYEYvsj7jyfCv/4BfKToQThz20SP71N3AtFn3ia3yAR8Qt2T3aVQhuJzunWs2b38ZsQV0qsZPdwZr7VQ==", + "dependencies": { + "@xmldom/xmldom": "^0.7.0", + "async": "^2.6.3", + "axios": "^0.21.1", + "date-utils": "*", + "jws": "3.x.x", + "underscore": ">= 1.3.1", + "uuid": "^3.1.0", + "xpath.js": "~1.1.0" + }, + "engines": { + "node": ">= 0.6.15" + } + }, + "node_modules/adal-node/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/adal-node/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/adal-node/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/botbuilder": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.20.0.tgz", + "integrity": "sha512-YfJgAcUyjKZQP3XzXqBoQmj8S5NoIGmqX5g/5coLlsNEaFLAbQXmOEBddN+ww4gz49S246MDspoGaqtweTu/pw==", + "dependencies": { + "@azure/ms-rest-js": "^2.6.1", + "axios": "^0.25.0", + "botbuilder-core": "4.20.0", + "botbuilder-stdlib": "4.20.0-internal", + "botframework-connector": "4.20.0", + "botframework-schema": "4.20.0", + "botframework-streaming": "4.20.0", + "dayjs": "^1.10.3", + "filenamify": "^4.1.0", + "fs-extra": "^7.0.1", + "htmlparser2": "^6.0.1", + "uuid": "^8.3.2", + "zod": "~1.11.17" + } + }, + "node_modules/botbuilder-core": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.20.0.tgz", + "integrity": "sha512-UxJF31nkIuiVHerPhtJKAyzfIbdG7sTgsS4bXvCqkQvxaY+60p6mIwuxOZZQf3AIOPIxCysMKAmhfoaFyTc+Uw==", + "dependencies": { + "botbuilder-dialogs-adaptive-runtime-core": "4.20.0-preview", + "botbuilder-stdlib": "4.20.0-internal", + "botframework-connector": "4.20.0", + "botframework-schema": "4.20.0", + "uuid": "^8.3.2", + "zod": "~1.11.17" + } + }, + "node_modules/botbuilder-dialogs": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs/-/botbuilder-dialogs-4.20.0.tgz", + "integrity": "sha512-ErxiUFfrTCbgK/6oNE06UG9ZKSd7+3rEiaw+m5A98D3nmUNNc94v2y7mtYKsHOWrQKf+QYobuY3zpMQr8+ZoKg==", + "dependencies": { + "@microsoft/recognizers-text-choice": "1.1.4", + "@microsoft/recognizers-text-date-time": "1.1.4", + "@microsoft/recognizers-text-number": "1.1.4", + "@microsoft/recognizers-text-suite": "1.1.4", + "botbuilder-core": "4.20.0", + "botbuilder-dialogs-adaptive-runtime-core": "4.20.0-preview", + "botframework-connector": "4.20.0", + "globalize": "^1.4.2", + "lodash": "^4.17.21", + "uuid": "^8.3.2", + "zod": "~1.11.17" + } + }, + "node_modules/botbuilder-dialogs-adaptive-runtime-core": { + "version": "4.20.0-preview", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs-adaptive-runtime-core/-/botbuilder-dialogs-adaptive-runtime-core-4.20.0-preview.tgz", + "integrity": "sha512-P7ezlaFsv5xPHGRYHHsb5UgvkbyxCj0OTHpIfIRCPYLWaKYrzcLI46zzIj76XImn/aYLUsKU7Xg/qw13l9sPKA==", + "dependencies": { + "dependency-graph": "^0.10.0" + } + }, + "node_modules/botbuilder-stdlib": { + "version": "4.20.0-internal", + "resolved": "https://registry.npmjs.org/botbuilder-stdlib/-/botbuilder-stdlib-4.20.0-internal.tgz", + "integrity": "sha512-WtMQkl1PHWX+GkdqufDC4nv+JZTUitvjLpdh56piQaakxozK6FQqQzJFdMvUdOMgfJ/mQMPmtojLhfbQOKYvfA==" + }, + "node_modules/botbuilder/node_modules/axios": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "dependencies": { + "follow-redirects": "^1.14.7" + } + }, + "node_modules/botframework-connector": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/botframework-connector/-/botframework-connector-4.20.0.tgz", + "integrity": "sha512-3mP67NHOGdLeODxuXNchK9gzzTafzLdBGZDSWkJDRvIPORbfoxvA/kXsWU2USwMXBnu/M5YeDZn/eUPjDu1nvw==", + "dependencies": { + "@azure/identity": "^2.0.4", + "@azure/ms-rest-js": "^2.6.1", + "adal-node": "0.2.3", + "axios": "^0.25.0", + "base64url": "^3.0.0", + "botbuilder-stdlib": "4.20.0-internal", + "botframework-schema": "4.20.0", + "cross-fetch": "^3.0.5", + "jsonwebtoken": "^9.0.0", + "rsa-pem-from-mod-exp": "^0.8.4", + "zod": "~1.11.17" + } + }, + "node_modules/botframework-connector/node_modules/axios": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "dependencies": { + "follow-redirects": "^1.14.7" + } + }, + "node_modules/botframework-schema": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.20.0.tgz", + "integrity": "sha512-Tda488691XFlkBKdMLdlGWRI8IebLprxqQf57LpuRQHqK2ttbvmfwjFiW5V3VcTBBz1SVzMhwJBAWVDG+MexLA==", + "dependencies": { + "uuid": "^8.3.2", + "zod": "~1.11.17" + } + }, + "node_modules/botframework-streaming": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/botframework-streaming/-/botframework-streaming-4.20.0.tgz", + "integrity": "sha512-yPH9+BYJ9RPb76OcARjls3QHfwRejNQz9RxR9YXt6OX0nMfP+sdMfE8BYTDqvBiIXLivbPi+pJG334PwskfohA==", + "dependencies": { + "@types/node": "^10.17.27", + "@types/ws": "^6.0.3", + "uuid": "^8.3.2", + "ws": "^7.1.2" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/bunyan": { + "version": "1.8.15", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", + "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", + "engines": [ + "node >=0.10.0" + ], + "bin": { + "bunyan": "bin/bunyan" + }, + "optionalDependencies": { + "dtrace-provider": "~0.8", + "moment": "^2.19.3", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, + "node_modules/busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==", + "dependencies": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cldrjs": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/cldrjs/-/cldrjs-0.5.5.tgz", + "integrity": "sha512-KDwzwbmLIPfCgd8JERVDpQKrUUM1U4KpFJJg2IROv89rF172lLufoJnqJ/Wea6fXL5bO6WjuLMzY8V52UWPvkA==" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csv": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/csv/-/csv-5.5.3.tgz", + "integrity": "sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==", + "dependencies": { + "csv-generate": "^3.4.3", + "csv-parse": "^4.16.3", + "csv-stringify": "^5.6.5", + "stream-transform": "^2.1.3" + }, + "engines": { + "node": ">= 0.1.90" + } + }, + "node_modules/csv-generate": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-3.4.3.tgz", + "integrity": "sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==" + }, + "node_modules/csv-parse": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", + "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==" + }, + "node_modules/csv-stringify": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", + "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/date-utils": { + "version": "1.2.21", + "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", + "integrity": "sha512-wJMBjqlwXR0Iv0wUo/lFbhSQ7MmG1hl36iuxuE91kW+5b5sWbase73manEqNH9sOLFAMG83B4ffNKq9/Iq0FVA==", + "engines": { + "node": ">0.4.0" + } + }, + "node_modules/dayjs": { + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", + "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.10.0.tgz", + "integrity": "sha512-c9amUgpgxSi1bE5/sbLwcs5diLD0ygCQYmhfM5H1s5VH1mCsYkcmAL3CcNdv4kdSw6JuMoHeDGzLgj/gAXdWVg==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==", + "dependencies": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/dtrace-provider": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "nan": "^2.14.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-regexp-component": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz", + "integrity": "sha512-B0yxafj1D1ZTNEHkFoQxz4iboZSfaZHhaNhIug7GcUCL4ZUrVSJZTmWUAkPOFaYDfi3RNT9XM082TuGE6jpmiQ==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-standard": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", + "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", + "dev": true, + "peerDependencies": { + "eslint": ">=6.2.2", + "eslint-plugin-import": ">=2.18.0", + "eslint-plugin-node": ">=9.1.0", + "eslint-plugin-promise": ">=4.2.1", + "eslint-plugin-standard": ">=4.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "has": "^1.0.3", + "is-core-module": "^2.13.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", + "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-standard": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", + "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ewma": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ewma/-/ewma-2.0.1.tgz", + "integrity": "sha512-MYYK17A76cuuyvkR7MnqLW4iFYPEi5Isl2qb8rXiWpLiwFS9dxW/rncuNnjjgSENuVqZQkIuR4+DChVL4g1lnw==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-my-way": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-2.2.5.tgz", + "integrity": "sha512-GjRZZlGcGmTh9t+6Xrj5K0YprpoAFCAiCPgmAH9Kb09O4oX6hYuckDfnDipYj+Q7B1GtYWSzDI5HEecNYscLQg==", + "dependencies": { + "fast-decode-uri-component": "^1.0.0", + "safe-regex2": "^2.0.0", + "semver-store": "^0.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/flat-cache": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "dev": true, + "dependencies": { + "flatted": "^3.2.7", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globalize": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/globalize/-/globalize-1.7.0.tgz", + "integrity": "sha512-faR46vTIbFCeAemyuc9E6/d7Wrx9k2ae2L60UhakztFg6VuE42gENVJNuPFtt7Sdjrk9m2w8+py7Jj+JTNy59w==", + "dependencies": { + "cldrjs": "^0.5.4" + } + }, + "node_modules/globals": { + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "devOptional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.last": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash.last/-/lodash.last-3.0.0.tgz", + "integrity": "sha512-14mq7rSkCxG4XMy9lF2FbIOqqgF0aH0NfPuQ3LPR3vIh0kHnUvIYP70dqa1Hf47zyXfQ8FzAg0MYOQeSuE1R7A==" + }, + "node_modules/lodash.max": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.max/-/lodash.max-4.0.1.tgz", + "integrity": "sha512-iykTDTb7PK33HSQmKy34zv+hh4WEu7WonJPXQcgODzUbbtradtNs8RsD/GI7XV++60KaKR1xhW56N4ISqHesfQ==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/lodash.tonumber": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz", + "integrity": "sha512-SY0SwuPOHRwKcCNTdsntPYb+Zddz5mDUIVFABzRMqmAiL41pMeyoQFGxYAw5zdc9NnH4pbJqiqqp5ckfxa+zSA==" + }, + "node_modules/lodash.trimend": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.trimend/-/lodash.trimend-4.5.1.tgz", + "integrity": "sha512-lsD+k73XztDsMBKPKvzHXRKFNMohTjoTKIIo4ADLn5dA65LZ1BqlAvSXhR2rPEC3BgAUQnzMnorqDtqn2z4IHA==" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mixme": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/mixme/-/mixme-0.5.9.tgz", + "integrity": "sha512-VC5fg6ySUscaWUpI4gxCBTQMH2RdUpNrk+MsbpCYtIvf9SBJdiUey4qE7BXviJsJR4nDQxCZ+3yaYNW3guz/Pw==", + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/multer": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz", + "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==", + "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "optional": true, + "dependencies": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/mv/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "optional": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mv/node_modules/rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "optional": true, + "dependencies": { + "glob": "^6.0.1" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "optional": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "optional": true, + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemon": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidusage": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "dependencies": { + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restify": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/restify/-/restify-8.5.1.tgz", + "integrity": "sha512-g+xciouvSDg2vmCZuCinztt2mvQynCfnGIE1y8vMjfcUrjBo4AP8DJ9RNheu0mdGpiI0cMoCHYA/GdZ3TEW+DA==", + "dependencies": { + "assert-plus": "^1.0.0", + "bunyan": "^1.8.12", + "csv": "^5.1.1", + "escape-regexp-component": "^1.0.2", + "ewma": "^2.0.1", + "find-my-way": "^2.0.1", + "formidable": "^1.2.1", + "http-signature": "^1.2.0", + "lodash": "^4.17.11", + "lru-cache": "^5.1.1", + "mime": "^2.4.3", + "negotiator": "^0.6.2", + "once": "^1.4.0", + "pidusage": "^2.0.17", + "qs": "^6.7.0", + "restify-errors": "^8.0.2", + "semver": "^6.1.1", + "send": "^0.16.2", + "spdy": "^4.0.0", + "uuid": "^3.3.2", + "vasync": "^2.2.0" + }, + "bin": { + "report-latency": "bin/report-latency" + }, + "engines": { + "node": ">=8.3.0" + }, + "optionalDependencies": { + "dtrace-provider": "^0.8.1" + } + }, + "node_modules/restify-errors": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/restify-errors/-/restify-errors-8.0.2.tgz", + "integrity": "sha512-UsXUVQo7M26xoQzeUcZQ0+H8L2t9DGzrXcAgR3WB/1vnbl+UdI4tZ1PqYsN+sS5WnqHKZ0Xy9w0CKf83bbrwYA==", + "dependencies": { + "@netflix/nerror": "^1.0.0", + "assert-plus": "^1.0.0", + "lodash": "^4.17.15" + }, + "optionalDependencies": { + "safe-json-stringify": "^1.0.4" + } + }, + "node_modules/restify/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/restify/node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" + }, + "node_modules/restify/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/restify/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/restify/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/restify/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/restify/node_modules/send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/restify/node_modules/send/node_modules/mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "bin": { + "mime": "cli.js" + } + }, + "node_modules/restify/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/restify/node_modules/statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/restify/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/ret": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rsa-pem-from-mod-exp": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.6.tgz", + "integrity": "sha512-c5ouQkOvGHF1qomUUDJGFcXsomeSO2gbEs6hVhMAtlkE1CuaZase/WzoaKFG/EZQuNmq6pw/EMCeEnDvOgCJYQ==" + }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-json-stringify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "optional": true + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz", + "integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==", + "dependencies": { + "ret": "~0.2.0" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-store": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/semver-store/-/semver-store-0.3.0.tgz", + "integrity": "sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg==" + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy-transport/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/spdy-transport/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/spdy-transport/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/spdy/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/stream-transform": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-2.1.3.tgz", + "integrity": "sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==", + "dependencies": { + "mixme": "^0.5.1" + } + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vasync": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-2.2.1.tgz", + "integrity": "sha512-Hq72JaTpcTFdWiNA4Y22Amej2GH3BFmBaKPPlDZ4/oC8HNn2ISHLkFrJU4Ds8R3jcUi7oo5Y9jcMHKjES+N9wQ==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "verror": "1.10.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-fetch": { + "version": "3.6.18", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.18.tgz", + "integrity": "sha512-ltN7j66EneWn5TFDO4L9inYC1D+Czsxlrw2SalgjMmEMkLfA5SIZxEFdE6QtHFiiM6Q7WL32c7AkI3w6yxM84Q==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xpath.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", + "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/zod": { + "version": "1.11.17", + "resolved": "https://registry.npmjs.org/zod/-/zod-1.11.17.tgz", + "integrity": "sha512-UzIwO92D0dSFwIRyyqAfRXICITLjF0IP8tRbEK/un7adirMssWZx8xF/1hZNE7t61knWZ+lhEuUvxlu2MO8qqA==" + } + } +} diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/package.json b/samples/TeamsSDK/Archived/app-auth/nodejs/package.json new file mode 100644 index 0000000000..e6571d9e5d --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/package.json @@ -0,0 +1,44 @@ +{ + "name": "teams-bot", + "version": "1.0.0", + "description": "Bot Builder v4 Bot Teams sample", + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "build": "node build.js", + "lint": "eslint .", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples.git" + }, + "dependencies": { + "@azure/msal-node": "^2.5.0", + "@microsoft/microsoft-graph-client": "^3.0.6", + "axios": "^1.6.0", + "botbuilder": "^4.22.0", + "botbuilder-dialogs": "^4.22.0", + "cors": "^2.8.5", + "dotenv": "^16.3.1", + "ejs": "^3.1.8", + "express": "^4.18.2", + "html-entities": "^2.4.0", + "jsonwebtoken": "^9.0.0", + "multer": "^1.4.4", + "restify": "^8.5.1" + }, + "devDependencies": { + "esbuild": "^0.19.8", + "eslint": "^8.53.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-standard": "^5.0.0", + "nodemon": "^3.0.2" + } +} diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/simpleGraphClient.js b/samples/TeamsSDK/Archived/app-auth/nodejs/simpleGraphClient.js new file mode 100644 index 0000000000..432271e76e --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/simpleGraphClient.js @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { Client } = require('@microsoft/microsoft-graph-client'); + +/** +* This class is a wrapper for the Microsoft Graph API. +* See: https://developer.microsoft.com/en-us/graph for more information. +*/ +class SimpleGraphClient { + constructor(token) { + if (!token || !token.trim()) { + throw new Error('SimpleGraphClient: Invalid token received.'); + } + + this._token = token; + + // Get an Authenticated Microsoft Graph client using the token issued to the user. + this.graphClient = Client.init({ + authProvider: (done) => { + done(null, this._token); // First parameter takes an error if you can't get an access token. + } + }); + } + + /** + * Collects information about the user in the bot. + */ + async getMeAsync() { + return await this.graphClient.api('/me').get(); + } + + async getUserPhoto() { + return await this.graphClient.api('/me/photo/$value').get(); + } + + /** + * Collects information about the SharePoint drive based on SharePoint id passed. + */ + async getDriveDetails(siteId) { + return await this.graphClient + .api('/sites/'+siteId+'/drives').version('beta') + .get().then((res) => { + return res; + }); + } + + /** + * Collects information about the documents stored in SharePoint drive. + */ + async getContentList(siteId, driveId) { + return await this.graphClient + .api('/sites/'+siteId+'/drives/'+driveId+'/root/children').version('beta') + .get().then((res) => { + return res; + }); + } + + /** + * This endpoint will upload the user's file to SharePoint drive. + */ + async uploadFile(siteId, driveId, stream, fileName) { + return await this.graphClient + .api('/sites/'+siteId+'/drives/'+driveId+'/root:/'+fileName+':/content').version('beta') + .put(stream).then((res) => { + return res; + }); + } +} + +exports.SimpleGraphClient = SimpleGraphClient; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/ssoOauthHelpler.js b/samples/TeamsSDK/Archived/app-auth/nodejs/ssoOauthHelpler.js new file mode 100644 index 0000000000..1433d83b64 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/ssoOauthHelpler.js @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { StatusCodes, ActivityTypes, tokenExchangeOperationName } = require('botbuilder'); + +class SsoOAuthHelpler { + constructor(oAuthConnectName, storage) { + this.oAuthConnectName = oAuthConnectName; + this.storage = storage; + } + + async shouldProcessTokenExchange(turnContext) { + if (turnContext.activity.name !== tokenExchangeOperationName) { + throw new Error("Only 'signin/tokenExchange' invoke activities can be processed by TokenExchangeHelper."); + } + + if (!await this.exchangedToken(turnContext)) { + return false; + } + + return true; + } + + async exchangedToken(turnContext) { + let tokenExchangeResponse = null; + const tokenExchangeRequest = turnContext.activity.value; + + try { + tokenExchangeResponse = await turnContext.adapter.exchangeToken( + turnContext, + tokenExchangeRequest.connectionName, + turnContext.activity.from.id, + { token: tokenExchangeRequest.token }); + + console.log('Token exchange successful'); + } catch (err) { + console.error('Token exchange failed:', err.message); + } + + if (!tokenExchangeResponse || !tokenExchangeResponse.token) { + await turnContext.sendActivity( + { + type: ActivityTypes.InvokeResponse, + value: { + status: StatusCodes.PRECONDITION_FAILED, + body: { + id: tokenExchangeRequest.id, + connectionName: tokenExchangeRequest.connectionName, + failureDetail: 'The bot is unable to exchange token. Proceed with regular login.' + } + } + }); + + return false; + } else { + turnContext.turnState.tokenExchangeInvokeRequest = tokenExchangeRequest; + turnContext.turnState.tokenResponse = tokenExchangeResponse; + } + + return true; + } + + getStorageKey(turnContext) { + if (!turnContext || !turnContext.activity || !turnContext.activity.conversation) { + throw new Error('Invalid context, cannot get storage key.'); + } + + const activity = turnContext.activity; + const channelId = activity.channelId; + const conversationId = activity.conversation.id; + + if (activity.type !== ActivityTypes.Invoke || activity.name !== tokenExchangeOperationName) { + throw new Error('TokenExchangeState can only be used with Invokes of signin/tokenExchange.'); + } + + const value = activity.value; + if (!value || !value.id) { + throw new Error('Invalid signin/tokenExchange. Missing activity.value.id.'); + } + + return `${channelId}/${conversationId}/${value.id}`; + } +} + +exports.SsoOAuthHelpler = SsoOAuthHelpler; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/views/AuthTab.ejs b/samples/TeamsSDK/Archived/app-auth/nodejs/views/AuthTab.ejs new file mode 100644 index 0000000000..86e3256db5 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/views/AuthTab.ejs @@ -0,0 +1,148 @@ + + + + SSO Authentication Sample + + + +

+ This sample shows the basics of an single sign-on authentication flow in a Microsoft Teams tab. +

+

+ The "Grant access to Microsoft Graph" button will appear only if additional consent is required. +

+ + + + + + + +

Claims from SSO access_token

+ + + + +

Profile from Microsoft Graph (via On-Behalf-Of flow)

+ + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/views/auth-end.ejs b/samples/TeamsSDK/Archived/app-auth/nodejs/views/auth-end.ejs new file mode 100644 index 0000000000..b62194e221 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/views/auth-end.ejs @@ -0,0 +1,36 @@ + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/views/auth-start.ejs b/samples/TeamsSDK/Archived/app-auth/nodejs/views/auth-start.ejs new file mode 100644 index 0000000000..f78840d352 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/views/auth-start.ejs @@ -0,0 +1,41 @@ + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-end.ejs b/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-end.ejs new file mode 100644 index 0000000000..59cc594ee8 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-end.ejs @@ -0,0 +1,39 @@ + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-start.ejs b/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-start.ejs new file mode 100644 index 0000000000..355db632b8 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-start.ejs @@ -0,0 +1,37 @@ + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-tab.ejs b/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-tab.ejs new file mode 100644 index 0000000000..660dad2ce2 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-auth/nodejs/views/silent-tab.ejs @@ -0,0 +1,269 @@ + + + + Silent Authentication Sample + + + +

+ This sample demonstrates silent authentication in a Microsoft Teams tab. +

+

+ The tab will try to get an id token for the user silently and show information about the user. + The "Login" button will appear only if silent authentication failed. +

+ + + + + + + +

Claims from id_token

+ + + + +

Profile from Microsoft Graph (via On-Behalf-Of flow)

+ + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams.sln b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams.sln new file mode 100644 index 0000000000..d24e477c05 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35004.147 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinkUnfurlingInShareToTeams", "LinkUnfurlingInShareToTeams\LinkUnfurlingInShareToTeams.csproj", "{BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}" +EndProject +Project("{A9E3F50B-275E-4AF7-ADCE-8BE12D41E305}") = "M365Agent", "M365Agent\M365Agent.ttkproj", "{86639D2C-3E4A-4D6F-BD6E-2AD567176C15}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{245935F0-8099-4BB8-94A5-B0FCF4035DC9}" + ProjectSection(SolutionItems) = preProject + LinkUnfurlingInShareToTeams.slnLaunch.user = LinkUnfurlingInShareToTeams.slnLaunch.user + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}.Release|Any CPU.Build.0 = Release|Any CPU + {86639D2C-3E4A-4D6F-BD6E-2AD567176C15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86639D2C-3E4A-4D6F-BD6E-2AD567176C15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86639D2C-3E4A-4D6F-BD6E-2AD567176C15}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {86639D2C-3E4A-4D6F-BD6E-2AD567176C15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86639D2C-3E4A-4D6F-BD6E-2AD567176C15}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4D7C6DCC-3A5C-42E6-B6E8-2E80E5342C91} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/.gitignore b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/.gitignore new file mode 100644 index 0000000000..7466c01f9c --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +appPackage/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/AdapterWithErrorHandler.cs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/AdapterWithErrorHandler.cs new file mode 100644 index 0000000000..3aeaff6245 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/AdapterWithErrorHandler.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System; +using System.Threading.Tasks; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Connector; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Schema; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using System.Net.Http; + +namespace LinkUnfurlingInShareToTeams +{ + public class AdapterWithErrorHandler : CloudAdapter + { + public AdapterWithErrorHandler(IConfiguration configuration, IHttpClientFactory httpClientFactory, ILogger logger) + : base(configuration, httpClientFactory, logger) + { + OnTurnError = async (turnContext, exception) => + { + // Log any leaked exception from the application. + logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}"); + + // Send a trace activity, which will be displayed in the Bot Framework Emulator + await SendTraceActivityAsync(turnContext, exception); + }; + } + + private static async Task SendTraceActivityAsync(ITurnContext turnContext, Exception exception) + { + // Only send a trace activity if we're talking to the Bot Framework Emulator + if (turnContext.Activity.ChannelId == Channels.Emulator) + { + Activity traceActivity = new Activity(ActivityTypes.Trace) + { + Label = "TurnError", + Name = "OnTurnError Trace", + Value = exception.Message, + ValueType = "https://www.botframework.com/schemas/error", + }; + + // Send a trace activity + await turnContext.SendActivityAsync(traceActivity); + } + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Bots/ActivityBot.cs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Bots/ActivityBot.cs new file mode 100644 index 0000000000..4c9ceb77a4 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Bots/ActivityBot.cs @@ -0,0 +1,116 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using AdaptiveCards; +using LinkUnfurlingInShareToTeams.Models; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Teams; +using Microsoft.Bot.Schema; +using Microsoft.Bot.Schema.Teams; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace LinkUnfurlingInShareToTeams.Bots +{ + public class ActivityBot : TeamsActivityHandler + { + private readonly string _applicationBaseUrl; + private readonly string _microsoftAppId; + + public ActivityBot(IConfiguration configuration) + { + _applicationBaseUrl = configuration["ApplicationBaseUrl"] ?? throw new NullReferenceException("ApplicationBaseUrl"); + _microsoftAppId= configuration["TeamsAppId"] ?? throw new NullReferenceException("TeamsAppId"); + } + + /// + /// Invoked when an app based link query activity is received from the connector. + /// + /// Context object containing information cached for a single turn of conversation with a user. + /// The invoke request body type for app-based link query + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// The Messaging Extension Response for the query. + protected async override Task OnTeamsAppBasedLinkQueryAsync(ITurnContext turnContext, AppBasedLinkQuery query, CancellationToken cancellationToken) + { + var preview = new MessagingExtensionAttachment( + contentType: HeroCard.ContentType, + contentUrl: null, + content: GetUnfurlCard()); + + return new MessagingExtensionResponse + { + ComposeExtension = new MessagingExtensionResult + { + Type = "result", + AttachmentLayout = AttachmentLayoutTypes.List, + Attachments = new List() { + new MessagingExtensionAttachment + { + ContentType = AdaptiveCard.ContentType, + Content = GetUnfurlCard(), + Preview = preview, + } + } + }, + }; + } + + /// + /// Invoked when link is unfurled. + /// Adaptive card for link unfurling. + private AdaptiveCard GetUnfurlCard() + { + AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion("1.2")) + { + Body = new List + { + new AdaptiveTextBlock + { + Text = "Analytics details:", + Size = AdaptiveTextSize.Default + }, + new AdaptiveImage() + { + Url = new Uri(_applicationBaseUrl+"/report.png") + } + }, + Actions = new List + { + new AdaptiveSubmitAction + { + Title = "View via card action", + Data = new AdaptiveCardAction + { + MsteamsCardAction = new CardAction + { + Type = "invoke", + Value = new TabInfoAction + { + Type = "tab/tabInfoAction", + TabInfo = new TabInfo + { + ContentUrl = $"{_applicationBaseUrl}/tab?openInTeams=true", + WebsiteUrl = $"{_applicationBaseUrl}/tab?openInTeams=false", + Name = "Stage view", + EntityId = "entityId" + } + } + }, + }, + }, + new AdaptiveOpenUrlAction + { + Title = "View via deeplink", + Url = new Uri($"https://teams.microsoft.com/l/entity/{_microsoftAppId}/tab?webUrl={_applicationBaseUrl}/tab?openInTeams=true"), + }, + }, + }; + + return card; + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Controllers/BotController.cs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Controllers/BotController.cs new file mode 100644 index 0000000000..a0d4961869 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Controllers/BotController.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Generated with Bot Builder V4 SDK Template for Visual Studio EchoBot v4.14.0 + +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using System.Threading.Tasks; + +namespace LinkUnfurlingInShareToTeams.Controllers +{ + // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot + // implementation at runtime. Multiple different IBot implementations running at different endpoints can be + // achieved by specifying a more specific type for the bot constructor argument. + [Route("api/messages")] + [ApiController] + public class BotController : ControllerBase + { + private readonly IBotFrameworkHttpAdapter Adapter; + private readonly IBot Bot; + + public BotController(IBotFrameworkHttpAdapter adapter, IBot bot) + { + Adapter = adapter; + Bot = bot; + } + + [HttpPost, HttpGet] + public async Task PostAsync() + { + // Delegate the processing of the HTTP POST to the adapter. + // The adapter will invoke the bot. + await Adapter.ProcessAsync(Request, Response, Bot); + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/1.Install.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/1.Install.png new file mode 100644 index 0000000000..b8778224ae Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/2.Tab.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/2.Tab.png new file mode 100644 index 0000000000..928411a094 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/2.Tab.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/3.ShareToTeams.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/3.ShareToTeams.png new file mode 100644 index 0000000000..9d2a3eba80 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/3.ShareToTeams.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/4.SharedSuccess.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/4.SharedSuccess.png new file mode 100644 index 0000000000..57253cfe72 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/4.SharedSuccess.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/5.InTeams.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/5.InTeams.png new file mode 100644 index 0000000000..acfcfe26d0 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/5.InTeams.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/6.ViewViaCard.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/6.ViewViaCard.png new file mode 100644 index 0000000000..029114100b Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/6.ViewViaCard.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/app-link-unfurling-stt.gif b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/app-link-unfurling-stt.gif new file mode 100644 index 0000000000..f17d0bc24c Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/app-link-unfurling-stt.gif differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/LinkUnfurlingInShareToTeams.csproj b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/LinkUnfurlingInShareToTeams.csproj new file mode 100644 index 0000000000..8c2a9b68ac --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/LinkUnfurlingInShareToTeams.csproj @@ -0,0 +1,26 @@ + + + + net10.0 + latest + enable + enable + + + + + + + + + + + Always + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/AdaptiveCardAction.cs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/AdaptiveCardAction.cs new file mode 100644 index 0000000000..f0d15c59d0 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/AdaptiveCardAction.cs @@ -0,0 +1,21 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +namespace LinkUnfurlingInShareToTeams.Models +{ + using Microsoft.Bot.Schema; + using Newtonsoft.Json; + + /// + /// Adaptive card action model class. + /// + public class AdaptiveCardAction + { + /// + /// Gets or sets Ms Teams card action. + /// + [JsonProperty("msteams")] + public CardAction? MsteamsCardAction { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/TabInfo.cs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/TabInfo.cs new file mode 100644 index 0000000000..7905d46c19 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/TabInfo.cs @@ -0,0 +1,38 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +namespace LinkUnfurlingInShareToTeams.Models +{ + using Newtonsoft.Json; + + /// + /// Tab info model class. + /// + public class TabInfo + { + /// + /// Gets or sets content url. + /// + [JsonProperty("contentUrl")] + public string? ContentUrl { get; set; } + + /// + /// Gets or sets website url. + /// + [JsonProperty("websiteUrl")] + public string? WebsiteUrl { get; set; } + + /// + /// Gets or sets name. + /// + [JsonProperty("name")] + public string? Name { get; set; } + + /// + /// Gets or sets entity id. + /// + [JsonProperty("entityId")] + public string? EntityId { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/TabInfoAction.cs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/TabInfoAction.cs new file mode 100644 index 0000000000..22aca57e33 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Models/TabInfoAction.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +namespace LinkUnfurlingInShareToTeams.Models +{ + using Newtonsoft.Json; + + /// + /// Tab info action model class. + /// + public class TabInfoAction + { + /// + /// Gets or sets type of tab. + /// + [JsonProperty("type")] + public string? Type { get; set; } + + /// + /// Gets or sets tab info. + /// + [JsonProperty("tabInfo")] + public TabInfo? TabInfo { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Pages/Tab.cshtml b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Pages/Tab.cshtml new file mode 100644 index 0000000000..c03259b53b --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Pages/Tab.cshtml @@ -0,0 +1,60 @@ +@page +@model LinkUnfurlingInShareToTeams.Pages.TabModel +@{ +} + + + + + + + + + + + +
+

Link unfurling in STT

+ + + +
+ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Pages/Tab.cshtml.cs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Pages/Tab.cshtml.cs new file mode 100644 index 0000000000..f091beb2bb --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Pages/Tab.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace LinkUnfurlingInShareToTeams.Pages +{ + public class TabModel : PageModel + { + public void OnGet() + { + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Program.cs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Program.cs new file mode 100644 index 0000000000..1dfc45fa0d --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Program.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using LinkUnfurlingInShareToTeams; +using LinkUnfurlingInShareToTeams.Bots; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers().AddNewtonsoftJson(); +builder.Services.AddRazorPages(); +builder.Services.AddHttpClient(); + +// Create the Bot Framework Adapter with error handling enabled. +builder.Services.AddSingleton(); + +// Create the storage we'll be using for User and Conversation state. +builder.Services.AddSingleton(); + +// Create the Conversation state. +builder.Services.AddSingleton(); + +// Create the bot as a transient. +builder.Services.AddTransient(); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +} + +app.UseDefaultFiles() + .UseStaticFiles() + .UseRouting() + .UseAuthorization(); + +app.MapControllers(); +app.MapRazorPages(); + +app.Run(); + diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Properties/launchSettings.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Properties/launchSettings.json new file mode 100644 index 0000000000..ff9d8fe153 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "Start Project": { + "commandName": "Project", + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7130;http://localhost:5130", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/appsettings.Development.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/appsettings.Development.json new file mode 100644 index 0000000000..b49abfc201 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } + } diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/appsettings.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/appsettings.json new file mode 100644 index 0000000000..c3fac2b19e --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/appsettings.json @@ -0,0 +1,8 @@ +{ + "MicrosoftAppType": "SingleTenant", + "MicrosoftAppId": "", + "MicrosoftAppPassword": "", + "MicrosoftAppTenantId": "", + "ApplicationBaseUrl": "", + "TeamsAppId": "" +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/css/tab.css b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/css/tab.css new file mode 100644 index 0000000000..74cb760204 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/css/tab.css @@ -0,0 +1,12 @@ +#tabheader { + margin-left: 38rem; +} + +#reportimg { + margin-left: 28rem; +} + +#stt-btn-teams, #stt-btn-custom { + margin-left: 40rem; + margin-top: 2rem; +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/default.htm b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/default.htm new file mode 100644 index 0000000000..59130f3371 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/default.htm @@ -0,0 +1,420 @@ + + + + + + + LinkUnfurlingShareToTeams + + + + + +
+
+
+
LinkUnfurlingShareToTeams
+
+
+
+
+
Your bot is ready!
+
You can test your bot in the Bot Framework Emulator
+ by connecting to http://localhost:3978/api/messages.
+ +
Visit Azure + Bot Service to register your bot and add it to
+ various channels. The bot's endpoint URL typically looks + like this:
+
https://your_bots_hostname/api/messages
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/report.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/report.png new file mode 100644 index 0000000000..bcf588ac21 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/wwwroot/report.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/M365Agent.ttkproj b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/M365Agent.ttkproj new file mode 100644 index 0000000000..2bb454613b --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/M365Agent.ttkproj @@ -0,0 +1,13 @@ + + + + 86639d2c-3e4a-4d6f-bd6e-2ad567176c15 + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/color.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/color.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/manifest.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/manifest.json new file mode 100644 index 0000000000..8db77f4408 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/manifest.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Link unfurling STT", + "full": "This sample demos the feature of link unfurling in share to teams" + }, + "description": { + "short": "Sample app demonstrating link unfurling for sharing in Microsoft Teams.", + "full": "This sample app showcases the link unfurling feature for sharing content in Microsoft Teams." + }, + "accentColor": "#FFFFFF", + "staticTabs": [ + { + "contentUrl": "https://${{BOT_DOMAIN}}/Tab", + "entityId": "tab", + "name": "Tab", + "scopes": [ + "personal" + ] + } + ], + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "canUpdateConfiguration": true, + "commands": [ + { + "id": "searchQuery", + "type": "query", + "title": "Search" + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "${{BOT_DOMAIN}}" + ] + } + } + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/outline.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/appPackage/outline.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/env/.env.local b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/env/.env.local new file mode 100644 index 0000000000..ae4c5f84cf --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/env/.env.local @@ -0,0 +1,25 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local +APP_NAME_SUFFIX=local + +# Generated during provision, you can also add your own variables. +BOT_ID= +TEAMS_APP_ID= +TEAMSFX_M365_USER_NAME= + +BOT_ENDPOINT= +BOT_DOMAIN= + +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/infra/azure.bicep b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/infra/azure.parameters.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/infra/azure.parameters.json new file mode 100644 index 0000000000..201ab98435 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "app-link-unfurling-in-share-to-teams" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/launchSettings.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/launchSettings.json new file mode 100644 index 0000000000..d6491ef52c --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/launchSettings.json @@ -0,0 +1,15 @@ +{ + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + }, + // Launch project within Teams without prepare app dependencies + "Microsoft Teams (browser) (skip update app)": { + "commandName": "Project", + "environmentVariables": { "UPDATE_TEAMS_APP": "false" }, + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/m365agents.local.yml b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/m365agents.local.yml new file mode 100644 index 0000000000..78839b5f66 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/m365agents.local.yml @@ -0,0 +1,86 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:app-link-unfurling-in-share-to-teams-csharp + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: app-link-unfurling-in-share-to-teams-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # SingleTenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: app-link-unfurling-in-share-to-teams-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ../LinkUnfurlingInShareToTeams/appsettings.json + content: + MicrosoftAppType: ${{MICROSOFT_APP_TYPE}} + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppTenantId: ${{MICROSOFT_APP_TENANT_ID}} + ApplicationBaseUrl: ${{BOT_ENDPOINT}} + TeamsAppId: ${{TEAMS_APP_ID}} + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appPackage/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/m365agents.yml b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/m365agents.yml new file mode 100644 index 0000000000..bc4d4c29d5 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/M365Agent/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:app-link-unfurling-in-share-to-teams-csharp + +environmentFolderPath: ./env \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/README.md b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/README.md new file mode 100644 index 0000000000..da90af4919 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/README.md @@ -0,0 +1,160 @@ +--- +page_type: sample +description: This sample app showcases the link unfurling feature for sharing content in Microsoft Teams. +products: +- office-teams +- office +- office-365 +languages: +- csharp +extensions: + contentType: samples + createdDate: "14-12-2022 00:15:13" +urlFragment: officedev-microsoft-teams-samples-app-link-unfurling-in-share-to-teams-csharp +--- + +## Link unfurling in Share to teams sample + +This sample app illustrates the link unfurling functionality in Microsoft Teams, enabling users to effortlessly share content with contacts or groups. With a focus on user experience, the app showcases how to enhance sharing capabilities in Teams through interactive features and integration support. + +## Interaction with app + +![App linkunfurling in share to teams](LinkUnfurlingInShareToTeams/Images/app-link-unfurling-stt.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**App link unfurling in share to teams:** [Manifest](/samples/app-link-unfurling-in-share-to-teams/csharp/demo-manifest/app-link-unfurling-stt.zip) + +## Prerequisites + +- [.NET Core SDK](https://dotnet.microsoft.com/download) version 6.0 + + determine dotnet version + ```bash + dotnet --version + ``` +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/download) (For local environment testing) latest version (any other tunneling software can also be used) + +- [Teams](https://teams.microsoft.com) Microsoft Teams is installed and you have an account + +- [Microsoft 365 Agents Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.14 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Microsoft 365 Agents Toolkit for Visual Studio [Microsoft 365 Agents Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In the debug dropdown menu of Visual Studio, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel. +1. Right-click the 'M365Agent' project in Solution Explorer and select **Microsoft 365 Agents Toolkit > Select Microsoft 365 Account** +1. Sign in to Microsoft 365 Agents Toolkit with a **Microsoft 365 work or school account** +1. Set `Startup Item` as `Microsoft Teams (browser)`. +1. Press F5, or select Debug > Start Debugging menu in Visual Studio to start your app +
![image](https://raw.githubusercontent.com/OfficeDev/TeamsFx/dev/docs/images/visualstudio/debug/debug-button.png) +1. In the opened web browser, select Add button to install the app in Teams +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +1) Setup for Bot +- Register a Microsoft Entra ID aap registration in Azure portal. +- Also, register a bot with Azure Bot Service, following the instructions [here](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration?view=azure-bot-service-3.0). +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) +- While registering the bot, use `https:///api/messages` as the messaging endpoint. + + > NOTE: When you create your app registration, you will create an App ID and App password - make sure you keep these for later. + +2) Setup NGROK +- Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +3) Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + + A) Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. + B) On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. + C) Navigate to **API Permissions**, and make sure to add the follow permissions: + Select Add a permission + * Select Add a permission + * Select Microsoft Graph -\> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + + +4) Setup for code + +- Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +- Modify the `/appsettings.json` and fill in the following details: + - `{{Microsoft-App-Id}}` - Generated from Step 1 while doing Microsoft Entra ID app registration in Azure portal. + - `{{ Microsoft-App-Password}}` - Generated from Step 1, also referred to as Client secret + - `{{ Application-Base-Url }}` - Your application's base url. E.g. https://12345.ngrok-free.app if you are using ngrok and if you are using dev tunnels, your URL will be https://12345.devtunnels.ms. + +- Run the bot from a terminal or from Visual Studio: + + A) From a terminal, navigate to `samples/app-link-unfurling-in-share-to-teams/csharp` + + ```bash + # run the bot + dotnet run + ``` + B) Or from Visual Studio + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `LinkUnfurlingInShareToTeams` folder + - Select `LinkUnfurlingInShareToTeams.csproj` file + - Press `F5` to run the project + +5) Setup Manifest for Teams +- __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the ./appPackage folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `{{Microsoft-App-Id}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` and replace `{{domain-name}}` with base Url of your domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `appPackage` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appPackage folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your app is uploaded to Teams. + +## Running the sample + + ![tab](LinkUnfurlingInShareToTeams/Images/1.Install.png) + + ![Link unfurling STT](LinkUnfurlingInShareToTeams/Images/2.Tab.png) + + ![Share To Teams](LinkUnfurlingInShareToTeams/Images/3.ShareToTeams.png) + + ![Shared](LinkUnfurlingInShareToTeams/Images/4.SharedSuccess.png) + + ![In Teams](LinkUnfurlingInShareToTeams/Images/5.InTeams.png) + + ![View Via Card](LinkUnfurlingInShareToTeams/Images/6.ViewViaCard.png) + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Share to teams](https://learn.microsoft.com/microsoftteams/platform/concepts/build-and-test/share-to-teams-from-personal-app-or-tab) + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/assets/sample.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/assets/sample.json new file mode 100644 index 0000000000..2a67346d4f --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/csharp/assets/sample.json @@ -0,0 +1,72 @@ +[ + { + "name": "officedev-microsoft-teams-samples-app-link-unfurling-in-share-to-teams-csharp", + "source": "officeDev", + "title": "App link unfurling in share to teams", + "shortDescription": "This sample app showcases the link unfurling feature for sharing content in Microsoft Teams.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/app-link-unfurling-in-share-to-teams/csharp", + "longDescription": [ + "This sample app demonstrates the link unfurling feature, allowing users to seamlessly share site content with individuals or groups on Microsoft Teams. It provides a practical example of how to integrate and utilize this feature within the Teams environment." + ], + "creationDateTime": "2022-12-14", + "updateDateTime": "2024-10-10", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "csharp" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "netframework" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/app-link-unfurling-in-share-to-teams/csharp/LinkUnfurlingInShareToTeams/Images/app-link-unfurling-stt.gif", + "alt": "Link unfurling in share to teams" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.env b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.env new file mode 100644 index 0000000000..852c10b07f --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.env @@ -0,0 +1,5 @@ +MicrosoftAppId= +MicrosoftAppPassword= +ApplicationBaseUrl= +MicrosoftAppType=SingleTenant +MicrosoftAppTenantId= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.gitignore b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.gitignore new file mode 100644 index 0000000000..8f78731e17 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appManifest/build +/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store + +# build +lib/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/extensions.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/extensions.json new file mode 100644 index 0000000000..2d88dee21b --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/launch.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/launch.json new file mode 100644 index 0000000000..d027ed91e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/launch.json @@ -0,0 +1,73 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Local Service", + "type": "node", + "request": "attach", + "port": 9239, + "restart": true, + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/settings.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/settings.json new file mode 100644 index 0000000000..4299620253 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ] +} diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/tasks.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/tasks.json new file mode 100644 index 0000000000..b79f108ff5 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/.vscode/tasks.json @@ -0,0 +1,105 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Teams App Locally", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy", + "Start application" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "nodejs", // Validate if Node.js is installed. + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + 9239 // app inspector port for Node.js debugger + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + }, + { + "label": "Start application", + "type": "shell", + "command": "npm run dev:teamsfx", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": { + "pattern": [ + { + "regexp": "^.*$", + "file": 0, + "location": 1, + "message": 2 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "[nodemon] starting", + "endsPattern": "Server listening on port:" + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/1.Install.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/1.Install.png new file mode 100644 index 0000000000..910e07d1d0 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/2.Continue.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/2.Continue.png new file mode 100644 index 0000000000..c820ced446 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/2.Continue.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/3.Tab.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/3.Tab.png new file mode 100644 index 0000000000..a4c3a572a4 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/3.Tab.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/4.ShareTOTeams2.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/4.ShareTOTeams2.png new file mode 100644 index 0000000000..c50f60088d Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/4.ShareTOTeams2.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/4.ShareToTeams.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/4.ShareToTeams.png new file mode 100644 index 0000000000..6cc5bc0ffd Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/4.ShareToTeams.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/5.Shared.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/5.Shared.png new file mode 100644 index 0000000000..f2580e8713 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/5.Shared.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/6.InTeams.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/6.InTeams.png new file mode 100644 index 0000000000..8ef77916f6 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/6.InTeams.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/7.ViewViaCard.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/7.ViewViaCard.png new file mode 100644 index 0000000000..95a91a54d2 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/7.ViewViaCard.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/app-link-unfurling-stt.gif b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/app-link-unfurling-stt.gif new file mode 100644 index 0000000000..a111e4ccbe Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/app-link-unfurling-stt.gif differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/report.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/report.png new file mode 100644 index 0000000000..bcf588ac21 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/Images/report.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/README.md b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/README.md new file mode 100644 index 0000000000..b97cee9c2c --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/README.md @@ -0,0 +1,149 @@ +--- +page_type: sample +description: This sample demonstrates how to implement link unfurling in Share to Teams for seamless sharing of site content directly to individual contacts or groups on Teams. +products: +- office-teams +- office +- office-365 +languages: +- nodejs +- javascript +extensions: + contentType: samples + createdDate: "14-12-2022 00:15:13" +urlFragment: officedev-microsoft-teams-samples-app-link-unfurling-in-share-to-teams-nodejs +--- + +## Link unfruling Share to teams sample + +This sample demonstrates the Share to Teams feature, which allows users to seamlessly share site content directly to contacts or groups in Microsoft Teams, leveraging link unfurling to provide rich previews and context for shared links. It includes comprehensive setup instructions, bot registration, and local deployment steps, making it easy to integrate and test within your Teams environment. + +## Interaction with app + +![App linkunfurling in share to teams](Images/app-link-unfurling-stt.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**App check-in location:** [Manifest](/samples/app-link-unfurling-in-share-to-teams/nodejs/demo-manifest/app-link-unfurling-stt.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account (not a guest account) +- To test locally, [NodeJS](https://nodejs.org/en/download/) must be installed on your development machine (version 16.14.2 or higher) +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunneling solution +- [M365 developer account](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the + appropriate permissions to install an app. +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +> the Teams service needs to call into the bot. + +### 1. Setup for Bot +- In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp%2Caadv2). +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) +- While registering the bot, use `https:///api/messages` as the messaging endpoint. +**NOTE:** When you create app registration, you will create an App ID and App password - make sure you keep these for later. + +### 2. Setup NGROK +1) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +### 3. Register your app with Azure AD. + + 1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + 2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * For **supported account types**, select **Accounts in this organizational directory only (Single tenant)**. This sample is configured for single-tenant use. + * Leave **Redirect URI** empty. + * Choose **Register**. + 3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. + 4. Navigate to **API Permissions**, and make sure to add the follow permissions: + Select Add a permission + * Select Add a permission + * Select Microsoft Graph -\> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + + +### 4. Setup for code +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +2) In a terminal, navigate to `samples/app-link-unfurling-in-share-to-teams/nodejs` + +3) Install modules + + ```bash + npm install + ``` + +4) Update the `.env` configuration for the bot to use the `MicrosoftAppId` and `MicrosoftAppPassword`, `BaseUrl` with application base url. For e.g., your ngrok url or your dev tunnels url. (Note the MicrosoftAppId is the AppId created in step 1 (Setup for Bot), the MicrosoftAppPassword is referred to as the "client secret" in step 1 (Setup for Bot) and you can always create a new client secret anytime.) + +5) Run your app + + ```bash + npm start + ``` + +### 5. Setup Manifest for Teams + +- __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the ./appManifest folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `{{Microsoft-App-Id}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` and replace `{{domain-name}}` with base Url of your domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +## Running the sample + + ![tab](Images/1.Install.png) + + ![Continue Devtunnel](Images/2.Continue.png) + + ![Tab](Images/3.Tab.png) + + ![Share To Teams](Images/4.ShareToTeams.png) + + ![Link Shared](Images/5.Shared.png) + + ![Link unfurling STT Teams](Images/6.InTeams.png) + + ![View Via Card](Images/7.ViewViaCard.png) + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Share to teams](https://learn.microsoft.com/microsoftteams/platform/concepts/build-and-test/share-to-teams-from-personal-app-or-tab) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/aad.manifest.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/aad.manifest.json new file mode 100644 index 0000000000..65312fbaa6 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/aad.manifest.json @@ -0,0 +1,100 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "displayName": "app-link-unfurling-in-share-to-teams-aad", + "signInAudience": "AzureADMyOrg", + "api": { + "requestedAccessTokenVersion": 2, + "oauth2PermissionScopes": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ] + }, + "info": {}, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "publicClient": {}, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "web": { + "implicitGrantSettings": {} + }, + "spa": {} +} diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/color.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/manifest.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/manifest.json new file mode 100644 index 0000000000..32c80c9312 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/manifest.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Link unfurling STT", + "full": "Link unfurling STT" + }, + "description": { + "short": "Demonstrates link unfurling in Share to Teams feature for easy content sharing.", + "full": "This sample demonstrates how to implement link unfurling in Share to Teams for seamless sharing of site content directly to individual contacts or groups on Teams." + }, + "accentColor": "#FFFFFF", + "staticTabs": [ + { + "contentUrl": "https://${{BOT_DOMAIN}}/Tab", + "entityId": "tab", + "name": "Tab", + "scopes": [ + "personal" + ] + } + ], + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "canUpdateConfiguration": true, + "commands": [ + { + "id": "searchQuery", + "type": "query", + "title": "Search" + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "${{BOT_DOMAIN}}" + ] + } + } + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/outline.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/assets/sample.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/assets/sample.json new file mode 100644 index 0000000000..d3e24d6efc --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/assets/sample.json @@ -0,0 +1,72 @@ +[ + { + "name": "officedev-microsoft-teams-samples-app-link-unfurling-in-share-to-teams-nodejs", + "source": "officeDev", + "title": "App link unfurling in share to teams", + "shortDescription": "This sample demonstrates how to implement link unfurling in Share to Teams for seamless sharing of site content directly to individual contacts or groups on Teams.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/app-link-unfurling-in-share-to-teams/nodejs", + "longDescription": [ + "This sample showcases the implementation of link unfurling in the Share to Teams feature, enabling users to easily share site content and context within Microsoft Teams. It supports sharing links directly to individual contacts or groups, and displays rich link previews for enhanced collaboration." + ], + "creationDateTime": "2022-12-14", + "updateDateTime": "2024-10-10", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/app-link-unfurling-in-share-to-teams/nodejs/Images/app-link-unfurling-stt.gif", + "alt": "Link unfurling in share to teams." + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/bots/teamsBot.js b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/bots/teamsBot.js new file mode 100644 index 0000000000..a4dbd0d9ad --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/bots/teamsBot.js @@ -0,0 +1,73 @@ +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// + +const { TeamsActivityHandler, CardFactory } = require("botbuilder"); + +class TeamsBot extends TeamsActivityHandler { + // Invoked when an app based link query activity is received from the connector. + async handleTeamsAppBasedLinkQuery(context, query) { + const userCard = CardFactory.adaptiveCard(this.getLinkUnfurlingCard()); + const preview = CardFactory.thumbnailCard( + 'Adaptive Card', + 'Please select to get the card' + ); + + return { + composeExtension: { + attachmentLayout: 'list', + type: 'result', + attachments: [{ ...userCard, preview }] + } + }; + } + + // Adaptive card for link unfurling. + getLinkUnfurlingCard() { + return { + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.4", + "body": [ + { + "type": "TextBlock", + "size": "Medium", + "weight": "Bolder", + "text": "Analytics details:" + }, + { + "type": "Image", + "url": `${process.env.ApplicationBaseUrl}/Images/report.png` + } + ], + "actions": [ + { + "type": "Action.OpenUrl", + "title": "Open tab", + "url": `https://teams.microsoft.com/l/entity/${process.env.MicrosoftAppId}/tab?webUrl=${process.env.ApplicationBaseUrl}/tab?openInTeams=true` + }, + { + "type": "Action.Submit", + "title": "View via card", + "data": { + "msteams": { + "type": "invoke", + "value": { + "type": "tab/tabInfoAction", + "tabInfo": { + "contentUrl": `${process.env.ApplicationBaseUrl}/tab?openInTeams=true`, + "websiteUrl": `${process.env.ApplicationBaseUrl}/tab?openInTeams=true`, + "name": "Stage view", + "entityId": "entityId" + } + } + } + } + } + ] + }; + } +} + +module.exports.TeamsBot = TeamsBot; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/build.js b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/build.js new file mode 100644 index 0000000000..a59684a045 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/build.js @@ -0,0 +1,14 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js' +}) + .then((r) => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/env/.env.local b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/env/.env.local new file mode 100644 index 0000000000..ef1cabe7de --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/env/.env.local @@ -0,0 +1,21 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/index.js b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/index.js new file mode 100644 index 0000000000..0ee3da01cf --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/index.js @@ -0,0 +1,69 @@ +const path = require('path'); +const express = require('express'); +const cors = require('cors'); + +// Load environment variables from Teams Toolkit environment files +const TEAMSFX_ENV = process.env.TEAMSFX_ENV || 'local'; +require('dotenv').config({ path: path.join(__dirname, 'env', `.env.${TEAMSFX_ENV}`) }); +require('dotenv').config({ path: path.join(__dirname, 'env', `.env.${TEAMSFX_ENV}.user`) }); + +const PORT = process.env.PORT || 3978; +const server = express(); + +server.use(cors()); +server.use(express.json()); +server.use(express.urlencoded({ extended: true })); +server.engine('html', require('ejs').renderFile); +server.set('view engine', 'ejs'); +server.set('views', __dirname); +server.use(express.static(path.join(__dirname, 'static'))); +server.use('/Images', express.static(path.resolve(__dirname, 'Images'))); + +// Import required bot services. +// See https://aka.ms/bot-services to learn more about the different parts of a bot. +const { + CloudAdapter, + ConfigurationBotFrameworkAuthentication +} = require('botbuilder'); + +const { TeamsBot } = require('./bots/teamsBot'); + +// Create adapter. +// See https://aka.ms/about-bot-adapter to learn more about adapters. +const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env); +const adapter = new CloudAdapter(botFrameworkAuthentication); + +adapter.onTurnError = async (context, error) => { + console.error(`\n [onTurnError] unhandled error: ${error}`); + + await context.sendTraceActivity( + 'OnTurnError Trace', + `${error}`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); + + await context.sendActivity('The bot encountered an error or bug.'); + await context.sendActivity('To continue to run this bot, please fix the bot source code.'); +}; + +// Create the bot that will handle incoming messages. +const bot = new TeamsBot(); + +// Endpoint to fetch Link unfurling tab page. +server.get('/tab', (req, res) => { + res.render('./views/tab'); +}); + +server.post('/api/messages', async (req, res) => { + await adapter.process(req, res, (context) => bot.run(context)); +}); + +server.get('*', (req, res) => { + res.json({ error: 'Route not found' }); +}); + +server.listen(PORT, () => { + console.log(`Server listening on port: ${PORT}`); +}); + diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/infra/azure.bicep b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/infra/azure.parameters.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/infra/azure.parameters.json new file mode 100644 index 0000000000..201ab98435 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "app-link-unfurling-in-share-to-teams" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/m365agents.local.yml b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/m365agents.local.yml new file mode 100644 index 0000000000..b07d9030b4 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/m365agents.local.yml @@ -0,0 +1,99 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:app-link-unfurling-in-share-to-teams-nodejs + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: app-link-unfurling-in-share-to-teams-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # SingleTenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: app-link-unfurling-in-share-to-teams${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Run npm command + - uses: cli/runNpmCommand + with: + args: install --no-audit + + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: SingleTenant + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} + ApplicationBaseUrl: ${{BOT_ENDPOINT}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/m365agents.yml b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/m365agents.yml new file mode 100644 index 0000000000..e61c284f90 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:app-link-unfurling-in-share-to-teams-nodejs + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/package-lock.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/package-lock.json new file mode 100644 index 0000000000..e7bf26c69d --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/package-lock.json @@ -0,0 +1,4164 @@ +{ + "name": "teams-bot", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "teams-bot", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "botbuilder": "^4.23.1", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "ejs": "^3.1.10", + "express": "^4.21.2" + }, + "devDependencies": { + "esbuild": "^0.24.0", + "eslint": "^8.57.0", + "nodemon": "^3.1.7" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-auth/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-client": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz", + "integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-client/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-http-compat": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.4.0.tgz", + "integrity": "sha512-f1P96IB399YiN2ARYHP7EpZi3Bf3wH4SN2lGzrw7JVwm7bbsVYtf2iKSBwTywD2P62NOPZGHFSZi+6jjb75JuA==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@azure/core-client": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0" + } + }, + "node_modules/@azure/core-http-compat/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-http-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.23.0.tgz", + "integrity": "sha512-Evs1INHo+jUjwHi1T6SG6Ua/LHOQBCLuKEEE6efIpt4ZOoNonaT1kP32GoOcdNDbfqsD2445CPri3MubBy5DEQ==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-tracing": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz", + "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-tracing/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-util": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/logger": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz", + "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==", + "license": "MIT", + "dependencies": { + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/logger/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", + "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.19.0" + } + }, + "node_modules/@types/ws": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.5.tgz", + "integrity": "sha512-yURCknZhvywvQItHMMmFSo+fq5arCUIyz/CVk7jD89MSai7dkaX8ufjCWp3NttLojoTVbcE72ri+be/TnEbMHw==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@typespec/ts-http-runtime/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/adaptivecards": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/adaptivecards/-/adaptivecards-1.2.3.tgz", + "integrity": "sha512-amQ5OSW3OpIkrxVKLjxVBPk/T49yuOtnqs1z5ZPfZr0+OpTovzmiHbyoAGDIsu5SNYHwOZFp/3LGOnRaALFa/g==", + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/botbuilder": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.23.3.tgz", + "integrity": "sha512-1gDIQHHYosYBHGXMjvZEJDrcp3NGy3lzHBml5wn9PFqVuIk/cbsCDZs3KJ3g+aH/GGh4CH/ij9iQ2KbQYHAYKA==", + "license": "MIT", + "dependencies": { + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/msal-node": "^2.13.1", + "axios": "^1.8.2", + "botbuilder-core": "4.23.3", + "botbuilder-stdlib": "4.23.3-internal", + "botframework-connector": "4.23.3", + "botframework-schema": "4.23.3", + "botframework-streaming": "4.23.3", + "dayjs": "^1.11.13", + "filenamify": "^6.0.0", + "fs-extra": "^11.2.0", + "htmlparser2": "^9.0.1", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botbuilder/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/botbuilder/node_modules/@azure/identity": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.13.1.tgz", + "integrity": "sha512-5C/2WD5Vb1lHnZS16dNQRPMjN6oV/Upba+C9nBIs15PmOi6A3ZGs4Lr2u60zw4S04gi+u3cEXiqTVP7M4Pz3kw==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^5.5.0", + "@azure/msal-node": "^5.1.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/botbuilder/node_modules/@azure/identity/node_modules/@azure/msal-common": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.5.1.tgz", + "integrity": "sha512-WS9w9SfI8SEYO7mTnxGeZ3UwQfhAVYCWglYF2/7GNx3ioHiAs2gPkl9eSwVs8cPrmiGh+zi9ai/OOKoq4cyzDw==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/botbuilder/node_modules/@azure/identity/node_modules/@azure/msal-node": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-5.1.4.tgz", + "integrity": "sha512-G4LXGGggok1QC48uKu64/SV2DPRDlddmV8EieK8pflsNYMj9/Zz+Y9OHoEBhT15h+zpdwXXLYA/7PJCR/yZ8aw==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "16.5.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/botbuilder/node_modules/@azure/identity/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/botbuilder/node_modules/@azure/msal-browser": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-5.8.0.tgz", + "integrity": "sha512-X7IZV77bN56l7sbLjkcbQJX1t3U4tgxqztDr/XFbUcUfKk+z2FavcLgKP+OYUNj0wl/pEEtV9lldW9siY8BuHQ==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "16.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/botbuilder/node_modules/@azure/msal-browser/node_modules/@azure/msal-common": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.5.1.tgz", + "integrity": "sha512-WS9w9SfI8SEYO7mTnxGeZ3UwQfhAVYCWglYF2/7GNx3ioHiAs2gPkl9eSwVs8cPrmiGh+zi9ai/OOKoq4cyzDw==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/botbuilder/node_modules/@azure/msal-common": { + "version": "14.16.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.1.tgz", + "integrity": "sha512-nyxsA6NA4SVKh5YyRpbSXiMr7oQbwark7JU9LMeg6tJYTSPyAGkdx61wPT4gyxZfxlSxMMEyAsWaubBlNyIa1w==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/botbuilder/node_modules/@azure/msal-node": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.16.3.tgz", + "integrity": "sha512-CO+SE4weOsfJf+C5LM8argzvotrXw252/ZU6SM2Tz63fEblhH1uuVaaO4ISYFuN4Q6BhTo7I3qIdi8ydUQCqhw==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "14.16.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/botbuilder/node_modules/@azure/msal-node/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/botbuilder/node_modules/axios": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/botbuilder/node_modules/botbuilder-core": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.23.3.tgz", + "integrity": "sha512-48iW739I24piBH683b/Unvlu1fSzjB69ViOwZ0PbTkN2yW5cTvHJWlW7bXntO8GSqJfssgPaVthKfyaCW457ig==", + "license": "MIT", + "dependencies": { + "botbuilder-dialogs-adaptive-runtime-core": "4.23.3-preview", + "botbuilder-stdlib": "4.23.3-internal", + "botframework-connector": "4.23.3", + "botframework-schema": "4.23.3", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botbuilder/node_modules/botbuilder-dialogs-adaptive-runtime-core": { + "version": "4.23.3-preview", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs-adaptive-runtime-core/-/botbuilder-dialogs-adaptive-runtime-core-4.23.3-preview.tgz", + "integrity": "sha512-EssyvqK9MobX3gbnUe/jjhLuxpCEeyQeQsyUFMJ236U6vzSQdrAxNH7Jc5DyZw2KKelBdK1xPBdwTYQNM5S0Qw==", + "license": "MIT", + "dependencies": { + "dependency-graph": "^1.0.0" + } + }, + "node_modules/botbuilder/node_modules/botbuilder-stdlib": { + "version": "4.23.3-internal", + "resolved": "https://registry.npmjs.org/botbuilder-stdlib/-/botbuilder-stdlib-4.23.3-internal.tgz", + "integrity": "sha512-fwvIHnKU8sXo1gTww+m/k8wnuM5ktVBAV/3vWJ+ou40zapy1HYjWQuu6sVCRFgMUngpKwhdmoOQsTXsp58SNtA==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-http-compat": "^2.1.2", + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/core-tracing": "^1.2.0" + } + }, + "node_modules/botbuilder/node_modules/botframework-connector": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botframework-connector/-/botframework-connector-4.23.3.tgz", + "integrity": "sha512-sChwCFJr3xhcMCYChaOxJoE8/YgdjOPWzGwz5JAxZDwhbQonwYX5O/6Z9EA+wB3TCFNEh642SGeC/rOitaTnGQ==", + "license": "MIT", + "dependencies": { + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/identity": "^4.4.1", + "@azure/msal-node": "^2.13.1", + "@types/jsonwebtoken": "9.0.6", + "axios": "^1.8.2", + "base64url": "^3.0.0", + "botbuilder-stdlib": "4.23.3-internal", + "botframework-schema": "4.23.3", + "buffer": "^6.0.3", + "cross-fetch": "^4.0.0", + "https-proxy-agent": "^7.0.5", + "jsonwebtoken": "^9.0.2", + "node-fetch": "^2.7.0", + "openssl-wrapper": "^0.3.4", + "rsa-pem-from-mod-exp": "^0.8.6", + "zod": "^3.23.8" + } + }, + "node_modules/botbuilder/node_modules/botframework-schema": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.23.3.tgz", + "integrity": "sha512-/W0uWxZ3fuPLAImZRLnPTbs49Z2xMpJSIzIBxSfvwO0aqv9GsM3bTk3zlNdJ1xr40SshQ7WiH2H1hgjBALwYJw==", + "license": "MIT", + "dependencies": { + "adaptivecards": "1.2.3", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botbuilder/node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/botbuilder/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/botbuilder/node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/botbuilder/node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/botbuilder/node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/botbuilder/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/botbuilder/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/botbuilder/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/botframework-streaming": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botframework-streaming/-/botframework-streaming-4.23.3.tgz", + "integrity": "sha512-GMtciQGfZXtAW6syUqFpFJQ2vDyVbpxL3T1DqFzq/GmmkAu7KTZ1zvo7PTww6+IT1kMW0lmL/XZJVq3Rhg4PQA==", + "license": "MIT", + "dependencies": { + "@types/ws": "^6.0.3", + "uuid": "^10.0.0", + "ws": "^7.5.10" + } + }, + "node_modules/botframework-streaming/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filename-reserved-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/filenamify": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-6.0.0.tgz", + "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemon": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz", + "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^10.2.1", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nodemon/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/openssl-wrapper": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/openssl-wrapper/-/openssl-wrapper-0.3.4.tgz", + "integrity": "sha512-iITsrx6Ho8V3/2OVtmZzzX8wQaKAaFXEJQdzoPUZDtyf5jWFlqo+h+OhGT4TATQ47f9ACKHua8nw7Qoy85aeKQ==", + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rsa-pem-from-mod-exp": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.6.tgz", + "integrity": "sha512-c5ouQkOvGHF1qomUUDJGFcXsomeSO2gbEs6hVhMAtlkE1CuaZase/WzoaKFG/EZQuNmq6pw/EMCeEnDvOgCJYQ==", + "license": "MIT" + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/undici-types": { + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/package.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/package.json new file mode 100644 index 0000000000..a60f737974 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/package.json @@ -0,0 +1,33 @@ +{ + "name": "teams-bot", + "version": "1.0.0", + "description": "App share to teams link unfurling sample.", + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev:teamsfx": "npm run dev", + "dev": "nodemon --inspect=9239 --signal SIGINT ./index.js", + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "build": "node build.js", + "lint": "eslint .", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples" + }, + "dependencies": { + "botbuilder": "^4.23.1", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "ejs": "^3.1.10", + "express": "^4.21.2" + }, + "devDependencies": { + "esbuild": "^0.24.0", + "eslint": "^8.57.0", + "nodemon": "^3.1.7" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/static/tab.css b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/static/tab.css new file mode 100644 index 0000000000..b62285a4b6 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/static/tab.css @@ -0,0 +1,12 @@ +#tabheader { + margin-left: 38rem; +} + +#reportimg { + margin-left: 28rem; +} + +#stt-btn-teams, #stt-btn-custom { + margin-left: 40rem; + margin-top: 2rem; +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/views/tab.ejs b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/views/tab.ejs new file mode 100644 index 0000000000..6952025647 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/nodejs/views/tab.ejs @@ -0,0 +1,63 @@ + + + + + + + + + + +
+

Link unfurling in STT

+ + + +
+ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.env b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.env new file mode 100644 index 0000000000..d3efef2971 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.env @@ -0,0 +1,5 @@ +MicrosoftAppId= +MicrosoftAppPassword= +BaseUrl= +MicrosoftAppType= +MicrosoftAppTenantId= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.gitignore b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.gitignore new file mode 100644 index 0000000000..3144f60181 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.gitignore @@ -0,0 +1,12 @@ +# TeamsFx files +env/.env.*.user +appManifest/build/ + +# python virtual environment +.venv/ + +# misc +.deployment/ + +# tmp files +__pycache__/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/extensions.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/extensions.json new file mode 100644 index 0000000000..bf8c33db9c --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension", + "ms-python.python", + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/launch.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/launch.json new file mode 100644 index 0000000000..6d66d8beb8 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/launch.json @@ -0,0 +1,69 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Python: Run App Locally", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/app.py", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/settings.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/settings.json new file mode 100644 index 0000000000..40ea4c3290 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "debug.onTaskErrors": "abort", + "python-envs.defaultEnvManager": "ms-python.python:system", + "python-envs.pythonProjects": [] +} diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/tasks.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/tasks.json new file mode 100644 index 0000000000..643dd9b802 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/.vscode/tasks.json @@ -0,0 +1,78 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Prepare Teams App Resources", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the sideloading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/AppLinkUnfurling.gif b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/AppLinkUnfurling.gif new file mode 100644 index 0000000000..6b4cf9fcb6 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/AppLinkUnfurling.gif differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/OpenApp.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/OpenApp.png new file mode 100644 index 0000000000..71dd8abbe9 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/OpenApp.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/PostView.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/PostView.png new file mode 100644 index 0000000000..60ffdebabf Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/PostView.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/Preview.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/Preview.png new file mode 100644 index 0000000000..65d3aa7af7 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/Preview.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/SelectChannel.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/SelectChannel.png new file mode 100644 index 0000000000..b4509bd325 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/SelectChannel.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/SharedSuccessfully.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/SharedSuccessfully.png new file mode 100644 index 0000000000..1c2ae4e29a Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/SharedSuccessfully.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/StageView.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/StageView.png new file mode 100644 index 0000000000..f1ec914078 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/StageView.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/TabView.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/TabView.png new file mode 100644 index 0000000000..ceb98e9274 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/TabView.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/report.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/report.png new file mode 100644 index 0000000000..bcf588ac21 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/Images/report.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/README.md b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/README.md new file mode 100644 index 0000000000..c36c1ada4e --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/README.md @@ -0,0 +1,169 @@ +--- +page_type: sample +description: This sample demonstrates how to implement link unfurling in Share to Teams for seamless sharing of site content directly to individual contacts or groups on Teams, using Python. +products: +- office-teams +- office +- office-365 +languages: +- python +extensions: + contentType: samples + createdDate: "30-06-2025" +urlFragment: officedev-microsoft-teams-samples-app-link-unfurling-in-share-to-teams-python +--- + +# Link Unfurling in Share to Teams (Python) + +This sample demonstrates the Share to Teams feature, allowing users to seamlessly share site content directly to contacts or groups in Microsoft Teams, leveraging link unfurling to provide rich previews and context for shared links. It includes comprehensive setup instructions, bot registration, and local deployment steps for easy integration and testing within your Teams environment using Python. + +## Included Features + +* Link unfurling in Share to Teams + +## Interaction with app + +![App linkunfurling in share to teams](Images/AppLinkUnfurling.gif) + +## Try it yourself - experience the App in your Microsoft Teams client + +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your Teams and/or as a personal app. (Sideloading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**App check-in location:** [Manifest](/samples/app-link-unfurling-in-share-to-teams/python/demo-manifest/app-link-unfurling-stt.zip) + +## Prerequisites + +1. Office 365 tenant. You can get a free tenant for development use by signing up for the [Office 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program). + +2. To test locally, [Python](https://www.python.org/downloads/) must be installed on your development machine (version 3.7 or higher). + + ```bash + python --version + ``` + +3. [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) or equivalent tunneling solution. + +4. [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +2. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +3. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +4. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +5. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +6. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (sideloading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +### 1. Register a new application in Microsoft Entra ID + +- Go to [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) and register a new app. + A) Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose **Accounts in this organizational directory only (Single tenant)** as the supported account type. + * Leave **Redirect URI** empty. + * Choose **Register**. + B) On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. + C) Navigate to **API Permissions**, and make sure to add the follow permissions: + Select Add a permission + * Select Add a permission + * Select Microsoft Graph -\> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. +- Note the Application (client) ID and create a client secret (App password). Save these for later. +- In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=python). +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) +- While registering the bot, use `https:///api/messages` as the messaging endpoint. + +### 2. Setup tunneling + +- Run ngrok or dev tunnel to expose your local port 3978: + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Or using dev tunnels: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +### 3. Setup for code + +- In a terminal, navigate to `samples/app-link-unfurling-in-share-to-teams/python` + + ```bash + cd samples/app-link-unfurling-in-share-to-teams/python + ``` + +- (Optional) Create a virtual environment + + ```bash + python -m venv venv + ``` + +- Activate the virtual environment + + - On Windows: + ```bash + venv\Scripts\activate + ``` + - On macOS/Linux: + ```bash + source venv/bin/activate + ``` + +- Install dependencies + + ```bash + pip install -r requirements.txt + ``` + +- Update the `.env` configuration for the bot to use the `MicrosoftAppId`, `MicrosoftAppPassword`, `MicrosoftAppType` (set to `SingleTenant`), `MicrosoftAppTenantId`, and `BaseUrl` (your ngrok or dev tunnel URL). + +- Run your app + + ```bash + python app.py + ``` + +### 4. Setup Manifest for Teams + +- **Edit** the `manifest.json` contained in the ./appManifest folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `{{Microsoft-App-Id}}`. +- **Edit** the `manifest.json` for `validDomains` and replace `{{domain-name}}` with the base URL of your domain (e.g., `1234.ngrok-free.app` or `12345.devtunnels.ms`). +- **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` (Make sure that zip file does not contain any subfolder otherwise you will get error while uploading your .zip package). +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app"). + +## Running the sample + + ![Continue Devtunnel](Images/OpenApp.png) + + ![Tab](Images/TabView.png) + + ![Share To Teams](Images/Preview.png) + + ![Link unfurling](Images/SelectChannel.png) + + ![Link Shared](Images/SharedSuccessfully.png) + + ![Link unfurling STT Teams](Images/PostView.png) + + ![View Via Card](Images/StageView.png) + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Share to teams](https://learn.microsoft.com/microsoftteams/platform/concepts/build-and-test/share-to-teams-from-personal-app-or-tab) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/app.py b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/app.py new file mode 100644 index 0000000000..41f14225e9 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/app.py @@ -0,0 +1,72 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os +import sys +import traceback +from datetime import datetime + +from aiohttp import web +from aiohttp.web import Request, Response +from botbuilder.core import TurnContext +from botbuilder.integration.aiohttp import CloudAdapter, ConfigurationBotFrameworkAuthentication +from botbuilder.schema import Activity, ActivityTypes + +from bots import LinkUnfurlingBot +from config import DefaultConfig + +CONFIG = DefaultConfig() + +ADAPTER = CloudAdapter(ConfigurationBotFrameworkAuthentication(CONFIG)) + + +# Catch-all for errors. +async def on_error(context: TurnContext, error: Exception): + print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr) + traceback.print_exc() + + await context.send_activity("The bot encountered an error or bug.") + await context.send_activity("To continue to run this bot, please fix the bot source code.") + + if context.activity.channel_id == "emulator": + trace_activity = Activity( + label="TurnError", + name="on_turn_error Trace", + timestamp=datetime.utcnow(), + type=ActivityTypes.trace, + value=f"{error}", + value_type="https://www.botframework.com/schemas/error", + ) + await context.send_activity(trace_activity) + + +ADAPTER.on_turn_error = on_error + +BOT = LinkUnfurlingBot() + + +# Listen for incoming requests on /api/messages. +async def messages(req: Request) -> Response: + return await ADAPTER.process(req, BOT) + + +async def serve_tab_page(request: Request) -> Response: + file_path = os.path.join("templates", "tab.html") + if os.path.isfile(file_path): + return web.FileResponse(path=file_path, headers={"Content-Type": "text/html"}) + return web.Response(text="tab.html not found", status=404) + + +APP = web.Application() +APP.router.add_post("/api/messages", messages) +APP.router.add_get("/tab", serve_tab_page) +APP.router.add_static("/static", path="static", name="static") +APP.router.add_static("/Images", path="Images", name="images") + +if __name__ == "__main__": + try: + print(f"Bot running on http://localhost:{CONFIG.PORT}") + web.run_app(APP, port=CONFIG.PORT) + except Exception as error: + raise error + diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/color.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/manifest.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/manifest.json new file mode 100644 index 0000000000..10e1fd5026 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/manifest.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Link unfurling STT", + "full": "Link unfurling STT" + }, + "description": { + "short": "Demonstrates link unfurling in Share to Teams feature for easy content sharing.", + "full": "This sample demonstrates how to implement link unfurling in Share to Teams for seamless sharing of site content directly to individual contacts or groups on Teams." + }, + "accentColor": "#FFFFFF", + "staticTabs": [ + { + "contentUrl": "https://${{BOT_DOMAIN}}/tab", + "entityId": "tab", + "name": "Tab", + "scopes": [ + "personal" + ] + } + ], + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "canUpdateConfiguration": true, + "commands": [ + { + "id": "searchQuery", + "type": "query", + "title": "Search" + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "${{BOT_DOMAIN}}" + ] + } + } + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/outline.png b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/assets/sample.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/assets/sample.json new file mode 100644 index 0000000000..9a21f9680e --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/assets/sample.json @@ -0,0 +1,72 @@ +[ + { + "name": "officedev-microsoft-teams-samples-app-link-unfurling-in-share-to-teams-python", + "source": "officeDev", + "title": "App link unfurling in share to teams", + "shortDescription": "This sample demonstrates how to implement link unfurling in Share to Teams for seamless sharing of site content directly to individual contacts or groups on Teams.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/app-link-unfurling-in-share-to-teams/python", + "longDescription": [ + "This sample showcases the implementation of link unfurling in the Share to Teams feature, enabling users to easily share site content and context within Microsoft Teams. It supports sharing links directly to individual contacts or groups, and displays rich link previews for enhanced collaboration." + ], + "creationDateTime": "2025-06-30", + "updateDateTime": "2025-06-30", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "python" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "python" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/app-link-unfurling-in-share-to-teams/python/Images/app-link-unfurling-stt.gif", + "alt": "Link unfurling in share to teams." + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/bots/__init__.py b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/bots/__init__.py new file mode 100644 index 0000000000..fecc91feed --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/bots/__init__.py @@ -0,0 +1,3 @@ +from .bot import LinkUnfurlingBot + +__all__ = ["LinkUnfurlingBot"] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/bots/bot.py b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/bots/bot.py new file mode 100644 index 0000000000..edd30356dd --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/bots/bot.py @@ -0,0 +1,67 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from botbuilder.core import TurnContext, CardFactory +from botbuilder.core.card_factory import ContentTypes +from botbuilder.core.teams import TeamsActivityHandler +from botbuilder.schema import ThumbnailCard, CardImage, HeroCard +from botbuilder.schema.teams import ( + AppBasedLinkQuery, + MessagingExtensionQuery, + MessagingExtensionAttachment, + MessagingExtensionResult, + MessagingExtensionResponse, +) + + +class LinkUnfurlingBot(TeamsActivityHandler): + async def on_teams_app_based_link_query( + self, turn_context: TurnContext, query: AppBasedLinkQuery + ): + thumbnail_card = ThumbnailCard( + title="Analytics Details: ", + text=query.url, + images=[ + CardImage( + url="https://raw.githubusercontent.com/microsoft/botframework-sdk/master/icon.png" + ) + ], + ) + + attachment = MessagingExtensionAttachment( + content_type=ContentTypes.hero_card, content=thumbnail_card + ) + + result = MessagingExtensionResult( + attachment_layout="list", type="result", attachments=[attachment] + ) + + return MessagingExtensionResponse(compose_extension=result) + + async def on_teams_messaging_extension_query( + self, turn_context: TurnContext, query: MessagingExtensionQuery + ): + # These commandIds are defined in the Teams App Manifest. + if query.command_id != "searchQuery": + raise NotImplementedError(f"Invalid CommandId: {query.command_id}") + + card = HeroCard( + title="This is a Link Unfurling Sample", + subtitle="It will unfurl links from *.BotFramework.com", + text="This sample demonstrates how to handle link unfurling in Teams. " + "Please review the readme for more information.", + ) + + return MessagingExtensionResponse( + compose_extension=MessagingExtensionResult( + attachment_layout="list", + type="result", + attachments=[ + MessagingExtensionAttachment( + content=card, + content_type=ContentTypes.hero_card, + preview=CardFactory.hero_card(card), + ) + ], + ) + ) diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/config.py b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/config.py new file mode 100644 index 0000000000..d660185922 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/config.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os + +""" Bot Configuration """ + + +class DefaultConfig: + """ Bot Configuration """ + + PORT = 3978 + APP_TYPE = os.environ.get("MicrosoftAppType", "SingleTenant") + APP_ID = os.environ.get("MicrosoftAppId", "") + APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "") + APP_TENANTID = os.environ.get("MicrosoftAppTenantId", "") diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/env/.env.local b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/env/.env.local new file mode 100644 index 0000000000..20e303de1a --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/env/.env.local @@ -0,0 +1,22 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +APP_NAME_SUFFIX=local \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/infra/azure.bicep b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/infra/azure.bicep new file mode 100644 index 0000000000..31504479c0 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/infra/azure.bicep @@ -0,0 +1,43 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string +param botAadAppTenantId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: 'SingleTenant' + msaAppTenantId: botAadAppTenantId + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/infra/azure.parameters.json b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/infra/azure.parameters.json new file mode 100644 index 0000000000..df3e88e592 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/infra/azure.parameters.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAadAppTenantId": { + "value": "${{AAD_APP_TENANT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "app-link-unfurling-in-share-to-teams" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/m365agents.local.yml b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/m365agents.local.yml new file mode 100644 index 0000000000..6734d46ab6 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/m365agents.local.yml @@ -0,0 +1,81 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:app-link-unfurling-in-share-to-teams-python + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: app-link-unfurling-in-share-to-teams-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # Single tenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: app-link-unfurling-in-share-to-teams${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Teams Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppType: SingleTenant + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} + BaseUrl: ${{BOT_ENDPOINT}} + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/m365agents.yml b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/m365agents.yml new file mode 100644 index 0000000000..3d7de57589 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:app-link-unfurling-in-share-to-teams-python + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/requirements.txt b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/requirements.txt new file mode 100644 index 0000000000..210b381cf4 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/requirements.txt @@ -0,0 +1,2 @@ +botbuilder-integration-aiohttp>=4.17.1 +aiohttp>=3.10.11 diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/static/tab.css b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/static/tab.css new file mode 100644 index 0000000000..b62285a4b6 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/static/tab.css @@ -0,0 +1,12 @@ +#tabheader { + margin-left: 38rem; +} + +#reportimg { + margin-left: 28rem; +} + +#stt-btn-teams, #stt-btn-custom { + margin-left: 40rem; + margin-top: 2rem; +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/templates/tab.html b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/templates/tab.html new file mode 100644 index 0000000000..7790dafa77 --- /dev/null +++ b/samples/TeamsSDK/Archived/app-link-unfurling-in-share-to-teams/python/templates/tab.html @@ -0,0 +1,64 @@ + + + + + + Link Unfurling Tab + + + + + + + + + + +
+

Link unfurling in STT

+ + + + + +
+ + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/.gitignore b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/.gitignore new file mode 100644 index 0000000000..ebf8f70b0e --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/.gitignore @@ -0,0 +1,463 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET +project.lock.json +project.fragment.lock.json +artifacts/ +appSettings.Development.json + +# Tye +.tye/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppManifest/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +## +## Visual studio for Mac +## + + +# globs +Makefile.in +*.userprefs +*.usertasks +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.tar.gz +tarballs/ +test-results/ + +# Mac bundle stuff +*.dmg +*.app + +# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# JetBrains Rider +.idea/ +*.sln.iml + +## +## Visual Studio Code +## +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + + +## +## Microsoft Teams development +## +**/Manifest/*.zip + +Source/CallingBotSample/wwwroot/temp/* \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/1.install-personal.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/1.install-personal.png new file mode 100644 index 0000000000..2d2a80071a Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/1.install-personal.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/10.transfer-call.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/10.transfer-call.png new file mode 100644 index 0000000000..f3a09347ac Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/10.transfer-call.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/11.callingbot-teams.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/11.callingbot-teams.png new file mode 100644 index 0000000000..5d10c94da3 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/11.callingbot-teams.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/12.Play-record-prompt.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/12.Play-record-prompt.png new file mode 100644 index 0000000000..099c4096a8 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/12.Play-record-prompt.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/13.hang-up.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/13.hang-up.png new file mode 100644 index 0000000000..9e1a2a9b2a Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/13.hang-up.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/14.installin-teams.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/14.installin-teams.png new file mode 100644 index 0000000000..bf2eeb1b39 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/14.installin-teams.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/15.callingbottoteam.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/15.callingbottoteam.png new file mode 100644 index 0000000000..7e60d95457 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/15.callingbottoteam.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/16.adaptive-card-from-bot.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/16.adaptive-card-from-bot.png new file mode 100644 index 0000000000..8b00dcae4d Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/16.adaptive-card-from-bot.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/17.new-one.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/17.new-one.png new file mode 100644 index 0000000000..84bdd90acf Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/17.new-one.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/18.create-call.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/18.create-call.png new file mode 100644 index 0000000000..ea98421109 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/18.create-call.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/19.user-join.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/19.user-join.png new file mode 100644 index 0000000000..04ad63463f Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/19.user-join.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/2.welcome-card.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/2.welcome-card.png new file mode 100644 index 0000000000..c9d59b46a2 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/2.welcome-card.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/20.control-the-meet.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/20.control-the-meet.png new file mode 100644 index 0000000000..8c4383a644 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/20.control-the-meet.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/21.install-in-meet.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/21.install-in-meet.png new file mode 100644 index 0000000000..cca4b617d3 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/21.install-in-meet.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/22.add-bot-to-meet.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/22.add-bot-to-meet.png new file mode 100644 index 0000000000..c49d470d93 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/22.add-bot-to-meet.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/23.adaptivecard-frombot.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/23.adaptivecard-frombot.png new file mode 100644 index 0000000000..5c62b155f1 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/23.adaptivecard-frombot.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/24.create-call.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/24.create-call.png new file mode 100644 index 0000000000..81edb19062 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/24.create-call.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/25.user-join-call.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/25.user-join-call.png new file mode 100644 index 0000000000..1cb94525ba Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/25.user-join-call.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/26.control-meet.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/26.control-meet.png new file mode 100644 index 0000000000..c1ecd9a629 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/26.control-meet.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/27.join-meet.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/27.join-meet.png new file mode 100644 index 0000000000..f0db1a82e4 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/27.join-meet.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/3.bots-adaptive-card.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/3.bots-adaptive-card.png new file mode 100644 index 0000000000..38cbde63c4 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/3.bots-adaptive-card.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/4.createcall.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/4.createcall.png new file mode 100644 index 0000000000..73d4a0c9a9 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/4.createcall.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/5.calling-bot.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/5.calling-bot.png new file mode 100644 index 0000000000..49fe19ed2e Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/5.calling-bot.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/6.user-join.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/6.user-join.png new file mode 100644 index 0000000000..04ad63463f Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/6.user-join.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/7.successfully-call.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/7.successfully-call.png new file mode 100644 index 0000000000..424e1033e3 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/7.successfully-call.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/8.control-meet.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/8.control-meet.png new file mode 100644 index 0000000000..4c0df343f3 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/8.control-meet.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/9.create-incident.png b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/9.create-incident.png new file mode 100644 index 0000000000..67a92fad63 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/9.create-incident.png differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/EnableCallingEndpoint.PNG b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/EnableCallingEndpoint.PNG new file mode 100644 index 0000000000..6c44198a65 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/EnableCallingEndpoint.PNG differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/PolicySetup.PNG b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/PolicySetup.PNG new file mode 100644 index 0000000000..26f0461818 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/PolicySetup.PNG differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/bot-calling-meeting.gif b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/bot-calling-meeting.gif new file mode 100644 index 0000000000..67f894fd3f Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Images/bot-calling-meeting.gif differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/README.md b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/README.md new file mode 100644 index 0000000000..3436ad868f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/README.md @@ -0,0 +1,305 @@ +--- +page_type: sample +description: This sample demonstrates how a bot can create, join, and transfer calls or meetings within Microsoft Teams. +products: + - office-teams + - office + - office-365 +languages: + - csharp +extensions: + contentType: samples + createdDate: "07/07/2021 01:38:25 PM" +urlFragment: officedev-microsoft-teams-samples-bot-calling-meeting-csharp +--- + +# Calling and Meeting Bot Sample V4 + +## Summary + +This sample app demonstrates a bot's ability to create, join, and manage calls and meetings within Microsoft Teams using Microsoft Graph APIs. Users can leverage this bot to transfer calls, join scheduled meetings, and handle participant invitations, offering a comprehensive communication solution in a unified interface. + +- **Interaction with bot** + ![bot-calling-meeting ](Images/bot-calling-meeting.gif) + +## Frameworks + +![drop](https://img.shields.io/badge/.NET Core-6.0-green.svg) +![drop](https://img.shields.io/badge/Bot Framework-3.0-green.svg) + +## Prerequisites + +- [Office 365 tenant](https://developer.microsoft.com/en-us/microsoft-365/dev-program) + +- Microsoft Teams is installed and you have an account +- [.NET Core SDK](https://dotnet.microsoft.com/download) version 6.0 +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution +- [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-macos) if on macOS (`brew install --cask powershell`) + +## Setup + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +> the Teams service needs to call into the bot. + +1. Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +2. If you are using Visual Studio + + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `samples/bot-calling-meeting/csharp` folder + - Select `CallingBotSample.csproj` file + +3. Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +## Register Azure AD application + +Register one Azure AD application in your tenant's directory for the bot and tab app authentication. + +1. Log in to the Azure portal from your subscription, and go to the "App registrations" blade [here](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps). Ensure that you use a tenant where admin consent for API permissions can be provided. + +2. Click on "New registration", and create an Azure AD application. + +3. **Name:** The name of your Teams app - if you are following the template for a default deployment, we recommend "App catalog lifecycle". + +4. **Supported account types:** Select "Accounts in any organizational directory" + +5. Leave the "Redirect URL" field blank. + +6. Click on the "Register" button. + +7. When the app is registered, you'll be taken to the app's "Overview" page. Copy the **Application (client) ID**; we will need it later. Verify that the "Supported account types" is set to **Multiple organizations**. + +8. On the side rail in the Manage section, navigate to the "Certificates & secrets" section. In the Client secrets section, click on "+ New client secret". Add a description for the secret and select Expires as "Never". Click "Add". + +9. Once the client secret is created, copy its **Value**, please take a note of the secret as it will be required later. + + At this point you have 3 unique values: + + - Application (client) ID which will be later used during Azure bot creation + - Client secret for the bot which will be later used during Azure bot creation + - Directory (tenant) ID + + We recommend that you copy these values into a text file, using an application like Notepad. We will need these values later. + +10. Under left menu, navigate to **API Permissions**, and make sure to add the following permissions of Microsoft Graph API > Application permissions: + + - `Calls.AccessMedia.All` + - `Calls.Initiate.All` + - `Calls.InitiateGroupCall.All` + - `Calls.JoinGroupCall.All` + - `Calls.JoinGroupCallAsGuest.All` + - `OnlineMeetings.ReadWrite.All` + + Click on Add Permissions to commit your changes. + +11. If you are logged in as the Global Administrator, click on the "Grant admin consent for <%tenant-name%>" button to grant admin consent else, inform your admin to do the same through the portal or follow the steps provided here to create a link and send it to your admin for consent. + +12. Global Administrator can grant consent using following link: [https://login.microsoftonline.com/common/adminconsent?client_id=](https://login.microsoftonline.com/common/adminconsent?client_id=)<%appId%> +13. [Install Microsoft Teams PowerShell Module](https://learn.microsoft.com/en-us/microsoftteams/teams-powershell-install). For basic install, run `Import-Module MicrosoftTeams` in PowerShell, or check the link for detailed other advanced installs. + - For macOS, the following command should be executed in [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-macos) (`brew install --cask powershell`). +14. Create a policy for a demo tenant user for creating the online meeting on behalf of that user using the following PowerShell script + + ```powershell + # Import-Module MicrosoftTeams + # Call Connect-MicrosoftTeams using no parameters to open a window allowing for MFA accounts to authenticate + Connect-MicrosoftTeams + New-CsApplicationAccessPolicy -Identity “<>” -AppIds "<>" -Description "<>" + Grant-CsApplicationAccessPolicy -PolicyName “<>” -Identity "<>" + ``` + + e.g.: + + ```powershell + # Import-Module MicrosoftTeams + Connect-MicrosoftTeams + + New-CsApplicationAccessPolicy -Identity Meeting-policy-dev -AppIds "d0bdaa0f-8be2-4e85-9e0d-2e446676b88c" -Description "Online meeting policy - contoso town" + Grant-CsApplicationAccessPolicy -PolicyName Meeting-policy-dev -Identity "782f076f-f6f9-4bff-9673-ea1997283e9c" + ``` + + ![PolicySetup](Images/PolicySetup.PNG) + +15. Update `PolicyName`, `microsoft-app-id`, `policy-description`, `object-id-of-the-user-to-whom-policy-need-to-be-granted` in powershell script. +16. Run `Windows Powershell PSI` as an administrator and execute above script. +17. Run following command to verify policy is create successfully or not: `Get-CsApplicationAccessPolicy -Identity Meeting-policy-dev` + +## Setup Bot Service + +1. In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) +2. Select Type of App as "Multi Tenant" +3. Select Creation type as "Use existing app registration" +4. Use the copied App Id and Client secret from above step and fill in App Id and App secret respectively. +5. Click on 'Create' on the Azure bot. +6. Go to the created resource, ensure that you've [enabled the Teams Channel](https://learn.microsoft.com/en-us/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) +7. In Settings/Configuration/Messaging endpoint, enter the current `https` URL you have given by running the tunneling application. Append with the path `/api/messages` +8. Select the Calling tab on the Teams channel page. Select Enable calling, and then update Webhook (for calling) with your HTTPS URL (`https:///callback`) where you receive incoming notifications. + For example `https://contoso.com/teamsapp/callback` + ![EnableCallingEndpoint ](Images/EnableCallingEndpoint.PNG) +9. Save your changes. + +### Configuring the sample + +1. **_Update appsettings.json for calling Bot_** + + ```json + { + "MicrosoftAppId": "<>", + "MicrosoftAppPassword": "<>", + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "TenantId": "<>", + "ClientId": "<>", + "ClientSecret": "<>" + }, + "Bot": { + "AppId": "<>", + "AppSecret": "<>", + "PlaceCallEndpointUrl": "https://graph.microsoft.com/v1.0", + "BotBaseUrl": "https://<>.ngrok-free.app", + "GraphApiResourceUrl": "https://graph.microsoft.com", + "MicrosoftLoginUrl": "https://login.microsoftonline.com/", + "RecordingDownloadDirectory": "temp", + "CatalogAppId": "<>" + }, + "CognitiveServices": { + "Enabled": false, + "SpeechKey": "<>", + "SpeechRegion": "<>", + "SpeechRecognitionLanguage": "<>" + }, + "Users": { + "UserIdWithAssignedOnlineMeetingPolicy": "<>" + } + } + ``` + + - Update `microsoft-app-id`, `tenant-Id`, `microsoft-app-client-secret` with your app's client id and client secret registered in demo tenant. + - Update `BotBaseUrl` with your `tunnel` URL. + - Update `object-id-of-the-user-to-whom-online-meeting-policy-has-been-granted` with the ID of the user who has had the policy assigned to them above + + **Create a Cognitive Services resource using the Azure portal:** + [Create Cognitive Services resource](https://learn.microsoft.com/en-us/azure/cognitive-services/cognitive-services-apis-create-account?tabs=multiservice%2Canomaly-detector%2Clanguage-service%2Ccomputer-vision%2Cwindows) + + - Update `cognitive-speech-key` replace `your-key`with one of the keys for your resource. + - Update `cognitive-speech-key` replace `your-region`with one of the regions for your resource. + - Update `cognitive-speech-language` replace `your-language`with one of the language for your resource. + +2. **_This step is specific to Teams_** + - **Edit** the `manifest.json` contained in the `AppManifest` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) _everywhere_ you see the place holder string `<>` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains`, replace `<>` with base Url domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `AppManifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + - **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.) + - Add the app to personal/team/groupChat scope (Supported scopes) + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-calling-meeting/csharp/Source/CallingBotSample/AdapterWithErrorHandler.cs#L22) line and put your debugger for local debug. + +## Running the sample + +- Install app in personal teams. + ![CallingBotInstallation ](Images/1.install-personal.png) + +- Select welcome card. + ![BotCallingMeeting2 ](Images/2.welcome-card.png) + +- Bot will send adaptive card as mentioned below. + ![BotCallingMeeting3 ](Images/3.bots-adaptive-card.png) + +- Select 'Create Call'. + ![BotCallingMeeting4 ](Images/4.createcall.png) + +- 'Calling Bot' selected user. + ![BotCallingMeeting5 ](Images/5.calling-bot.png) + +- User join call. + ![BotCallingMeeting55 ](Images/6.user-join.png) + +- Successfully call . + ![BotCallingMeeting6 ](Images/7.successfully-call.png) + +- Control this meeting. + ![BotCallingMeeting7 ](Images/8.control-meet.png) + +- Create Incident. + ![BotCallingMeeting8 ](Images/9.create-incident.png) + +- Transfer call. + ![BotCallingMeeting9 ](Images/10.transfer-call.png) + +- 'Calling Bot' selected user. + ![BotCallingMeeting10 ](Images/11.callingbot-teams.png) + +- Play record prompt. + ![BotCallingMeeting11 ](Images/12.Play-record-prompt.png) + +- Hang up. + ![BotCallingMeeting12 ](Images/13.hang-up.png) + +- Install app in team. + ![BotCallingMeeting13 ](Images/14.installin-teams.png) + +- Add calling bot to a team. + ![BotCallingMeeting14 ](Images/15.callingbottoteam.png) + +- Bot will send adaptive card as mentioned below. + ![BotCallingMeeting16 ](Images/16.adaptive-card-from-bot.png) + +- Select 'Create Call'. + ![BotCallingMeeting17 ](Images/17.new-one.png) + +- User join call. + ![BotCallingMeeting18 ](Images/18.create-call.png) + +- Control this meeting. + ![BotCallingMeeting19 ](Images/19.user-join.png) + +- Install app in meeting. + ![BotCallingMeeting20 ](Images/20.control-the-meet.png) + +- Add calling bot to a meeting. + ![BotCallingMeeting21 ](Images/21.install-in-meet.png) + +- Bot will send adaptive card as mentioned below. + ![BotCallingMeeting22 ](Images/22.add-bot-to-meet.png) + +- Select 'Create Call'. + ![BotCallingMeeting23 ](Images/23.adaptivecard-frombot.png) + +- User join call. + ![BotCallingMeeting24 ](Images/24.create-call.png) + +- Control this meeting. + ![BotCallingMeeting25 ](Images/25.user-join-call.png) + +- Join scheduled meeting. + ![BotCallingMeeting26 ](Images/26.control-meet.png) + + ![BotCallingMeeting26 ](Images/27.join-meet.png) + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Disclaimer + +**THIS CODE IS PROVIDED _AS IS_ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** + +## Further reading + +- [Register a calling Bot](https://docs.microsoft.com/en-us/microsoftteams/platform/bots/calls-and-meetings/registering-calling-bot#create-new-bot-or-add-calling-capabilities) +- [Cloud Communications API](https://docs.microsoft.com/en-us/graph/api/resources/call?view=graph-rest-1.0) +- [Recognize and convert speech to text](https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/get-started-speech-to-text?pivots=programming-language-csharp&tabs=windows%2Cterminal) diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/.editorconfig b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/.editorconfig new file mode 100644 index 0000000000..78fadc4234 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/.editorconfig @@ -0,0 +1,510 @@ +# editorconfig.org + +# top-most EditorConfig file +root = true + +# Default settings: +# A newline ending every file +# Use 4 spaces as indentation +[*] +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.json] +indent_size = 2 + +# Generated code +[*{_AssemblyInfo.cs,.notsupported.cs,*/obj/*/External/**/*,*/obj/dotnet-new.IntegrationTests/*/TemplatePackagesPaths.cs}] +generated_code = true + +# C# files +[*.cs] +# New line preferences +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_switch_labels = true +csharp_indent_labels = one_less_than_current + +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion + +# avoid this. unless absolutely necessary +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion + +# Types: use keywords instead of BCL types, and permit var only when the type is clear +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = false:none +csharp_style_var_elsewhere = false:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# name all constant fields using PascalCase +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.required_modifiers = const +dotnet_naming_style.pascal_case_style.capitalization = pascal_case + +# static fields should have s_ prefix +dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion +dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields +dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style +dotnet_naming_symbols.static_fields.applicable_kinds = field +dotnet_naming_symbols.static_fields.required_modifiers = static +dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected +dotnet_naming_style.static_prefix_style.required_prefix = s_ +dotnet_naming_style.static_prefix_style.capitalization = camel_case + +# internal and private fields should be _camelCase +dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion +dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields +dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style +dotnet_naming_symbols.private_internal_fields.applicable_kinds = field +dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal +dotnet_naming_style.camel_case_underscore_style.required_prefix = _ +dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case + +# Code style defaults +csharp_using_directive_placement = outside_namespace:suggestion +dotnet_diagnostic.IDE0065.severity = warning +dotnet_sort_system_directives_first = true +csharp_prefer_braces = true:silent +csharp_preserve_single_line_blocks = true:none +csharp_preserve_single_line_statements = false:none +csharp_prefer_static_local_function = true:suggestion +csharp_prefer_simple_using_statement = false:none +csharp_style_prefer_switch_expression = true:suggestion + +# Code quality +dotnet_style_readonly_field = true:suggestion +dotnet_code_quality_unused_parameters = non_public:suggestion + +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +csharp_prefer_simple_default_expression = true:suggestion + +# Expression-bodied members +csharp_style_expression_bodied_methods = true:silent +csharp_style_expression_bodied_constructors = true:silent +csharp_style_expression_bodied_operators = true:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = true:silent + +# Pattern matching +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion + +# Null checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Other features +csharp_style_prefer_index_operator = false:none +csharp_style_prefer_range_operator = false:none +csharp_style_pattern_local_over_anonymous_function = false:none + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = do_not_ignore +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Default analyzed API surface = 'all' (public APIs + non-public APIs) +dotnet_code_quality.api_surface = all + +# License header +file_header_template = Copyright (c) Microsoft Corporation. All rights reserved.\nLicensed under the MIT license. See LICENSE file in the project root for full license information. +dotnet_diagnostic.IDE0073.severity = warning + +csharp_style_namespace_declarations = block_scoped:warning +dotnet_diagnostic.IDE0160.severity = warning + +dotnet_style_namespace_match_folder = true + +# Code files +[*.{cs,vb}] +# Analyzers +dotnet_code_quality.ca1802.api_surface = private, internal +dotnet_code_quality.ca1822.api_surface = private, internal +dotnet_code_quality.ca2208.api_surface = public +# Mark attributes with AttributeUsageAttribute +dotnet_diagnostic.CA1018.severity = warning +# Properties should not be write only +dotnet_diagnostic.CA1044.severity = warning +# Do not declare protected member in sealed type +dotnet_diagnostic.CA1047.severity = warning +# Declare types in namespaces +dotnet_diagnostic.CA1050.severity = warning +# Avoid using cref tags with a prefix +dotnet_diagnostic.CA1200.severity = suggestion +# P/Invokes should not be visible +dotnet_diagnostic.CA1401.severity = warning +# Parameter names should match base declaration +dotnet_diagnostic.CA1725.severity = suggestion +# Remove empty Finalizers +dotnet_diagnostic.CA1821.severity = warning +# Mark assemblies with NeutralResourcesLanguageAttribute +dotnet_diagnostic.CA1824.severity = warning +# Do not use CountAsync() or LongCountAsync() when AnyAsync() can be used +dotnet_diagnostic.CA1828.severity = warning +# Prefer strongly-typed Append and Insert method overloads on StringBuilder. +dotnet_diagnostic.CA1830.severity = warning +# Use AsSpan or AsMemory instead of Range-based indexers when appropriate +dotnet_diagnostic.CA1832.severity = warning +# Use AsSpan or AsMemory instead of Range-based indexers when appropriate +dotnet_diagnostic.CA1833.severity = warning +# Prefer IsEmpty over Count +dotnet_diagnostic.CA1836.severity = warning +# Use 'Environment.ProcessPath' +dotnet_diagnostic.CA1839.severity = warning +# Do not call ToImmutableCollection on an ImmutableCollection value +dotnet_diagnostic.CA2009.severity = warning +# Avoid infinite recursion +dotnet_diagnostic.CA2011.severity = warning +# Initialize value type static fields inline +dotnet_diagnostic.CA2207.severity = warning +# Implement serialization constructors +dotnet_diagnostic.CA2229.severity = warning +# Provide correct arguments to formatting methods +dotnet_diagnostic.CA2241.severity = warning +# Test for NaN correctly +dotnet_diagnostic.CA2242.severity = warning +# Do not assign a property to itself. +dotnet_diagnostic.CA2245.severity = warning +# Provide correct 'enum' argument to 'Enum.HasFlag' +dotnet_diagnostic.CA2248.severity = warning +# Do Not Add Schema By URL +dotnet_diagnostic.CA3061.severity = warning +# Insecure DTD processing in XML +dotnet_diagnostic.CA3075.severity = warning +# Insecure XSLT script processing. +dotnet_diagnostic.CA3076.severity = warning +# Insecure Processing in API Design, XmlDocument and XmlTextReader +dotnet_diagnostic.CA3077.severity = warning +# Mark Verb Handlers With Validate Antiforgery Token +dotnet_diagnostic.CA3147.severity = warning +# Do Not Use Broken Cryptographic Algorithms +dotnet_diagnostic.CA5351.severity = warning +# Do Not Disable Certificate Validation +dotnet_diagnostic.CA5359.severity = warning +# Do Not Call Dangerous Methods In Deserialization +dotnet_diagnostic.CA5360.severity = warning +# Do Not Disable SChannel Use of Strong Crypto +dotnet_diagnostic.CA5361.severity = warning +# Do Not Disable Request Validation +dotnet_diagnostic.CA5363.severity = warning +# Do Not Use Deprecated Security Protocols +dotnet_diagnostic.CA5364.severity = warning +# Do Not Disable HTTP Header Checking +dotnet_diagnostic.CA5365.severity = warning +# Set ViewStateUserKey For Classes Derived From Page +dotnet_diagnostic.CA5368.severity = warning +# Use XmlReader For Validating Reader +dotnet_diagnostic.CA5370.severity = warning +# Do not use obsolete key derivation function +dotnet_diagnostic.CA5373.severity = warning +# Do Not Use XslTransform +dotnet_diagnostic.CA5374.severity = warning +# Use SharedAccessProtocol HttpsOnly +dotnet_diagnostic.CA5376.severity = warning +# Use Container Level Access Policy +dotnet_diagnostic.CA5377.severity = warning +# Do not disable ServicePointManagerSecurityProtocols +dotnet_diagnostic.CA5378.severity = warning +# Do Not Use Weak Key Derivation Function Algorithm +dotnet_diagnostic.CA5379.severity = warning +# Do Not Add Certificates To Root Store +dotnet_diagnostic.CA5380.severity = warning +# Ensure Certificates Are Not Added To Root Store +dotnet_diagnostic.CA5381.severity = warning +# Do Not Use Digital Signature Algorithm (DSA) +dotnet_diagnostic.CA5384.severity = warning +# Use Rivest–Shamir–Adleman (RSA) Algorithm With Sufficient Key Size +dotnet_diagnostic.CA5385.severity = warning +dotnet_diagnostic.CS1591.severity = suggestion +# UseIsNullCheck +dotnet_diagnostic.IDE0041.severity = warning +# ValidateFormatString +dotnet_diagnostic.IDE0043.severity = warning +# MakeLocalFunctionStatic +dotnet_diagnostic.IDE0062.severity = warning +# ConvertTypeOfToNameOf +dotnet_diagnostic.IDE0082.severity = warning +# Remove redundant nullable directive +dotnet_diagnostic.IDE0240.severity = warning + +# Additional rules for template engine source code +[src/**{Microsoft.TemplateEngine.*,dotnet-new?*}/**.cs] +# Default analyzed API surface = 'public' (public APIs) +dotnet_code_quality.api_surface = public +# Provide ObsoleteAttribute message +dotnet_diagnostic.CA1041.severity = warning +# Static holder types should be Static or NotInheritable +dotnet_diagnostic.CA1052.severity = warning +# Use nameof to express symbol names +dotnet_diagnostic.CA1507.severity = warning +# Use literals where appropriate +dotnet_diagnostic.CA1802.severity = warning +# Do not initialize unnecessarily +dotnet_diagnostic.CA1805.severity = warning +# Initialize reference type static fields inline +dotnet_diagnostic.CA1810.severity = warning +# Avoid unused private fields +dotnet_diagnostic.CA1823.severity = warning +# Avoid zero-length array allocations. +dotnet_diagnostic.CA1825.severity = warning +# Do not use Enumerable methods on indexable collections. Instead use the collection directly +dotnet_diagnostic.CA1826.severity = warning +# Do not use Count() or LongCount() when Any() can be used +dotnet_diagnostic.CA1827.severity = warning +# Use Length/Count property instead of Count() when available +dotnet_diagnostic.CA1829.severity = warning +# Consider using 'StringBuilder.Append(char)' when applicable. +dotnet_diagnostic.CA1834.severity = warning +# Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' +dotnet_diagnostic.CA1835.severity = warning +# Use 'Environment.ProcessId' +dotnet_diagnostic.CA1837.severity = warning +# Avoid 'StringBuilder' parameters for P/Invokes +dotnet_diagnostic.CA1838.severity = warning +# Use 'Environment.CurrentManagedThreadId' +dotnet_diagnostic.CA1840.severity = warning +# Consider calling ConfigureAwait on the awaited task +dotnet_diagnostic.CA2007.severity = warning +# Do not create tasks without passing a TaskScheduler +dotnet_diagnostic.CA2008.severity = warning +# Use ValueTasks correctly +dotnet_diagnostic.CA2012.severity = warning +# Forward the 'CancellationToken' parameter to methods that take one +dotnet_diagnostic.CA2016.severity = warning +# Instantiate argument exceptions correctly +dotnet_diagnostic.CA2208.severity = warning +# Consider using 'string.Contains' instead of 'string.IndexOf' +dotnet_diagnostic.CA2249.severity = warning +# Do Not Use Weak Cryptographic Algorithms +dotnet_diagnostic.CA5350.severity = warning +# Do not use insecure randomness +dotnet_diagnostic.CA5394.severity = warning +# Remove unnecessary using directives +dotnet_diagnostic.IDE0005.severity = warning +# Fix formating +dotnet_diagnostic.IDE0055.severity = warning +# FileHeaderMismatch +dotnet_diagnostic.IDE0073.severity = warning +# Single line comment should begin with a space +dotnet_diagnostic.SA1005.severity = none +# Opening parenthesis should not be preceded by a space +dotnet_diagnostic.SA1008.severity = none +# Closing parenthesis should not be followed by a space +dotnet_diagnostic.SA1009.severity = none +# Prefix local calls with this +dotnet_diagnostic.SA1101.severity = none +# Block statements should not contain embedded comments +dotnet_diagnostic.SA1108.severity = none +# Closing parenthesis should be on line of last parameter +dotnet_diagnostic.SA1111.severity = none +# Parameter should not span multiple lines +dotnet_diagnostic.SA1118.severity = none +# Statement should not use unnecessary parenthesis +dotnet_diagnostic.SA1119.severity = none +# Comments should contain text +dotnet_diagnostic.SA1120.severity = none +# Use string.Empty for empty strings +dotnet_diagnostic.SA1122.severity = none +# Region should not be located within a code element +dotnet_diagnostic.SA1123.severity = none +# Do not use regions +dotnet_diagnostic.SA1124.severity = none +# Generic type constraints should be on their own line +dotnet_diagnostic.SA1127.severity = none +# Put constructor initializers on their own line +dotnet_diagnostic.SA1128.severity = none +# Constant values should appear on the right-hand side of comparisons +dotnet_diagnostic.SA1131.severity = none +# Elements should have the same indentation +dotnet_diagnostic.SA1137.severity = none +# Use literal suffix notation instead of casting +dotnet_diagnostic.SA1139.severity = none +# Use tuple syntax +dotnet_diagnostic.SA1141.severity = warning +# Refer to tuple elements by name +dotnet_diagnostic.SA1142.severity = warning +# Using directive should appear within a namespace declaration +dotnet_diagnostic.SA1200.severity = none +# Field names should not begin with underscore +dotnet_diagnostic.SA1309.severity = none +# Type parameter names should begin with T +dotnet_diagnostic.SA1314.severity = none +# Tuple element names should use correct casing +dotnet_diagnostic.SA1316.severity = warning +# File may only contain a single type +dotnet_diagnostic.SA1402.severity = none +# Debug.Assert should provide message text +dotnet_diagnostic.SA1405.severity = none +# Arithmetic expressions should declare precedence +dotnet_diagnostic.SA1407.severity = none +# Conditional expressions should declare precedence +dotnet_diagnostic.SA1408.severity = none +# Use trailing comma in multi-line initializers +dotnet_diagnostic.SA1413.severity = none +# Tuple types in signatures should have element names +dotnet_diagnostic.SA1414.severity = none +# Statement should not be on a single line +dotnet_diagnostic.SA1501.severity = none +# Element should not be on a single line +dotnet_diagnostic.SA1502.severity = none +# All accessors should be single-line or multi-line +dotnet_diagnostic.SA1504.severity = none +# A closing brace should not be preceded by a blank line +dotnet_diagnostic.SA1508.severity = none +# Opening braces should not be preceded by blank line +dotnet_diagnostic.SA1509.severity = none +# Single-line comments should not be followed by blank line +dotnet_diagnostic.SA1512.severity = none +# Closing brace should be followed by blank line +dotnet_diagnostic.SA1513.severity = none +# Single-line comment should be preceded by blank line +dotnet_diagnostic.SA1515.severity = none +# Code should not contain blank lines at the end of the file +dotnet_diagnostic.SA1518.severity = none +# Elements should be documented +dotnet_diagnostic.SA1600.severity = none +# Partial elements should be documented +dotnet_diagnostic.SA1601.severity = none +# Enumeration items should be documented +dotnet_diagnostic.SA1602.severity = none +# The documentation for parameter 'message' is missing +dotnet_diagnostic.SA1611.severity = none +# Element parameter documentation should have text +dotnet_diagnostic.SA1614.severity = none +# Element return value should be documented +dotnet_diagnostic.SA1615.severity = none +# Element return value documentation should have text +dotnet_diagnostic.SA1616.severity = none +# The documentation for type parameter is missing +dotnet_diagnostic.SA1618.severity = none +# Generic type parameter documentation should have text +dotnet_diagnostic.SA1622.severity = none +# Property documentation text +dotnet_diagnostic.SA1623.severity = none +# Element documentation should not be copied and pasted +dotnet_diagnostic.SA1625.severity = none +# The documentation text within the \'exception\' tag should not be empty +dotnet_diagnostic.SA1627.severity = none +# File should have header +dotnet_diagnostic.SA1633.severity = none +# Constructor summary documentation should begin with standard text +dotnet_diagnostic.SA1642.severity = none +# File name should match first type name +dotnet_diagnostic.SA1649.severity = none + +# Disable some StyleCop rules for test common Program.cs that is linked to test project of template engine +[src/Tests/Common/Program.cs] +# Declare types in namespaces +dotnet_diagnostic.CA1050.severity = none +# Elements should be documented +dotnet_diagnostic.SA1600.severity = none +# Partial elements should be documented +dotnet_diagnostic.SA1601.severity = none +# File should have header: The file header XML is invalid. +dotnet_diagnostic.SA1633.severity = none + +# Additional rules for test source code for template engine +[src/Tests/{Microsoft.TemplateEngine.*,dotnet-new.Tests}/**.cs] +# Test methods should not be skipped +dotnet_diagnostic.xUnit1004.severity = warning +# Elements should appear in the correct order +dotnet_diagnostic.SA1201.severity = none +# Elements should be ordered by access +dotnet_diagnostic.SA1202.severity = none +# Static elements should appear before instance elements +dotnet_diagnostic.SA1204.severity = none + +# C++ Files +[*.{cpp,h,in}] +curly_bracket_next_line = true +indent_brace_style = Allman + +# Xml project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}] +indent_size = 2 + +[*.{csproj,vbproj,proj,nativeproj,locproj}] +charset = utf-8-bom + +# Xml build files +[*.builds] +indent_size = 2 + +# Xml files +[*.{xml,stylecop,resx,ruleset}] +indent_size = 2 + +# Xml config files +[*.{props,targets,config,nuspec}] +indent_size = 2 + +# YAML config files +[*.{yml,yaml}] +indent_size = 2 + +# Shell scripts +[*.sh] +end_of_line = lf +[*.{cmd, bat}] +end_of_line = crlf + +# IDE0040: Add accessibility modifiers +dotnet_diagnostic.IDE0040.severity = warning + +[*.txt] +insert_final_newline = false diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample.sln b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample.sln new file mode 100644 index 0000000000..163f6dffa0 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CallingBotSample", "CallingBotSample\CallingBotSample.csproj", "{ACA36300-B09B-4937-92C4-4E6CB095BEEB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{33C72F09-71AA-471D-99D2-C018BFACF90E}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ACA36300-B09B-4937-92C4-4E6CB095BEEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACA36300-B09B-4937-92C4-4E6CB095BEEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACA36300-B09B-4937-92C4-4E6CB095BEEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACA36300-B09B-4937-92C4-4E6CB095BEEB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AF4B2E2E-BC10-40E7-A7F2-F90C36D21846} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdapterWithErrorHandler.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdapterWithErrorHandler.cs new file mode 100644 index 0000000000..8584b82b33 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdapterWithErrorHandler.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Builder.TraceExtensions; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Extensions.Logging; + +namespace CallingBotSample +{ + public class AdapterWithErrorHandler : CloudAdapter + { + public AdapterWithErrorHandler(BotFrameworkAuthentication auth, ILogger logger) + : base(auth, logger) + { + OnTurnError = async (turnContext, exception) => + { + // Log any leaked exception from the application. + logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}"); + + // Uncomment below commented line for local debugging. + // await turnContext.SendActivityAsync($"Sorry, it looks like something went wrong. Exception Caught: {exception.Message}"); + + // Send a trace activity, which will be displayed in the Bot Framework Emulator + await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError"); + }; + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdaptiveCards/AdaptiveCardFactory.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdaptiveCards/AdaptiveCardFactory.cs new file mode 100644 index 0000000000..fc332046a5 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdaptiveCards/AdaptiveCardFactory.cs @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IO; +using global::AdaptiveCards; +using global::AdaptiveCards.Templating; +using Microsoft.Bot.Schema; + +namespace CallingBotSample.AdaptiveCards +{ + public class AdaptiveCardFactory : IAdaptiveCardFactory + { + /// + /// Date Time must be in RFC 3389 format https://learn.microsoft.com/en-us/adaptive-cards/authoring-cards/text-features#datetime-function-rules + /// + public const string DateTimeStringFormat = "yyyy-MM-dd'T'HH:mm:ssK"; + + /// + public Attachment CreateWelcomeCard(bool showJoinMeetingButton) + { + var template = GetCardTemplate("WelcomeCard.json"); + + var serializedJson = template.Expand(new { showJoinMeetingButton }); + return CreateAttachment(serializedJson); + } + + /// + public Attachment CreateIncidentCard() + { + var template = GetCardTemplate("CreateIncidentCard.json"); + + var serializedJson = template.Expand(new { }); + return CreateAttachment(serializedJson); + } + + /// + public Attachment CreateIncidentMeetingCard(string title, string callId, DateTime startTime, DateTime? endTime) + { + var template = GetCardTemplate("IncidentMeetingActionsCard.json"); + + var serializedJson = template.Expand(new + { + title, + callId, + startTime = startTime.ToString(DateTimeStringFormat), + endTime = endTime?.ToString(DateTimeStringFormat) ?? string.Empty + }); + return CreateAttachment(serializedJson); + } + + /// + public Attachment CreateMeetingActionsCard(string? callId) + { + var template = GetCardTemplate("MeetingActions.json"); + + var serializedJson = template.Expand(new { callId = callId ?? string.Empty }); + return CreateAttachment(serializedJson); + } + + /// + public Attachment CreatePeoplePickerCard(string choiceLabel, string action, string? callId, bool isMultiSelect = false) + { + var template = GetCardTemplate("PeoplePicker.json"); + + var serializedJson = template.Expand(new + { + choiceLabel, + action, + callId = callId ?? string.Empty, + isMultiSelect + }); + return CreateAttachment(serializedJson); + + } + + private AdaptiveCardTemplate GetCardTemplate(string fileName) + { + string templatePath = Path.Combine(Directory.GetCurrentDirectory(), "Resources", fileName); + return new AdaptiveCardTemplate(File.ReadAllText(templatePath)); + } + + private Attachment CreateAttachment(string adaptiveCardJson) + { + var adaptiveCard = AdaptiveCard.FromJson(adaptiveCardJson); + return new Attachment + { + ContentType = AdaptiveCard.ContentType, + Content = adaptiveCard.Card, + }; + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdaptiveCards/IAdaptiveCardFactory.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdaptiveCards/IAdaptiveCardFactory.cs new file mode 100644 index 0000000000..09f47fbdf1 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/AdaptiveCards/IAdaptiveCardFactory.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using Microsoft.Bot.Schema; + +namespace CallingBotSample.AdaptiveCards +{ + public interface IAdaptiveCardFactory + { + /// + /// Create a card shown on welcome/when a action is unknown + /// + /// Shows a join meeting button if true + /// A card with "Create call", "Create incident" and "Join Meeting" + Attachment CreateWelcomeCard(bool showJoinMeetingButton); + + /// + /// Card for creating an incident + /// + /// Card with people picker and incident title + Attachment CreateIncidentCard(); + + /// + /// Create a card for showing in an incident meeting. + /// + /// Title of the incident + /// Call's id + /// Start time of the incident + /// End time of the incident + /// Card with the incidents details, and action set that can be performed on the meeting + Attachment CreateIncidentMeetingCard(string title, string callId, DateTime startTime, DateTime? endTime); + + /// + /// Create a card for showing in a meeting. + /// + /// Call 'sid + /// Card with action set that can be performed on the meeting + Attachment CreateMeetingActionsCard(string? callId); + + /// + /// Create a card for choosing a user + /// + /// Label for the picker + /// Action being undertaken by the card + /// Call's id + /// Is multiple users able to be selected + /// Card with people picker for choosing users + Attachment CreatePeoplePickerCard(string choiceLabel, string action, string? callId, bool isMultiSelect = false); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Authentication/AuthenticationProvider.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Authentication/AuthenticationProvider.cs new file mode 100644 index 0000000000..eca79ab2ba --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Authentication/AuthenticationProvider.cs @@ -0,0 +1,206 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IdentityModel.Tokens.Jwt; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Security.Claims; +using System.Threading; +using System.Threading.Tasks; +using Azure.Identity; +using Microsoft.Graph.Communications.Client.Authentication; +using Microsoft.Graph.Communications.Common; +using Microsoft.Graph.Communications.Common.Telemetry; +using Microsoft.IdentityModel.Protocols; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using Microsoft.IdentityModel.Tokens; + +namespace CallingBotSample.Authentication +{ + public class AuthenticationProvider : ObjectRoot, IRequestAuthenticationProvider + { + private readonly string appName; + private readonly string appId; + private readonly string appSecret; + + /// + /// The open ID configuration refresh interval. + /// + private readonly TimeSpan openIdConfigRefreshInterval = TimeSpan.FromHours(2); + + /// + /// The previous update timestamp for OpenIdConfig. + /// + private DateTime prevOpenIdConfigUpdateTimestamp = DateTime.MinValue; + + /// + /// The open identifier configuration. + /// + private OpenIdConnectConfiguration openIdConfiguration; + + + public AuthenticationProvider(string appName, string appId, string appSecret, IGraphLogger logger) + : base(logger.NotNull(nameof(logger)).CreateShim(nameof(AuthenticationProvider))) + { + this.appName = appName.NotNullOrWhitespace(nameof(appName)); + this.appId = appId.NotNullOrWhitespace(nameof(appId)); + this.appSecret = appSecret.NotNullOrWhitespace(nameof(appSecret)); + } + + /// + /// Authenticates the specified request message. + /// This method will be called any time there is an outbound request. + /// In this case we are using the Microsoft.IdentityModel.Clients.ActiveDirectory library + /// to stamp the outbound http request with the OAuth 2.0 token using an AAD application id + /// and application secret. Alternatively, this method can support certificate validation. + /// + /// The request. + /// The tenant. + /// + /// The . + /// + public async Task AuthenticateOutboundRequestAsync(HttpRequestMessage request, string tenant) + { + const string schema = "Bearer"; + const string resource = "https://graph.microsoft.com/.default"; + + tenant = string.IsNullOrWhiteSpace(tenant) ? "common" : tenant; + + this.GraphLogger.Info("AuthenticationProvider: Generating OAuth token."); + + var credential = new ClientSecretCredential(tenant, this.appId, this.appSecret); + Azure.Core.AccessToken tokenResult; + try + { + tokenResult = await this.AcquireTokenWithRetryAsync(credential, resource, attempts: 3).ConfigureAwait(false); + } + catch (Exception ex) + { + this.GraphLogger.Error(ex, $"Failed to generate token for client: {this.appId}"); + throw; + } + + this.GraphLogger.Info($"AuthenticationProvider: Generated OAuth token. Expires at {tokenResult.ExpiresOn}."); + + request.Headers.Authorization = new AuthenticationHeaderValue(schema, tokenResult.Token); + } + + /// + /// Validates the request asynchronously. + /// This method will be called any time we have an incoming request. + /// Returning invalid result will trigger a Forbidden response. + /// + /// The request. + /// + /// The structure. + /// + public async Task ValidateInboundRequestAsync(HttpRequestMessage request) + { + var token = request?.Headers?.Authorization?.Parameter; + if (string.IsNullOrWhiteSpace(token)) + { + return new RequestValidationResult { IsValid = false }; + } + + // Currently the service does not sign outbound request using AAD, instead it is signed + // with a private certificate. In order for us to be able to ensure the certificate is + // valid we need to download the corresponding public keys from a trusted source. + const string authDomain = "https://api.aps.skype.com/v1/.well-known/OpenIdConfiguration"; + if (this.openIdConfiguration == null || DateTime.Now > this.prevOpenIdConfigUpdateTimestamp.Add(this.openIdConfigRefreshInterval)) + { + this.GraphLogger.Info("Updating OpenID configuration"); + + // Download the OIDC configuration which contains the JWKS + IConfigurationManager configurationManager = + new ConfigurationManager( + authDomain, + new OpenIdConnectConfigurationRetriever()); + this.openIdConfiguration = await configurationManager.GetConfigurationAsync(CancellationToken.None).ConfigureAwait(false); + + this.prevOpenIdConfigUpdateTimestamp = DateTime.Now; + } + + // The incoming token should be issued by graph. + var authIssuers = new[] + { + "https://graph.microsoft.com", + "https://api.botframework.com", + }; + + // Configure the TokenValidationParameters. + // Aet the Issuer(s) and Audience(s) to validate and + // assign the SigningKeys which were downloaded from AuthDomain. + TokenValidationParameters validationParameters = new TokenValidationParameters + { + ValidIssuers = authIssuers, + ValidAudience = this.appId, + IssuerSigningKeys = this.openIdConfiguration.SigningKeys, + }; + + ClaimsPrincipal claimsPrincipal; + try + { + // Now validate the token. If the token is not valid for any reason, an exception will be thrown by the method + JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); + claimsPrincipal = handler.ValidateToken(token, validationParameters, out _); + } + + // Token expired... should somehow return 401 (Unauthorized) + // catch (SecurityTokenExpiredException ex) + // Tampered token + // catch (SecurityTokenInvalidSignatureException ex) + // Some other validation error + // catch (SecurityTokenValidationException ex) + catch (Exception ex) + { + // Some other error + this.GraphLogger.Error(ex, $"Failed to validate token for client: {this.appId}."); + return new RequestValidationResult() { IsValid = false }; + } + + const string ClaimType = "http://schemas.microsoft.com/identity/claims/tenantid"; + var tenantClaim = claimsPrincipal.FindFirst(claim => claim.Type.Equals(ClaimType, StringComparison.Ordinal)); + + if (string.IsNullOrEmpty(tenantClaim?.Value)) + { + // No tenant claim given to us. reject the request. + return new RequestValidationResult { IsValid = false }; + } + + request.Properties.Add(HttpConstants.HeaderNames.Tenant, tenantClaim.Value); + return new RequestValidationResult { IsValid = true, TenantId = tenantClaim.Value }; + } + + /// + /// Acquires the token and retries if failure occurs. + /// + /// The client secret credential. + /// The scope. + /// The attempts. + /// + /// The . + /// + private async Task AcquireTokenWithRetryAsync(ClientSecretCredential credential, string scope, int attempts) + { + while (true) + { + attempts--; + + try + { + return await credential.GetTokenAsync(new Azure.Core.TokenRequestContext(new[] { scope }), CancellationToken.None).ConfigureAwait(false); + } + catch (Exception) + { + if (attempts < 1) + { + throw; + } + } + + await Task.Delay(1000).ConfigureAwait(false); + } + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Authentication/AuthenticationWrapper.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Authentication/AuthenticationWrapper.cs new file mode 100644 index 0000000000..608113e2dd --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Authentication/AuthenticationWrapper.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Graph.Communications.Client.Authentication; +using Microsoft.Graph.Communications.Common; + +namespace CallingBotSample.Authentication +{ + public class AuthenticationWrapper : IRequestAuthenticationProvider + { + private readonly IRequestAuthenticationProvider authenticationProvider; + private readonly string tenant; + + /// + /// Initializes a new instance of the class. + /// + /// The authentication provider. + /// The tenant. + public AuthenticationWrapper(IRequestAuthenticationProvider authenticationProvider, string? tenant = null) + { + this.authenticationProvider = authenticationProvider.NotNull(nameof(authenticationProvider)); + this.tenant = tenant; + } + + /// + public Task AuthenticateOutboundRequestAsync(HttpRequestMessage request, string tenant) + { + return this.authenticationProvider.AuthenticateOutboundRequestAsync(request, tenant); + } + + /// + public Task ValidateInboundRequestAsync(HttpRequestMessage request) + { + return this.authenticationProvider.ValidateInboundRequestAsync(request); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Bots/CallingBot.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Bots/CallingBot.cs new file mode 100644 index 0000000000..6d8d9541de --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Bots/CallingBot.cs @@ -0,0 +1,304 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using CallingBotSample.Authentication; +using CallingBotSample.Cache; +using CallingBotSample.Models; +using CallingBotSample.Options; +using CallingBotSample.Services.BotFramework; +using CallingBotSample.Services.CognitiveServices; +using CallingBotSample.Services.MicrosoftGraph; +using CallingBotSample.Services.TeamsRecordingService; +using CallingBotSample.Utility; +using CallingMeetingBot.Extensions; +using Microsoft.AspNetCore.Http; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Schema; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.Graph.Models; +using Microsoft.Graph.Models.ODataErrors; +using Microsoft.Graph.Communications.Client.Authentication; +using Microsoft.Graph.Communications.Common.Telemetry; +using Microsoft.Graph.Communications.Core.Notifications; +using Microsoft.Graph.Communications.Core.Serialization; + +namespace CallingBotSample.Bots +{ + public class CallingBot : ActivityHandler + { + // TODO: What does GraphLogger provide? + private readonly IGraphLogger graphLogger; + private readonly IRequestAuthenticationProvider authenticationProvider; + private readonly INotificationProcessor notificationProcessor; + private readonly CommsSerializer serializer; + private readonly BotOptions botOptions; + private readonly ICallService callService; + private readonly AudioRecordingConstants audioRecordingConstants; + private readonly ITeamsRecordingService teamsRecordingService; + private readonly ICallCache callCache; + private readonly IIncidentCache incidentCache; + private readonly ISpeechService speechService; + private readonly IBotService botService; + private readonly ILogger logger; + + public CallingBot( + ICallService callService, + AudioRecordingConstants audioRecordingConstants, + ITeamsRecordingService teamsRecordingService, + IGraphLogger graphLogger, + ICallCache callCache, + IIncidentCache incidentCache, + ISpeechService speechService, + IBotService botService, + IOptions botOptions, + ILogger logger) + { + this.botOptions = botOptions.Value; + this.callService = callService; + this.audioRecordingConstants = audioRecordingConstants; + this.teamsRecordingService = teamsRecordingService; + this.graphLogger = graphLogger; + this.callCache = callCache; + this.incidentCache = incidentCache; + this.speechService = speechService; + this.botService = botService; + this.logger = logger; + + var name = this.GetType().Assembly.GetName().Name; + authenticationProvider = new AuthenticationProvider(name, this.botOptions.AppId, this.botOptions.AppSecret, graphLogger); + + serializer = new CommsSerializer(); + notificationProcessor = new NotificationProcessor(serializer); + notificationProcessor.OnNotificationReceived += this.NotificationProcessor_OnNotificationReceived; + } + + /// + /// Process "/callback" notifications asynchronously. + /// + /// + /// + /// + public async Task ProcessNotificationAsync( + HttpRequest request, + HttpResponse response) + { + try + { + var httpRequest = request.CreateRequestMessage(); + var results = await authenticationProvider.ValidateInboundRequestAsync(httpRequest).ConfigureAwait(false); + if (results.IsValid) + { + var httpResponse = await notificationProcessor.ProcessNotificationAsync(httpRequest).ConfigureAwait(false); + await httpResponse.CreateHttpResponseAsync(response).ConfigureAwait(false); + } + else + { + response.StatusCode = StatusCodes.Status403Forbidden; + } + } + catch (Exception e) + { + response.StatusCode = (int)HttpStatusCode.InternalServerError; + await response.WriteAsync(e.ToString()).ConfigureAwait(false); + } + } + + private void NotificationProcessor_OnNotificationReceived(NotificationEventArgs args) + { + _ = NotificationProcessor_OnNotificationReceivedAsync(args).ForgetAndLogExceptionAsync( + graphLogger, + $"Error processing notification {args.Notification.ResourceUrl} with scenario {args.ScenarioId}"); + } + + private async Task NotificationProcessor_OnNotificationReceivedAsync(NotificationEventArgs args) + { + graphLogger.CorrelationId = args.ScenarioId; + var callId = GetCallIdFromNotification(args); + + if (args.ResourceData is Call call) + { + // If the notification is a newly created, incoming call, answer it + if (args.ChangeType.ToString() == "Created" && call.State == CallState.Incoming) + { + await callService.Answer( + callId, + new List + { + audioRecordingConstants.Speech, + audioRecordingConstants.PleaseRecordYourMessage + }); + } + // If the notification is established (answered), fire a recording prompt + else if ( + args.ChangeType.ToString() == "Updated" + && call.State == CallState.Established) + { + // Some scenarios fire two CallState.Established events. The use of a cache ensures we only play the prompt once on meeting join + // This works by keeping track of when the record prompt on meeting established is sent, and if another notifications comes in + // we do not send the prompt any more. + if (!callCache.GetIsEstablished(callId)) + { + callCache.SetIsEstablished(callId); + await callService.Record(callId, audioRecordingConstants.PleaseRecordYourMessage); + } + + if (incidentCache.TryGetValue(callId, out IncidentDetails incidentDetails)) + { + await callService.InviteParticipant(callId, incidentDetails.Participants.Select(p => new IdentitySet { User = p })); + } + } + } + // If the notification is a recording, download from the Teams Recording Service, and then echo the audio back to the call + // We also convert the recording to text and send it to the meeting chat. + else if (args.ResourceData is RecordOperation recording) + { + if (recording.ResultInfo.Code >= 400) + { + return; + } + + var recordingLocation = await teamsRecordingService.DownloadRecording(recording.RecordingLocation, recording.RecordingAccessToken); + + // Here we are transcribing the recording and sending it as a message in the call chat. + try + { + var callDetails = callService.Get(callId); + var threadId = (await callDetails)?.ChatInfo?.ThreadId; + + // Calls initiated in a 1:1 chat with the bot do not have a threadId + if (threadId != null) + { + var result = await speechService.ConvertWavToText(recordingLocation); + + if (result != null) + { + await botService.SendToConversation($"You said: {result}", threadId); + } + else + { + await botService.SendToConversation($"Sorry, something went wrong while trying to transcribe your recording.", threadId); + } + } + } + catch (ODataError ex) + { + logger.LogError(ex, "Failure while sending a message to the coversation. The app might not be installed in the conversation scope."); + } + catch (Exception ex) + { + logger.LogError(ex, "Failure converting speech to text."); + } + + await callService.PlayPrompt( + callId, + new List + { + new MediaInfo { + // This URL needs to be publicly accessible, so Microsoft Teams can play the audio. + // In a production environment, you might want to consider a better location than + // this server's content directory. + Uri = new Uri(botOptions.BotBaseUrl, recordingLocation).ToString(), + ResourceId = Guid.NewGuid().ToString(), + } + }); + } + // If the notification is a play prompt operation, we should check if the prompt is temporary and delete the file + else if (args.ResourceData is PlayPromptOperation playPromptOperation) + { + if (playPromptOperation.ResultInfo.Code >= 400 || + playPromptOperation.Status != OperationStatus.Completed) + { + return; + } + + if (playPromptOperation.AdditionalData.TryGetValue("prompts", out object? obj)) + { + object[] objs = obj as object[] ?? new object[0]; + MediaPrompt[] prompts = Array.ConvertAll(objs, (object o) => (MediaPrompt)o); + + foreach (MediaPrompt prompt in prompts) + { + if (prompt.MediaInfo.Uri.Contains(botOptions.RecordingDownloadDirectory) && + botOptions.BotBaseUrl != null && + prompt.MediaInfo.Uri.StartsWith(botOptions.BotBaseUrl.ToString())) + { + var relativeRecordingPath = prompt.MediaInfo.Uri.Substring(botOptions.BotBaseUrl.ToString().Length); + + // If this deletion attempt fails we do not reattempt. If you implement this pattern you should improve the resiliency of this call. + teamsRecordingService.DeleteRecording(relativeRecordingPath); + } + } + } + } + // If the notification is participants change, keep track of if a User has joined the call at some point + // if at least one user has joined, and only the bot is remaining in the call, get the bot to hang up. + // This ensures that the Bot doesn't keep a call active for a long period of time. + else if (args.IsParticipantsNotification() && args.ResourceData is object[] objs) + { + Participant[] participants = Array.ConvertAll(objs, (object obj) => (Participant)obj); + + if (participants.Length > 0) + { + bool atLeastOneUserJoined = callCache.GetAtLeastOneUserJoined(callId); + + if (!atLeastOneUserJoined && participants.Any(p => p.Info.Identity.User != null)) + { + callCache.SetAtLeastOneUserJoined(callId); + + if (incidentCache.TryGetValue(callId, out IncidentDetails incidentDetails)) + { + string? textToSpeechRecordingLocation = await speechService.ConvertTextToSpeech( + $"There is an ongoing incident for {incidentDetails.IncidentSubject}. Your assistance is required."); + + if (textToSpeechRecordingLocation != null) + { + await callService.PlayPrompt( + callId, + new List + { + new MediaInfo + { + Uri = new Uri(botOptions.BotBaseUrl, textToSpeechRecordingLocation).ToString(), + ResourceId = Guid.NewGuid().ToString(), + } }); + } + } + else + { + // Play the record prompt only when the first user joins the call + await callService.Record(callId, audioRecordingConstants.PleaseRecordYourMessage); + } + } + + // If there is only one participant remaining, and it's this application, and at least one user has joined at some point, hang up + if (participants.Length == 1 && + participants[0]?.Info?.Identity?.Application?.Id == botOptions.AppId && + atLeastOneUserJoined) + { + await callService.HangUp(callId); + return; + } + } + } + } + + private string GetCallIdFromNotification(NotificationEventArgs notificationArgs) + { + if (notificationArgs.ResourceData is CommsOperation operation && !string.IsNullOrEmpty(operation.ClientContext)) + { + return operation.ClientContext; + } + + // Resource URLs are in the format below, with the call id in the 3rd position (position 0 will be empty) + // #microsoft.graph.call: /communications/calls/<> + // #microsoft.graph.recordOperation: /communications/calls/<>/operations/<> + return notificationArgs.Notification.ResourceUrl.Split('/')[3]; + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Bots/MessageBot.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Bots/MessageBot.cs new file mode 100644 index 0000000000..80853ed3f3 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Bots/MessageBot.cs @@ -0,0 +1,367 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using CallingBotSample.AdaptiveCards; +using CallingBotSample.Cache; +using CallingBotSample.Helpers; +using CallingBotSample.Models; +using CallingBotSample.Options; +using CallingBotSample.Services.MicrosoftGraph; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Teams; +using Microsoft.Bot.Schema; +using Microsoft.Bot.Schema.Teams; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.Graph.Models; +using Microsoft.Graph.Models.ODataErrors; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using MeetingInfo = Microsoft.Graph.Models.MeetingInfo; + +namespace CallingBotSample.Bots +{ + public class MessageBot : TeamsActivityHandler + { + private readonly IAdaptiveCardFactory adaptiveCardFactory; + private readonly AudioRecordingConstants audioRecordingConstants; + + private readonly ICallService callService; + private readonly IChatService chatService; + private readonly IOnlineMeetingService onlineMeetingService; + private readonly IIncidentCache incidentCache; + + private readonly AzureAdOptions azureAdOptions; + private readonly BotOptions botOptions; + private readonly ILogger logger; + + public MessageBot( + IAdaptiveCardFactory adaptiveCardFactory, + AudioRecordingConstants audioRecordingConstants, + ICallService callService, + IChatService chatService, + IOnlineMeetingService onlineMeetingService, + IIncidentCache incidentCache, + IOptions azureAdOptions, + IOptions botOptions, + ILogger logger) + { + this.adaptiveCardFactory = adaptiveCardFactory; + this.audioRecordingConstants = audioRecordingConstants; + + this.callService = callService; + this.chatService = chatService; + this.onlineMeetingService = onlineMeetingService; + this.incidentCache = incidentCache; + + this.azureAdOptions = azureAdOptions.Value; + this.botOptions = botOptions.Value; + this.logger = logger; + } + + protected override async Task OnMessageActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) + { + if (string.IsNullOrEmpty(turnContext.Activity.Text)) + { + dynamic value = turnContext.Activity.Value; + if (value != null) + { + string type = value["type"]; + type = string.IsNullOrEmpty(type) ? "." : type.ToLower(); + string? callId = value["callId"] ?? null; + await SendResponse(turnContext, type, callId, cancellationToken); + } + } + else + { + turnContext.Activity.RemoveRecipientMention(); + await SendResponse(turnContext, turnContext.Activity.Text.Trim().ToLower(), null, cancellationToken); + } + } + + protected override Task OnTeamsTaskModuleFetchAsync(ITurnContext turnContext, TaskModuleRequest taskModuleRequest, CancellationToken cancellationToken) + { + var asJobject = JObject.FromObject(taskModuleRequest.Data); + var fetchData = asJobject.ToObject(); + + var taskInfo = new TaskModuleTaskInfo(); + + switch (fetchData?.Action) + { + // Opens a module with a people picker where users can be selected. Later those user will be used to create a call + case "createcall": + taskInfo.Card = adaptiveCardFactory.CreatePeoplePickerCard("Choose who to create a call with:", "Create", callId: null, isMultiSelect: true); + taskInfo.Title = "Create call"; + break; + // Opens a module with a people picker where a user can be selected to transfer the current call to + case "transfercall": + taskInfo.Card = adaptiveCardFactory.CreatePeoplePickerCard("Choose who to transfer the call to:", "Transfer", fetchData?.CallId); + taskInfo.Title = "Transfer call"; + break; + // Opens a module with a people picker where a user can be selected to invite a participant to the current call + case "inviteparticipant": + taskInfo.Card = adaptiveCardFactory.CreatePeoplePickerCard("Choose who to invite to the call:", "Invite", fetchData?.CallId); + taskInfo.Title = "Select the user to invite"; + break; + // Opens a modules with a form to create an incident. This includes a incident title, and those who should be on the call. + case "openincidenttask": + taskInfo.Card = adaptiveCardFactory.CreateIncidentCard(); + taskInfo.Title = "Create incident"; + break; + default: + break; + } + + return Task.FromResult(new TaskModuleResponse + { + Task = new TaskModuleContinueResponse() + { + Value = taskInfo, + }, + }); + } + + protected override async Task OnTeamsTaskModuleSubmitAsync(ITurnContext turnContext, TaskModuleRequest taskModuleRequest, CancellationToken cancellationToken) + { + var asJobject = JObject.FromObject(taskModuleRequest.Data); + var moduleSubmitData = asJobject.ToObject(); + var peoplePicker = moduleSubmitData?.PeoplePicker; + + if (peoplePicker != null) + { + // Adaptive Card people picker returns a comma separated list of aad IDs + var peoplePickerAadIds = peoplePicker.Split(','); + var action = moduleSubmitData?.Action?.ToLowerInvariant(); + var callId = moduleSubmitData?.CallId; + + try + { + switch (action) + { + case "create": + var call = await callService.Create(users: peoplePickerAadIds.Select(p => new Identity { Id = p })); + + if (call != null) + { + await turnContext.SendActivityAsync(MessageFactory.Attachment(adaptiveCardFactory.CreateMeetingActionsCard(call.Id))); + + return await CreateTaskModuleMessageResponse("Working on that, you can close this dialog now."); + } + break; + case "transfer": + return await CallService.HandleTeamsCallNotBeingFound( + callId, + (nonNullCallId) => callService.Transfer( + nonNullCallId, + new Identity { Id = peoplePicker }), + CreateTaskModuleMessageResponse); + case "invite": + return await CallService.HandleTeamsCallNotBeingFound( + callId, + (nonNullCallId) => callService.InviteParticipant( + nonNullCallId, + new[] { new IdentitySet { User = new Identity { Id = peoplePicker } } }), + CreateTaskModuleMessageResponse); + case "createincident": + if (moduleSubmitData?.IncidentName != null) + { + return await CreateIncidentCall( + turnContext, + moduleSubmitData.IncidentName, + peoplePickerAadIds, + cancellationToken); + } + break; + default: + break; + } + } + catch (ODataError ex) + { + logger.LogError(ex, "Failure while making Graph Call"); + return await CreateTaskModuleMessageResponse($"Something went wrong 😖. {ex.Message}"); + } + } + + return await CreateTaskModuleMessageResponse("Something went wrong 😖"); + } + + private async Task SendResponse(ITurnContext turnContext, string input, string? callId, CancellationToken cancellationToken) + { + switch (input) + { + case "playrecordprompt": + await CallService.HandleTeamsCallNotBeingFound( + callId, + (nonNullCallId) => callService.Record(nonNullCallId, audioRecordingConstants.PleaseRecordYourMessage), + (message) => UpdateActivityAsync(message, turnContext, cancellationToken)); + break; + case "hangup": + await CallService.HandleTeamsCallNotBeingFound( + callId, + (nonNullCallId) => callService.HangUp(nonNullCallId), + (message) => UpdateActivityAsync(message, turnContext, cancellationToken)); + break; + case "joinscheduledmeeting": + if (turnContext.Activity.ChannelData["meeting"] != null) + { + var call = await JoinScheduledMeeting(turnContext, cancellationToken); + + if (call != null) + { + await turnContext.SendActivityAsync(MessageFactory.Attachment(adaptiveCardFactory.CreateMeetingActionsCard(call.Id))); + } + } + else + { + await turnContext.SendActivityAsync("Meeting not found. Are you calling this from a meeting chat?", cancellationToken: cancellationToken); + } + break; + default: + await turnContext.SendActivityAsync( + MessageFactory.Attachment( + adaptiveCardFactory.CreateWelcomeCard(turnContext.Activity.ChannelData["meeting"] != null)), cancellationToken); + break; + } + } + + private async Task JoinScheduledMeeting(ITurnContext turnContext, CancellationToken cancellationToken) + { + var organiser = await GetMeetingOrganiser(turnContext, cancellationToken); + + var channelDataTenant = JObject.Parse(JsonConvert.SerializeObject(turnContext.Activity.ChannelData)).SelectToken("tenant"); + organiser.AdditionalData = new Dictionary + { + { "tenantId", channelDataTenant["id"].ToString() } + }; + + return await callService.Create( + new ChatInfo + { + ThreadId = turnContext.Activity.Conversation.Id, + // NOTE: If you don't provide a Message Id, users will not be able to join the call the bot creates. + MessageId = "0" + }, + new OrganizerMeetingInfo + { + Organizer = new IdentitySet + { + User = organiser + }, + }); + } + + private async Task GetMeetingOrganiser(ITurnContext turnContext, CancellationToken cancellationToken) + { + var users = await TeamsInfo.GetPagedMembersAsync(turnContext, cancellationToken: cancellationToken); + + foreach (TeamsChannelAccount user in users.Members) + { + TeamsMeetingParticipant participant = await TeamsInfo.GetMeetingParticipantAsync(turnContext, participantId: user.AadObjectId).ConfigureAwait(false); + + if (participant.Meeting.Role == "Organizer") + { + return new Identity + { + // This needs to be the organiser of the meeting, so you can't use the activity invoker + Id = user.AadObjectId, + }; + } + } + + return null; + } + + private async Task CreateIncidentCall(ITurnContext turnContext, string incidentSubject, string[] peoplePickerAadIds, CancellationToken cancellationToken) + { + var onlineMeeting = await onlineMeetingService.Create(incidentSubject, peoplePickerAadIds); + + if (onlineMeeting != null) + { + MeetingInfo meetingInfo = JoinInfo.ParseMeetingInfo(onlineMeeting.JoinWebUrl); + + var meetingCall = await callService.Create(onlineMeeting.ChatInfo, meetingInfo); + + if (meetingCall != null) + { + await chatService.InstallApp(meetingCall.ChatInfo.ThreadId, botOptions.CatalogAppId); + + var incidentDetails = new IncidentDetails + { + CallId = meetingCall.Id, + IncidentSubject = incidentSubject, + MeetingInfo = meetingInfo, + ChatInfo = onlineMeeting.ChatInfo, + StartTime = DateTime.Now, + Participants = peoplePickerAadIds.Select(p => new Identity + { + Id = p, + }) + }; + incidentCache.Set(meetingCall.Id, incidentDetails); + + await SendActivityToConversation( + turnContext, + onlineMeeting.ChatInfo.ThreadId, + MessageFactory.Attachment(adaptiveCardFactory.CreateIncidentMeetingCard( + incidentDetails.IncidentSubject, + incidentDetails.CallId, + incidentDetails.StartTime, + null + )), + cancellationToken); + + await turnContext.SendActivityAsync("Created incident call successfully.", cancellationToken: cancellationToken); + } + + return await CreateTaskModuleMessageResponse("Working on that, you can close this dialog now."); + } + + return await CreateTaskModuleMessageResponse("Something went wrong 😖"); + } + + private async Task SendActivityToConversation(ITurnContext turnContext, string conversationId, IActivity activity, CancellationToken cancellationToken) + { + var newReference = new ConversationReference + { + Conversation = new ConversationAccount + { + Id = conversationId + }, + ServiceUrl = turnContext.Activity.ServiceUrl + }; + + await (turnContext.Adapter).ContinueConversationAsync( + azureAdOptions.ClientId, + newReference, + async (ITurnContext turnContext, CancellationToken cancellationToken) => + { + await turnContext.SendActivityAsync(activity, cancellationToken); + }, + cancellationToken); + } + + private async Task CreateTaskModuleMessageResponse(string value) + { + return new TaskModuleResponse + { + Task = new TaskModuleMessageResponse() + { + Value = value + }, + }; + } + + private async Task UpdateActivityAsync(string responseText, ITurnContext turnContext, CancellationToken cancellationToken) + { + var updatedActivity = MessageFactory.Text(responseText); + updatedActivity.Id = turnContext.Activity.ReplyToId; + await turnContext.UpdateActivityAsync(updatedActivity, cancellationToken); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/CacheExtensions.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/CacheExtensions.cs new file mode 100644 index 0000000000..b7f3d5a19b --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/CacheExtensions.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Extensions.DependencyInjection; + +namespace CallingBotSample.Cache +{ + public static class CacheExtensions + { + /// + /// Adds Caches + /// + /// + /// + public static IServiceCollection AddCaches(this IServiceCollection services) + { + services.AddMemoryCache(); + services.AddSingleton(); + services.AddSingleton(); + + return services; + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/CallCache.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/CallCache.cs new file mode 100644 index 0000000000..d1aad8531c --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/CallCache.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; + +namespace CallingBotSample.Cache +{ + public class CallCache : ICallCache + { + private readonly IMemoryCache cache; + private readonly ILogger logger; + + private const string AtLeastOneUserJoinedKey = "atLeastOneUserJoined:"; + private const string IsEstablishedKey = "established:"; + + public CallCache(IMemoryCache cache, ILogger logger) + { + this.cache = cache; + this.logger = logger; + } + + /// + public bool GetIsEstablished(string callId) + { + return cache.Get(IsEstablishedKey + callId); + } + + /// + public void SetIsEstablished(string callId, bool isEstablished = true) + { + cache.Set(IsEstablishedKey + callId, isEstablished, new MemoryCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(30) + }); + } + + /// + public bool GetAtLeastOneUserJoined(string callId) + { + return cache.Get(AtLeastOneUserJoinedKey + callId); + } + + /// + public void SetAtLeastOneUserJoined(string callId, bool hasAtLeastOneUserJoined = true) + { + cache.Set(AtLeastOneUserJoinedKey + callId, hasAtLeastOneUserJoined, new MemoryCacheEntryOptions + { + // This 1 hour cache is sufficient for this sample. + // If you are replicating this code, you might want to consider an alternative value which takes into account + // the meeting's scheduled length. + AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1) + }); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/ICallCache.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/ICallCache.cs new file mode 100644 index 0000000000..a40fe6fdf6 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/ICallCache.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CallingBotSample.Cache +{ + public interface ICallCache + { + /// + /// If the at least one user has joined the call + /// + /// The call's ID + /// Whether the a user has joined the call + bool GetAtLeastOneUserJoined(string callId); + + /// + /// Set's whether a user has joined a call + /// + /// The call's ID + /// + /// + void SetAtLeastOneUserJoined(string callId, bool hasAtLeastOneUserJoined = true); + + /// + /// + /// + /// The call's ID + /// Whether the call has been established + bool GetIsEstablished(string callId); + + /// + /// Set's if the call has been established + /// + /// The call's ID + /// + /// + void SetIsEstablished(string callId, bool isEstablished = true); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/IIncidentCache.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/IIncidentCache.cs new file mode 100644 index 0000000000..1e099683ba --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/IIncidentCache.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using CallingBotSample.Models; + +namespace CallingBotSample.Cache +{ + public interface IIncidentCache + { + /// + /// Try get the an incident's details + /// + /// The incident's call ID + /// The incident's details if it exists + /// Whether the details exists + bool TryGetValue(string callId, out IncidentDetails incidentDetails); + + /// + /// Sets the incident's details + /// + /// The incident's call ID + /// The incident's details + /// + void Set(string callId, IncidentDetails incidentDetails); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/IncidentCache.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/IncidentCache.cs new file mode 100644 index 0000000000..9d9c855acf --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Cache/IncidentCache.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using CallingBotSample.Models; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; + +namespace CallingBotSample.Cache +{ + public class IncidentCache : IIncidentCache + { + private readonly IMemoryCache cache; + private readonly ILogger logger; + private const string IncidentKey = "incident:"; + + public IncidentCache(IMemoryCache cache, ILogger logger) + { + this.cache = cache; + this.logger = logger; + } + + /// + public bool TryGetValue(string callId, out IncidentDetails incidentDetails) + { + return cache.TryGetValue(IncidentKey + callId, out incidentDetails); + } + + /// + public void Set(string callId, IncidentDetails incidentDetails) + { + cache.Set(IncidentKey + callId, incidentDetails, new MemoryCacheEntryOptions + { + // This 1 hour cache is sufficient for this sample. + // If you are replicating this code, you might want to consider an alternative value which takes into account + // the meeting's scheduled length. + AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1) + }); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/CallingBotSample.csproj b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/CallingBotSample.csproj new file mode 100644 index 0000000000..d403bdd7d9 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/CallingBotSample.csproj @@ -0,0 +1,30 @@ + + + + net10.0 + latest + enable + enable + true + preview-recommended + + + + + + + + + + + + + + + + + Always + + + + diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Controllers/CallingCallbackController.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Controllers/CallingCallbackController.cs new file mode 100644 index 0000000000..a0a4c0966b --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Controllers/CallingCallbackController.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using CallingBotSample.Bots; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; + +namespace CallingMeetingBot.Controllers +{ + [Route("callback")] + public class CallingCallbackController : Controller + { + private readonly CallingBot bot; + + public CallingCallbackController(CallingBot bot) + { + this.bot = bot; + } + + [HttpPost, HttpGet] + public async Task HandleCallbackRequestAsync() + { + await bot.ProcessNotificationAsync(Request, Response).ConfigureAwait(false); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Controllers/MessageBotController.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Controllers/MessageBotController.cs new file mode 100644 index 0000000000..07c0da2489 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Controllers/MessageBotController.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; + +namespace CallingBotSample.Controllers +{ + // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot + // implementation at runtime. Multiple different IBot implementations running at different endpoints can be + // achieved by specifying a more specific type for the bot constructor argument. + [Route("api/messages")] + [ApiController] + public class MessageBotController : ControllerBase + { + private readonly IBotFrameworkHttpAdapter Adapter; + private readonly IBot Bot; + + public MessageBotController(IBotFrameworkHttpAdapter adapter, IBot bot) + { + Adapter = adapter; + Bot = bot; + } + + [HttpPost, HttpGet] + public async Task PostAsync() + { + // Delegate the processing of the HTTP POST to the adapter. + // The adapter will invoke the bot. + await Adapter.ProcessAsync(Request, Response, Bot); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/new-rg-parameters.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/new-rg-parameters.json new file mode 100644 index 0000000000..ead3390932 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/new-rg-parameters.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "value": "" + }, + "groupName": { + "value": "" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "botId": { + "value": "" + }, + "botSku": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "newAppServicePlanLocation": { + "value": "" + }, + "newWebAppName": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/preexisting-rg-parameters.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/preexisting-rg-parameters.json new file mode 100644 index 0000000000..b6f5114fcc --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/preexisting-rg-parameters.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "botId": { + "value": "" + }, + "botSku": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appServicePlanLocation": { + "value": "" + }, + "existingAppServicePlan": { + "value": "" + }, + "newWebAppName": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/template-with-new-rg.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/template-with-new-rg.json new file mode 100644 index 0000000000..138a613c21 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/template-with-new-rg.json @@ -0,0 +1,184 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "newAppServicePlanLocation": { + "type": "string", + "metadata": { + "description": "The location of the App Service Plan. Defaults to \"westus\"." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "appServicePlanName": "[parameters('newAppServicePlanName')]", + "resourcesLocation": "[parameters('newAppServicePlanLocation')]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]", + "resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "properties": { + "name": "[variables('appServicePlanName')]" + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "10.14.1" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + }, + { + "apiVersion": "2017-12-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "bot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "developerAppInsightsApplicationId": null, + "developerAppInsightKey": null, + "publishingCredentials": null, + "storageResourceId": null + }, + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', variables('webAppName'))]" + ] + } + ], + "outputs": {} + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/template-with-preexisting-rg.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/template-with-preexisting-rg.json new file mode 100644 index 0000000000..170089a511 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/DeploymentTemplates/template-with-preexisting-rg.json @@ -0,0 +1,155 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "F0", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appServicePlanLocation": { + "type": "string", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "existingAppServicePlan": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", + "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", + "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), parameters('newAppServicePlanName'))]", + "resourcesLocation": "[parameters('appServicePlanLocation')]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingAppServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "properties": { + "name": "[variables('servicePlanName')]" + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "10.14.1" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + }, + { + "apiVersion": "2017-12-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "bot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "developerAppInsightsApplicationId": null, + "developerAppInsightKey": null, + "publishingCredentials": null, + "storageResourceId": null + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ] + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Extensions/HttpExtensions.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Extensions/HttpExtensions.cs new file mode 100644 index 0000000000..2a76799a47 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Extensions/HttpExtensions.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; + +namespace CallingMeetingBot.Extensions +{ + public static class HttpExtensions + { + public static HttpRequestMessage CreateRequestMessage(this HttpRequest request) + { + var displayUri = request.GetDisplayUrl(); + var httpRequest = new HttpRequestMessage + { + RequestUri = new Uri(displayUri), + Method = new HttpMethod(request.Method), + }; + + if (request.ContentLength.HasValue && request.ContentLength.Value > 0) + { + httpRequest.Content = new StreamContent(request.Body); + } + + // Copy headers + foreach (var header in request.Headers) + { + httpRequest.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()); + } + + return httpRequest; + } + + public static async Task CreateHttpResponseAsync(this HttpResponseMessage response, HttpResponse httpResponse) + { + httpResponse.StatusCode = (int)response.StatusCode; + + if (response.Content != null) + { + var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + await httpResponse.WriteAsync(content).ConfigureAwait(false); + } + + // Copy headers + foreach (var header in response.Headers) + { + response.Headers.Add(header.Key, header.Value); + } + + return httpResponse; + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Extensions/NotificationEventArgsExtenstions.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Extensions/NotificationEventArgsExtenstions.cs new file mode 100644 index 0000000000..5f3a929ce9 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Extensions/NotificationEventArgsExtenstions.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Graph.Communications.Core.Notifications; + +namespace CallingMeetingBot.Extensions +{ + /// + /// Extensions for NotificationEventArgs + /// + public static class NotificationEventArgsExtensions + { + /// + /// Checks if an incoming notification is about participants changing + /// + /// The notification + /// Whether it is a participant notification + public static bool IsParticipantsNotification(this NotificationEventArgs args) => + args.ChangeType.ToString() == "Updated" && + args.Notification.ResourceUrl.Contains("/participants"); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Helpers/JoinInfo.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Helpers/JoinInfo.cs new file mode 100644 index 0000000000..7994fd6074 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Helpers/JoinInfo.cs @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IO; +using System.Net; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Text.RegularExpressions; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Helpers +{ + /// + /// Gets the join information. + /// + public class JoinInfo + { + /// + /// Parse Join URL into its components. + /// + /// Join URL from Team's meeting body. + /// Parsed data. + public static MeetingInfo ParseMeetingInfo(string joinURL) + { + var decodedURL = WebUtility.UrlDecode(joinURL); + + //// URL being needs to be in this format. + //// https://teams.microsoft.com/l/meetup-join/19:cd9ce3da56624fe69c9d7cd026f9126d@thread.skype/1509579179399?context={"Tid":"72f988bf-86f1-41af-91ab-2d7cd011db47","Oid":"550fae72-d251-43ec-868c-373732c2704f","MessageId":"1536978844957"} + //// https://teams.microsoft.com/l/meetup-join/19:meeting_MDQzYmJlMDctMWJiZS00OGExLTlmYjUtZTczNzVhZGM1OTQx@thread.v2/0?context={"Tid":"c80f38d3-c04c-49bf-a48b-9d99278d4ac6","Oid":"782f076f-f6f9-4bff-9673-ea1997283e9c"} + + var regex = new Regex("https://teams\\.microsoft\\.com.*/(?[^/]+)/(?[^/]+)\\?context=(?{.*})"); + var match = regex.Match(decodedURL); + if (!match.Success) + { + throw new ArgumentException($"Join URL cannot be parsed: {joinURL}.", nameof(joinURL)); + } + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(match.Groups["context"].Value))) + { + var ctxt = (Context)new DataContractJsonSerializer(typeof(Context)).ReadObject(stream); + + var meetingInfo = new OrganizerMeetingInfo + { + Organizer = new IdentitySet + { + User = new Identity { Id = ctxt.Oid }, + }, + }; + meetingInfo.Organizer.User.AdditionalData = new Dictionary + { + { "tenantId", ctxt.Tid } + }; + + return meetingInfo; + } + } + + /// + /// Join URL context. + /// + [DataContract] + private class Context + { + /// + /// Gets or sets the Tenant Id. + /// + [DataMember] + public string? Tid { get; set; } + + /// + /// Gets or sets the AAD object id of the user. + /// + [DataMember] + public string? Oid { get; set; } + + /// + /// Gets or sets the chat message id. + /// + [DataMember] + public string? MessageId { get; set; } + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/IncidentDetails.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/IncidentDetails.cs new file mode 100644 index 0000000000..38c81954fa --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/IncidentDetails.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Models +{ + public class IncidentDetails + { + /// + /// The Incident's call's ID + /// + public string? CallId { get; set; } + + /// + /// Subject of the incident. This will be spoken in the meeting + /// + public string? IncidentSubject { get; set; } + + /// + /// Meeting's info, used for creating the call + /// + public MeetingInfo? MeetingInfo { get; set; } + + /// + /// Meeting's chat info, used for creating the call + /// + public ChatInfo? ChatInfo { get; set; } + + /// + /// The start time of the meeting, used in the Adaptive Card with the details shown in the chat + /// + public DateTime StartTime { get; set; } + + /// + /// The end time of the meeting, used in the Adaptive Card with the details shown in the chat + /// + public DateTime? EndTime { get; set; } + + /// + /// Meeting participants, used to ensure the participants are invited to the call + /// + public IEnumerable Participants { get; set; } = new List(); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/MeetingActionDetails.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/MeetingActionDetails.cs new file mode 100644 index 0000000000..d682c095f1 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/MeetingActionDetails.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CallingBotSample.Models +{ + public class MeetingActionDetails + { + public string? MeetingActionsCardActivityId { get; set; } + public string? MeetingId { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/TaskModuleFetchData.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/TaskModuleFetchData.cs new file mode 100644 index 0000000000..89402a296d --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/TaskModuleFetchData.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CallingBotSample.Models +{ + public class TaskModuleFetchData + { + public string? Action { get; set; } + public string? CallId { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/TaskModuleSubmitData.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/TaskModuleSubmitData.cs new file mode 100644 index 0000000000..e398ddbcd9 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Models/TaskModuleSubmitData.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CallingBotSample.Models +{ + public class TaskModuleSubmitData + { + public string? PeoplePicker { get; set; } + public string? Action { get; set; } + public string? CallId { get; set; } + public string? IncidentName { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/AzureAdOptions.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/AzureAdOptions.cs new file mode 100644 index 0000000000..63019e283f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/AzureAdOptions.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CallingBotSample.Options +{ + /// + /// The Azure AD options class. + /// + public class AzureAdOptions + { + /// + /// Gets or sets the application id as auth client id. + /// + public string? ClientId { get; set; } + + /// + /// Gets or sets the application secret as auth client secret. + /// + public string? ClientSecret { get; set; } + + /// + /// Gets or sets the instance. + /// + public string? Instance { get; set; } + + /// + /// Gets or sets the tenant id. + /// + public string? TenantId { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/BotOptions.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/BotOptions.cs new file mode 100644 index 0000000000..4a248e4dc6 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/BotOptions.cs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace CallingBotSample.Options +{ + public class BotOptions + { + /// + /// Gets the application id. + /// + public string? AppId { get; set; } + + /// + /// Gets the application secret. + /// + public string? AppSecret { get; set; } + + /// + /// Gets the calls uri of the application. + /// + public Uri? BotBaseUrl { get; set; } + + /// + /// Gets the comms platform endpoint uri. + /// + public Uri? PlaceCallEndpointUrl { get; set; } + + /// + /// Gets the graph resource url. + /// + public string? GraphApiResourceUrl { get; set; } + + /// + /// Gets The Microsoft login url + /// + public string? MicrosoftLoginUrl { get; set; } + + /// + /// The download directory of recordings + /// + public string RecordingDownloadDirectory { get; set; } = "temp"; + + /// + /// The ID assigned to the app in the catalog + /// + public string CatalogAppId { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/CognitiveServicesOptions.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/CognitiveServicesOptions.cs new file mode 100644 index 0000000000..e835364cd5 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/CognitiveServicesOptions.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CallingBotSample.Options +{ + /// + /// The Cognitive Services options class. + /// + public class CognitiveServicesOptions + { + /// + /// Is the service enabled + /// + public bool Enabled { get; set; } + + /// + /// Cognitive Services speech key + /// + public string? SpeechKey { get; set; } + + /// + /// Cognitive Services speech region + /// + public string? SpeechRegion { get; set; } + + /// + /// The language to use when recognising speech + /// + public string? SpeechRecognitionLanguage { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/UsersOptions.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/UsersOptions.cs new file mode 100644 index 0000000000..9a0fb7cd6f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Options/UsersOptions.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace CallingBotSample.Options +{ + /// + /// The Users options + /// + public class UsersOptions + { + /// + /// A user id that has been assigned an online meeting policy + /// + public string? UserIdWithAssignedOnlineMeetingPolicy { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Program.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Program.cs new file mode 100644 index 0000000000..0a8d178dc1 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Program.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using CallingBotSample; +using CallingBotSample.AdaptiveCards; +using CallingBotSample.Bots; +using CallingBotSample.Cache; +using CallingBotSample.Options; +using CallingBotSample.Services.BotFramework; +using CallingBotSample.Services.CognitiveServices; +using CallingBotSample.Services.MicrosoftGraph; +using CallingBotSample.Services.TeamsRecordingService; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Graph.Communications.Common.Telemetry; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); +builder.Services.AddOptions(); +builder.Services.AddHttpClient("TeamsRecordingService"); + +builder.Services.AddSingleton(new GraphLogger(typeof(Program).Assembly.GetName().Name)); + +// Create the Bot Framework Authentication to be used with the Bot Adapter. +// Configured as single-tenant. +builder.Services.AddSingleton(); + +// Create the Bot Framework Adapter with error handling enabled. +builder.Services.AddSingleton(); + +// Create the bot as a transient. In this case the ASP Controller is expecting an IBot. +builder.Services.AddTransient(); +builder.Services.AddTransient(); + +builder.Services.Configure(builder.Configuration.GetSection("AzureAd")); +builder.Services.Configure(builder.Configuration.GetSection("Bot")); +builder.Services.Configure(builder.Configuration.GetSection("CognitiveServices")); +builder.Services.Configure(builder.Configuration.GetSection("Users")); + +builder.Services.AddSingleton(); +builder.Services.AddMicrosoftGraphServices(options => builder.Configuration.Bind("AzureAd", options)); + +builder.Services.AddSingleton(); +builder.Services.AddScoped(); + +builder.Services.AddTransient(); +builder.Services.AddCaches(); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +} + +app.UseHttpsRedirection(); +app.UseCookiePolicy(); + +app.UseDefaultFiles(); +app.UseStaticFiles(); +app.UseWebSockets(); +app.UseRouting(); +app.UseAuthorization(); +app.MapControllers(); + +app.Run(); diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Properties/launchSettings.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Properties/launchSettings.json new file mode 100644 index 0000000000..adf7587de9 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:3978/", + "sslPort": 3978 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "CallingBotSample": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:3978" + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/CreateIncidentCard.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/CreateIncidentCard.json new file mode 100644 index 0000000000..1292699d38 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/CreateIncidentCard.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.4", + "type": "AdaptiveCard", + "body": [ + { + "type": "Input.Text", + "id": "incidentName", + "label": "Incident Name" + }, + { + "type": "Input.ChoiceSet", + "label": "Choose incident attendees", + "choices.data": { + "type": "Data.Query", + "dataset": "graph.microsoft.com/users" + }, + "id": "peoplePicker", + "isMultiSelect": "true" + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "Create incident", + "data": { + "action": "createincident", + "msteams": { + "type": "task/submit" + } + } + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/IncidentMeetingActionsCard.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/IncidentMeetingActionsCard.json new file mode 100644 index 0000000000..39fb0f3c71 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/IncidentMeetingActionsCard.json @@ -0,0 +1,158 @@ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.4", + "body": [ + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "auto", + "items": [ + { + "type": "TextBlock", + "text": "Incident Title", + "isSubtle": true, + "wrap": true + }, + { + "type": "TextBlock", + "text": "${title}", + "spacing": "None", + "size": "Large", + "wrap": true, + "weight": "Bolder" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "Status", + "horizontalAlignment": "Right", + "isSubtle": true, + "wrap": true + }, + { + "type": "TextBlock", + "text": "${if(endTime != '', 'RESOLVED', 'ACTIVE')}", + "horizontalAlignment": "Right", + "spacing": "None", + "size": "Large", + "color": "${if(endTime != '', 'good', 'attention')}", + "wrap": true + } + ] + } + ] + }, + { + "type": "ColumnSet", + "spacing": "Medium", + "separator": true, + "columns": [ + { + "type": "Column", + "width": 1, + "items": [ + { + "type": "TextBlock", + "text": "Start time", + "isSubtle": true, + "weight": "Bolder", + "wrap": true + }, + { + "type": "TextBlock", + "text": "{{TIME(${string(startTime)})}}", + "color": "${if(endTime != '', '', 'attention')}", + "weight": "Bolder", + "spacing": "Small", + "wrap": true + } + ] + }, + { + "type": "Column", + "width": 1, + "items": [ + { + "type": "TextBlock", + "text": "End time", + "isSubtle": true, + "horizontalAlignment": "Right", + "weight": "Bolder", + "wrap": true + }, + { + "type": "TextBlock", + "text": "--", + "$when": "${endTime == ''}", + "horizontalAlignment": "Right", + "weight": "Bolder", + "spacing": "Small", + "wrap": true + }, + { + "type": "TextBlock", + "text": "{{TIME(${string(endTime)})}}", + "$when": "${endTime != ''}", + "color": "Good", + "horizontalAlignment": "Right", + "weight": "Bolder", + "spacing": "Small", + "wrap": true + } + ] + } + ] + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "Transfer call", + "id": "transfercall", + "data": { + "action": "transfercall", + "msteams": { + "type": "task/fetch" + } + } + }, + { + "type": "Action.Submit", + "title": "Invite participant to meeting", + "id": "inviteparticipant", + "data": { + "action": "inviteparticipant", + "msteams": { + "type": "task/fetch" + }, + "callId": "${callId}" + } + }, + { + "type": "Action.Submit", + "title": "Play record prompt", + "id": "playrecordprompt", + "data": { + "type": "playrecordprompt", + "callId": "${callId}" + } + }, + { + "type": "Action.Submit", + "title": "Hang up", + "id": "hangup", + "data": { + "type": "hangup", + "callId": "${callId}" + } + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/MeetingActions.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/MeetingActions.json new file mode 100644 index 0000000000..7d7ec9a06a --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/MeetingActions.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.4", + "type": "AdaptiveCard", + "body": [ + { + "type": "TextBlock", + "size": "Medium", + "weight": "Bolder", + "text": "Control this meeting" + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "Transfer call", + "id": "transfercall", + "data": { + "action": "transfercall", + "msteams": { + "type": "task/fetch" + }, + "callId": "${callId}" + } + }, + { + "type": "Action.Submit", + "title": "Invite participant to meeting", + "id": "inviteparticipant", + "data": { + "action": "inviteparticipant", + "msteams": { + "type": "task/fetch" + }, + "callId": "${callId}" + } + }, + { + "type": "Action.Submit", + "title": "Play record prompt", + "id": "playrecordprompt", + "data": { + "type": "playrecordprompt", + "callId": "${callId}" + } + }, + { + "type": "Action.Submit", + "title": "Hang up", + "id": "hangup", + "data": { + "type": "hangup", + "callId": "${callId}" + } + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/PeoplePicker.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/PeoplePicker.json new file mode 100644 index 0000000000..db0fe41234 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/PeoplePicker.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.4", + "type": "AdaptiveCard", + "body": [ + { + "type": "Input.ChoiceSet", + "label": "${choiceLabel}", + "choices.data": { + "type": "Data.Query", + "dataset": "graph.microsoft.com/users" + }, + "id": "peoplePicker", + "isMultiSelect": "${isMultiSelect}" + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "${action}", + "data": { + "action": "${action}", + "msteams": { + "type": "task/submit" + }, + "callId": "${callId}" + } + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/WelcomeCard.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/WelcomeCard.json new file mode 100644 index 0000000000..b82a8f74c2 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Resources/WelcomeCard.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.4", + "type": "AdaptiveCard", + "body": [ + { + "type": "TextBlock", + "size": "Medium", + "weight": "Bolder", + "text": "Calling Bot" + }, + { + "type": "TextBlock", + "text": "Sample Calling Bot", + "wrap": true + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "Create Call", + "id": "createcall", + "data": { + "action": "createcall", + "msteams": { + "type": "task/fetch" + } + } + }, + { + "type": "Action.Submit", + "title": "Create Incident", + "id": "openincidenttask", + "data": { + "action": "openincidenttask", + "msteams": { + "type": "task/fetch" + } + } + }, + { + "type": "Action.Submit", + "title": "Join scheduled meeting", + "id": "joinscheduledmeeting", + "data": { + "type": "joinscheduledmeeting" + }, + "$when": "${showJoinMeetingButton}" + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/BotService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/BotService.cs new file mode 100644 index 0000000000..b26f6b5ffc --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/BotService.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Connector; +using Microsoft.Bot.Schema; +using Microsoft.Extensions.Logging; + +namespace CallingBotSample.Services.BotFramework +{ + /// + public class BotService : IBotService + { + private readonly IConnectorClientFactory connectorClientFactory; + private readonly ILogger logger; + + /// + /// Initializes a new instance of the class. + /// + /// Connector client factory + /// Logger. + public BotService(IConnectorClientFactory connectorClientFactory, ILogger logger) + { + this.connectorClientFactory = connectorClientFactory; + this.logger = logger; + } + + /// + public Task SendToConversation(string message, string conversationId) + { + return SendToConversation(MessageFactory.Text(message), conversationId); + } + + /// + public Task SendToConversation(Attachment attachment, string conversationId) + { + return SendToConversation(MessageFactory.Attachment(attachment), conversationId); + } + + private async Task SendToConversation(IActivity activity, string conversationId) + { + ConnectorClient client = connectorClientFactory.CreateConnectorClient(); + + return await client.Conversations.SendToConversationAsync(conversationId, (Activity)activity); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/ConnectorClientFactory.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/ConnectorClientFactory.cs new file mode 100644 index 0000000000..fef195e065 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/ConnectorClientFactory.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Concurrent; +using System.Net.Http; +using CallingBotSample.Options; +using Microsoft.Bot.Connector; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace CallingBotSample.Services.BotFramework +{ + /// + public class ConnectorClientFactory : IConnectorClientFactory + { + private readonly BotOptions botOptions; + private readonly ConcurrentDictionary connectorClients = new ConcurrentDictionary(); + private readonly ILogger logger; + + /// + /// Initializes a new instance of the class. + /// + /// Logger. + public ConnectorClientFactory(IOptions botOptions, ILogger logger) + { + this.botOptions = botOptions.Value; + this.logger = logger; + } + + /// + public ConnectorClient CreateConnectorClient() + { + return CreateConnectorClient( + // We are using the Global Service URL endpoint which will work if you only call public clouds. If you need to support government clouds, + // you will need to keep track of the serviceUrl used in MessageBot handler, and pass it here. + // You can learn more about this in the documentation: https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages?tabs=dotnet#create-the-conversation + new Uri("https://smba.trafficmanager.net/teams/"), + new MicrosoftAppCredentials(botOptions.AppId, botOptions.AppSecret)); + } + + private ConnectorClient CreateConnectorClient(Uri serviceUrl, AppCredentials appCredentials) + { + // As multiple bots can listen on a single serviceUrl, the clientKey also includes the OAuthScope. + var clientKey = $"{serviceUrl}:{appCredentials?.MicrosoftAppId}:{appCredentials?.OAuthScope}"; + + return connectorClients.GetOrAdd(clientKey, (key) => + { + return new ConnectorClient(serviceUrl, appCredentials, new HttpClient()); + }); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/IBotService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/IBotService.cs new file mode 100644 index 0000000000..6fff5e3881 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/IBotService.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; +using Microsoft.Bot.Schema; + +namespace CallingBotSample.Services.BotFramework +{ + /// + /// Service for calling Bot Framework + /// + public interface IBotService + { + /// + /// Send a string message to a conversation + /// + /// Message to send to the conversation + /// The Id of the conversation to send the message to + /// The created resource + Task SendToConversation(string message, string conversationId); + + /// + /// Send an attachment to a conversation + /// + /// Attachment to send to the conversation + /// The Id of the conversation to send the message to + /// The created resource + Task SendToConversation(Attachment attachment, string conversationId); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/IConnectorClientFactory.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/IConnectorClientFactory.cs new file mode 100644 index 0000000000..d9da578a69 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/BotFramework/IConnectorClientFactory.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Bot.Connector; + +namespace CallingBotSample.Services.BotFramework +{ + /// + /// Factory to for handling a Bot Framework connector client + /// + public interface IConnectorClientFactory + { + /// + /// Creates a connector client based on the service url. + /// Ensures only one client per serviceUrl/appId/scope is created + /// + /// The connector client + ConnectorClient CreateConnectorClient(); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/CognitiveServices/ISpeechService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/CognitiveServices/ISpeechService.cs new file mode 100644 index 0000000000..777e1f42ee --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/CognitiveServices/ISpeechService.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; + +namespace CallingBotSample.Services.CognitiveServices +{ + /// + /// Service for handling calls to the Cognitive Speech + /// + public interface ISpeechService + { + /// + /// Convert the speech of a Wav recording to the text value of the recording + /// + /// The file name of the recording + /// The result text of the recognition of the recording. Null if recognition failed + Task ConvertWavToText(string fileName); + + /// + /// Convert text to speech recording + /// + /// The text to covert to speech + /// The path to the audio file of the converted text. Null if conversion failed + Task ConvertTextToSpeech(string text); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/CognitiveServices/SpeechService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/CognitiveServices/SpeechService.cs new file mode 100644 index 0000000000..1b55a3113e --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/CognitiveServices/SpeechService.cs @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IO; +using System.Threading.Tasks; +using CallingBotSample.Options; +using Microsoft.AspNetCore.Hosting; +using Microsoft.CognitiveServices.Speech; +using Microsoft.CognitiveServices.Speech.Audio; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace CallingBotSample.Services.CognitiveServices +{ + /// + public class SpeechService : ISpeechService + { + private readonly IWebHostEnvironment environment; + private readonly CognitiveServicesOptions cognitiveServicesOptions; + private readonly ILogger logger; + + public SpeechService(IWebHostEnvironment environment, IOptions cognitiveServicesOptions, ILogger logger) + { + this.environment = environment; + this.cognitiveServicesOptions = cognitiveServicesOptions.Value; + this.logger = logger; + } + + /// + public async Task ConvertWavToText(string fileName) + { + if (!cognitiveServicesOptions.Enabled) + { + throw new Exception("Cognitive services is not enabled."); + } + + var speechConfig = SpeechConfig.FromSubscription(cognitiveServicesOptions.SpeechKey, cognitiveServicesOptions.SpeechRegion); + speechConfig.SpeechRecognitionLanguage = cognitiveServicesOptions.SpeechRecognitionLanguage; + + var fullFilePath = Path.Combine(environment.WebRootPath, fileName); + + using var audioConfig = AudioConfig.FromWavFileInput(fullFilePath); + using var speechRecognizer = new SpeechRecognizer(speechConfig, audioConfig); + + var result = await speechRecognizer.RecognizeOnceAsync(); + + if (result.Reason == ResultReason.RecognizedSpeech) + { + return result.Text; + } + + logger.LogTrace($"Speech was not recognized, result reason: {result.Reason}"); + return null; + } + + public async Task ConvertTextToSpeech(string text) + { + if (!cognitiveServicesOptions.Enabled) + { + throw new Exception(); + } + + var speechConfig = SpeechConfig.FromSubscription(cognitiveServicesOptions.SpeechKey, cognitiveServicesOptions.SpeechRegion); + speechConfig.SpeechSynthesisVoiceName = "en-US-JennyNeural"; + + using (var speechSynthesizer = new SpeechSynthesizer(speechConfig)) + { + SpeechSynthesisResult result = await speechSynthesizer.SpeakTextAsync(text); + + if (result.Reason == ResultReason.SynthesizingAudioCompleted) + { + AudioDataStream stream = AudioDataStream.FromResult(result); + + var outputFile = $"temp/{Guid.NewGuid()}.wav"; + await stream.SaveToWaveFileAsync(Path.Combine(environment.WebRootPath, outputFile)); + + return outputFile; + } + } + + return null; + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/AudioRecordingConstants.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/AudioRecordingConstants.cs new file mode 100644 index 0000000000..7a192f7952 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/AudioRecordingConstants.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using CallingBotSample.Options; +using Microsoft.Extensions.Options; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Services.MicrosoftGraph +{ + public class AudioRecordingConstants + { + public AudioRecordingConstants(IOptions botOptions) + { + Speech = new MediaInfo + { + Uri = new Uri(botOptions.Value.BotBaseUrl, "audio/speech.wav").ToString(), + ResourceId = Guid.NewGuid().ToString(), + }; + + PleaseRecordYourMessage = new MediaInfo + { + Uri = new Uri(botOptions.Value.BotBaseUrl, "audio/please-record-your-message.wav").ToString(), + ResourceId = Guid.NewGuid().ToString(), + }; + } + + public readonly MediaInfo Speech; + public readonly MediaInfo PleaseRecordYourMessage; + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/CallService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/CallService.cs new file mode 100644 index 0000000000..4eec133be5 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/CallService.cs @@ -0,0 +1,330 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using CallingBotSample.Options; +using Microsoft.Extensions.Options; +using Microsoft.Graph; +using Microsoft.Graph.Communications.Calls.Item.Answer; +using Microsoft.Graph.Communications.Calls.Item.PlayPrompt; +using Microsoft.Graph.Communications.Calls.Item.Participants.Invite; +using Microsoft.Graph.Communications.Calls.Item.RecordResponse; +using Microsoft.Graph.Communications.Calls.Item.Reject; +using Microsoft.Graph.Communications.Calls.Item.Transfer; +using Microsoft.Graph.Models; +using Microsoft.Graph.Models.ODataErrors; + +namespace CallingBotSample.Services.MicrosoftGraph +{ + public class CallService : ICallService + { + private readonly GraphServiceClient graphServiceClient; + private readonly AzureAdOptions azureAdOptions; + private readonly BotOptions botOptions; + + private readonly string callbackUri; + + public CallService(GraphServiceClient graphServiceClient, IOptions azureAdOptions, IOptions botOptions) + { + this.graphServiceClient = graphServiceClient; + this.azureAdOptions = azureAdOptions.Value; + this.botOptions = botOptions.Value; + + callbackUri = new Uri(botOptions.Value.BotBaseUrl, "callback").ToString(); + } + + /// + public Task Answer(string id, IEnumerable? preFetchMedia) + { + return graphServiceClient.Communications.Calls[id] + .Answer + .PostAsync(new AnswerPostRequestBody + { + CallbackUri = callbackUri, + MediaConfig = new ServiceHostedMediaConfig + { + PreFetchMedia = preFetchMedia?.ToList() + }, + AcceptedModalities = new List { Modality.Audio } + }); + } + + /// + public Task Create(IEnumerable users) + { + var call = new Call + { + Direction = CallDirection.Outgoing, + CallbackUri = callbackUri, + TenantId = azureAdOptions.TenantId, + Targets = users.Select(user => new InvitationParticipantInfo + { + Identity = new IdentitySet + { + User = user + } + }).ToList(), + RequestedModalities = new List() + { + Modality.Audio + }, + MediaConfig = new ServiceHostedMediaConfig + { + } + }; + + return graphServiceClient.Communications.Calls + .PostAsync(call); + } + + /// + public Task Create(ChatInfo chatInfo, MeetingInfo meetingInfo) + { + var call = new Call + { + Direction = CallDirection.Outgoing, + CallbackUri = callbackUri, + ChatInfo = chatInfo, + TenantId = azureAdOptions.TenantId, + MeetingInfo = meetingInfo, + RequestedModalities = new List() + { + Modality.Audio + }, + MediaConfig = new ServiceHostedMediaConfig + { + } + }; + + return graphServiceClient.Communications.Calls + .PostAsync(call); + } + + /// + public Task Get(string id) + { + return graphServiceClient.Communications.Calls[id] + .GetAsync(); + } + + /// + public Task HangUp(string id) + { + return graphServiceClient.Communications.Calls[id] + .DeleteAsync(); + } + + /// + public Task InviteParticipant(string id, IEnumerable participants) + { + var invitationParticipants = participants.Select(participant => + new InvitationParticipantInfo + { + Identity = participant + }).ToList(); + + return graphServiceClient.Communications.Calls[id].Participants + .Invite + .PostAsync(new InvitePostRequestBody + { + Participants = invitationParticipants, + ClientContext = id + }); + } + + /// + public Task PlayPrompt(string id, IEnumerable mediaPrompts) + { + return graphServiceClient.Communications.Calls[id] + .PlayPrompt + .PostAsync(new PlayPromptPostRequestBody + { + Prompts = CreatePromptsFromMediaInfos(mediaPrompts).ToList(), + ClientContext = id + }); + } + + /// + public Task Record( + string id, + MediaInfo mediaPrompt, + int maxRecordDurationInSeconds = 10, + IEnumerable? stopTones = null) + { + if (stopTones == null) + { + stopTones = new List() + { + "#", + "1", + "*" + }; + } + + return graphServiceClient.Communications.Calls[id] + .RecordResponse + .PostAsync(new RecordResponsePostRequestBody + { + Prompts = CreatePromptsFromMediaInfos(new List() { mediaPrompt }).ToList(), + BargeInAllowed = null, + InitialSilenceTimeoutInSeconds = null, + MaxSilenceTimeoutInSeconds = null, + MaxRecordDurationInSeconds = maxRecordDurationInSeconds, + PlayBeep = null, + StopTones = stopTones.ToList(), + ClientContext = id + }); + + } + + /// + public Task Redirect(string id) + { + throw new NotImplementedException(); + } + + /// + public Task Reject(string id, RejectReason rejectReason) + { + return graphServiceClient.Communications.Calls[id] + .Reject + .PostAsync(new RejectPostRequestBody + { + Reason = rejectReason + }); + } + + /// + public Task Reject(string id) + { + throw new NotImplementedException(); + } + + /// + public Task Transfer(string id, Identity transferIdentity, Identity? transfereeIdentity = null) + { + var transferTarget = new InvitationParticipantInfo + { + Identity = new IdentitySet + { + User = transferIdentity + }, + AdditionalData = new Dictionary() + { + {"endpointType", "default"} + } + }; + + ParticipantInfo? transferee = null; + if (transfereeIdentity != null) + { + if (transfereeIdentity.AdditionalData == null) + { + transfereeIdentity.AdditionalData = new Dictionary(); + } + transfereeIdentity.AdditionalData["tenantId"] = azureAdOptions.TenantId; + + transferee = new ParticipantInfo + { + Identity = new IdentitySet + { + User = transfereeIdentity + }, + }; + } + + return graphServiceClient.Communications.Calls[id] + .Transfer + .PostAsync(new TransferPostRequestBody + { + TransferTarget = transferTarget, + Transferee = transferee + }); + } + + private IEnumerable CreatePromptsFromMediaInfos(IEnumerable mediaInfos) + { + return mediaInfos.Select(mediaPrompt => + new MediaPrompt + { + MediaInfo = mediaPrompt + }); + } + + /// + /// Wrapper around Graph calls. Handles cases where a call is not found. + /// This might happen when an API call is made using a CallId that has already ended + /// + /// Call's id + /// Function to call + /// Handler for when there is an error + /// A Task + public static async Task HandleTeamsCallNotBeingFound(string? callId, Func function, Func errorHandler) + { + string? errorString = await MakeGraphCallThatMightNotBeFound(callId, function); + + if (errorString != null) + { + await errorHandler(errorString); + } + } + + /// + /// Wrapper around Graph calls. Handles cases where a call is not found. + /// This might happen when an API call is made using a CallId that has already ended + /// + /// Return value + /// Call's id + /// Function to call + /// Handler for when there is an error. + /// A Task, when there is an error a will be returned + public static async Task HandleTeamsCallNotBeingFound(string? callId, Func function, Func> errorHandler) + { + string? errorString = await MakeGraphCallThatMightNotBeFound(callId, function); + + if (errorString != null) + { + return await errorHandler(errorString); + } + + return default; + } + + /// + /// Wrapper around Graph calls. Handles cases where a call is not found. + /// This might happen when an API call is made using a CallId that has already ended + /// + /// Call's id + /// Function to call + /// A Task, when there is an error a string will be returned + private static async Task MakeGraphCallThatMightNotBeFound(string? callId, Func function) + { + if (callId == null) + { + // Without the Meeting ID we are unable to call the API + return "Meeting ID not found, please use the 'Create call' button to create the call."; + } + + try + { + await function(callId); + } + catch (ODataError ex) + { + if (ex.ResponseStatusCode != (int)HttpStatusCode.NotFound) + { + // If it's not a NotFound error please ignore + throw; + } + + return "That action failed. Unable to find call"; + } + + return default; + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/ChatService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/ChatService.cs new file mode 100644 index 0000000000..343fe9ed67 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/ChatService.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; +using Microsoft.Graph; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Services.MicrosoftGraph +{ + public class ChatService : IChatService + { + private readonly GraphServiceClient graphServiceClient; + + public ChatService(GraphServiceClient graphServiceClient) + { + this.graphServiceClient = graphServiceClient; + } + + /// + public Task InstallApp(string chatId, string teamsCatalogAppId) + { + var teamsAppInstallation = new TeamsAppInstallation + { + AdditionalData = new Dictionary() + { + {"teamsApp@odata.bind", $"https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/{teamsCatalogAppId}"} + } + }; + + return graphServiceClient.Chats[chatId].InstalledApps + .PostAsync(teamsAppInstallation); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/ICallService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/ICallService.cs new file mode 100644 index 0000000000..bc233733f9 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/ICallService.cs @@ -0,0 +1,102 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Services.MicrosoftGraph +{ + public interface ICallService + { + /// + /// Answer a call + /// + /// The ID of the call to answer + /// Media that Teams will prefetch. + /// Task + Task Answer(string id, IEnumerable? preFetchMedia); + + /// + /// Create a new call + /// + /// Users to add to the call + /// The calls details + Task Create(IEnumerable users); + + /// + /// Create a new call + /// + /// Chat info of the call + /// Meeting info + /// The calls details + Task Create(ChatInfo chatInfo, MeetingInfo meetingInfo); + + /// + /// Get a calls details + /// + /// The ID of the call + /// The calls details + Task Get(string id); + + /// + /// Delete/Hang up a call + /// + /// The ID of the call + /// Task + Task HangUp(string id); + + /// + /// Invite participants to a call + /// + /// The ID of the call + /// The participants to invite + /// Task + Task InviteParticipant(string id, IEnumerable participants); + + /// + /// Plays a media prompt in a call + /// + /// The ID of the call where you want to play the prompt + /// The Media to play + /// The Play Prompt Operation + Task PlayPrompt(string id, IEnumerable mediaPrompts); + + /// + /// Play the provided prompt in a call, and then record what is said. + /// + /// The ID of the call where you want to record + /// The media to play before recording + /// The maximum duration to record the response before stopping the recording + /// Stop tones to stop the recording + /// The record operation with access token to and file location of the recording + Task Record( + string id, + MediaInfo mediaPrompt, + int maxRecordDurationInSeconds = 10, + IEnumerable? stopTones = null); + + /// + /// Reject a call + /// + /// The ID of the call to reject + /// + Task Reject(string id); + + /// + /// Redirect a call that has not been answered yet + /// + /// The ID of the call to redirect + /// + Task Redirect(string id); + + /// + /// Transfer an ongoing call to another user + /// + /// The ID of the call to transfer + /// + /// + /// + Task Transfer(string id, Identity transferIdentity, Identity? transfereeIdentity = null); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/IChatService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/IChatService.cs new file mode 100644 index 0000000000..65f197b9d6 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/IChatService.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Services.MicrosoftGraph +{ + public interface IChatService + { + /// + /// Install a Teams app to a chat + /// + /// The chat Id to install the app to + /// + /// The app Id to install to the chat. + /// This should be the external app id defined in Teams Admin Center or Platform Center. + /// You need to upload your app to either your org or Teams app store to test this API + /// + /// + Task InstallApp(string chatId, string teamsCatalogAppId); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/IOnlineMeetingService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/IOnlineMeetingService.cs new file mode 100644 index 0000000000..06604b922f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/IOnlineMeetingService.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Services.MicrosoftGraph +{ + public interface IOnlineMeetingService + { + /// + /// Create a meeting. Tied to the + /// + /// Subject of the meeting to create + /// Array of AAD Ids for participants + /// + Task Create(string subject, IEnumerable participantsIds); + + /// + /// + /// + /// + /// + Task Get(string subject); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/MicrosoftGraphExtensions.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/MicrosoftGraphExtensions.cs new file mode 100644 index 0000000000..84c36836d0 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/MicrosoftGraphExtensions.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using Azure.Identity; +using CallingBotSample.Options; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Graph; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Services.MicrosoftGraph +{ + public static class MicrosoftGraphExtensions + { + /// + /// Adds the services that are available in this project to Dependency Injection. + /// Include this in your Startup.cs ConfigureServices if you need to access these services. + /// + /// Service collection. + /// AzureAD Options. + /// Service collections. + public static IServiceCollection AddMicrosoftGraphServices(this IServiceCollection services, Action azureAdOptionsAction) + { + var options = new AzureAdOptions(); + azureAdOptionsAction(options); + + ClientSecretCredential authenticationProvider = new ClientSecretCredential(options.TenantId, options.ClientId, options.ClientSecret); + + services.AddScoped(sp => + { + return new GraphServiceClient(authenticationProvider); + }); + + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddSingleton(); + return services; + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/OnlineMeetingService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/OnlineMeetingService.cs new file mode 100644 index 0000000000..6f40e284aa --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/MicrosoftGraph/OnlineMeetingService.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using CallingBotSample.Options; +using Microsoft.Extensions.Options; +using Microsoft.Graph; +using Microsoft.Graph.Models; + +namespace CallingBotSample.Services.MicrosoftGraph +{ + public class OnlineMeetingService : IOnlineMeetingService + { + private readonly GraphServiceClient graphServiceClient; + private readonly UsersOptions usersOptions; + + public OnlineMeetingService(GraphServiceClient graphServiceClient, IOptions usersOptions) + { + this.graphServiceClient = graphServiceClient; + this.usersOptions = usersOptions.Value; + } + + /// + public Task Create(string subject, IEnumerable participantsIds) + { + var onlineMeeting = new OnlineMeeting + { + StartDateTime = DateTime.UtcNow, + EndDateTime = DateTime.UtcNow.AddMinutes(30), + Subject = subject, + Participants = new MeetingParticipants + { + Attendees = participantsIds.Select(p => new MeetingParticipantInfo + { + Identity = new IdentitySet + { + User = new Identity + { + Id = p, + } + }, + Role = OnlineMeetingRole.Presenter, + }).ToList() + } + }; + + return graphServiceClient.Users[usersOptions.UserIdWithAssignedOnlineMeetingPolicy].OnlineMeetings + .PostAsync(onlineMeeting); + } + + /// + public Task Get(string meetingId) + { + return graphServiceClient.Users[usersOptions.UserIdWithAssignedOnlineMeetingPolicy].OnlineMeetings[meetingId] + .GetAsync(); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/TeamsRecordingService/ITeamsRecordingService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/TeamsRecordingService/ITeamsRecordingService.cs new file mode 100644 index 0000000000..45b3573028 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/TeamsRecordingService/ITeamsRecordingService.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; + +namespace CallingBotSample.Services.TeamsRecordingService +{ + /// + /// Handles recordings created by the Microsoft Teams/Microsoft Graph Interactive voice response (IVR) service + /// + public interface ITeamsRecordingService + { + /// + /// Downloads a recording from the Teams/Microsoft Graph IVR service + /// + /// URL of the recording + /// Access token to download the URL + /// File location of the downloaded file on disk + Task DownloadRecording(string recordingUrl, string accessToken); + + /// + /// Delete a recording that is saved locally. + /// + /// + /// File path of the recording. + /// This should not include the base url, and should be relative to WebRootPath + /// + /// Whether the file was deleted successfully + bool DeleteRecording(string recordingRelativePath); + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/TeamsRecordingService/TeamsRecordingService.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/TeamsRecordingService/TeamsRecordingService.cs new file mode 100644 index 0000000000..0c4bf73133 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Services/TeamsRecordingService/TeamsRecordingService.cs @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IO; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using CallingBotSample.Options; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace CallingBotSample.Services.TeamsRecordingService +{ + /// + public class TeamsRecordingService : ITeamsRecordingService + { + private readonly IWebHostEnvironment environment; + private readonly HttpClient httpClient; + private readonly BotOptions botOptions; + private readonly ILogger logger; + + public TeamsRecordingService(IWebHostEnvironment environment, HttpClient httpClient, IOptions botOptions, ILogger logger) + { + this.environment = environment; + this.httpClient = httpClient; + this.botOptions = botOptions.Value; + this.logger = logger; + } + + /// + public async Task DownloadRecording(string recordingUrl, string accessToken) + { + var fileName = $"{Guid.NewGuid()}.wav"; + var downloadDirectory = Path.Combine(environment.WebRootPath, botOptions.RecordingDownloadDirectory); + var downloadPath = $"{downloadDirectory}/{fileName}"; + + var content = await GetUrlContent(recordingUrl, accessToken); + + if (content == null) + { + throw new Exception("Unable to download file"); + } + + if (!Directory.Exists(downloadDirectory)) + { + Directory.CreateDirectory(downloadDirectory); + } + + // In our sample we are downloading the recording to the server's content directory. In an actual deployment + // if might be better to upload the file to blob storage where you can use SAS tokens and policies to limit + // access to the files + await File.WriteAllBytesAsync(downloadPath, content); + + return $"{botOptions.RecordingDownloadDirectory}/{fileName}"; + } + + public bool DeleteRecording(string recordingRelativePath) + { + var recordingPath = Path.Combine(environment.WebRootPath, recordingRelativePath); + + try + { + File.Delete(recordingPath); + return true; + } + catch (Exception ex) + { + logger.LogError(ex, "Error deleting recording."); + + return false; + } + } + + private async Task GetUrlContent(string url, string accessToken) + { + using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, url)) + { + requestMessage.Headers.Authorization = + new AuthenticationHeaderValue("Bearer", accessToken); + + var result = await httpClient.SendAsync(requestMessage); + + return result.IsSuccessStatusCode ? await result.Content.ReadAsByteArrayAsync() : null; + } + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Utility/CommonUtils.cs b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Utility/CommonUtils.cs new file mode 100644 index 0000000000..4e89662ddf --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/Utility/CommonUtils.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Microsoft.Graph.Communications.Common.Telemetry; + +namespace CallingBotSample.Utility +{ + public static class CommonUtils + { + public static async Task ForgetAndLogExceptionAsync( + this Task task, + IGraphLogger logger, + string? description = null, + [CallerMemberName] string? memberName = null, + [CallerFilePath] string? filePath = null, + [CallerLineNumber] int lineNumber = 0) + { + try + { + await task.ConfigureAwait(false); + logger?.Verbose( + $"Completed running task successfully: {description ?? string.Empty}", + memberName: memberName, + filePath: filePath, + lineNumber: lineNumber); + } + catch (Exception e) + { + // Log and absorb all exceptions here. + logger?.Error( + e, + $"Caught an Exception running the task: {description ?? string.Empty}", + memberName: memberName, + filePath: filePath, + lineNumber: lineNumber); + } + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/appsettings.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/appsettings.json new file mode 100644 index 0000000000..65f7a14210 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/appsettings.json @@ -0,0 +1,31 @@ +{ + "MicrosoftAppId": "<>", + "MicrosoftAppPassword": "<>", + "MicrosoftAppType": "SingleTenant", + "MicrosoftAppTenantId": "<>", + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "TenantId": "<>", + "ClientId": "<>", + "ClientSecret": "<>" + }, + "Bot": { + "AppId": "<>", + "AppSecret": "<>", + "PlaceCallEndpointUrl": "https://graph.microsoft.com/v1.0", + "BotBaseUrl": "https://<>.ngrok-free.app", + "GraphApiResourceUrl": "https://graph.microsoft.com", + "MicrosoftLoginUrl": "https://login.microsoftonline.com/", + "RecordingDownloadDirectory": "temp", + "CatalogAppId": "<>" + }, + "CognitiveServices": { + "Enabled": false, + "SpeechKey": "<>", + "SpeechRegion": "<>", + "SpeechRecognitionLanguage": "<>" + }, + "Users": { + "UserIdWithAssignedOnlineMeetingPolicy": "<>" + } +} diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/audio/please-record-your-message.wav b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/audio/please-record-your-message.wav new file mode 100644 index 0000000000..1eda0b4ea1 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/audio/please-record-your-message.wav differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/audio/speech.wav b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/audio/speech.wav new file mode 100644 index 0000000000..ff85d5f6ad Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/audio/speech.wav differ diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/default.htm b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/default.htm new file mode 100644 index 0000000000..e4401b5e69 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/Source/CallingBotSample/wwwroot/default.htm @@ -0,0 +1,420 @@ + + + + + + + CallingBotSample + + + + + +
+
+
+
CallingBotSample Bot
+
+
+
+
+
Your bot is ready!
+
You can test your bot in the Bot Framework Emulator
+ by connecting to http://localhost:3978/api/messages.
+ +
Visit Azure + Bot Service to register your bot and add it to
+ various channels. The bot's endpoint URL typically looks + like this:
+
https://your_bots_hostname/api/messages
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/assets/sample.json b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/assets/sample.json new file mode 100644 index 0000000000..de6f1dfbab --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-calling-meeting/csharp/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-bot-calling-meeting-csharp", + "source": "officeDev", + "title": "Calling and Meeting Bot Sample V4", + "shortDescription": "This sample demonstrates how a bot can create, join, and transfer calls or meetings within Microsoft Teams.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-calling-meeting/csharp", + "longDescription": [ + "This bot sample showcases the integration of Microsoft Teams and Azure Bot services, enabling functionalities such as call creation, meeting joining, and call transfer. It utilizes cloud communication APIs to streamline the meeting and calling experience in Microsoft Teams." + ], + "creationDateTime": "2021-07-07", + "updateDateTime": "2024-10-10", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "csharp" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "netframework" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://user-images.githubusercontent.com/50989436/122867719-92904800-d347-11eb-87a6-3d61c24c6451.png", + "alt": "Solution UX showing calling and meeting bot sample v4" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/BotSSOSetup.md b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/BotSSOSetup.md new file mode 100644 index 0000000000..b24d263157 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/BotSSOSetup.md @@ -0,0 +1,135 @@ +## Bot SSO Setup +This document guide you to setup AAD and Azure Bot Service, which are the pre-requisites steps to enable Bot SSO. + +### 1. Create and configure AAD app + +#### 1.1 Create AAD app for SSO + +This step will create an AAD app, it will be reused wherever it needs AAD throughout this sample to simpler the steps. + +- Navigate to [Azure _App Registration_ Blade](https://ms.portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade) + +- Click "New Registration" on the upper left corner + +- Fill out name and select third option for supported account type +- Set Redirect Uri to "https://token.botframework.com/.auth/web/redirect" and click "Register": + + ![App Registration Organization](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/AppRegistration.png) + +- Navigate to the AAD app you just created, _copy and paste the Application ID(will referred as **AppId** in this document) somewhere safe_. You'll need it in a future step: + ![Save Application ID](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/AppId.png) + +#### 1.2 Create Client Secret + +- Navigate to the "Certificates & secrets" blade and add a client secret by clicking "New Client Secret" + + ![New Secret](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/ClientSecret.png) +
+ +- _Copy and paste the secret value somewhere safe_. You'll need it in a future step + +#### 1.3. Expose API endpoint + +- Click "_Expose an API_" in the left rail + + - Set your Application ID URL to include your bot id - api://botid-, where is the id of the bot that will be making the SSO request and found in your Teams Application Manifest, which is the same you create and saved in step1.1: + ![Application ID URI](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/AppIdUri.png) + + - Click "_Add a scope_" + + - access_as_user as the Scope name. + + - Set Who can consent? to Admins and users + + - Fill in the fields for configuring the admin and user consent prompts with values that are appropriate for the access_as_user scope. Suggestions: + + - Admin consent display name: Teams can access the user’s profile + + - Admin consent description: Allows Teams to call the app’s web APIs as the current user. + + - User consent display name: Teams can access your user profile and make requests on your behalf + + - User consent description: Enable Teams to call this app’s APIs with the same rights that you have + + - Ensure that State is set to Enabled + + - Click on Add scope button (Note: The domain part of the Scope name displayed just below the text field should automatically match the Application ID URI set in the previous step, with /access_as_user appended to the end) + + ![Add Scope](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/CreateScope.png) + +#### 1.4. Authorize client applications + +Add the following Ids as authorized clients for your application + +- 1fec8e78-bce4-4aaf-ab1b-5451cc387264 (Teams mobile/desktop application) + +- 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 (Teams web application) + + ![Add Client Application](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/AddClient.png) + +#### 1.5. Add any necessary API permissions for downstream calls + +- Navigate to "API permissions" blade on the left hand side + +- Add any user delegated permissions that your app will need to downstream APIs. This quick start only requires User.Read. + + ![Add Permissions](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/image013.png) + +#### 1.6. Enable implicit grant + +- Navigate to "Authentication" + +- Check the *Access tokens* and *ID tokens* boxes and click on Save button. + +### 2. Setup bot in Azure Bot Service + +#### 2.1. Run ngrok - point to port 3978 + +```bash +ngrok http 3978 --host-header="localhost:3978" +``` + +#### 2.2. Create new Azure Bot resource in Azure + +Create [Azure Bot resource](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) in Azure + +- Select Type of App as "Multi Tenant" or as per your need +- Select Creation type as "Use existing app registration" +- Use the copied AppId from the above step and fill in AppId. +- Click on Create on the Azure bot. +- Go to the created resource, navigate to channels and ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/en-us/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + +- Go to the created resource, navigate to and update the "_Messaging endpoint_", use the current `https` URL you were given by running ngrok. Append with the path `/api/messages`: +- For "Microsoft App ID and password", click "Create New", fill in the AppId and client secret you created in step1.1 and step 1.2: + ![Create Azure Bot](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/AzureBotCreate.png) + + ![Create Azure Bot2](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/AzureBotCreate2.png) + +- After you select *Create*, it will take a few moments for your bot service to be provisioned. Once you see a notification indicating the validation process is complete, navigate back to *Home > Bot Services* to find your bot. You may have to refresh the page to see your bot listed. +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/en-us/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + +### 3. Setup Bot Service Connection (TokenStore) + +- In the Azure Portal, navigate back to the Azure Bot resource created in Step 2 + +- Switch to the "Settings" blade and click "Add Setting" under the OAuth Connection Settings section + + ![Add OAuth Settings](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/AzureBotConfigurationPage.png) + +- Fill out the Connection Setting form + + - Enter a name for your new Connection setting. This will be the name that gets referenced inside the settings of your bot service code in step 5 + + - In the Service Provider dropdown, select Azure Active Directory V2 + + - Enter in the client id and client secret obtained in step 1.1 and 1.2 + + - For the Token Exchange URL use the Application ID URL obtained in step 1.3 + + - Specify "common" as the Tenant ID. If you are using Single Tenant app registration then set your tenant Id where the bot is registered. + + - Add all the scopes configured when specifying permissions to downstream APIs in step 1.3 + + - Click "Save" + + ![SSO Connection Settings](https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/AzureBotConnectionString.png) diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart.sln b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart.sln new file mode 100644 index 0000000000..f6300a3e82 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.34814.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotConversationSsoQuickstart", "BotConversationSsoQuickstart\BotConversationSsoQuickstart.csproj", "{BFDF6B3D-BB62-42DD-88EF-528FFE9FCBAD}" +EndProject +Project("{A9E3F50B-275E-4AF7-ADCE-8BE12D41E305}") = "M365Agent", "M365Agent\M365Agent.ttkproj", "{0E7BBEDA-46AA-4CCD-A303-5A97A2148C6B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AB776400-0B2E-4D16-809A-16FDE054C241}" + ProjectSection(SolutionItems) = preProject + BotConversationSsoQuickstart.slnLaunch.user = BotConversationSsoQuickstart.slnLaunch.user + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BFDF6B3D-BB62-42DD-88EF-528FFE9FCBAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFDF6B3D-BB62-42DD-88EF-528FFE9FCBAD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFDF6B3D-BB62-42DD-88EF-528FFE9FCBAD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFDF6B3D-BB62-42DD-88EF-528FFE9FCBAD}.Release|Any CPU.Build.0 = Release|Any CPU + {0E7BBEDA-46AA-4CCD-A303-5A97A2148C6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E7BBEDA-46AA-4CCD-A303-5A97A2148C6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E7BBEDA-46AA-4CCD-A303-5A97A2148C6B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {0E7BBEDA-46AA-4CCD-A303-5A97A2148C6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E7BBEDA-46AA-4CCD-A303-5A97A2148C6B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8F7F570D-74C3-4CF3-AACD-361A3D3F8E37} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/.gitignore b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/.gitignore new file mode 100644 index 0000000000..7466c01f9c --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +appPackage/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/AdapterWithErrorHandler.cs b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/AdapterWithErrorHandler.cs new file mode 100644 index 0000000000..bcde739890 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/AdapterWithErrorHandler.cs @@ -0,0 +1,63 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System; +using System.Net.Http; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Builder.Teams; +using Microsoft.Bot.Builder.TraceExtensions; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace Microsoft.BotBuilderSamples +{ + public class AdapterWithErrorHandler : CloudAdapter + { + public AdapterWithErrorHandler( + IConfiguration configuration, + IHttpClientFactory httpClientFactory, + ILogger logger, + IStorage storage, + ConversationState conversationState) + : base(configuration, httpClientFactory, logger) + { + base.Use(new TeamsSSOTokenExchangeMiddleware(storage, configuration["ConnectionName"])); + + OnTurnError = async (turnContext, exception) => + { + // Log any leaked exception from the application. + // NOTE: In production environment, you should consider logging this to + // Azure Application Insights. Visit https://aka.ms/bottelemetry to see how + // to add telemetry capture to your bot. + logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}"); + + // Uncomment below commented line for local debugging.. + // await turnContext.SendActivityAsync($"Sorry, it looks like something went wrong. Exception Caught: {exception.Message}"); + + if (conversationState != null) + { + try + { + // Delete the conversationState for the current conversation to prevent the + // bot from getting stuck in a error-loop caused by being in a bad state. + // ConversationState should be thought of as similar to "cookie-state" in a Web pages. + await conversationState.DeleteAsync(turnContext); + } + catch (Exception e) + { + logger.LogError(e, $"Exception caught on attempting to Delete ConversationState : {e.Message}"); + } + } + + // Send a trace activity, which will be displayed in the Bot Framework Emulator + await turnContext.TraceActivityAsync( + "OnTurnError Trace", + exception.Message, + "https://www.botframework.com/schemas/error", + "TurnError"); + }; + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/BotConversationSsoQuickstart.csproj b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/BotConversationSsoQuickstart.csproj new file mode 100644 index 0000000000..cc71c20d80 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/BotConversationSsoQuickstart.csproj @@ -0,0 +1,21 @@ + + + + net10.0 + latest + + + + + + + + + + + + + + + + diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Bots/DialogBot.cs b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Bots/DialogBot.cs new file mode 100644 index 0000000000..4ce6181a8e --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Bots/DialogBot.cs @@ -0,0 +1,84 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Dialogs; +using Microsoft.Bot.Builder.Teams; +using Microsoft.Bot.Schema; +using Microsoft.Extensions.Logging; + +namespace Microsoft.BotBuilderSamples +{ + /// + /// This IBot implementation can run any type of Dialog. The use of type parameterization allows multiple different bots + /// to be run at different endpoints within the same project. This can be achieved by defining distinct Controller types + /// each with dependency on distinct IBot types, this way ASP Dependency Injection can glue everything together without ambiguity. + /// The ConversationState is used by the Dialog system. The UserState isn't, however, it might have been used in a Dialog implementation, + /// and the requirement is that all BotState objects are saved at the end of a turn. + /// + /// The type of the dialog. + public class DialogBot : TeamsActivityHandler where T : Dialog + { + protected readonly BotState _conversationState; + protected readonly Dialog _dialog; + protected readonly ILogger _logger; + protected readonly BotState _userState; + + /// + /// Initializes a new instance of the class. + /// + /// The conversation state. + /// The user state. + /// The dialog. + /// The logger. + public DialogBot(ConversationState conversationState, UserState userState, T dialog, ILogger> logger) + { + _conversationState = conversationState; + _userState = userState; + _dialog = dialog; + _logger = logger; + } + + /// + /// Handles an incoming activity. + /// + /// Context object containing information cached for a single turn of conversation with a user. + /// Propagates notification that operations should be canceled. + /// A task that represents the work queued to execute. + /// + /// Reference link: https://docs.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.activityhandler.onturnasync?view=botbuilder-dotnet-stable. + /// + public override async Task OnTurnAsync( + ITurnContext turnContext, + CancellationToken cancellationToken = default(CancellationToken)) + { + await base.OnTurnAsync(turnContext, cancellationToken); + + // Save any state changes that might have occurred during the turn. + await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken); + await _userState.SaveChangesAsync(turnContext, false, cancellationToken); + } + + /// + /// Handles when a message is addressed to the bot. + /// + /// Context object containing information cached for a single turn of conversation with a user. + /// Propagates notification that operations should be canceled. + /// A Task resolving to either a login card or the adaptive card of the Reddit post. + /// + /// For more information on bot messaging in Teams, see the documentation + /// https://docs.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/conversation-basics?tabs=dotnet#receive-a-message. + /// + protected override async Task OnMessageActivityAsync( + ITurnContext turnContext, + CancellationToken cancellationToken) + { + _logger.LogInformation("Running dialog with Message Activity."); + + await _dialog.RunAsync(turnContext, _conversationState.CreateProperty(nameof(DialogState)), cancellationToken); + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Bots/TeamsBot.cs b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Bots/TeamsBot.cs new file mode 100644 index 0000000000..23111ddc38 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Bots/TeamsBot.cs @@ -0,0 +1,66 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Dialogs; +using Microsoft.Bot.Schema; +using Microsoft.Extensions.Logging; + +namespace Microsoft.BotBuilderSamples +{ + /// + /// This bot is derived from the TeamsActivityHandler class and handles Teams-specific activities. + /// + /// The type of the dialog. + public class TeamsBot : DialogBot where T : Dialog + { + /// + /// Initializes a new instance of the class. + /// + /// The conversation state. + /// The user state. + /// The dialog. + /// The logger. + public TeamsBot(ConversationState conversationState, UserState userState, T dialog, ILogger> logger) + : base(conversationState, userState, dialog, logger) + { + } + + /// + /// Handles the event when members are added to the conversation. + /// + /// The list of members added. + /// The turn context. + /// The cancellation token. + /// A task that represents the work queued to execute. + protected override async Task OnMembersAddedAsync(IList membersAdded, ITurnContext turnContext, CancellationToken cancellationToken) + { + foreach (var member in membersAdded) + { + if (member.Id != turnContext.Activity.Recipient.Id) + { + await turnContext.SendActivityAsync(MessageFactory.Text("Welcome to AuthenticationBot. Type anything to get logged in. Type 'logout' to sign-out."), cancellationToken); + } + } + } + + /// + /// Handles the Teams sign-in verification state. + /// + /// The turn context. + /// The cancellation token. + /// A task that represents the work queued to execute. + protected override async Task OnTeamsSigninVerifyStateAsync(ITurnContext turnContext, CancellationToken cancellationToken) + { + _logger.LogInformation("Running dialog with sign-in/verify state from an Invoke Activity."); + + // The OAuth Prompt needs to see the Invoke Activity in order to complete the login process. + // Run the Dialog with the new Invoke Activity. + await _dialog.RunAsync(turnContext, _conversationState.CreateProperty(nameof(DialogState)), cancellationToken); + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Controllers/BotController.cs b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Controllers/BotController.cs new file mode 100644 index 0000000000..fee03d9bf5 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Controllers/BotController.cs @@ -0,0 +1,36 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; + +namespace Microsoft.BotBuilderSamples +{ + // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot + // implementation at runtime. Multiple different IBot implementations running at different endpoints can be + // achieved by specifying a more specific type for the bot constructor argument. + [Route("api/messages")] + [ApiController] + public class BotController : ControllerBase + { + private readonly IBotFrameworkHttpAdapter _adapter; + private readonly IBot _bot; + + public BotController(IBotFrameworkHttpAdapter adapter, IBot bot) + { + _adapter = adapter; + _bot = bot; + } + + [HttpPost] + public async Task PostAsync() + { + // Delegate the processing of the HTTP POST to the adapter. + // The adapter will invoke the bot. + await _adapter.ProcessAsync(Request, Response, _bot); + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Dialogs/LogoutDialog.cs b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Dialogs/LogoutDialog.cs new file mode 100644 index 0000000000..8b69c14dbc --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Dialogs/LogoutDialog.cs @@ -0,0 +1,105 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Dialogs; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Bot.Schema; + +namespace Microsoft.BotBuilderSamples +{ + /// + /// A dialog that handles user logout. + /// + public class LogoutDialog : ComponentDialog + { + /// + /// Initializes a new instance of the class. + /// + /// The dialog ID. + /// The connection name configured in Azure Bot service. + public LogoutDialog(string id, string connectionName) + : base(id) + { + ConnectionName = connectionName; + } + + /// + /// Gets the configured connection name in Azure Bot service. + /// + protected string ConnectionName { get; } + + /// + /// Called when the dialog is started and pushed onto the parent's dialog stack. + /// + /// The inner DialogContext for the current turn of conversation. + /// Initial information to pass to the dialog. + /// Propagates notification that operations should be canceled. + /// A task representing the asynchronous operation. + protected override async Task OnBeginDialogAsync( + DialogContext innerDc, + object options, + CancellationToken cancellationToken = default(CancellationToken)) + { + var result = await InterruptAsync(innerDc, cancellationToken); + if (result != null) + { + return result; + } + + return await base.OnBeginDialogAsync(innerDc, options, cancellationToken); + } + + /// + /// Called when the dialog is continued, where it is the active dialog and the user replies with a new activity. + /// + /// The inner DialogContext for the current turn of conversation. + /// Propagates notification that operations should be canceled. + /// A task representing the asynchronous operation. + protected override async Task OnContinueDialogAsync( + DialogContext innerDc, + CancellationToken cancellationToken = default(CancellationToken)) + { + var result = await InterruptAsync(innerDc, cancellationToken); + if (result != null) + { + return result; + } + + return await base.OnContinueDialogAsync(innerDc, cancellationToken); + } + + /// + /// Called when the dialog is interrupted, where it is the active dialog and the user replies with a new activity. + /// + /// The inner DialogContext for the current turn of conversation. + /// Propagates notification that operations should be canceled. + /// A task representing the asynchronous operation. + private async Task InterruptAsync( + DialogContext innerDc, + CancellationToken cancellationToken = default(CancellationToken)) + { + if (innerDc.Context.Activity.Type == ActivityTypes.Message) + { + var text = innerDc.Context.Activity.Text.ToLowerInvariant(); + + // Allow logout anywhere in the command + if (text.Contains("logout")) + { + // The UserTokenClient encapsulates the authentication processes. + var userTokenClient = innerDc.Context.TurnState.Get(); + await userTokenClient.SignOutUserAsync(innerDc.Context.Activity.From.Id, ConnectionName, innerDc.Context.Activity.ChannelId, cancellationToken).ConfigureAwait(false); + + await innerDc.Context.SendActivityAsync(MessageFactory.Text("You have been signed out."), cancellationToken); + return await innerDc.CancelAllDialogsAsync(cancellationToken); + } + } + + return null; + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Dialogs/MainDialog.cs b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Dialogs/MainDialog.cs new file mode 100644 index 0000000000..ebc51d54bb --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Dialogs/MainDialog.cs @@ -0,0 +1,165 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Dialogs; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Bot.Schema; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace Microsoft.BotBuilderSamples +{ + /// + /// Main dialog that handles the authentication and user interactions. + /// + public class MainDialog : LogoutDialog + { + protected readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The configuration. + /// The logger. + public MainDialog(IConfiguration configuration, ILogger logger) + : base(nameof(MainDialog), configuration["ConnectionName"]) + { + _logger = logger; + + AddDialog(new OAuthPrompt( + nameof(OAuthPrompt), + new OAuthPromptSettings + { + ConnectionName = ConnectionName, + Text = "Please Sign In", + Title = "Sign In", + Timeout = 300000, // User has 5 minutes to login (1000 * 60 * 5) + EndOnInvalidMessage = true + })); + + AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt))); + + AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[] + { + PromptStepAsync, + LoginStepAsync, + DisplayTokenPhase1Async, + DisplayTokenPhase2Async, + })); + + // The initial child Dialog to run. + InitialDialogId = nameof(WaterfallDialog); + } + + /// + /// Prompts the user to sign in. + /// + /// The waterfall step context. + /// The cancellation token. + /// A task representing the asynchronous operation. + private async Task PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) + { + _logger.LogInformation("PromptStepAsync() called."); + return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken); + } + + /// + /// Handles the login step. + /// + /// The waterfall step context. + /// The cancellation token. + /// A task representing the asynchronous operation. + private async Task LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) + { + var tokenResponse = (TokenResponse)stepContext.Result; + if (tokenResponse?.Token != null) + { + try + { + var client = new SimpleGraphClient(tokenResponse.Token); + var me = await client.GetMeAsync(); + var title = !string.IsNullOrEmpty(me.JobTitle) ? me.JobTitle : "Unknown"; + + await stepContext.Context.SendActivityAsync($"You're logged in as {me.DisplayName} ({me.UserPrincipalName}); your job title is: {title}"); + + var photo = await client.GetPhotoAsync(); + + if (!string.IsNullOrEmpty(photo)) + { + var cardImage = new CardImage(photo); + var card = new ThumbnailCard(images: new List { cardImage }); + var reply = MessageFactory.Attachment(card.ToAttachment()); + + await stepContext.Context.SendActivityAsync(reply, cancellationToken); + } + else + { + await stepContext.Context.SendActivityAsync(MessageFactory.Text("Sorry! User doesn't have a profile picture to display."), cancellationToken); + } + + return await stepContext.PromptAsync( + nameof(ConfirmPrompt), + new PromptOptions { Prompt = MessageFactory.Text("Would you like to view your token?") }, + cancellationToken); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error occurred while processing your request."); + } + } + else + { + _logger.LogInformation("Response token is null or empty."); + } + + await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful, please try again."), cancellationToken); + return await stepContext.EndDialogAsync(cancellationToken: cancellationToken); + } + + /// + /// Displays the token if the user confirms. + /// + /// The waterfall step context. + /// The cancellation token. + /// A task representing the asynchronous operation. + private async Task DisplayTokenPhase1Async(WaterfallStepContext stepContext, CancellationToken cancellationToken) + { + _logger.LogInformation("DisplayTokenPhase1Async() method called."); + + await stepContext.Context.SendActivityAsync(MessageFactory.Text("Thank you."), cancellationToken); + + var result = (bool)stepContext.Result; + if (result) + { + return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), cancellationToken: cancellationToken); + } + + return await stepContext.EndDialogAsync(cancellationToken: cancellationToken); + } + + /// + /// Displays the token to the user. + /// + /// The waterfall step context. + /// The cancellation token. + /// A task representing the asynchronous operation. + private async Task DisplayTokenPhase2Async(WaterfallStepContext stepContext, CancellationToken cancellationToken) + { + _logger.LogInformation("DisplayTokenPhase2Async() method called."); + + var tokenResponse = (TokenResponse)stepContext.Result; + if (tokenResponse != null) + { + await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Here is your token: {tokenResponse.Token}"), cancellationToken); + } + + return await stepContext.EndDialogAsync(cancellationToken: cancellationToken); + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/1.Install.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/1.Install.png new file mode 100644 index 0000000000..3097dd592d Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/2.Installed.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/2.Installed.png new file mode 100644 index 0000000000..be684d27af Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/2.Installed.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/3.Logged_In.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/3.Logged_In.png new file mode 100644 index 0000000000..481cce0d84 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/3.Logged_In.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/4.Your_Token.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/4.Your_Token.png new file mode 100644 index 0000000000..4bda339196 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/4.Your_Token.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/5.GroupChatAuthCard.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/5.GroupChatAuthCard.png new file mode 100644 index 0000000000..19f1977c63 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/5.GroupChatAuthCard.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/6.PostOauth.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/6.PostOauth.png new file mode 100644 index 0000000000..d556ae1440 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/6.PostOauth.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/BotConversationSsoQuickStart.gif b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/BotConversationSsoQuickStart.gif new file mode 100644 index 0000000000..e13571b90e Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/BotConversationSsoQuickStart.gif differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Program.cs b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Program.cs new file mode 100644 index 0000000000..7a4d1bf630 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Program.cs @@ -0,0 +1,60 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.BotBuilderSamples; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddHttpClient().AddControllers().AddNewtonsoftJson(); + +// Create the Bot Framework Adapter with error handling enabled. +builder.Services.AddSingleton(); + +// Create the Bot Framework Authentication to be used with the Bot Adapter. +builder.Services.AddSingleton(); + +// Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.) +builder.Services.AddSingleton(); + +// Create the User state. (Used in this bot's Dialog implementation.) +builder.Services.AddSingleton(); + +// Create the Conversation state. (Used by the Dialog system itself.) +builder.Services.AddSingleton(); + +// The Dialog that will be run by the bot. +builder.Services.AddSingleton(); + +// Create the bot as a transient. In this case the ASP Controller is expecting an IBot. +builder.Services.AddTransient>(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline.l +if (!app.Environment.IsDevelopment()) +{ + app.UseHsts(); +} +else +{ + app.UseDeveloperExceptionPage(); +} + +app.UseDefaultFiles() + .UseStaticFiles() + .UseRouting() + .UseAuthorization() + .UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + +app.Run(); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Properties/launchSettings.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Properties/launchSettings.json new file mode 100644 index 0000000000..e38db2a9db --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "Start Project": { + "commandName": "Project", + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7130;http://localhost:5130", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + } +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/README.md b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/README.md new file mode 100644 index 0000000000..0d9c6962f7 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/README.md @@ -0,0 +1,153 @@ +--- +page_type: sample +description: Quickly set up Teams bot with SSO for seamless user authentication. +products: +- office-teams +- office +- office-365 +languages: +- csharp +extensions: + contentType: samples + createdDate: "07-07-2021 13:38:26" +urlFragment: officedev-microsoft-teams-samples-bot-conversation-sso-quickstart-csharp_dotnetcore +--- + +# Teams Conversation Bot SSO quick-start + +This sample demonstrates how to implement Single Sign-On (SSO) for Teams bots using Azure Active Directory and the Bot Framework. It includes comprehensive setup instructions for authentication, tunneling, and deploying to Azure, offering a streamlined way to authenticate users and access Microsoft Graph data directly within Teams. + +This bot has been created using [Bot Framework](https://dev.botframework.com), it shows how to get started with SSO in a bot for Microsoft Teams. + +The focus of this sample is how to use the Bot Framework support for OAuth SSO in your bot. Teams behaves slightly differently than other channels in this regard. Specifically an Invoke Activity is sent to the bot rather than the Event Activity used by other channels. _This Invoke Activity must be forwarded to the dialog if the OAuthPrompt is being used._ This is done by subclassing the ActivityHandler and this sample includes a reusable TeamsActivityHandler. This class is a candidate for future inclusion in the Bot Framework SDK. + +The sample uses the bot authentication capabilities in [Azure Bot Service](https://docs.botframework.com), providing features to make it easier to develop a bot that authenticates users to various identity providers such as Microsoft Entra ID, GitHub, Uber, etc. The OAuth token is then used to make basic Microsoft Graph queries. + +> IMPORTANT: The manifest file in this app adds "token.botframework.com" to the list of `validDomains`. This must be included in any bot that uses the Bot Framework OAuth flow. + +## Included Features +* Teams SSO (bots) +* Adaptive Card +* Graph API + +## Interaction with app + +![Teams Conversation Bot SSO Sample](Images/BotConversationSsoQuickStart.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Conversation Bot SSO quick-start:** [Manifest](/samples/bot-conversation-sso-quickstart/csharp_dotnetcore/demo-manifest/bot-conversation-sso-quickstart.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account (not a guest account) +- [.Net](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) version 6.0 +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/download) latest version or equivalent tunneling solution +- [M365 developer account](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the appropriate permissions to install an app. +- [Microsoft 365 Agents Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.14 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Microsoft 365 Agents Toolkit for Visual Studio [Microsoft 365 Agents Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In the debug dropdown menu of Visual Studio, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel. +1. Right-click the 'M365Agent' project in Solution Explorer and select **Microsoft 365 Agents Toolkit > Select Microsoft 365 Account** +1. Sign in to Microsoft 365 Agents Toolkit with a **Microsoft 365 work or school account** +1. Set `Startup Item` as `Microsoft Teams (browser)`. +1. Press F5, or select Debug > Start Debugging menu in Visual Studio to start your app +
![image](https://raw.githubusercontent.com/OfficeDev/TeamsFx/dev/docs/images/visualstudio/debug/debug-button.png) +1. In the opened web browser, select Add button to install the app in Teams +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +> the Teams service needs to call into the bot. + +1. Setup for Bot SSO + +Refer to [Bot SSO Setup document](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-conversation-sso-quickstart/BotSSOSetup.md). + +2. Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +3. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + + A) Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. + B) On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. + C) Navigate to **API Permissions**, and make sure to add the following permissions: + Select Add a permission + * Select Add a permission + * Select Microsoft Graph -\> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + + +4. Setup for code + + - Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + - Modify the `/appsettings.json` and fill in the following details: + - `{{TODO: MicrosoftAppId}}` - Generated from Step 1 while doing Microsoft Entra ID app registration in Azure portal. + - `{{ TODO: ClientSecret}}` - Generated from Step 1, also referred to as Client secret + - `{{ TODO: ConnectionName}}` - Generated from Step 1, Connection Setting. + - `MicrosoftAppType` - Set this as MultiTenant to if your bot is supported on multiple tenants; SingleTenant otherwise. + - `MicrosoftAppTenantId` - Set your tenantId here if you are using single tenant app registration. + + + - If you are using Visual Studio + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `samples/bot-conversation-sso-quickstart/csharp_dotnetcore` folder + - Select `BotConversationSsoQuickstart.sln` file and open it in Visual Studio + - Press `F5` to run this project + +5. Manually update the manifest.json + - Edit the `manifest.json` contained in the `appPackage/` folder to replace with your MicrosoftAppId (that was created in step1.1 and is the same value of MicrosoftAppId in `appsettings.json` file) *everywhere* you see the place holder string `{TODO: MicrosoftAppId}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`). The `ConnectionName` is the name of OAuth Connection you configured in step3. + - Zip up the contents of the `appPackage/` folder to create a `manifest.zip` + - Upload the `manifest.zip` to Teams (in the left-bottom *Apps* view, click "Upload a custom app") + +**Note**: If you are facing any issue in your app, [please uncomment this line](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/AdapterWithErrorHandler.cs#L37) and put your debugger for local debug. + + +## Running the sample + +![Install](Images/1.Install.png) + +![bot signin card](Images/2.Installed.png) + +![user details card](Images/3.Logged_In.png) + +![token](Images/4.Your_Token.png) + +![GroupChat](Images/5.GroupChatAuthCard.png) + +![GroupChat](Images/6.PostOauth.png) + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Azure Portal](https://portal.azure.com) +- [Microsoft Teams Developer Platform](https://docs.microsoft.com/en-us/microsoftteams/platform/) + + + diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/SimpleGraphClient.cs b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/SimpleGraphClient.cs new file mode 100644 index 0000000000..26b1133161 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/SimpleGraphClient.cs @@ -0,0 +1,165 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Microsoft.Graph; +using Microsoft.Graph.Models; +using Microsoft.Graph.Me.SendMail; +using Microsoft.Kiota.Abstractions.Authentication; +using System.Threading; + + +namespace Microsoft.BotBuilderSamples +{ + /// + /// This class is a wrapper for the Microsoft Graph API. + /// See: https://developer.microsoft.com/en-us/graph + /// + public class SimpleGraphClient + { + private readonly string _token; + + /// + /// Initializes a new instance of the class. + /// + /// The token issued to the user. + public SimpleGraphClient(string token) + { + if (string.IsNullOrWhiteSpace(token)) + { + throw new ArgumentNullException(nameof(token)); + } + + _token = token; + } + + /// + /// Sends an email on the user's behalf using the Microsoft Graph API. + /// + /// The recipient's email address. + /// The subject of the email. + /// The content of the email. + /// A task representing the asynchronous operation. + public async Task SendMailAsync(string toAddress, string subject, string content) + { + if (string.IsNullOrWhiteSpace(toAddress)) + { + throw new ArgumentNullException(nameof(toAddress)); + } + + if (string.IsNullOrWhiteSpace(subject)) + { + throw new ArgumentNullException(nameof(subject)); + } + + if (string.IsNullOrWhiteSpace(content)) + { + throw new ArgumentNullException(nameof(content)); + } + + var graphClient = GetAuthenticatedClient(); + var recipients = new List + { + new Recipient + { + EmailAddress = new EmailAddress + { + Address = toAddress, + }, + }, + }; + + // Create the message. + var email = new Message + { + Body = new ItemBody + { + Content = content, + ContentType = BodyType.Text, + }, + Subject = subject, + ToRecipients = recipients, + }; + + // Send the message. + await graphClient.Me.SendMail.PostAsync(new SendMailPostRequestBody { Message = email, SaveToSentItems = true }); + } + + /// + /// Gets recent mail for the user using the Microsoft Graph API. + /// + /// An array of recent messages. + public async Task GetRecentMailAsync() + { + var graphClient = GetAuthenticatedClient(); + var messages = await graphClient.Me.MailFolders["inbox"].Messages.GetAsync(); + + return messages.Value?.Take(5).ToArray(); + } + + /// + /// Gets information about the user. + /// + /// The user information. + public async Task GetMeAsync() + { + var graphClient = GetAuthenticatedClient(); + var me = await graphClient.Me.GetAsync(); + return me; + } + + /// + /// Gets the user's photo. + /// + /// The user's photo as a base64 string. + public async Task GetPhotoAsync() + { + var graphClient = GetAuthenticatedClient(); + var photo = await graphClient.Me.Photo.Content.GetAsync(); + if (photo != null) + { + using var ms = new MemoryStream(); + await photo.CopyToAsync(ms); + var buffers = ms.ToArray(); + return $"data:image/png;base64,{Convert.ToBase64String(buffers)}"; + } + return string.Empty; + } + + /// + /// Gets an authenticated Microsoft Graph client using the token issued to the user. + /// + /// The authenticated GraphServiceClient. + private GraphServiceClient GetAuthenticatedClient() + { + var tokenProvider = new SimpleAccessTokenProvider(_token); + + var authProvider = new BaseBearerTokenAuthenticationProvider(tokenProvider); + + return new GraphServiceClient(authProvider); + } + + public class SimpleAccessTokenProvider : IAccessTokenProvider + { + private readonly string _accessToken; + + public SimpleAccessTokenProvider(string accessToken) + { + _accessToken = accessToken; + } + + public Task GetAuthorizationTokenAsync(Uri uri, Dictionary context = null, CancellationToken cancellationToken = default) + { + return Task.FromResult(_accessToken); + } + + public AllowedHostsValidator AllowedHostsValidator => new AllowedHostsValidator(); + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/appsettings.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/appsettings.json new file mode 100644 index 0000000000..d16ea5476d --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/appsettings.json @@ -0,0 +1,7 @@ +{ + "MicrosoftAppId": "", + "MicrosoftAppPassword": "", + "ConnectionName": "", + "MicrosoftAppType": "SingleTenant", // Set this to SingleTenant if you are using a single tenant app registration + "MicrosoftAppTenantId": "" // Set your tenantId here if you are using single tenant app registration. +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/wwwroot/default.htm b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/wwwroot/default.htm new file mode 100644 index 0000000000..d4a5f082b7 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/wwwroot/default.htm @@ -0,0 +1,417 @@ + + + + + + + Teams Sample + + + + + +
+
+
+
Teams Sample
+
+
+
+
+
Your bot is ready!
+
You can test your bot in the Bot Framework Emulator
+ by connecting to http://localhost:3978/api/messages.
+ +
Visit Azure + Bot Service to register your bot and add it to
+ various channels. The bot's endpoint URL typically looks + like this:
+
https://your_bots_hostname/api/messages
+
+
+
+
+ +
+ + diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/M365Agent.ttkproj b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/M365Agent.ttkproj new file mode 100644 index 0000000000..48769f7806 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/M365Agent.ttkproj @@ -0,0 +1,13 @@ + + + + 0e7bbeda-46aa-4ccd-a303-5a97a2148c6b + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/aad.manifest.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/aad.manifest.json new file mode 100644 index 0000000000..15d506a79c --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/aad.manifest.json @@ -0,0 +1,114 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "displayName": "bot-conversation-sso-quickstart-aad", + "identifierUris": [ + "api://botid-${{AAD_APP_CLIENT_ID}}" + ], + "signInAudience": "AzureADMultipleOrgs", + "api": { + "requestedAccessTokenVersion": 2, + "oauth2PermissionScopes": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ] + }, + "info": {}, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "publicClient": { + "redirectUris": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "web": { + "redirectUris": [ + "https://${{BOT_DOMAIN}}/auth-end.html", + "https://token.botframework.com/.auth/web/redirect" + ], + "implicitGrantSettings": { + "enableIdTokenIssuance": true, + "enableAccessTokenIssuance": true + } + }, + "spa": { + "redirectUris": [] + } +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/color.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/color.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/manifest.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/manifest.json new file mode 100644 index 0000000000..f5932896e9 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/manifest.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Teams App, Inc.", + "websiteUrl": "https://example.azurewebsites.net", + "privacyUrl": "https://example.azurewebsites.net/privacy", + "termsOfUseUrl": "https://example.azurewebsites.net/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Conversation Bot", + "full": "Conversation Bot" + }, + "description": { + "short": "Quickly set up Teams bot with SSO for seamless user authentication.", + "full": "This sample bot demonstrates implementing SSO in Microsoft Teams using Azure AD." + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "personal", + "groupChat" + ], + "supportsFiles": false, + "isNotificationOnly": false + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "token.botframework.com", + "${{BOT_DOMAIN}}" + ], + "webApplicationInfo": { + "id": "${{AAD_APP_CLIENT_ID}}", + "resource": "api://botid-${{AAD_APP_CLIENT_ID}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/outline.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/appPackage/outline.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/env/.env.local b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/env/.env.local new file mode 100644 index 0000000000..3a583b5177 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/env/.env.local @@ -0,0 +1,26 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local +APP_NAME_SUFFIX=local + +# Generated during provision, you can also add your own variables. +BOT_ID= +TEAMS_APP_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE=SingleTenant +MICROSOFT_APP_TENANT_ID= +CONNECTION_NAME= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +TEAMSFX_M365_USER_NAME= + +BOT_ENDPOINT= +BOT_DOMAIN= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/infra/azure.bicep b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/infra/azure.bicep new file mode 100644 index 0000000000..145ce9cd4f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/infra/azure.bicep @@ -0,0 +1,76 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param botAadAppClientId string +param botAppDomain string + +param aadAppClientId string +@secure() +param aadAppClientSecret string +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} + +resource botServiceConnection 'Microsoft.BotService/botServices/connections@2021-03-01' = { + parent: botService + name: 'oauthbotsetting' + location: 'global' + properties: { + serviceProviderDisplayName: 'Azure Active Directory v2' + serviceProviderId: '30dd229c-58e3-4a48-bdfd-91ec48eb906c' + scopes: 'User.Read' + parameters: [ + { + key: 'clientId' + value: aadAppClientId + } + { + key: 'clientSecret' + value: aadAppClientSecret + } + { + key: 'tenantID' + value: microsoftAppTenantId + } + { + key: 'tokenExchangeUrl' + value: 'api://botid-${aadAppClientId}' + } + ] + } +} + +output CONNECTION_NAME string = botServiceConnection.name diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/infra/azure.parameters.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/infra/azure.parameters.json new file mode 100644 index 0000000000..bd425ea345 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/infra/azure.parameters.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "bot-conversation-sso-quickstart" + }, + "aadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "aadAppClientSecret": { + "value": "${{SECRET_AAD_APP_CLIENT_SECRET}}" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/launchSettings.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/launchSettings.json new file mode 100644 index 0000000000..d6491ef52c --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/launchSettings.json @@ -0,0 +1,15 @@ +{ + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + }, + // Launch project within Teams without prepare app dependencies + "Microsoft Teams (browser) (skip update app)": { + "commandName": "Project", + "environmentVariables": { "UPDATE_TEAMS_APP": "false" }, + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/m365agents.local.yml b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/m365agents.local.yml new file mode 100644 index 0000000000..9830210189 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/m365agents.local.yml @@ -0,0 +1,90 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.8/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.8 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:bot-conversation-sso-quickstart-csharp + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: bot-conversation-sso-quickstart-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMultipleOrgs" # Multitenant + writeToEnvironmentFile: + # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: bot-conversation-sso-quickstart${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; echo + "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ../BotConversationSsoQuickstart/appsettings.json + content: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + ConnectionName: ${{CONNECTION_NAME}} + MicrosoftAppType: ${{MICROSOFT_APP_TYPE}} + MicrosoftAppTenantId: ${{MICROSOFT_APP_TENANT_ID}} + + - uses: aadApp/update # Apply the AAD manifest to an existing AAD app. Will use the object id in manifest file to determine which AAD app to update. + with: + manifestPath: ./aad.manifest.json # Relative path to teamsfx folder. Environment variables in manifest will be replaced before apply to AAD app + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputFolder: ./appPackage/build + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/m365agents.yml b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/m365agents.yml new file mode 100644 index 0000000000..7b5c53c646 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/M365Agent/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.8/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.8 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:bot-conversation-sso-quickstart-csharp + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/assets/sample.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/assets/sample.json new file mode 100644 index 0000000000..c553a7ad77 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-bot-conversation-sso-quickstart-csharp_dotnetcore", + "source": "officeDev", + "title": "Teams Conversation Bot SSO quick-start", + "shortDescription": "This sample bot demonstrates implementing SSO in Microsoft Teams using Azure AD.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-conversation-sso-quickstart/csharp_dotnetcore", + "longDescription": [ + "This Teams bot sample showcases Single Sign-On (SSO) integration using Azure AD for seamless user authentication. It includes adaptive cards, and uses Microsoft Graph to fetch user details, making it easy to develop authenticated experiences within Teams." + ], + "creationDateTime": "2021-07-07", + "updateDateTime": "2024-10-10", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "csharp" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "netframework" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/csharp_dotnetcore/BotConversationSsoQuickstart/Images/BotConversationSsoQuickStart.gif", + "alt": "Solution UX showing teams conversation bot sso quick-start" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/csharp_dotnetcore.sln b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/csharp_dotnetcore.sln new file mode 100644 index 0000000000..efbe8638f8 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/csharp_dotnetcore.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotConversationSsoQuickstart", "BotConversationSsoQuickstart\BotConversationSsoQuickstart.csproj", "{83DF97DB-9BEC-0831-B3A4-E7B94751D226}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {83DF97DB-9BEC-0831-B3A4-E7B94751D226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83DF97DB-9BEC-0831-B3A4-E7B94751D226}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83DF97DB-9BEC-0831-B3A4-E7B94751D226}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83DF97DB-9BEC-0831-B3A4-E7B94751D226}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {222C6FA0-4ED2-4083-99C7-045090AFB02F} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/demo-manifest/bot-conversation-sso-quickstart.zip b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/demo-manifest/bot-conversation-sso-quickstart.zip new file mode 100644 index 0000000000..175bbb84c8 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/csharp_dotnetcore/demo-manifest/bot-conversation-sso-quickstart.zip differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.env b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.env new file mode 100644 index 0000000000..6c03b1323e --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.env @@ -0,0 +1,5 @@ +MicrosoftAppId= +MicrosoftAppPassword= +connectionName= +MicrosoftAppType=SingleTenant +MicrosoftAppTenantId= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.gitignore b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.gitignore new file mode 100644 index 0000000000..702bfe1a31 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.gitignore @@ -0,0 +1,43 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +############# + +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appManifest/build +/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store + +# build +lib/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/extensions.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/extensions.json new file mode 100644 index 0000000000..2d88dee21b --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/launch.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/launch.json new file mode 100644 index 0000000000..d027ed91e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/launch.json @@ -0,0 +1,73 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Local Service", + "type": "node", + "request": "attach", + "port": 9239, + "restart": true, + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/settings.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/settings.json new file mode 100644 index 0000000000..4299620253 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/tasks.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/tasks.json new file mode 100644 index 0000000000..8672ca6a9c --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/.vscode/tasks.json @@ -0,0 +1,105 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Teams App Locally", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy", + "Start application" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "nodejs", // Validate if Node.js is installed. + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + 9239 // app inspector port for Node.js debugger + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + }, + { + "label": "Start application", + "type": "shell", + "command": "npm run dev:teamsfx", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": { + "pattern": [ + { + "regexp": "^.*$", + "file": 0, + "location": 1, + "message": 2 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "[nodemon] starting", + "endsPattern": "restify listening to|Bot/ME service listening at|[nodemon] app crashed" + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/README.md b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/README.md new file mode 100644 index 0000000000..4fff87eb9d --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/README.md @@ -0,0 +1,193 @@ +--- +page_type: sample +description: This sample bot demonstrates implementing SSO in Microsoft Teams using Azure AD. +products: +- office-teams +- office +- office-365 +languages: +- javascript +- nodejs +extensions: + contentType: samples + createdDate: "07/07/2021 13:38:26 PM" +urlFragment: officedev-microsoft-teams-samples-bot-conversation-sso-quickstart-js +--- +# Teams Conversation Bot SSO quick-start + +This sample demonstrates how to implement Single Sign-On (SSO) for Teams bots using Azure Active Directory and the Bot Framework. It includes comprehensive setup instructions for authentication, tunneling, and deploying to Azure, offering a streamlined way to authenticate users and access Microsoft Graph data directly within Teams. + +This bot has been created using [Bot Framework](https://dev.botframework.com), it shows how to get started with SSO in a bot for Microsoft Teams. + +The focus of this sample is how to use the Bot Framework support for OAuth SSO in your bot. Teams behaves slightly differently than other channels in this regard. Specifically an Invoke Activity is sent to the bot rather than the Event Activity used by other channels. _This Invoke Activity must be forwarded to the dialog if the OAuthPrompt is being used._ This is done by subclassing the ActivityHandler and this sample includes a reusable TeamsActivityHandler. This class is a candidate for future inclusion in the Bot Framework SDK. + +The sample uses the bot authentication capabilities in [Azure Bot Service](https://docs.botframework.com), providing features to make it easier to develop a bot that authenticates users to various identity providers such as Microsoft Entra ID, GitHub, Uber, etc. The OAuth token is then used to make basic Microsoft Graph queries. + +> IMPORTANT: The manifest file in this app adds "token.botframework.com" to the list of `validDomains`. This must be included in any bot that uses the Bot Framework OAuth flow. + +## Included Features +* Teams SSO (bots) +* Adaptive Card +* Graph API + +## Interaction with app + +![Bot Conversation SSO QuickstartGif](sso_media/BotConversationSSOQuickstart.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Conversation Bot SSO quick-start:** [Manifest](/samples/bot-conversation-sso-quickstart/csharp_dotnetcore/demo-manifest/bot-conversation-sso-quickstart.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account (not a guest account) +- To test locally, [NodeJS](https://nodejs.org/en/download/) must be installed on your development machine (version 16.14.2 or higher) +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/download) latest version or equivalent tunneling solution +- [M365 developer account](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the appropriate permissions to install an app. +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) +- If you are using Ngrok to test locally, you'll need [Ngrok](https://ngrok.com/) installed on your development machine. + Make sure you've downloaded and installed Ngrok on your local machine. ngrok will tunnel requests from the Internet to your local computer and terminate the SSL connection from Teams. + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Run the app (Manually Uploading to Teams) + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +> the Teams service needs to call into the bot. + +1) Setup for Bot SSO +- Refer to [Bot SSO Setup document](../BotSSOSetup.md) + +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/en-us/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + +- While registering the Azure bot, use `https:///api/messages` as the messaging endpoint. + + > NOTE: When you create your app registration in Azure portal, you will create an App ID and App password - make sure you keep these for later. + +2) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +3) Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + + A) Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. + B) On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. + C) Navigate to **API Permissions**, and make sure to add the following permissions: + Select Add a permission + * Select Add a permission + * Select Microsoft Graph -\> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + + +4) Setup for code +- Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +- In a terminal, navigate to `samples/bot-conversation-sso-quickstart/js` + +- Install modules + + ```bash + npm install + ``` + +- Update the `.env` configuration for the bot to use the Microsoft App Id and App Password from the step 1 (Microsoft Entra ID app registration in Azure portal or from Bot Framework registration. (Note the MicrosoftAppId is the AppId created in step 1, the MicrosoftAppPassword is referred to as the "client secret" in step1 and you can always create a new client secret anytime.) + Also, update `connectionName` as the name of your Azure Bot connection created in step 1. + - `MicrosoftAppType` - Set this as MultiTenant to if your bot is supported on multiple tenants, otherwise SingleTenant. + - `MicrosoftAppTenantId` - Set your tenantId here if you are using single tenant app registration. + +- Run your bot at the command line: + + ```bash + npm start + ``` +5) Setup Manifest for Teams + +- **This step is specific to Teams.** + - Edit the `manifest.json` contained in the `appManifest/` folder to replace with your MicrosoftAppId (that was created in step1.1 and is the same value of MicrosoftAppId in `.env` file) *everywhere* you see the place holder string `{MicrosoftAppId}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + `<>` with base Url domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - Zip up the contents of the `appManifest/` folder to create a `manifest.zip` + - Upload the `manifest.zip` to Teams (in the left-bottom *Apps* view, click "Upload a custom app") + +**Note**: If you are facing any issue in your app, [please uncomment this line](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-conversation-sso-quickstart/js/index.js#L60) and put your debugger for local debug. + +## Running the sample + +**Adding bot UI:** + +![Install](sso_media/1.Install.png) + +![Install](sso_media/2.Open_App.png) + +**Welcome to teamsBot:** + +![Install](sso_media/3.Welcome_Message.png) + +**Login command interaction:** + +![BotSigninCard](sso_media/4.Logged_In.png) + +**View your token:** + +![Token](sso_media/5.Token.png) + +**Logout Dialog:** + +![Logout](sso_media/6.Logout.png) + +**Group Chat auth card** + +![GroupChat](sso_media/7.GroupChatAuthCard.png) + +**Post auth card** + +![GroupChat](sso_media/8.PostOauth.png) + +You can interact with this bot by sending it a message. The bot will respond by asking for your consent, by this consent the Bot will exchange an SSO token, then making a call to the Graph API on your behalf and returning the results. It will keep you loggined unless you send a message "logout". + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Azure Portal](https://portal.azure.com) +- [Add Authentication to Your Bot Via Azure Bot Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp) +- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) +- [.NET Core CLI tools](https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x) +- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest) +- [Azure Portal](https://portal.azure.com) +- [Language Understanding using LUIS](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/) +- [Channels and Bot Connector Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-concepts?view=azure-bot-service-4.0) +- [Microsoft Teams Developer Platform](https://docs.microsoft.com/en-us/microsoftteams/platform/) + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/aad.manifest.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/aad.manifest.json new file mode 100644 index 0000000000..fc3e480e7a --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/aad.manifest.json @@ -0,0 +1,107 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "bot-conversation-sso-quickstart-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADandPersonalMicrosoftAccount", + "oauth2AllowIdTokenImplicitFlow": true, + "oauth2AllowImplicitFlow": true, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "oauth2Permissions": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ], + "identifierUris":[ + "api://botid-${{AAD_APP_CLIENT_ID}}" + ], + "replyUrlsWithType":[ + { + "url": "https://${{BOT_DOMAIN}}/auth-end.html", + "type": "Web" + }, + { + "url": "https://token.botframework.com/.auth/web/redirect", + "type": "Web" + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/color.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/manifest.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/manifest.json new file mode 100644 index 0000000000..9e9a324be0 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/manifest.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Teams App, Inc.", + "websiteUrl": "https://example.azurewebsites.net", + "privacyUrl": "https://example.azurewebsites.net/privacy", + "termsOfUseUrl": "https://example.azurewebsites.net/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Conversation Bot", + "full": "Conversation Bot" + }, + "description": { + "short": "Quickly set up Teams bot with SSO for seamless user authentication.", + "full": "This sample bot demonstrates implementing SSO in Microsoft Teams using Azure AD." + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "personal", + "groupChat" + ], + "supportsFiles": false, + "isNotificationOnly": false + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "token.botframework.com", + "*.ngrok-free.app", + "*.ngrok.io", + "${{BOT_DOMAIN}}" + ], + "webApplicationInfo": { + "id": "${{AAD_APP_CLIENT_ID}}", + "resource": "api://botid-${{AAD_APP_CLIENT_ID}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/outline.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/assets/sample.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/assets/sample.json new file mode 100644 index 0000000000..349c29003b --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-bot-conversation-sso-quickstart-js", + "source": "officeDev", + "title": "Teams Conversation Bot SSO quick-start", + "shortDescription": "This sample bot demonstrates implementing SSO in Microsoft Teams using Azure AD.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-conversation-sso-quickstart/js", + "longDescription": [ + "This Teams bot sample showcases Single Sign-On (SSO) integration using Azure AD for seamless user authentication. It includes adaptive cards, and uses Microsoft Graph to fetch user details, making it easy to develop authenticated experiences within Teams." + ], + "creationDateTime": "2021-07-07", + "updateDateTime": "2024-10-10", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/js/sso_media/BotConversationSSOQuickstart.gif", + "alt": "Solution UX showing teams conversation bot sso quick-start" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/bots/dialogBot.js b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/bots/dialogBot.js new file mode 100644 index 0000000000..100a4f9345 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/bots/dialogBot.js @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { TeamsActivityHandler } = require('botbuilder'); + +/** + * DialogBot class extends TeamsActivityHandler to handle Teams activities. + */ +class DialogBot extends TeamsActivityHandler { + /** + * Creates an instance of DialogBot. + * @param {ConversationState} conversationState - The state management object for conversation state. + * @param {UserState} userState - The state management object for user state. + * @param {Dialog} dialog - The dialog to be run by the bot. + */ + constructor(conversationState, userState, dialog) { + super(); + + if (!conversationState) { + throw new Error('[DialogBot]: Missing parameter. conversationState is required'); + } + if (!userState) { + throw new Error('[DialogBot]: Missing parameter. userState is required'); + } + if (!dialog) { + throw new Error('[DialogBot]: Missing parameter. dialog is required'); + } + + this.conversationState = conversationState; + this.userState = userState; + this.dialog = dialog; + this.dialogState = this.conversationState.createProperty('DialogState'); + + this.onMessage(this.handleMessage.bind(this)); + } + + /** + * Handles incoming message activities. + * @param {TurnContext} context - The context object for the turn. + * @param {Function} next - The next middleware function in the pipeline. + */ + async handleMessage(context, next) { + console.log('Running dialog with Message Activity.'); + + // Run the Dialog with the new message Activity. + await this.dialog.run(context, this.dialogState); + + await next(); + } + + /** + * Override the ActivityHandler.run() method to save state changes after the bot logic completes. + * @param {TurnContext} context - The context object for the turn. + */ + async run(context) { + await super.run(context); + + // Save any state changes. The load happened during the execution of the Dialog. + await this.conversationState.saveChanges(context, false); + await this.userState.saveChanges(context, false); + } +} + +module.exports.DialogBot = DialogBot; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/bots/teamsBot.js b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/bots/teamsBot.js new file mode 100644 index 0000000000..ee823309d2 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/bots/teamsBot.js @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { DialogBot } = require('./dialogBot'); + +/** + * TeamsBot class extends DialogBot to handle Teams-specific activities. + */ +class TeamsBot extends DialogBot { + /** + * Creates an instance of TeamsBot. + * @param {ConversationState} conversationState - The state management object for conversation state. + * @param {UserState} userState - The state management object for user state. + * @param {Dialog} dialog - The dialog to be run by the bot. + */ + constructor(conversationState, userState, dialog) { + super(conversationState, userState, dialog); + + this.onMembersAdded(this.handleMembersAdded.bind(this)); + } + + /** + * Handles members being added to the conversation. + * @param {TurnContext} context - The context object for the turn. + * @param {Function} next - The next middleware function in the pipeline. + */ + async handleMembersAdded(context, next) { + const membersAdded = context.activity.membersAdded; + for (const member of membersAdded) { + if (member.id !== context.activity.recipient.id) { + await context.sendActivity('Welcome to TeamsBot. Type anything to get logged in. Type \'logout\' to sign-out.'); + } + } + await next(); + } + + /** + * Handles the Teams signin verify state. + * @param {TurnContext} context - The context object for the turn. + * @param {Object} query - The query object from the invoke activity. + */ + async handleTeamsSigninVerifyState(context, query) { + console.log('Running dialog with signin/verifystate from an Invoke Activity.'); + await this.dialog.run(context, this.dialogState); + } + + /** + * Handles the Teams signin token exchange. + * @param {TurnContext} context - The context object for the turn. + * @param {Object} query - The query object from the invoke activity. + */ + async handleTeamsSigninTokenExchange(context, query) { + console.log('Running dialog with signin/tokenExchange from an Invoke Activity.'); + await this.dialog.run(context, this.dialogState); + } +} + +module.exports.TeamsBot = TeamsBot; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/build.js b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/build.js new file mode 100644 index 0000000000..487ac7ea05 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/build.js @@ -0,0 +1,15 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js', + external: ['dtrace-provider'] +}) + .then((r) => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/dialogs/logoutDialog.js b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/dialogs/logoutDialog.js new file mode 100644 index 0000000000..8c3ac2289b --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/dialogs/logoutDialog.js @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { ActivityTypes } = require('botbuilder'); +const { ComponentDialog } = require('botbuilder-dialogs'); + +/** + * LogoutDialog class extends ComponentDialog to handle user logout. + */ +class LogoutDialog extends ComponentDialog { + /** + * Creates an instance of LogoutDialog. + * @param {string} id - The dialog ID. + * @param {string} connectionName - The connection name for the OAuth provider. + */ + constructor(id, connectionName) { + super(id); + this.connectionName = connectionName; + } + + /** + * Called when the dialog is started and pushed onto the dialog stack. + * @param {DialogContext} innerDc - The dialog context for the current turn of conversation. + * @param {Object} options - Optional. Initial information to pass to the dialog. + */ + async onBeginDialog(innerDc, options) { + const result = await this.interrupt(innerDc); + if (result) { + return result; + } + + return await super.onBeginDialog(innerDc, options); + } + + /** + * Called when the dialog is continued, where it is the active dialog and the user replies with a new activity. + * @param {DialogContext} innerDc - The dialog context for the current turn of conversation. + */ + async onContinueDialog(innerDc) { + const result = await this.interrupt(innerDc); + if (result) { + return result; + } + + return await super.onContinueDialog(innerDc); + } + + /** + * Interrupts the dialog to handle the 'logout' command. + * @param {DialogContext} innerDc - The dialog context for the current turn of conversation. + */ + async interrupt(innerDc) { + if (innerDc.context.activity.type === ActivityTypes.Message) { + const text = innerDc.context.activity.text.toLowerCase(); + if (text === 'logout') { + const userTokenClient = innerDc.context.turnState.get(innerDc.context.adapter.UserTokenClientKey); + + const { activity } = innerDc.context; + await userTokenClient.signOutUser(activity.from.id, this.connectionName, activity.channelId); + + await innerDc.context.sendActivity('You have been signed out.'); + return await innerDc.cancelAllDialogs(); + } + } + } +} + +module.exports.LogoutDialog = LogoutDialog; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/dialogs/mainDialog.js b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/dialogs/mainDialog.js new file mode 100644 index 0000000000..b6733e28e6 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/dialogs/mainDialog.js @@ -0,0 +1,114 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { ConfirmPrompt, DialogSet, DialogTurnStatus, OAuthPrompt, WaterfallDialog } = require('botbuilder-dialogs'); +const { LogoutDialog } = require('./logoutDialog'); +const { SimpleGraphClient } = require('../simpleGraphClient'); +const { CardFactory } = require('botbuilder-core'); + +const CONFIRM_PROMPT = 'ConfirmPrompt'; +const MAIN_DIALOG = 'MainDialog'; +const MAIN_WATERFALL_DIALOG = 'MainWaterfallDialog'; +const OAUTH_PROMPT = 'OAuthPrompt'; + +/** + * MainDialog class extends LogoutDialog to handle the main dialog flow. + */ +class MainDialog extends LogoutDialog { + /** + * Creates an instance of MainDialog. + * @param {string} connectionName - The connection name for the OAuth provider. + */ + constructor() { + super(MAIN_DIALOG, process.env.connectionName); + + this.addDialog(new OAuthPrompt(OAUTH_PROMPT, { + connectionName: process.env.connectionName, + text: 'Please Sign In', + title: 'Sign In', + timeout: 300000 + })); + this.addDialog(new ConfirmPrompt(CONFIRM_PROMPT)); + this.addDialog(new WaterfallDialog(MAIN_WATERFALL_DIALOG, [ + this.promptStep.bind(this), + this.loginStep.bind(this), + this.ensureOAuth.bind(this), + this.displayToken.bind(this) + ])); + + this.initialDialogId = MAIN_WATERFALL_DIALOG; + } + + /** + * The run method handles the incoming activity (in the form of a DialogContext) and passes it through the dialog system. + * If no dialog is active, it will start the default dialog. + * @param {TurnContext} context - The context object for the turn. + * @param {StatePropertyAccessor} accessor - The state property accessor for the dialog state. + */ + async run(context, accessor) { + const dialogSet = new DialogSet(accessor); + dialogSet.add(this); + const dialogContext = await dialogSet.createContext(context); + const results = await dialogContext.continueDialog(); + if (results.status === DialogTurnStatus.empty) { + await dialogContext.beginDialog(this.id); + } + } + + /** + * Prompts the user to sign in. + * @param {WaterfallStepContext} stepContext - The waterfall step context. + */ + async promptStep(stepContext) { + return await stepContext.beginDialog(OAUTH_PROMPT); + } + + /** + * Handles the login step. + * @param {WaterfallStepContext} stepContext - The waterfall step context. + */ + async loginStep(stepContext) { + const tokenResponse = stepContext.result; + if (!tokenResponse || !tokenResponse.token) { + await stepContext.context.sendActivity('Login was not successful, please try again.'); + return await stepContext.endDialog(); + } else { + const client = new SimpleGraphClient(tokenResponse.token); + const me = await client.getMe(); + const title = me ? me.jobTitle : 'Unknown'; + await stepContext.context.sendActivity(`You're logged in as ${me.displayName} (${me.userPrincipalName}); your job title is: ${title}; your photo is: `); + const photoBase64 = await client.getPhotoAsync(tokenResponse.token); + const card = CardFactory.thumbnailCard("", CardFactory.images([photoBase64])); + await stepContext.context.sendActivity({ attachments: [card] }); + return await stepContext.prompt(CONFIRM_PROMPT, 'Would you like to view your token?'); + } + } + + /** + * Ensures the OAuth token is available. + * @param {WaterfallStepContext} stepContext - The waterfall step context. + */ + async ensureOAuth(stepContext) { + await stepContext.context.sendActivity('Thank you.'); + + const result = stepContext.result; + if (result) { + return await stepContext.beginDialog(OAUTH_PROMPT); + } + return await stepContext.endDialog(); + } + + /** + * Displays the OAuth token to the user. + * @param {WaterfallStepContext} stepContext - The waterfall step context. + */ + async displayToken(stepContext) { + const tokenResponse = stepContext.result; + if (tokenResponse && tokenResponse.token) { + await stepContext.context.sendActivity(`Here is your token: ${tokenResponse.token}`); + } + return await stepContext.endDialog(); + } +} + +module.exports.MainDialog = MainDialog; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/env/.env.local b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/env/.env.local new file mode 100644 index 0000000000..8149d3abfc --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/env/.env.local @@ -0,0 +1,23 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +CONNECTION_NAME= +MICROSOFT_APP_TYPE=SingleTenant +MICROSOFT_APP_TENANT_ID= +APP_NAME_SUFFIX=local +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/index.js b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/index.js new file mode 100644 index 0000000000..7ea534b2c2 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/index.js @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// index.js is used to setup and configure your bot + +// Import required packages +const path = require('path'); + +const ENV_FILE = path.join(__dirname, '.env'); +require('dotenv').config({ path: ENV_FILE }); + +const restify = require('restify'); + +// Import required bot services. +// See https://aka.ms/bot-services to learn more about the different parts of a bot. +const { + CloudAdapter, + ConversationState, + MemoryStorage, + UserState, + ConfigurationBotFrameworkAuthentication, + TeamsSSOTokenExchangeMiddleware +} = require('botbuilder'); + +const { TeamsBot } = require('./bots/teamsBot'); +const { MainDialog } = require('./dialogs/mainDialog'); + +const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env); + +// Create adapter. +// See https://aka.ms/about-bot-adapter to learn more about how bots work. +const adapter = new CloudAdapter(botFrameworkAuthentication); +const memoryStorage = new MemoryStorage(); +const tokenExchangeMiddleware = new TeamsSSOTokenExchangeMiddleware(memoryStorage, process.env.connectionName); +adapter.use(tokenExchangeMiddleware); + +adapter.onTurnError = async (context, error) => { + // This check writes out errors to console log .vs. app insights. + // NOTE: In production environment, you should consider logging this to Azure + // application insights. See https://aka.ms/bottelemetry for telemetry + // configuration instructions. + console.error(`\n [onTurnError] unhandled error: ${ error }`); + + // Send a trace activity, which will be displayed in Bot Framework Emulator + await context.sendTraceActivity( + 'OnTurnError Trace', + `${ error }`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); + + // Clear out state + await conversationState.delete(context); +}; + +// Create conversation and user state with in-memory storage provider. +const conversationState = new ConversationState(memoryStorage); +const userState = new UserState(memoryStorage); + +// Create the main dialog. +const dialog = new MainDialog(); +// Create the bot that will handle incoming messages. +const bot = new TeamsBot(conversationState, userState, dialog); + +// Create HTTP server. +const server = restify.createServer(); +server.use(restify.plugins.bodyParser()); + +server.listen(process.env.port || process.env.PORT || 3978, function() { + console.log(`\n${ server.name } listening to ${ server.url }`); + console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator'); + console.log('\nTo talk to your bot, open the emulator select "Open Bot"'); +}); + +// Listen for incoming requests. +server.post('/api/messages', async (req, res) => { + // Route received a request to adapter for processing + await adapter.process(req, res, (context) => bot.run(context)); +}); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/infra/azure.bicep b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/infra/azure.bicep new file mode 100644 index 0000000000..145ce9cd4f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/infra/azure.bicep @@ -0,0 +1,76 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param botAadAppClientId string +param botAppDomain string + +param aadAppClientId string +@secure() +param aadAppClientSecret string +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} + +resource botServiceConnection 'Microsoft.BotService/botServices/connections@2021-03-01' = { + parent: botService + name: 'oauthbotsetting' + location: 'global' + properties: { + serviceProviderDisplayName: 'Azure Active Directory v2' + serviceProviderId: '30dd229c-58e3-4a48-bdfd-91ec48eb906c' + scopes: 'User.Read' + parameters: [ + { + key: 'clientId' + value: aadAppClientId + } + { + key: 'clientSecret' + value: aadAppClientSecret + } + { + key: 'tenantID' + value: microsoftAppTenantId + } + { + key: 'tokenExchangeUrl' + value: 'api://botid-${aadAppClientId}' + } + ] + } +} + +output CONNECTION_NAME string = botServiceConnection.name diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/infra/azure.parameters.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/infra/azure.parameters.json new file mode 100644 index 0000000000..bd425ea345 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/infra/azure.parameters.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "bot-conversation-sso-quickstart" + }, + "aadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "aadAppClientSecret": { + "value": "${{SECRET_AAD_APP_CLIENT_SECRET}}" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/m365agents.local.yml b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/m365agents.local.yml new file mode 100644 index 0000000000..f4966ca8dd --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/m365agents.local.yml @@ -0,0 +1,95 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:bot-conversation-sso-quickstart-js + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: bot-conversation-sso-quickstart-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # Authenticate users with a Microsoft work or school account in your organization's Azure AD tenant (for example, single tenant). + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: bot-conversation-sso-quickstart${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Teams Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + - uses: aadApp/update # Apply the AAD manifest to an existing AAD app. Will use the object id in manifest file to determine which AAD app to update. + with: + manifestPath: ./aad.manifest.json # Relative path to teamsfx folder. Environment variables in manifest will be replaced before apply to AAD app + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to teamsfx folder. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Run npm command + - uses: cli/runNpmCommand + with: + args: install --no-audit + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + connectionName: ${{CONNECTION_NAME}} + MicrosoftAppType: ${{MICROSOFT_APP_TYPE}} + MicrosoftAppTenantId: ${{MICROSOFT_APP_TENANT_ID}} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/m365agents.yml b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/m365agents.yml new file mode 100644 index 0000000000..bf9a96e62f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:bot-conversation-sso-quickstart-js + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/package.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/package.json new file mode 100644 index 0000000000..87e6d5b814 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/package.json @@ -0,0 +1,33 @@ +{ + "name": "teams-bot", + "version": "1.0.0", + "description": "Bot conversation sso quickstart js sample", + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev:teamsfx": "npm run dev", + "dev": "nodemon --inspect=9239 --signal SIGINT ./index.js", + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "build": "node build.js", + "lint": "eslint .", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples.git" + }, + "dependencies": { + "@microsoft/microsoft-graph-client": "^3.0.7", + "botbuilder": "^4.23.3", + "botbuilder-dialogs": "^4.23.3", + "dotenv": "^16.4.7", + "restify": "^11.1.0" + }, + "devDependencies": { + "eslint": "^9.17.0", + "nodemon": "^3.1.14", + "esbuild": "^0.28.0" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/simpleGraphClient.js b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/simpleGraphClient.js new file mode 100644 index 0000000000..c5c744fd07 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/simpleGraphClient.js @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { Client } = require('@microsoft/microsoft-graph-client'); + +/** + * This class is a wrapper for the Microsoft Graph API. + * See: https://developer.microsoft.com/en-us/graph for more information. + */ +class SimpleGraphClient { + /** + * Creates an instance of SimpleGraphClient. + * @param {string} token - The token issued to the user. + */ + constructor(token) { + if (!token || !token.trim()) { + throw new Error('SimpleGraphClient: Invalid token received.'); + } + + this._token = token; + + // Get an Authenticated Microsoft Graph client using the token issued to the user. + this.graphClient = Client.init({ + authProvider: (done) => { + done(null, this._token); // First parameter takes an error if you can't get an access token. + } + }); + } + + /** + * Collects information about the user in the bot. + * @returns {Promise} The user information. + */ + async getMe() { + try { + const res = await this.graphClient.api('/me').get(); + return res; + } catch (error) { + console.error('Error getting user information:', error); + throw error; + } + } + + /** + * Gets the user's photo. + * @param {string} token - The token issued to the user. + * @returns {Promise} The user's photo as a base64 encoded string. + */ + async getPhotoAsync(token) { + const graphPhotoEndpoint = 'https://graph.microsoft.com/v1.0/me/photos/240x240/$value'; + const graphRequestParams = { + method: 'GET', + headers: { + 'Content-Type': 'image/png', + 'Authorization': `Bearer ${token}` + } + }; + + try { + const response = await fetch(graphPhotoEndpoint, graphRequestParams); + if (!response.ok) { + console.error('Error fetching photo:', response); + throw new Error('Error fetching photo'); + } + + const imageBuffer = await response.arrayBuffer(); + const imageUri = `data:image/png;base64,${Buffer.from(imageBuffer).toString('base64')}`; + return imageUri; + } catch (error) { + console.error('Error fetching photo:', error); + throw error; + } + } +} + +module.exports.SimpleGraphClient = SimpleGraphClient; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/1.Install.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/1.Install.png new file mode 100644 index 0000000000..59c868b246 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/2.Open_App.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/2.Open_App.png new file mode 100644 index 0000000000..1e12306194 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/2.Open_App.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/3.Welcome_Message.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/3.Welcome_Message.png new file mode 100644 index 0000000000..7ef29594c6 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/3.Welcome_Message.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/4.Logged_In.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/4.Logged_In.png new file mode 100644 index 0000000000..cbf983b75e Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/4.Logged_In.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/5.Token.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/5.Token.png new file mode 100644 index 0000000000..3638af4c23 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/5.Token.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/6.Logout.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/6.Logout.png new file mode 100644 index 0000000000..349e16e080 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/6.Logout.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/7.GroupChatAuthCard.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/7.GroupChatAuthCard.png new file mode 100644 index 0000000000..19f1977c63 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/7.GroupChatAuthCard.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/8.PostOauth.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/8.PostOauth.png new file mode 100644 index 0000000000..d556ae1440 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/8.PostOauth.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AddClient.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AddClient.png new file mode 100644 index 0000000000..3c5fa076c3 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AddClient.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AddOauth.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AddOauth.png new file mode 100644 index 0000000000..536a02dfce Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AddOauth.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppId.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppId.png new file mode 100644 index 0000000000..e1ae4e87aa Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppId.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppIdUri.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppIdUri.png new file mode 100644 index 0000000000..d65ab85178 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppIdUri.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppRegistration.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppRegistration.png new file mode 100644 index 0000000000..3c20d2dd49 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AppRegistration.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotConfigurationPage.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotConfigurationPage.png new file mode 100644 index 0000000000..1a0b5eb6ce Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotConfigurationPage.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotConnectionString.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotConnectionString.png new file mode 100644 index 0000000000..bc618c8edf Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotConnectionString.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotCreate.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotCreate.png new file mode 100644 index 0000000000..927a9d5ee5 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotCreate.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotCreate2.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotCreate2.png new file mode 100644 index 0000000000..301ca64910 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureBotCreate2.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureCreateResource.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureCreateResource.png new file mode 100644 index 0000000000..4474d20947 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/AzureCreateResource.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/BotChannelsRegistration.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/BotChannelsRegistration.png new file mode 100644 index 0000000000..d49d803387 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/BotChannelsRegistration.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/BotConversationSSOQuickstart.gif b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/BotConversationSSOQuickstart.gif new file mode 100644 index 0000000000..07cfe0a481 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/BotConversationSSOQuickstart.gif differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/ClientSecret.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/ClientSecret.png new file mode 100644 index 0000000000..dc23ad77df Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/ClientSecret.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateBot.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateBot.png new file mode 100644 index 0000000000..823e0fab8a Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateBot.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateBot2.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateBot2.png new file mode 100644 index 0000000000..d19010a0ac Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateBot2.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateScope.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateScope.png new file mode 100644 index 0000000000..e6a9a49738 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/CreateScope.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/TeamsChannel.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/TeamsChannel.png new file mode 100644 index 0000000000..35732b58b0 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/TeamsChannel.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/image013.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/image013.png new file mode 100644 index 0000000000..61372c740f Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/image013.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/image017.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/image017.png new file mode 100644 index 0000000000..775197a31a Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/js/sso_media/image017.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.env b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.env new file mode 100644 index 0000000000..97ef4fa45d --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.env @@ -0,0 +1,3 @@ +MicrosoftAppId= +MicrosoftAppPassword= +connectionName= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.gitignore b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.gitignore new file mode 100644 index 0000000000..e8442994dd --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.gitignore @@ -0,0 +1,14 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +appManifest/build/ + +# python virtual environment +.venv/ + +# misc +.env +.deployment/ + +# tmp files +__pycache__/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/extensions.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/extensions.json new file mode 100644 index 0000000000..e81b1beb93 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension", + "ms-python.python" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/launch.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/launch.json new file mode 100644 index 0000000000..9c7356e267 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/launch.json @@ -0,0 +1,69 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Python: Run App Locally", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/app.py", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/settings.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/settings.json new file mode 100644 index 0000000000..3014fd9cf0 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "debug.onTaskErrors": "abort" +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/tasks.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/tasks.json new file mode 100644 index 0000000000..a11f46be58 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/.vscode/tasks.json @@ -0,0 +1,78 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Prepare Teams App Resources", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978 // app service port + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/1.Install.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/1.Install.png new file mode 100644 index 0000000000..ff3a853dc9 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/2.Welcome.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/2.Welcome.png new file mode 100644 index 0000000000..b15c06fb7b Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/2.Welcome.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/3.OauthPrompt.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/3.OauthPrompt.png new file mode 100644 index 0000000000..09c93e05fd Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/3.OauthPrompt.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/4.ConsentPopup.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/4.ConsentPopup.png new file mode 100644 index 0000000000..3e209e8429 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/4.ConsentPopup.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/5.UserLoggedIn.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/5.UserLoggedIn.png new file mode 100644 index 0000000000..93e3693609 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/5.UserLoggedIn.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/6.UserToken.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/6.UserToken.png new file mode 100644 index 0000000000..c2ffc0d8a7 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/6.UserToken.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/Bot-conversation-sso-quickstart.gif b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/Bot-conversation-sso-quickstart.gif new file mode 100644 index 0000000000..7a1b323bcc Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/Images/Bot-conversation-sso-quickstart.gif differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/README.md b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/README.md new file mode 100644 index 0000000000..4d25263b3f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/README.md @@ -0,0 +1,154 @@ +--- +page_type: sample +description: This sample bot demonstrates implementing SSO in Microsoft Teams using Azure AD. +products: +- office-teams +- office +- office-365 +languages: +- Python +extensions: + contentType: samples + createdDate: "21-07-2015 13:38:25" +urlFragment: officedev-microsoft-teams-samples-bot-conversation-sso-quickstart-python + +--- + +# Teams Conversation Bot SSO quick-start + +This sample demonstrates how to implement Single Sign-On (SSO) for Teams bots using Azure Active Directory and the Bot Framework. It includes comprehensive setup instructions for authentication, tunneling, and deploying to Azure, offering a streamlined way to authenticate users and access Microsoft Graph data directly within Teams. + +This bot has been created using [Bot Framework](https://dev.botframework.com), it shows how to get started with SSO in a bot for Microsoft Teams. + +The focus of this sample is how to use the Bot Framework support for OAuth SSO in your bot. Teams behaves slightly differently than other channels in this regard. Specifically an Invoke Activity is sent to the bot rather than the Event Activity used by other channels. _This Invoke Activity must be forwarded to the dialog if the OAuthPrompt is being used._ This is done by subclassing the ActivityHandler and this sample includes a reusable TeamsActivityHandler. This class is a candidate for future inclusion in the Bot Framework SDK. + +The sample uses the bot authentication capabilities in [Azure Bot Service](https://docs.botframework.com), providing features to make it easier to develop a bot that authenticates users to various identity providers such as Microsoft Entra ID, GitHub, Uber, etc. The OAuth token is then used to make basic Microsoft Graph queries. + +> IMPORTANT: The manifest file in this app adds "token.botframework.com" to the list of `validDomains`. This must be included in any bot that uses the Bot Framework OAuth flow. + +## Included Features +* Teams SSO (bots) +* Graph API + +## Interaction with app + +- **Bot Conversation SSO Quickstart** +![bot-teams-auth](Images/Bot-conversation-sso-quickstart.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app manifest (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Conversation Bot SSO quick-start:** [Manifest](/samples/bot-conversation-sso-quickstart/csharp_dotnetcore/demo-manifest/bot-conversation-sso-quickstart.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account (not a guest account) +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution +- [Python SDK](https://www.python.org/downloads/) min version 3.11 + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) and [Python Extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Press **CTRL+Shift+P** to open the command box and enter **Python: Create Environment** to create and activate your desired virtual environment. Remember to select `requirements.txt` as dependencies to install when creating the virtual environment. +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Run the app (Manually Uploading to Teams) + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +> the Teams service needs to call into the bot. +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + +2. Setup for Bot + Create [Bot Framework registration resource](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration) in Azure + - Use the current `https` URL you were given by running the tunneling application. Append with the path `/api/messages` used by this sample + - Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - __*If you don't have an Azure account*__ you can use this [Bot Framework registration](https://docs.microsoft.com/microsoftteams/platform/bots/how-to/create-a-bot-for-teams#register-your-web-service-with-the-bot-framework) + + > NOTE: When you create your app registration, you will create an App ID and App password - make sure you keep these for later. + +3. Setup NGROK + - Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +4. Setup for code + + - Clone the repository + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + - In a terminal, navigate to `Microsoft-Teams-samples\samples\bot-conversation-sso-quickstart\python` folder + + - Activate your desired virtual environment + + - In the terminal, type `pip install -r requirements.txt` + + - Update the `config.py` configuration for the bot to use the Microsoft App Id and App Password from the Bot Framework registration. (Note the App Password is referred to as the "client secret" in the azure portal and you can always create a new client secret anytime.) + +5. Setup Manifest for Teams +- __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the ./teams_app_manifest folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `${{AAD_APP_CLIENT_ID}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` and replace `${{BOT_DOMAIN}}` with base Url of your domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `teams_app_manifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appManifest folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your app is uploaded to Teams. + +- Run your bot with `python app.py` + +> Note this `manifest.json` specified that the bot will be installed in a "personal" scope only. Please refer to Teams documentation for more details. + +## Running the sample + +You can interact with this bot by sending it a message. The bot will respond by requesting you to login to Microsoft Entra ID, then making a call to the Graph API on your behalf and returning the results. + +**Adding bot UI:** +![Install](Images/1.Install.png) + +**Welcome to teamsBot:** +![Welcome](Images/2.Welcome.png) + +**Oauth Prompt:** +![OauthPrompt](Images/3.OauthPrompt.png) + +**Consent Popup:** +![Consent Popup](Images/4.ConsentPopup.png) + +**User Logged In:** +![User Logged In](Images/5.UserLoggedIn.png) + +**User Access token:** +![User Access token](Images/6.UserToken.png) + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [AzuMessagere Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) +- [Bot Authentication Basics](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/authentication/bot-sso-overview) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/__init__.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/aad.manifest.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/aad.manifest.json new file mode 100644 index 0000000000..96b3487a91 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/aad.manifest.json @@ -0,0 +1,107 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "bot-conversation-sso-quickstart-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMyOrg", + "oauth2AllowIdTokenImplicitFlow": true, + "oauth2AllowImplicitFlow": true, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "oauth2Permissions": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ], + "identifierUris":[ + "api://botid-${{AAD_APP_CLIENT_ID}}" + ], + "replyUrlsWithType":[ + { + "url": "https://${{BOT_DOMAIN}}/auth-end.html", + "type": "Web" + }, + { + "url": "https://token.botframework.com/.auth/web/redirect", + "type": "Web" + } + ] +} diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/app.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/app.py new file mode 100644 index 0000000000..69b3ef1a9c --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/app.py @@ -0,0 +1,124 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import sys +import traceback +from datetime import datetime, timezone +from http import HTTPStatus +from botbuilder.schema import InvokeResponse +from aiohttp import web +from aiohttp.web import Request, Response, json_response +from botbuilder.core import ( + BotFrameworkAdapter, + BotFrameworkAdapterSettings, + ConversationState, + MemoryStorage, + TurnContext, + UserState, +) +from botbuilder.core.integration import aiohttp_error_middleware +from botbuilder.schema import Activity, ActivityTypes + +from bots import TeamsBot +import logging +from config import DefaultConfig +from dialogs import MainDialog + +CONFIG = DefaultConfig() + +# Create adapter. +# See https://aka.ms/about-bot-adapter to learn more about how bots work. +SETTINGS = BotFrameworkAdapterSettings(CONFIG.APP_ID, CONFIG.APP_PASSWORD) +ADAPTER = BotFrameworkAdapter(SETTINGS) + + +# Catch-all for errors. +async def on_error(context: TurnContext, error: Exception): + # Handles uncaught exceptions during turn execution + print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr) + traceback.print_exc() + + # Inform user that an error occurred + await context.send_activity("The bot encountered an error or bug.") + await context.send_activity( + "To continue to run this bot, please fix the bot source code." + ) + + # Send a trace activity if using Bot Framework Emulator + if context.activity.channel_id == "emulator": + # Create a trace activity for debugging + trace_activity = Activity( + label="TurnError", + name="on_turn_error Trace", + timestamp=datetime.now(timezone.utc), + type=ActivityTypes.trace, + value=f"{error}", + value_type="https://www.botframework.com/schemas/error", + ) + # Send trace activity to emulator + await context.send_activity(trace_activity) + + +# Assign the global error handler to the adapter +ADAPTER.on_turn_error = on_error + +# Create MemoryStorage and state management objects +MEMORY = MemoryStorage() +USER_STATE = UserState(MEMORY) +CONVERSATION_STATE = ConversationState(MEMORY) + +# Create dialog instance +DIALOG = MainDialog(CONFIG.CONNECTION_NAME) + +# Create the main bot instance +BOT = TeamsBot(CONVERSATION_STATE, USER_STATE, DIALOG) + + +# Listen for incoming requests on /api/messages. +async def messages(req: Request) -> Response: + # Deserialize incoming request to Activity object + if "application/json" in req.headers["Content-Type"]: + body = await req.json() + else: + return Response(status=HTTPStatus.UNSUPPORTED_MEDIA_TYPE) + + activity = Activity().deserialize(body) + auth_header = req.headers["Authorization"] if "Authorization" in req.headers else "" + + # Log incoming activity type and name + logging.info(f"Incoming activity type: {activity.type}") + logging.info(f"Activity name: {getattr(activity, 'name', None)}") + + try: + # Process activity with the bot adapter and bot logic + response = await ADAPTER.process_activity(activity, auth_header, BOT.on_turn) + + # Handle special Invoke response case + if isinstance(response, InvokeResponse): + if isinstance(response.body, dict): + return json_response(status=response.status, data=response.body) + else: + return Response(status=response.status) + + return Response(status=HTTPStatus.OK) + + except Exception as e: + # Log unexpected errors during activity processing + logging.error(f"Exception in processing activity: {e}") + traceback.print_exc() + return Response( + status=HTTPStatus.INTERNAL_SERVER_ERROR, + text="Internal server error while processing the activity." + ) + + +# Create aiohttp app and register message route +APP = web.Application(middlewares=[aiohttp_error_middleware]) +APP.router.add_post("/api/messages", messages) + +# Run aiohttp web server +if __name__ == "__main__": + try: + web.run_app(APP, host="localhost", port=CONFIG.PORT) + except Exception as error: + raise error diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/color.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/manifest.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/manifest.json new file mode 100644 index 0000000000..0fd27158c2 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/manifest.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Teams App, Inc.", + "websiteUrl": "https://example.azurewebsites.net", + "privacyUrl": "https://example.azurewebsites.net/privacy", + "termsOfUseUrl": "https://example.azurewebsites.net/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Conversation Bot", + "full": "Conversation Bot" + }, + "description": { + "short": "Quickly set up Teams bot with SSO for seamless user authentication.", + "full": "This sample bot demonstrates implementing SSO in Microsoft Teams using Azure AD." + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "personal" + ], + "supportsFiles": false, + "isNotificationOnly": false + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "token.botframework.com", + "*.ngrok-free.app", + "*.ngrok.io", + "${{BOT_DOMAIN}}" + ], + "webApplicationInfo": { + "id": "${{AAD_APP_CLIENT_ID}}", + "resource": "api://botid-${{AAD_APP_CLIENT_ID}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/outline.png b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/assets/sample.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/assets/sample.json new file mode 100644 index 0000000000..5e67097864 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-bot-conversation-sso-quickstart-python", + "source": "officeDev", + "title": "Teams Conversation Bot SSO quick-start", + "shortDescription": "This sample bot demonstrates implementing SSO in Microsoft Teams using Azure AD.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-conversation-sso-quickstart/python", + "longDescription": [ + "This Teams bot sample showcases Single Sign-On (SSO) integration using Azure AD for seamless user authentication. It includes adaptive cards, and uses Microsoft Graph to fetch user details, making it easy to develop authenticated experiences within Teams." + ], + "creationDateTime": "2015-07-21", + "updateDateTime": "2025-07-21", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "python" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "python" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/bot-conversation-sso-quickstart/python/Images/Bot-conversation-sso-quickstart.gif", + "alt": "Solution UX showing teams conversation bot sso quick-start" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bot_activity_handler.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bot_activity_handler.py new file mode 100644 index 0000000000..1e8ab7054f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bot_activity_handler.py @@ -0,0 +1,95 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from botbuilder.core import ( + TurnContext, + MessageFactory, + CardFactory, +) +from botbuilder.core.teams import TeamsActivityHandler +from botbuilder.schema import ( + Activity, + Mention, + ActionTypes, + HeroCard, + CardAction, +) +import html + + +class BotActivityHandler(TeamsActivityHandler): + """ + BotActivityHandler class extends TeamsActivityHandler to handle Teams-specific activities. + """ + + def __init__(self): + super().__init__() + # Teams bots are Microsoft Bot Framework bots. + # If a bot receives a message activity, the turn handler sees that incoming activity + # and sends it to the on_message_activity handler. + # Learn more: https://aka.ms/teams-bot-basics. + # + # NOTE: Ensure the bot endpoint that services incoming conversational bot queries is + # registered with Bot Framework. + # Learn more: https://aka.ms/teams-register-bot. + + async def on_message_activity(self, turn_context: TurnContext): + """ + Handles incoming message activities. + """ + # Remove recipient mention from the activity text + TurnContext.remove_recipient_mention(turn_context.activity) + + text = (turn_context.activity.text or "").strip() + + if text.lower() == "hello": + await self._mention_activity(turn_context) + else: + # By default for unknown activity sent by user show + # a card with the available actions. + await self._send_hero_card(turn_context) + + async def _mention_activity(self, turn_context: TurnContext): + """ + Say hello and @ mention the current user. + """ + # Create mention + mention = Mention( + mentioned=turn_context.activity.sender, + text=f"{html.escape(turn_context.activity.sender.name or 'User')}", + type="mention" + ) + + # Create reply activity with mention + reply_text = f"Hi {mention.text}" + reply_activity = MessageFactory.text(reply_text) + reply_activity.entities = [mention] + + await turn_context.send_activity(reply_activity) + + async def _send_hero_card(self, turn_context: TurnContext): + """ + Send a hero card with available actions. + """ + # Create hero card + card = HeroCard( + title="Let's talk...", + subtitle=None, + text=None, + images=None, + buttons=[ + CardAction( + type=ActionTypes.message_back, + title="Say Hello", + value={"count": 0}, + text="Hello" + ) + ] + ) + + # Create card attachment + card_attachment = CardFactory.hero_card(card) + + # Send card + response = MessageFactory.attachment(card_attachment) + await turn_context.send_activity(response) diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/__init__.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/__init__.py new file mode 100644 index 0000000000..4078c5a896 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from .dialog_bot import DialogBot +from .auth_bot import AuthBot +from .teams_bot import TeamsBot + +__all__ = ["DialogBot", "AuthBot", "TeamsBot"] diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/auth_bot.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/auth_bot.py new file mode 100644 index 0000000000..cb15d04c2c --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/auth_bot.py @@ -0,0 +1,44 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from typing import List +from botbuilder.core import ( + ConversationState, + UserState, + TurnContext, +) +from botbuilder.dialogs import Dialog +from botbuilder.schema import ChannelAccount +from helpers.dialog_helper import DialogHelper +from .dialog_bot import DialogBot + + +class AuthBot(DialogBot): + def __init__( + self, + conversation_state: ConversationState, + user_state: UserState, + dialog: Dialog, + ): + super(AuthBot, self).__init__(conversation_state, user_state, dialog) + + async def on_members_added_activity( + self, members_added: List[ChannelAccount], turn_context: TurnContext + ): + # Handles new members added to the conversation and sends a welcome message. + for member in members_added: + # Greet anyone that was not the target (recipient) of this message. + # To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details. + if member.id != turn_context.activity.recipient.id: + await turn_context.send_activity( + "Welcome to AuthenticationBot. Type anything to get logged in. Type " + "'logout' to sign-out." + ) + + async def on_token_response_event(self, turn_context: TurnContext): + # Handles the token response event by continuing the dialog. + await DialogHelper.run_dialog( + self.dialog, + turn_context, + self.conversation_state.create_property("DialogState"), + ) diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/dialog_bot.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/dialog_bot.py new file mode 100644 index 0000000000..c062a7533f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/dialog_bot.py @@ -0,0 +1,75 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from botbuilder.core import ConversationState, UserState, TurnContext +from botbuilder.core.teams import TeamsActivityHandler +from helpers.dialog_helper import DialogHelper +from botbuilder.dialogs import Dialog +import logging +import traceback + +class DialogBot(TeamsActivityHandler): + def __init__( + self, + conversation_state: ConversationState, + user_state: UserState, + dialog: Dialog, + ): + # Initializes the DialogBot with conversation state, user state, and main dialog. + if conversation_state is None: + raise Exception( + "[DialogBot]: Missing parameter. conversation_state is required" + ) + if user_state is None: + raise Exception("[DialogBot]: Missing parameter. user_state is required") + if dialog is None: + raise Exception("[DialogBot]: Missing parameter. dialog is required") + + self.conversation_state = conversation_state + self.user_state = user_state + self.dialog = dialog + + async def on_turn(self, turn_context: TurnContext): + # Handles every turn of the bot and saves any state changes. + try: + await super().on_turn(turn_context) + + # Save any state changes that might have occurred during the turn. + await self.conversation_state.save_changes(turn_context, False) + await self.user_state.save_changes(turn_context, False) + + except Exception as e: + logging.error(f"Error in on_turn: {e}") + traceback.print_exc() + await turn_context.send_activity("Sorry, something went wrong processing your message.") + + async def on_message_activity(self, turn_context: TurnContext): + # Handles message activities and manages dialog flow including 'clear' command. + logging.info("on_message_activity triggered.") + try: + text = (turn_context.activity.text or "").strip().lower() + dialog_state_accessor = self.conversation_state.create_property("DialogState") + + if text == "clear": + logging.info("'clear' command received. Attempting to reset dialog state.") + dialog_state = await dialog_state_accessor.get(turn_context) + + if dialog_state: + await dialog_state_accessor.delete(turn_context) + logging.info("Dialog state deleted.") + await turn_context.send_activity("Dialog state cleared. You can start again.") + else: + logging.info("No dialog state found to delete.") + await turn_context.send_activity("No active dialog state found to clear.") + return + + await DialogHelper.run_dialog( + self.dialog, + turn_context, + dialog_state_accessor, + ) + + except Exception as e: + logging.error(f"Error in on_message_activity: {e}") + traceback.print_exc() + await turn_context.send_activity("An error occurred handling your message.") diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/teams_bot.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/teams_bot.py new file mode 100644 index 0000000000..11a4cd5d9f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/bots/teams_bot.py @@ -0,0 +1,55 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from typing import List +from botbuilder.core import ( + ConversationState, + UserState, + TurnContext, +) +from botbuilder.dialogs import Dialog +from botbuilder.schema import ChannelAccount +from helpers.dialog_helper import DialogHelper +from botbuilder.schema import InvokeResponse +from bots.dialog_bot import DialogBot +import logging + +class TeamsBot(DialogBot): + def __init__( + self, + conversation_state: ConversationState, + user_state: UserState, + dialog: Dialog, + ): + # Initializes the TeamsBot with conversation and user state, and main dialog. + super(TeamsBot, self).__init__(conversation_state, user_state, dialog) + + # Sends a welcome message to new members added to the conversation. + async def on_members_added_activity( + self, members_added: List[ChannelAccount], turn_context: TurnContext + ): + for member in members_added: + if member.id != turn_context.activity.recipient.id: + await turn_context.send_activity( + "Welcome to TeamsBot. Type anything to get logged in. Type 'logout' to sign-out." + ) + + # Handles the Teams signin/verifyState invoke activity and continues the dialog. + async def on_teams_signin_verify_state(self, turn_context: TurnContext): + logging.info("Running dialog with signin/verifyState from an Invoke Activity.") + await DialogHelper.run_dialog( + self.dialog, + turn_context, + self.conversation_state.create_property("DialogState"), + ) + return InvokeResponse(status=200) + + # Handles the Teams signin/tokenExchange invoke activity and continues the dialog. + async def on_teams_signin_token_exchange(self, turn_context: TurnContext): + logging.info("Running dialog with signin/tokenExchange from an Invoke Activity.") + await DialogHelper.run_dialog( + self.dialog, + turn_context, + self.conversation_state.create_property("DialogState"), + ) + return InvokeResponse(status=200) diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/config.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/config.py new file mode 100644 index 0000000000..35da469b28 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/config.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os + +""" Bot Configuration """ + + +class DefaultConfig: + """ Bot Configuration """ + + PORT = 3978 + APP_ID = os.environ.get("MicrosoftAppId", "") + APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "") + CONNECTION_NAME = os.environ.get("ConnectionName", "") \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/__init__.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/__init__.py new file mode 100644 index 0000000000..ab5189cd5f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from .logout_dialog import LogoutDialog +from .main_dialog import MainDialog + +__all__ = ["LogoutDialog", "MainDialog"] diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/logout_dialog.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/logout_dialog.py new file mode 100644 index 0000000000..143e329cfb --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/logout_dialog.py @@ -0,0 +1,37 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from botbuilder.dialogs import DialogTurnResult, ComponentDialog, DialogContext +from botbuilder.core import BotFrameworkAdapter +from botbuilder.schema import ActivityTypes + +class LogoutDialog(ComponentDialog): + def __init__(self, dialog_id: str, connection_name: str): + # Initializes the LogoutDialog with a dialog ID and OAuth connection name. + super(LogoutDialog, self).__init__(dialog_id) + + self.connection_name = connection_name + + async def on_begin_dialog(self, inner_dc: DialogContext, options: object) -> DialogTurnResult: + # Intercepts the dialog at the beginning to check for logout command. + result = await self._interrupt(inner_dc) + if result: + return result + return await super().on_begin_dialog(inner_dc, options) + + async def on_continue_dialog(self, inner_dc: DialogContext) -> DialogTurnResult: + # Intercepts the dialog while it is running to check for logout command. + result = await self._interrupt(inner_dc) + if result: + return result + return await super().on_continue_dialog(inner_dc) + + async def _interrupt(self, inner_dc: DialogContext): + # Checks for the 'logout' command and signs the user out if detected. + if inner_dc.context.activity.type == ActivityTypes.message: + text = inner_dc.context.activity.text.lower() + if text == "logout": + bot_adapter: BotFrameworkAdapter = inner_dc.context.adapter + await bot_adapter.sign_out_user(inner_dc.context, self.connection_name) + await inner_dc.context.send_activity("You have been signed out.") + return await inner_dc.cancel_all_dialogs() diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/main_dialog.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/main_dialog.py new file mode 100644 index 0000000000..5e242d01c1 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/dialogs/main_dialog.py @@ -0,0 +1,137 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from botbuilder.core import MessageFactory, CardFactory +from botbuilder.dialogs import ( + WaterfallDialog, + WaterfallStepContext, + DialogTurnResult, + PromptOptions, +) +from botbuilder.dialogs.prompts import OAuthPrompt, OAuthPromptSettings, ConfirmPrompt +from botbuilder.schema import ThumbnailCard, CardImage + +from dialogs import LogoutDialog +from simple_graph_client import SimpleGraphClient +import logging +# Set the logging level to INFO +logging.basicConfig(level=logging.INFO) + +class MainDialog(LogoutDialog): + def __init__(self, connection_name: str): + # Initializes the MainDialog with OAuthPrompt, ConfirmPrompt, and WaterfallDialog. + super(MainDialog, self).__init__(MainDialog.__name__, connection_name) + + self.add_dialog( + OAuthPrompt( + OAuthPrompt.__name__, + OAuthPromptSettings( + connection_name=connection_name, + text="Please Sign In", + title="Sign In", + timeout=300000 + ) + ) + ) + + self.add_dialog(ConfirmPrompt(ConfirmPrompt.__name__)) + + self.add_dialog( + WaterfallDialog( + "WFDialog", + [ + self.prompt_step, + self.login_step, + self.display_token_phase1, + self.display_token_phase2, + ], + ) + ) + + self.initial_dialog_id = "WFDialog" + + # Prompts the user to sign in using the OAuthPrompt. + async def prompt_step(self, step_context: WaterfallStepContext) -> DialogTurnResult: + logging.info("Reached OAuthPrompt step — prompting for login.") + return await step_context.begin_dialog(OAuthPrompt.__name__) + + # Handles the login result and optionally prompts to display the token. + async def login_step(self, step_context: WaterfallStepContext) -> DialogTurnResult: + token_response = step_context.result + if not token_response or not token_response.token: + await step_context.context.send_activity("Login was not successful, please try again.") + return await step_context.end_dialog() + else: + try: + # Create Graph client and get user info + client = SimpleGraphClient(token_response.token) + me = await client.get_me() + + if me: + title = me.get('jobTitle', 'Unknown') + display_name = me.get('displayName', 'Unknown User') + user_principal_name = me.get('userPrincipalName', 'Unknown') + + await step_context.context.send_activity( + f"You're logged in as {display_name} ({user_principal_name}); your job title is: {title}" + ) + + # Get user photo + logging.info("Attempting to fetch user photo...") + photo_base64 = await client.get_photo_async(token_response.token) + if photo_base64: + logging.info("Photo retrieved successfully") + await step_context.context.send_activity("Your photo is:") + # Create thumbnail card with photo + thumbnail_card = ThumbnailCard( + title="Your Profile Photo", + images=[CardImage(url=photo_base64)] + ) + card = CardFactory.thumbnail_card(thumbnail_card) + await step_context.context.send_activity(MessageFactory.attachment(card)) + else: + logging.info("Photo not available") + await step_context.context.send_activity("Profile photo not available.") + else: + await step_context.context.send_activity("Could not retrieve user information.") + + except Exception as e: + logging.error(f"Error getting user info: {e}") + await step_context.context.send_activity("You are now logged in.") + + return await step_context.prompt( + ConfirmPrompt.__name__, + PromptOptions( + prompt=MessageFactory.text("Would you like to view your token?") + ), + ) + + # Re-prompts for OAuth token if the user wants to view it. + async def display_token_phase1( + self, step_context: WaterfallStepContext + ) -> DialogTurnResult: + await step_context.context.send_activity("Thank you.") + + if step_context.result: + # Call the prompt again because we need the token. The reasons for this are: + # 1. If the user is already logged in we do not need to store the token locally in the bot and worry + # about refreshing it. We can always just call the prompt again to get the token. + # 2. We never know how long it will take a user to respond. By the time the + # user responds the token may have expired. The user would then be prompted to login again. + # + # There is no reason to store the token locally in the bot because we can always just call + # the OAuth prompt to get the token or get a new token if needed. + return await step_context.begin_dialog(OAuthPrompt.__name__) + + return await step_context.end_dialog() + + # Displays the token to the user if they confirmed. + async def display_token_phase2( + self, step_context: WaterfallStepContext + ) -> DialogTurnResult: + if step_context.result: + await step_context.context.send_activity( + f"Here is your token {step_context.result.token}" + ) + + return await step_context.end_dialog() diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/env/.env.local b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/env/.env.local new file mode 100644 index 0000000000..835a63225b --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/env/.env.local @@ -0,0 +1,18 @@ +BOT_ENDPOINT= +BOT_DOMAIN= +TEAMSFX_ENV=local +APP_NAME_SUFFIX=local +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE=SingleTenant +MICROSOFT_APP_TENANT_ID= +CONNECTION_NAME= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/helpers/__init__.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/helpers/__init__.py new file mode 100644 index 0000000000..a824eb8f40 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/helpers/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from . import dialog_helper + +__all__ = ["dialog_helper"] diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/helpers/dialog_helper.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/helpers/dialog_helper.py new file mode 100644 index 0000000000..1fb49f51d5 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/helpers/dialog_helper.py @@ -0,0 +1,55 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import logging +from botbuilder.core import StatePropertyAccessor, TurnContext +from botbuilder.dialogs import Dialog, DialogSet, DialogTurnStatus +from botbuilder.schema import InvokeResponse + +# Set the logging level to INFO +logging.basicConfig(level=logging.INFO) + +class DialogHelper: + # Runs the provided dialog, handling both normal and OAuth invoke activities. + @staticmethod + async def run_dialog( + dialog: Dialog, turn_context: TurnContext, accessor: StatePropertyAccessor + ): + try: + logging.info("Initializing DialogSet and adding dialog.") + dialog_set = DialogSet(accessor) + dialog_set.add(dialog) + + dialog_context = await dialog_set.create_context(turn_context) + + logging.info("Continuing any existing dialog.") + results = await dialog_context.continue_dialog() + + if results.status == DialogTurnStatus.Empty: + logging.info(f"No active dialog. Starting new dialog: {dialog.id}") + await dialog_context.begin_dialog(dialog.id) + else: + logging.info(f"Continuing dialog. Status: {results.status.name}") + + # Special handling for OAuth invoke activities + if turn_context.activity.name in ["signin/tokenExchange", "signin/verifyState"]: + logging.info("OAuth prompt token exchange or verifyState handled.") + return InvokeResponse(status=200) + + except AttributeError as attr_error: + # Handle the specific "'ErrorResponse' object has no attribute 'token'" error + if "has no attribute 'token'" in str(attr_error): + logging.error(f"OAuth token error handled: {attr_error}") + # Send a friendly message to the user + await turn_context.send_activity("Authentication failed. Please try signing in again.") + # Return successful invoke response to prevent framework errors + if turn_context.activity.name in ["signin/tokenExchange", "signin/verifyState"]: + return InvokeResponse(status=200) + else: + # Re-raise other AttributeError exceptions + raise + except Exception as e: + logging.error(f"Error running dialog: {e}") + import traceback + traceback.print_exc() + await turn_context.send_activity("Sorry, something went wrong starting the dialog.") \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/infra/azure.bicep b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/infra/azure.bicep new file mode 100644 index 0000000000..145ce9cd4f --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/infra/azure.bicep @@ -0,0 +1,76 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param botAadAppClientId string +param botAppDomain string + +param aadAppClientId string +@secure() +param aadAppClientSecret string +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} + +resource botServiceConnection 'Microsoft.BotService/botServices/connections@2021-03-01' = { + parent: botService + name: 'oauthbotsetting' + location: 'global' + properties: { + serviceProviderDisplayName: 'Azure Active Directory v2' + serviceProviderId: '30dd229c-58e3-4a48-bdfd-91ec48eb906c' + scopes: 'User.Read' + parameters: [ + { + key: 'clientId' + value: aadAppClientId + } + { + key: 'clientSecret' + value: aadAppClientSecret + } + { + key: 'tenantID' + value: microsoftAppTenantId + } + { + key: 'tokenExchangeUrl' + value: 'api://botid-${aadAppClientId}' + } + ] + } +} + +output CONNECTION_NAME string = botServiceConnection.name diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/infra/azure.parameters.json b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/infra/azure.parameters.json new file mode 100644 index 0000000000..bd425ea345 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/infra/azure.parameters.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "bot-conversation-sso-quickstart" + }, + "aadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "aadAppClientSecret": { + "value": "${{SECRET_AAD_APP_CLIENT_SECRET}}" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/m365agents.local.yml b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/m365agents.local.yml new file mode 100644 index 0000000000..d24346a05b --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/m365agents.local.yml @@ -0,0 +1,89 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:bot-conversation-sso-quickstart-python + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: bot-conversation-sso-quickstart-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # Authenticate users with a Microsoft work or school account in your organization's Azure AD tenant (for example, single tenant). + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: bot-conversation-sso-quickstart${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + - uses: aadApp/update # Apply the AAD manifest to an existing AAD app. Will use the object id in manifest file to determine which AAD app to update. + with: + manifestPath: ./aad.manifest.json # Relative path to teamsfx folder. Environment variables in manifest will be replaced before apply to AAD app + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to teamsfx folder. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + connectionName: ${{CONNECTION_NAME}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/m365agents.yml b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/m365agents.yml new file mode 100644 index 0000000000..3143fe2ec1 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:bot-conversation-sso-quickstart-python + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/requirements.txt b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/requirements.txt new file mode 100644 index 0000000000..6af8acfc36 --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/requirements.txt @@ -0,0 +1,2 @@ +botbuilder-integration-aiohttp==4.17.1 +botbuilder-dialogs==4.17.1 \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/simple_graph_client.py b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/simple_graph_client.py new file mode 100644 index 0000000000..e386603ecb --- /dev/null +++ b/samples/TeamsSDK/Archived/bot-conversation-sso-quickstart/python/simple_graph_client.py @@ -0,0 +1,97 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import aiohttp +import base64 +import logging +from typing import Optional, Dict, Any + + +class SimpleGraphClient: + """ + This class is a wrapper for the Microsoft Graph API. + See: https://developer.microsoft.com/en-us/graph for more information. + """ + + def __init__(self, token: str): + """ + Creates an instance of SimpleGraphClient. + + Args: + token (str): The token issued to the user. + """ + if not token or not token.strip(): + raise ValueError('SimpleGraphClient: Invalid token received.') + + self._token = token + self._base_url = 'https://graph.microsoft.com/v1.0' + self._headers = { + 'Authorization': f'Bearer {self._token}', + 'Content-Type': 'application/json' + } + + async def get_me(self) -> Optional[Dict[str, Any]]: + """ + Collects information about the user in the bot. + + Returns: + Optional[Dict[str, Any]]: The user information. + """ + try: + async with aiohttp.ClientSession() as session: + async with session.get( + f'{self._base_url}/me', + headers=self._headers + ) as response: + if response.status == 200: + return await response.json() + else: + logging.error(f'Error getting user information: {response.status} - {await response.text()}') + return None + except Exception as error: + logging.error(f'Error getting user information: {error}') + raise error + + async def get_photo_async(self, token: str) -> Optional[str]: + """ + Gets the user's photo. + + Args: + token (str): The token issued to the user. + + Returns: + Optional[str]: The user's photo as a base64 encoded string. + """ + # First try to get photo metadata to check if photo exists + photo_metadata_endpoint = f'{self._base_url}/me/photo' + photo_value_endpoint = f'{self._base_url}/me/photo/$value' + + headers = { + 'Authorization': f'Bearer {token}' + } + + try: + async with aiohttp.ClientSession() as session: + # Check if photo exists first + async with session.get(photo_metadata_endpoint, headers=headers) as metadata_response: + if metadata_response.status != 200: + logging.info(f'User photo metadata not available: {metadata_response.status}') + return None + + # If metadata exists, try to get the actual photo + async with session.get(photo_value_endpoint, headers=headers) as response: + if response.status == 200: + image_data = await response.read() + image_base64 = base64.b64encode(image_data).decode('utf-8') + image_uri = f'data:image/png;base64,{image_base64}' + return image_uri + elif response.status == 404: + logging.info('User photo not found (404). This is normal for users without profile photos.') + return None + else: + error_text = await response.text() + logging.error(f'Error fetching photo: {response.status} - {error_text}') + return None + except Exception as error: + logging.error(f'Error fetching photo: {error}') + return None \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/.gitignore b/samples/TeamsSDK/Archived/msgext-action/csharp/.gitignore new file mode 100644 index 0000000000..7466c01f9c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +appPackage/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/AdapterWithErrorHandler.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/AdapterWithErrorHandler.cs new file mode 100644 index 0000000000..8a948680b3 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/AdapterWithErrorHandler.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Builder.TraceExtensions; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Extensions.Logging; + +namespace Microsoft.BotBuilderSamples +{ + public class AdapterWithErrorHandler : CloudAdapter + { + public AdapterWithErrorHandler(BotFrameworkAuthentication auth, ILogger logger) + : base(auth, logger) + { + OnTurnError = async (turnContext, exception) => + { + // Log any leaked exception from the application. + // NOTE: In production environment, you should consider logging this to + // Azure Application Insights. Visit https://aka.ms/bottelemetry to see how + // to add telemetry capture to your bot. + logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}"); + + // Uncomment below commented line for local debugging. + // await turnContext.SendActivityAsync($"Sorry, it looks like something went wrong. Exception Caught: {exception.Message}"); + + // Send a trace activity, which will be displayed in the Bot Framework Emulator + await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError"); + }; + } + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Bots/TeamsMessagingExtensionsActionBot.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Bots/TeamsMessagingExtensionsActionBot.cs new file mode 100644 index 0000000000..456510bb51 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Bots/TeamsMessagingExtensionsActionBot.cs @@ -0,0 +1,346 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using AdaptiveCards; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Teams; +using Microsoft.Bot.Schema; +using Microsoft.Bot.Schema.Teams; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Microsoft.BotBuilderSamples.Helpers; +using Microsoft.BotBuilderSamples.Models; + +namespace Microsoft.BotBuilderSamples.Bots +{ + /// + /// TeamsMessagingExtensionsActionBot handles messaging extension actions for Teams. + /// + public class TeamsMessagingExtensionsActionBot : TeamsActivityHandler + { + private readonly string baseUrl; + + public TeamsMessagingExtensionsActionBot(IConfiguration configuration) : base() + { + this.baseUrl = configuration["BaseUrl"]; + } + + /// + /// Handles the submission of messaging extension actions. + /// + protected override async Task OnTeamsMessagingExtensionSubmitActionAsync( + ITurnContext turnContext, + MessagingExtensionAction action, + CancellationToken cancellationToken) + { + return action.CommandId switch + { + "createCard" => CreateCardCommand(turnContext, action), + "shareMessage" => ShareMessageCommand(turnContext, action), + "webView" => WebViewResponse(turnContext, action), + "createAdaptiveCard" => CreateAdaptiveCardResponse(turnContext, action), + "razorView" => RazorViewResponse(turnContext, action), + "HTML" => ShareHtmlCard(turnContext, action), + _ => await Task.FromResult(new MessagingExtensionActionResponse()) + }; + } + + private MessagingExtensionActionResponse RazorViewResponse(ITurnContext turnContext, MessagingExtensionAction action) + { + var cardData = JsonConvert.DeserializeObject(action.Data.ToString()); + var card = new HeroCard + { + Title = "Requested User: " + turnContext.Activity.From.Name, + Text = cardData.DisplayData, + }; + + var attachments = new List + { + new MessagingExtensionAttachment + { + Content = card, + ContentType = HeroCard.ContentType, + Preview = card.ToAttachment(), + } + }; + + return new MessagingExtensionActionResponse + { + ComposeExtension = new MessagingExtensionResult + { + AttachmentLayout = "list", + Type = "result", + Attachments = attachments, + }, + }; + } + + private MessagingExtensionActionResponse CreateCardCommand(ITurnContext turnContext, MessagingExtensionAction action) + { + var createCardData = ((JObject)action.Data).ToObject(); + + var card = new HeroCard + { + Title = createCardData.Title, + Subtitle = createCardData.Subtitle, + Text = createCardData.Text, + }; + + var attachments = new List + { + new MessagingExtensionAttachment + { + Content = card, + ContentType = HeroCard.ContentType, + Preview = card.ToAttachment(), + } + }; + + return new MessagingExtensionActionResponse + { + ComposeExtension = new MessagingExtensionResult + { + AttachmentLayout = "list", + Type = "result", + Attachments = attachments, + }, + }; + } + + private MessagingExtensionActionResponse ShareMessageCommand(ITurnContext turnContext, MessagingExtensionAction action) + { + var heroCard = new HeroCard + { + Title = $"{action.MessagePayload.From?.User?.DisplayName} originally sent this message:", + Text = action.MessagePayload.Body.Content, + }; + + if (action.MessagePayload.Attachments != null && action.MessagePayload.Attachments.Count > 0) + { + heroCard.Subtitle = $"({action.MessagePayload.Attachments.Count} Attachments not included)"; + } + + var includeImage = ((JObject)action.Data)["includeImage"]?.ToString(); + if (string.Equals(includeImage, bool.TrueString, StringComparison.OrdinalIgnoreCase)) + { + heroCard.Images = new List + { + new CardImage { Url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU" }, + }; + } + + return new MessagingExtensionActionResponse + { + ComposeExtension = new MessagingExtensionResult + { + Type = "result", + AttachmentLayout = "list", + Attachments = new List + { + new MessagingExtensionAttachment + { + Content = heroCard, + ContentType = HeroCard.ContentType, + Preview = heroCard.ToAttachment(), + }, + }, + }, + }; + } + + private MessagingExtensionActionResponse WebViewResponse(ITurnContext turnContext, MessagingExtensionAction action) + { + var cardData = JsonConvert.DeserializeObject(action.Data.ToString()); + var imgUrl = baseUrl + "/profile-image.png"; + + var card = new ThumbnailCard + { + Title = "ID: " + cardData.EmpId, + Subtitle = "Name: " + cardData.EmpName, + Text = "E-Mail: " + cardData.EmpEmail, + Images = new List { new CardImage { Url = imgUrl } }, + }; + + var attachments = new List + { + new MessagingExtensionAttachment + { + Content = card, + ContentType = ThumbnailCard.ContentType, + Preview = card.ToAttachment(), + } + }; + + return new MessagingExtensionActionResponse + { + ComposeExtension = new MessagingExtensionResult + { + AttachmentLayout = "list", + Type = "result", + Attachments = attachments, + }, + }; + } + + private MessagingExtensionActionResponse CreateAdaptiveCardResponse(ITurnContext turnContext, MessagingExtensionAction action) + { + var createCardResponse = ((JObject)action.Data).ToObject(); + var attachments = CardHelper.CreateAdaptiveCardAttachment(action, createCardResponse); + + return new MessagingExtensionActionResponse + { + ComposeExtension = new MessagingExtensionResult + { + AttachmentLayout = "list", + Type = "result", + Attachments = attachments, + }, + }; + } + + private MessagingExtensionActionResponse ShareHtmlCard(ITurnContext turnContext, MessagingExtensionAction action) + { + var createCardResponse = ((JObject)action.Data).ToObject(); + var attachments = CardHelper.CreateAdaptiveCardAttachmentForHtml(action, createCardResponse); + + return new MessagingExtensionActionResponse + { + ComposeExtension = new MessagingExtensionResult + { + AttachmentLayout = "list", + Type = "result", + Attachments = attachments, + }, + }; + } + + /// + /// Handles the fetching of tasks for messaging extensions. + /// + protected override async Task OnTeamsMessagingExtensionFetchTaskAsync( + ITurnContext turnContext, + MessagingExtensionAction action, + CancellationToken cancellationToken) + { + return action.CommandId switch + { + "webView" => EmpDetails(turnContext, action), + "HTML" => TaskModuleHtmlPage(turnContext, action), + "razorView" => DateDayInfo(turnContext, action), + _ => await HandleDefaultFetchTaskAsync(turnContext, cancellationToken) + }; + } + + private async Task HandleDefaultFetchTaskAsync(ITurnContext turnContext, CancellationToken cancellationToken) + { + string memberName; + try + { + var member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken); + memberName = member.Name; + } + catch (ErrorResponseException ex) + { + if (ex.Body.Error.Code == "BotNotInConversationRoster") + { + return new MessagingExtensionActionResponse + { + Task = new TaskModuleContinueResponse + { + Value = new TaskModuleTaskInfo + { + Card = GetAdaptiveCardAttachmentFromFile("justintimeinstallation.json"), + Height = 200, + Width = 400, + Title = "Adaptive Card - App Installation", + }, + }, + }; + } + throw; + } + + return new MessagingExtensionActionResponse + { + Task = new TaskModuleContinueResponse + { + Value = new TaskModuleTaskInfo + { + Card = GetAdaptiveCardAttachmentFromFile("adaptiveCard.json"), + Height = 200, + Width = 400, + Title = $"Welcome {memberName}", + }, + }, + }; + } + + private MessagingExtensionActionResponse DateDayInfo(ITurnContext turnContext, MessagingExtensionAction action) + { + return new MessagingExtensionActionResponse + { + Task = new TaskModuleContinueResponse + { + Value = new TaskModuleTaskInfo + { + Height = 175, + Width = 300, + Title = "Task Module Razor View", + Url = baseUrl + "/Home/RazorView", + }, + }, + }; + } + + private MessagingExtensionActionResponse TaskModuleHtmlPage(ITurnContext turnContext, MessagingExtensionAction action) + { + return new MessagingExtensionActionResponse + { + Task = new TaskModuleContinueResponse + { + Value = new TaskModuleTaskInfo + { + Height = 200, + Width = 400, + Title = "Task Module HTML Page", + Url = baseUrl + "/Home/HtmlPage", + }, + }, + }; + } + + private MessagingExtensionActionResponse EmpDetails(ITurnContext turnContext, MessagingExtensionAction action) + { + return new MessagingExtensionActionResponse + { + Task = new TaskModuleContinueResponse + { + Value = new TaskModuleTaskInfo + { + Height = 300, + Width = 450, + Title = "Task Module WebView", + Url = baseUrl + "/Home/CustomForm", + }, + }, + }; + } + + private static Attachment GetAdaptiveCardAttachmentFromFile(string fileName) + { + var adaptiveCardJson = File.ReadAllText(Path.Combine(".", "Resources", fileName)); + + return new Attachment + { + ContentType = "application/vnd.microsoft.card.adaptive", + Content = JsonConvert.DeserializeObject(adaptiveCardJson), + }; + } + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Controllers/BotController.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Controllers/BotController.cs new file mode 100644 index 0000000000..186070a240 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Controllers/BotController.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; + +namespace Microsoft.BotBuilderSamples.Controllers +{ + // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot + // implementation at runtime. Multiple different IBot implementations running at different endpoints can be + // achieved by specifying a more specific type for the bot constructor argument. + [Route("api/messages")] + [ApiController] + public class BotController : ControllerBase + { + private readonly IBotFrameworkHttpAdapter Adapter; + private readonly IBot Bot; + + public BotController(IBotFrameworkHttpAdapter adapter, IBot bot) + { + Adapter = adapter; + Bot = bot; + } + + [HttpPost] + public async Task PostAsync() + { + // Delegate the processing of the HTTP POST to the adapter. + // The adapter will invoke the bot. + await Adapter.ProcessAsync(Request, Response, Bot); + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Controllers/HomeController.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Controllers/HomeController.cs new file mode 100644 index 0000000000..4cdb83f913 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Controllers/HomeController.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Mvc; + +namespace TeamsMessagingExtensionsAction.Controllers +{ + /// + /// HomeController handles the routing for various views. + /// + public class HomeController : Controller + { + /// + /// Returns the RazorView view. + /// + [Route("/Home/RazorView")] + public IActionResult RazorView() + { + return View("RazorView"); + } + + /// + /// Returns the CustomForm view. + /// + [Route("/Home/CustomForm")] + public IActionResult CustomForm() + { + return View("CustomForm"); + } + + /// + /// Returns the HtmlPage view. + /// + [Route("/Home/HtmlPage")] + public IActionResult HtmlPage() + { + return View("HtmlPage"); + } + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json new file mode 100644 index 0000000000..c2c03ef307 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json new file mode 100644 index 0000000000..c4b2909008 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "value": "" + }, + "existingAppServicePlanName": { + "value": "" + }, + "existingAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/readme.md b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/readme.md new file mode 100644 index 0000000000..628f0a9546 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/readme.md @@ -0,0 +1,48 @@ +# Usage +The BotApp must be deployed prior to AzureBot. + +Command line: +- az login +- az deployment group create --resource-group --template-file --parameters @ + +# parameters-for-template-BotApp-with-rg: + +- **appServiceName**:(required) The Name of the Bot App Service. + +- (choose an existingAppServicePlan or create a new AppServicePlan) + - **existingAppServicePlanName**: The name of the App Service Plan. + - **existingAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanName**: The name of the App Service Plan. + - **newAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** + +- **appId**:(required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. + +- **appSecret**:(required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. + +- **UMSIName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. + +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. + +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +MoreInfo: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource + + + +# parameters-for-template-AzureBot-with-rg: + +- **azureBotId**:(required) The globally unique and immutable bot ID. +- **azureBotSku**: The pricing tier of the Bot Service Registration. **Allowed values are: F0, S1(default)**. +- **azureBotRegion**: Specifies the location of the new AzureBot. **Allowed values are: global(default), westeurope**. +- **botEndpoint**: Use to handle client messages, Such as https://.azurewebsites.net/api/messages. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** +- **appId**:(required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **UMSIName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +MoreInfo: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json new file mode 100644 index 0000000000..a8a960066f --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json @@ -0,0 +1,121 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default)." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope." + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]", + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "msiResourceId": "" + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "" + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "[variables('msiResourceId')]" + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "msiResourceId": "[variables('appTypeDef')[parameters('appType')].msiResourceId]" + } + }, + "resources": [ + { + "apiVersion": "2021-05-01-preview", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "msaAppTenantId": "[variables('appType').tenantId]", + "msaAppMSIResourceId": "[variables('appType').msiResourceId]", + "msaAppType": "[parameters('appType')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + }, + "dependsOn": [] + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json new file mode 100644 index 0000000000..ce3bb6322a --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json @@ -0,0 +1,191 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "existingAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "existingAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types. Defaults to \"\"." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication. Defaults to \"\"." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. Defaults to \"\"." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "useExistingServicePlan": "[not(empty(parameters('existingAppServicePlanName')))]", + "servicePlanName": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanName'), parameters('newAppServicePlanName'))]", + "servicePlanLocation": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanLocation'), parameters('newAppServicePlanLocation'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "identity": { "type": "None" } + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "identity": { "type": "None" } + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[variables('msiResourceId')]": {} + } + } + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "identity": "[variables('appTypeDef')[parameters('appType')].identity]" + } + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[parameters('newAppServicePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "properties": { + "name": "[variables('servicePlanName')]" + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('servicePlanLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]" + ], + "name": "[parameters('appServiceName')]", + "identity": "[variables('appType').identity]", + "properties": { + "name": "[parameters('appServiceName')]", + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "10.14.1" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + }, + { + "name": "MicrosoftAppTenantId", + "value": "[variables('appType').tenantId]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json new file mode 100644 index 0000000000..44f169e4d5 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json new file mode 100644 index 0000000000..8abb03d597 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "appServiceName": { + "value": "" + }, + "appServicePlanName": { + "value": "" + }, + "appServicePlanLocation": { + "value": "" + }, + "appServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/readme.md b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/readme.md new file mode 100644 index 0000000000..23bf7a5a51 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/readme.md @@ -0,0 +1,45 @@ +# Usage +The BotApp must be deployed prior to AzureBot. + +Command line: +- az login +- az deployment sub create --template-file --location --parameters @ + +# parameters-for-template-BotApp-new-rg: + +- **groupName**:(required) Specifies the name of the new Resource Group. +- **groupLocation**:(required) Specifies the location of the new Resource Group. + +- **appServiceName**:(required) The location of the App Service Plan. +- **appServicePlanName**:(required) The name of the App Service Plan. +- **appServicePlanLocation**: The location of the App Service Plan. Defaults to use groupLocation. +- **appServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** +- **appId**:(required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**:(required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. +- **UMSIName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +MoreInfo: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource + + + +# parameters-for-template-AzureBot-new-rg: + +- **groupName**:(required) Specifies the name of the new Resource Group. +- **groupLocation**:(required) Specifies the location of the new Resource Group. + +- **azureBotId**:(required) The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable. +- **azureBotSku**: The pricing tier of the Bot Service Registration. **Allowed values are: F0, S1(default)**. +- **azureBotRegion**: Specifies the location of the new AzureBot. **Allowed values are: global(default), westeurope**. +- **botEndpoint**: Use to handle client messages, Such as https://.azurewebsites.net/api/messages. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** +- **appId**:(required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **UMSIName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +MoreInfo: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json new file mode 100644 index 0000000000..ae073b7939 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json @@ -0,0 +1,160 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "" + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]", + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "msiResourceId": "" + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "" + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "[variables('msiResourceId')]" + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "msiResourceId": "[variables('appTypeDef')[parameters('appType')].msiResourceId]" + } + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "apiVersion": "2021-03-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "name": "[parameters('azureBotId')]", + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "msaAppTenantId": "[variables('appType').tenantId]", + "msaAppMSIResourceId": "[variables('appType').msiResourceId]", + "msaAppType": "[parameters('appType')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json new file mode 100644 index 0000000000..560bbbc443 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json @@ -0,0 +1,213 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "appServiceName": { + "type": "string", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "appServicePlanName": { + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "appServicePlanLocation": { + "type": "string", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "appServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "appServicePlanName": "[parameters('appServicePlanName')]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), parameters('groupLocation'), parameters('appServicePlanLocation'))]", + "appServiceName": "[parameters('appServiceName')]", + "resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "identity": { "type": "None" } + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "identity": { "type": "None" } + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[variables('msiResourceId')]": {} + } + } + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "identity": "[variables('appTypeDef')[parameters('appType')].identity]" + } + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('appServicePlanSku')]", + "properties": { + "name": "[variables('appServicePlanName')]" + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('appServiceName')]", + "identity": "[variables('appType').identity]", + "properties": { + "name": "[variables('appServiceName')]", + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "10.14.1" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + }, + { + "name": "MicrosoftAppTenantId", + "value": "[variables('appType').tenantId]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + } + ], + "outputs": {} + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Helpers/CardHelper.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Helpers/CardHelper.cs new file mode 100644 index 0000000000..5a7a786c5d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Helpers/CardHelper.cs @@ -0,0 +1,112 @@ +using AdaptiveCards; +using Microsoft.Bot.Schema.Teams; +using Microsoft.BotBuilderSamples.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace Microsoft.BotBuilderSamples.Helpers +{ + /// + /// Helper class for creating adaptive card attachments. + /// + public static class CardHelper + { + /// + /// Creates an adaptive card attachment. + /// + /// The messaging extension action. + /// The card response data. + /// A list of messaging extension attachments. + public static List CreateAdaptiveCardAttachment(MessagingExtensionAction action, CardResponse createCardResponse) + { + var adaptiveCard = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0)) + { + Body = new List + { + CreateAdaptiveColumnSet("Name :", createCardResponse.Title), + CreateAdaptiveColumnSet("Designation :", createCardResponse.Subtitle), + CreateAdaptiveColumnSet("Description :", createCardResponse.Text) + } + }; + + return new List + { + new MessagingExtensionAttachment + { + Content = JsonConvert.DeserializeObject(adaptiveCard.ToJson()), + ContentType = AdaptiveCard.ContentType + } + }; + } + + /// + /// Creates an adaptive card attachment for HTML. + /// + /// The messaging extension action. + /// The card response data. + /// A list of messaging extension attachments. + public static List CreateAdaptiveCardAttachmentForHtml(MessagingExtensionAction action, CardResponse createCardResponse) + { + var adaptiveCard = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0)) + { + Body = new List + { + CreateAdaptiveColumnSet("User Name :", createCardResponse.UserName), + CreateAdaptiveColumnSet("Password is :", createCardResponse.UserPwd) + } + }; + + return new List + { + new MessagingExtensionAttachment + { + Content = JsonConvert.DeserializeObject(adaptiveCard.ToJson()), + ContentType = AdaptiveCard.ContentType + } + }; + } + + /// + /// Creates an adaptive column set. + /// + /// The label text. + /// The value text. + /// An adaptive column set. + private static AdaptiveColumnSet CreateAdaptiveColumnSet(string label, string value) + { + return new AdaptiveColumnSet + { + Columns = new List + { + new AdaptiveColumn + { + Items = new List + { + new AdaptiveTextBlock + { + Text = label, + Wrap = true, + Size = AdaptiveTextSize.Medium, + Weight = AdaptiveTextWeight.Bolder + } + }, + Width = AdaptiveColumnWidth.Auto + }, + new AdaptiveColumn + { + Items = new List + { + new AdaptiveTextBlock + { + Text = value, + Wrap = true, + Size = AdaptiveTextSize.Medium + } + }, + Width = AdaptiveColumnWidth.Auto + } + } + }; + } + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/1-Add-ME.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/1-Add-ME.png new file mode 100644 index 0000000000..18dfb04054 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/1-Add-ME.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/10-ME-AdaptiveCard.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/10-ME-AdaptiveCard.png new file mode 100644 index 0000000000..d71b7a1ea2 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/10-ME-AdaptiveCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/11-AC-Form.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/11-AC-Form.png new file mode 100644 index 0000000000..fc9019747f Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/11-AC-Form.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/12-AC-Form-Preview.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/12-AC-Form-Preview.png new file mode 100644 index 0000000000..0d02f205dc Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/12-AC-Form-Preview.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/13-AC-Form-Posted.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/13-AC-Form-Posted.png new file mode 100644 index 0000000000..3f997229a0 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/13-AC-Form-Posted.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/14-WebView.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/14-WebView.png new file mode 100644 index 0000000000..c0e3cd2f60 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/14-WebView.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/15-WebView-Form-Fetched.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/15-WebView-Form-Fetched.png new file mode 100644 index 0000000000..633306bccc Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/15-WebView-Form-Fetched.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/16-WebView-Form-Preview.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/16-WebView-Form-Preview.png new file mode 100644 index 0000000000..195d4a2a85 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/16-WebView-Form-Preview.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/17-WebView-Form-Posted.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/17-WebView-Form-Posted.png new file mode 100644 index 0000000000..a9551b9ac4 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/17-WebView-Form-Posted.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/18-HTML.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/18-HTML.png new file mode 100644 index 0000000000..7f80c1a6f3 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/18-HTML.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/19-HTML-Form.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/19-HTML-Form.png new file mode 100644 index 0000000000..ae71bc6ff4 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/19-HTML-Form.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/2-Added-ME.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/2-Added-ME.png new file mode 100644 index 0000000000..7eb40a6d9e Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/2-Added-ME.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/20-RazorView.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/20-RazorView.png new file mode 100644 index 0000000000..9a94b4393d Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/20-RazorView.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/21-RazorView-Details.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/21-RazorView-Details.png new file mode 100644 index 0000000000..57714ab9df Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/21-RazorView-Details.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/3-ME-Open.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/3-ME-Open.png new file mode 100644 index 0000000000..c7015bdab4 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/3-ME-Open.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/4-ME-Card.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/4-ME-Card.png new file mode 100644 index 0000000000..186f853978 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/4-ME-Card.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/5-ME-Card-data.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/5-ME-Card-data.png new file mode 100644 index 0000000000..010ac70bf9 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/5-ME-Card-data.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/6-ME-Card-Preview.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/6-ME-Card-Preview.png new file mode 100644 index 0000000000..df5021c9c3 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/6-ME-Card-Preview.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/7-ME-Posted-Card.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/7-ME-Posted-Card.png new file mode 100644 index 0000000000..b89f0de23d Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/7-ME-Posted-Card.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/8-Roster-Fetch.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/8-Roster-Fetch.png new file mode 100644 index 0000000000..6f9df55520 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/8-Roster-Fetch.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/9-Roster-Fetched.png b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/9-Roster-Fetched.png new file mode 100644 index 0000000000..52d6e59069 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/9-Roster-Fetched.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Images/msgext-action.gif b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/msgext-action.gif new file mode 100644 index 0000000000..9414347afc Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/Images/msgext-action.gif differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/M365Agent.ttkproj b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/M365Agent.ttkproj new file mode 100644 index 0000000000..79e4ce2efd --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/M365Agent.ttkproj @@ -0,0 +1,14 @@ + + + + 95754b61-0437-49e0-a664-9564f36e58fb + + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/aad.manifest.json b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/aad.manifest.json new file mode 100644 index 0000000000..5aed194213 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/aad.manifest.json @@ -0,0 +1,100 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "displayName": "msgext-action-aad", + "signInAudience": "AzureADMultipleOrgs", + "api": { + "requestedAccessTokenVersion": 2, + "oauth2PermissionScopes": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ] + }, + "info": {}, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "publicClient": {}, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "web": { + "implicitGrantSettings": {} + }, + "spa": {} +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/color.png b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/color.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/manifest.json b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/manifest.json new file mode 100644 index 0000000000..60154220ce --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/manifest.json @@ -0,0 +1,168 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://dev.botframework.com", + "privacyUrl": "https://privacy.microsoft.com", + "termsOfUseUrl": "https://www.microsoft.com/en-us/legal/intellectualproperty/copyright/default.aspx" + }, + "name": { + "short": "Action MessagingExt C#", + "full": "Microsoft Teams Action Based Messaging Extension" + }, + "description": { + "short": "This sample app illustrates how to implement Action-Based Messaging Extensions.", + "full": "This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "needsChannelSelector": false, + "isNotificationOnly": false, + "supportsCalling": false, + "supportsVideo": false, + "supportsFiles": false, + "scopes": [ + "team", + "personal", + "groupChat" + ] + } + ], + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "commands": [ + { + "id": "createCard", + "type": "action", + "context": [ + "compose" + ], + "description": "Command to run action to create a Card from Compose Box", + "title": "Create Card", + "parameters": [ + { + "name": "title", + "title": "Card title", + "description": "Title for the card", + "inputType": "text" + }, + { + "name": "subTitle", + "title": "Subtitle", + "description": "Subtitle for the card", + "inputType": "text" + }, + { + "name": "text", + "title": "Text", + "description": "Text for the card", + "inputType": "textarea" + } + ] + }, + { + "id": "shareMessage", + "type": "action", + "context": [ + "message" + ], + "description": "Test command to run action on message context (message sharing)", + "title": "Share Message", + "parameters": [ + { + "name": "includeImage", + "title": "Include Image", + "description": "Include image in Hero Card", + "inputType": "toggle" + } + ] + }, + { + "id": "FetchRoster", + "description": "Fetch the conversation roster", + "title": "FetchRoster", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + }, + { + "id": "createAdaptiveCard", + "type": "action", + "context": [ + "compose" + ], + "description": "Command to run action to create a Card from Compose Box", + "title": "Adaptive Card", + "parameters": [ + { + "name": "title", + "title": "Name", + "description": "Name of the User", + "inputType": "text" + }, + { + "name": "subTitle", + "title": "Designation", + "description": "Designation of the User", + "inputType": "text" + }, + { + "name": "text", + "title": "Description", + "description": "Description", + "inputType": "textarea" + } + ] + }, + { + "id": "webView", + "description": "Fetch the Web View", + "title": "Web View", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + }, + { + "id": "HTML", + "description": "Fetch the HTML", + "title": "HTML", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + }, + { + "id": "razorView", + "description": "Fetch the Razor View", + "title": "Razor View", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + } + ] + } + ], + "permissions": [ + "identity" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/outline.png b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/appPackage/outline.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/env/.env.local b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/env/.env.local new file mode 100644 index 0000000000..c58f8fe9e3 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/env/.env.local @@ -0,0 +1,26 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local +APP_NAME_SUFFIX=local + +# Generated during provision, you can also add your own variables. +BOT_ID= +TEAMS_APP_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE=SingleTenant +MICROSOFT_APP_TENANT_ID= +TEAMSFX_M365_USER_NAME= + +BOT_ENDPOINT= +BOT_DOMAIN= + +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/infra/azure.bicep b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/infra/azure.parameters.json b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/infra/azure.parameters.json new file mode 100644 index 0000000000..2ca3c587cf --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "msgext-action" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/launchSettings.json b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/launchSettings.json new file mode 100644 index 0000000000..8c76c70d9e --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/launchSettings.json @@ -0,0 +1,17 @@ +{ + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } + }, + // Launch project within Teams without prepare app dependencies + "Microsoft Teams (browser) (skip update app)": { + "commandName": "Project", + "environmentVariables": { + "UPDATE_TEAMS_APP": "false" + }, + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/m365agents.local.yml b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/m365agents.local.yml new file mode 100644 index 0000000000..358f097fa2 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/m365agents.local.yml @@ -0,0 +1,94 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-action-csharp + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: msgext-action-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMultipleOrgs" # Multitenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: msgext-action${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ../appsettings.json + content: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: ${{MICROSOFT_APP_TYPE}} + MicrosoftAppTenantId: ${{MICROSOFT_APP_TENANT_ID}} + BaseUrl: ${{BOT_ENDPOINT}} + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appPackage/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/m365agents.yml b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/m365agents.yml new file mode 100644 index 0000000000..fdaf1ffd38 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/M365Agent/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-action-csharp + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Model/CardResponse.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Model/CardResponse.cs new file mode 100644 index 0000000000..968ca5fb75 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Model/CardResponse.cs @@ -0,0 +1,33 @@ +namespace Microsoft.BotBuilderSamples.Models +{ + /// + /// Represents the response data for a card. + /// + public class CardResponse + { + /// + /// Gets or sets the title of the card. + /// + public string Title { get; set; } + + /// + /// Gets or sets the subtitle of the card. + /// + public string Subtitle { get; set; } + + /// + /// Gets or sets the text of the card. + /// + public string Text { get; set; } + + /// + /// Gets or sets the username for the card. + /// + public string UserName { get; set; } + + /// + /// Gets or sets the user password for the card. + /// + public string UserPwd { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Model/CustomForm.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Model/CustomForm.cs new file mode 100644 index 0000000000..dae1f852eb --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Model/CustomForm.cs @@ -0,0 +1,23 @@ +namespace Microsoft.BotBuilderSamples.Models +{ + /// + /// Represents the response data for a custom form. + /// + public class CustomFormResponse + { + /// + /// Gets or sets the employee ID. + /// + public string EmpId { get; set; } + + /// + /// Gets or sets the employee name. + /// + public string EmpName { get; set; } + + /// + /// Gets or sets the employee email. + /// + public string EmpEmail { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Model/RazorView.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Model/RazorView.cs new file mode 100644 index 0000000000..e7a897b01c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Model/RazorView.cs @@ -0,0 +1,18 @@ +namespace Microsoft.BotBuilderSamples.Models +{ + /// + /// Represents the response data for a Razor view. + /// + public class RazorViewResponse + { + /// + /// Gets or sets the title of the Razor view. + /// + public string Title { get; set; } + + /// + /// Gets or sets the display data for the Razor view. + /// + public string DisplayData { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/Shared/_Layout.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/Shared/_Layout.cshtml new file mode 100644 index 0000000000..d111d4d37f --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/Shared/_Layout.cshtml @@ -0,0 +1,23 @@ + + + + Microsoft Teams Hello World Sample App + + + + + + + @RenderSection("scripts", required: false) + + +
+
+ @RenderBody() +
+
+ + diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/_ViewStart.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/htmlpage.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/htmlpage.cshtml new file mode 100644 index 0000000000..12537aa5ac --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/htmlpage.cshtml @@ -0,0 +1,45 @@ +@page +@model TeamsMessagingExtensionsAction.Pages.IndexModel +@{ + ViewData["Title"] = "HTML Page"; + Layout = "~/Pages/Shared/_Layout.cshtml"; +} + + + + + Login Form + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/htmlpage.cshtml.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/htmlpage.cshtml.cs new file mode 100644 index 0000000000..94c3acf068 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Pages/htmlpage.cshtml.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace TeamsMessagingExtensionsAction.Pages +{ + public class IndexModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Program.cs b/samples/TeamsSDK/Archived/msgext-action/csharp/Program.cs new file mode 100644 index 0000000000..9994a0424c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Program.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.BotBuilderSamples; +using Microsoft.BotBuilderSamples.Bots; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers().AddNewtonsoftJson(options => +{ + options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth; +}); +builder.Services.AddHttpClient(); +builder.Services.AddRazorPages(); + +// Create the Bot Framework Authentication to be used with the Bot Adapter. +builder.Services.AddSingleton(); + +// Create the Bot Adapter with error handling enabled. +builder.Services.AddSingleton(); + +// Create the bot as a transient. In this case the ASP Controller is expecting an IBot. +builder.Services.AddTransient(); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +} + +app.UseDefaultFiles(); +app.UseStaticFiles(); +app.UseRouting(); + +app.MapRazorPages(); +app.MapControllers(); + +app.Run(); diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Properties/launchSettings.json b/samples/TeamsSDK/Archived/msgext-action/csharp/Properties/launchSettings.json new file mode 100644 index 0000000000..ff9d8fe153 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "Start Project": { + "commandName": "Project", + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7130;http://localhost:5130", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/README.md b/samples/TeamsSDK/Archived/msgext-action/csharp/README.md new file mode 100644 index 0000000000..06e51fb867 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/README.md @@ -0,0 +1,167 @@ +--- +page_type: sample +description: This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality. +products: +- office-teams +- office +- office-365 +languages: +- csharp +extensions: + contentType: samples + createdDate: "10/17/2019 13:38:25 PM" +urlFragment: officedev-microsoft-teams-samples-msgext-action-csharp +--- +# Teams Messaging Extensions Action + +Explore the capabilities of Action-Based Messaging Extensions in Microsoft Teams with this sample app. It showcases how to implement interactive features, including bots and message extensions, allowing users to create content dynamically through a user-friendly interface. + +[Messaging Extensions](https://docs.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/what-are-messaging-extensions) are a special kind of Microsoft Teams application that is support by the [Bot Framework](https://dev.botframework.com) v4. + +There are two basic types of Messaging Extension in Teams: [Search-based](https://docs.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/how-to/search-commands/define-search-command) and [Action-based](https://docs.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/how-to/action-commands/define-action-command). This sample illustrates how to +build an Action-based Messaging Extension. + +## Included Features +* Bots +* Message Extensions +* Action Commands + +## Interaction with Messaging Extension +![msgext-action ](Images/msgext-action.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Teams Messaging Extensions Action:** [Manifest](/samples/msgext-action/csharp/demo-manifest/msgext-action.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account +- [.NET SDK](https://dotnet.microsoft.com/download) version 6.0 +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.14 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Microsoft 365 Agents Toolkit for Visual Studio [Microsoft 365 Agents Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In the debug dropdown menu of Visual Studio, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel. +1. In the debug dropdown menu of Visual Studio, select default startup project > **Microsoft Teams (browser)** +1. Right-click the 'M365Agent' project in Solution Explorer and select **Microsoft 365 Agents Toolkit > Select Microsoft 365 Account** +1. Sign in to Microsoft 365 Agents Toolkit with a **Microsoft 365 work or school account** +1. Set `Startup Item` as `Microsoft Teams (browser)`. +1. Press F5, or select Debug > Start Debugging menu in Visual Studio to start your app +
![image](https://raw.githubusercontent.com/OfficeDev/TeamsFx/dev/docs/images/visualstudio/debug/debug-button.png) +1. In the opened web browser, select Add button to install the app in Teams + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +the Teams service needs to call into the bot. + +1) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +2) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +3) Setup for Bot + + In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration). + - For bot handle, make up a name. + - Select "Use existing app registration" (Create the app registration in Microsoft Entra ID beforehand.) + - __*If you don't have an Azure account*__ create an [Azure free account here](https://azure.microsoft.com/free/) + + In the new Azure Bot resource in the Portal, + - Ensure that you've [enabled the Teams Channel](https://learn.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - In Settings/Configuration/Messaging endpoint, enter the current `https` URL you were given by running the tunnelling application. Append with the path `/api/messages` + +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +1) If you are using Visual Studio + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `samples/msgext-action/csharp` folder + - Select `TeamsMessagingExtensionsAction.csproj` or `TeamsMessagingExtensionsAction.sln`file + +1) Update the `appsettings.json` configuration for the bot to use the MicrosoftAppId, MicrosoftAppPassword, MicrosoftAppTenantId generated in Step 1 (App Registration creation). (Note the App Password is referred to as the "client secret" in the azure portal and you can always create a new client secret anytime.) + - Set "MicrosoftAppType" in the `appsettings.json`. (**Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI**) + + - Set "BaseUrl" in the `appsettings.json` as per your application like the ngrok forwarding url (ie `https://xxxx.ngrok-free.app`) after starting ngrok and if you are using dev tunnels, your URL will be like: https://12345.devtunnels.ms. + +1) Run your bot, either from Visual Studio with `F5` or using `dotnet run` in the appropriate folder. + +1) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appPackage` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `<>` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` with base Url domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `appPackage` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + - **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.) + - Add the bot to personal/team/groupChat scope (Supported scopes) + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/msgext-action/csharp/AdapterWithErrorHandler.cs#L25) line and put your debugger for local debug. + +## Running the sample + +> Note this `manifest.json` specified that the bot will be called from both the `compose` and `message` areas of Teams. Please refer to Teams documentation for more details. + +1) Selecting the **Create Card** command from the Compose Box command list. The parameters dialog will be displayed and can be submitted to initiate the card creation within the Messaging Extension code. + +![4-ME-Card ](Images/4-ME-Card.png) + +![5-ME-Card-data ](Images/5-ME-Card-data.png) + +![6-ME-Card-Preview ](Images/6-ME-Card-Preview.png) + +![7-ME-Posted-Card ](Images/7-ME-Posted-Card.png) + + +2) Selecting the **Fetch Roster** command from the Compose Box command list. You will presented with prompt for Just In Time installation if app is not already added to current team/chat. + +![8-Roster-Fetch ](Images/8-Roster-Fetch.png) + +![9-Roster-Fetched ](Images/9-Roster-Fetched.png) + +3) You can try with other supported commands as well like: **Adaptive Card**, **Web View**, **HTML**, **Razor View** + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Messaging extension action](https://learn.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/action-commands/define-action-command) +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Resources/adaptiveCard.json b/samples/TeamsSDK/Archived/msgext-action/csharp/Resources/adaptiveCard.json new file mode 100644 index 0000000000..8718e8bf66 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Resources/adaptiveCard.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.0", + "type": "AdaptiveCard", + "body": [ + { + "type": "TextBlock", + "text": "This app is installed in this conversation. You can now use it to do some great stuff!!", + "isSubtle": false, + "wrap": true + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "Close" + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Resources/justintimeinstallation.json b/samples/TeamsSDK/Archived/msgext-action/csharp/Resources/justintimeinstallation.json new file mode 100644 index 0000000000..5557814174 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Resources/justintimeinstallation.json @@ -0,0 +1,22 @@ +{ + "type": "AdaptiveCard", + "body": [ + { + "type": "TextBlock", + "text": "Looks like you haven't used Action Messaging Extension app in this team/chat. Please click **Continue** to add this app.", + "wrap": true + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "Continue", + "data": { + "msteams": { + "justInTimeInstall": true + } + } + } + ], + "version": "1.0" +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/TeamsMessagingExtensionsAction.csproj b/samples/TeamsSDK/Archived/msgext-action/csharp/TeamsMessagingExtensionsAction.csproj new file mode 100644 index 0000000000..a89bea4c30 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/TeamsMessagingExtensionsAction.csproj @@ -0,0 +1,174 @@ + + + + net10.0 + latest + enable + + + + + + + + + + + + + + + + + + Always + + + PreserveNewest + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/TeamsMessagingExtensionsAction.sln b/samples/TeamsSDK/Archived/msgext-action/csharp/TeamsMessagingExtensionsAction.sln new file mode 100644 index 0000000000..31cefc5737 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/TeamsMessagingExtensionsAction.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32901.215 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TeamsMessagingExtensionsAction", "TeamsMessagingExtensionsAction.csproj", "{C184FC67-19AD-43DA-9553-6A2B10E820BE}" +EndProject +Project("{A9E3F50B-275E-4AF7-ADCE-8BE12D41E305}") = "M365Agent", "M365Agent\M365Agent.ttkproj", "{95754B61-0437-49E0-A664-9564F36E58FB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CAEA9E49-DFC1-4705-8CE2-DE8A4E7ECFA3}" + ProjectSection(SolutionItems) = preProject + TeamsMessagingExtensionsAction.slnLaunch.user = TeamsMessagingExtensionsAction.slnLaunch.user + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C184FC67-19AD-43DA-9553-6A2B10E820BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C184FC67-19AD-43DA-9553-6A2B10E820BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C184FC67-19AD-43DA-9553-6A2B10E820BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C184FC67-19AD-43DA-9553-6A2B10E820BE}.Release|Any CPU.Build.0 = Release|Any CPU + {95754B61-0437-49E0-A664-9564F36E58FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95754B61-0437-49E0-A664-9564F36E58FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95754B61-0437-49E0-A664-9564F36E58FB}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {95754B61-0437-49E0-A664-9564F36E58FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95754B61-0437-49E0-A664-9564F36E58FB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3A3F5CEA-0632-46A1-BBEC-F604F8BB524F} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/CustomForm.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/CustomForm.cshtml new file mode 100644 index 0000000000..c04f79fc56 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/CustomForm.cshtml @@ -0,0 +1,48 @@ +@{ + ViewData["Title"] = "CustomForm"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + + + + + +
+
+ +
+
diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/RazorView.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/RazorView.cshtml new file mode 100644 index 0000000000..5c7a521abe --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/RazorView.cshtml @@ -0,0 +1,23 @@ +@{ ViewData["Title"] = "RazorView"; + Layout = "~/Views/Shared/_Layout.cshtml"; } + +@{ var Title = "Welcome to RazorView!"; + var weekDay = DateTime.Now.DayOfWeek; + var weekDate = DateTime.Now.Day + "-" + DateTime.Now.Month + "-" + DateTime.Now.Year; + var DisplayMessage = " Today's date is " + weekDate + ", " + weekDay; } + +

@Title

+

@DisplayMessage

+ + + diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/htmlpage.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/htmlpage.cshtml new file mode 100644 index 0000000000..cdfa676ef1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Home/htmlpage.cshtml @@ -0,0 +1,49 @@ +@page +@model TeamsMessagingExtensionsAction.Pages.IndexModel +@{ + Layout = "~/Pages/Shared/_Layout.cshtml"; +} + + + + + Login Form + + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Shared/_Layout.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..d111d4d37f --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Shared/_Layout.cshtml @@ -0,0 +1,23 @@ + + + + Microsoft Teams Hello World Sample App + + + + + + + @RenderSection("scripts", required: false) + + +
+
+ @RenderBody() +
+
+ + diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Shared/_ValidationScriptsPartial.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000000..ed86611b33 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/Views/_ViewStart.cshtml b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/appsettings.json b/samples/TeamsSDK/Archived/msgext-action/csharp/appsettings.json new file mode 100644 index 0000000000..ee2892f173 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/appsettings.json @@ -0,0 +1,7 @@ +{ + "MicrosoftAppType": "SingleTenant", + "MicrosoftAppId": "", + "MicrosoftAppPassword": "", + "MicrosoftAppTenantId": "", + "BaseUrl": "" +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/assets/sample.json b/samples/TeamsSDK/Archived/msgext-action/csharp/assets/sample.json new file mode 100644 index 0000000000..fdd751a060 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-msgext-action-csharp", + "source": "officeDev", + "title": "Action Based Messaging Extensions", + "shortDescription": "This sample app illustrates how to implement Action-Based Messaging Extensions in Teams.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/msgext-action/csharp", + "longDescription": [ + "This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality." + ], + "creationDateTime": "2019-10-17", + "updateDateTime": "2024-10-11", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "csharp" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "netframework" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot,ME" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/msgext-action/csharp/Images/msgext-action.gif", + "alt": "Solution UX showing action based Messaging Extensions" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/demo-manifest/msgext-action.zip b/samples/TeamsSDK/Archived/msgext-action/csharp/demo-manifest/msgext-action.zip new file mode 100644 index 0000000000..3083912a24 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/demo-manifest/msgext-action.zip differ diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/Site.css b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/Site.css new file mode 100644 index 0000000000..6c4c11c6b4 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/Site.css @@ -0,0 +1,8 @@ +html, body, div.surface, div.panel { + height: 100%; + margin: 0; +} + +div.panel { + padding: 15px; +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/custom.css b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/custom.css new file mode 100644 index 0000000000..84f20a8104 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/custom.css @@ -0,0 +1,8 @@ +html, body, div.surface, div.panel { + height: 100%; + margin: 0; +} + +div.panel { + padding: 15px; +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/msteams-16.css b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/msteams-16.css new file mode 100644 index 0000000000..54f033cae0 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/css/msteams-16.css @@ -0,0 +1,1272 @@ +.theme-light .surface { + background-color: #F0F2F4; + color: #16233A; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.25rem +} + +.theme-light .panel { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background-color: #FFFFFF; + border-color: transparent; + border-radius: 0.1875rem; + border-style: solid; + border-width: 0.125rem; + box-sizing: border-box; + display: flex; + flex-direction: column; + overflow: hidden +} + +.theme-light .panel-header { + flex: 0 0 auto; + margin-left: 2rem; + margin-right: 2rem; + margin-top: 2rem +} + +.theme-light .panel-body { + flex: 1 1 auto; + margin-left: 2rem; + margin-right: 2rem; + overflow: auto +} + +.theme-light .panel-footer { + flex: 0 0 auto; + margin-bottom: 2rem; + margin-left: 2rem; + margin-right: 2rem +} + +.theme-light .button-primary { + background: #5558AF; + border: 0.125rem solid; + border-color: transparent; + border-radius: 0.1875rem; + color: #FFFFFF; + cursor: pointer; + font: inherit; + height: 2rem; + min-width: 6rem; + padding: 0.25rem; + white-space: nowrap +} + + .theme-light .button-primary:hover:enabled { + background: #4C509D; + border-color: transparent; + color: #FFFFFF + } + + .theme-light .button-primary:active { + background: #454A92; + border-color: transparent; + color: #FFFFFF + } + + .theme-light .button-primary:disabled { + background: #F3F4F5; + border-color: transparent; + color: #ABB0B8 + } + + .theme-light .button-primary:focus { + background: #4C509D; + border-color: transparent; + color: #FFFFFF; + outline: 0.125rem solid #FFFFFF; + outline-offset: -0.25rem + } + +.theme-light .button-secondary { + background: #FFFFFF; + border: 0.125rem solid; + border-color: #ABB0B8; + border-radius: 0.1875rem; + color: #525C6D; + cursor: pointer; + font: inherit; + height: 2rem; + min-width: 6rem; + padding: 0.25rem; + white-space: nowrap +} + + .theme-light .button-secondary:hover:enabled { + background: #ABB0B8; + border-color: transparent; + color: #16233A + } + + .theme-light .button-secondary:active { + background: #858C98; + border-color: transparent; + color: #16233A + } + + .theme-light .button-secondary:disabled { + background: #FFFFFF; + border-color: #F3F4F5; + color: #ABB0B8 + } + + .theme-light .button-secondary:focus { + background: #ABB0B8; + border-color: transparent; + color: #16233A; + outline: 0.125rem solid #16233A; + outline-offset: -0.25rem + } + +.theme-light .radio-container { + align-items: center; + background: transparent; + border: none; + display: flex; + outline: none +} + + .theme-light .radio-container + .radio-container { + margin-top: 0.5rem + } + +.theme-light .radio-button { + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + background: transparent; + border: 0.0625rem solid; + border-color: #525C6D; + border-radius: 100%; + cursor: pointer; + display: inline-block; + font: inherit; + height: 0.75rem; + margin: 0.125rem; + margin-left: 0.375rem; + padding: 0; + position: relative; + width: 0.75rem +} + + .theme-light .radio-button:hover { + background: transparent; + border-color: #525C6D + } + + .theme-light .radio-button:disabled { + background: #F0F2F4; + border-color: #ABB0B8 + } + + .theme-light .radio-button:disabled + label { + color: #ABB0B8; + cursor: default + } + + .theme-light .radio-button:focus { + box-shadow: 0 0 0 0.125rem #9FA4FE; + outline: none + } + +.theme-light .hidden-input:checked + .radio-button { + background: #5558AF; + border-color: #5558AF +} + + .theme-light .hidden-input:checked + .radio-button + label { + color: #16233A + } + +.theme-light .radio-label { + color: #525C6D; + cursor: pointer; + font-size: 0.75rem; + line-height: 1rem; + margin-left: 0.625rem +} + +.theme-light .radio-group { + display: inline-block +} + +.theme-light .tab-group { + border-bottom: 0.0625rem solid #F3F4F5; + margin: 0; + padding: 0; + width: 100% +} + + .theme-light .tab-group .tab { + background: 0; + border: 0; + border-bottom: transparent 0.25rem solid; + color: #525C6D; + cursor: pointer; + display: inline-block; + font: inherit; + margin: 0; + margin-right: 1.25rem; + outline: none; + padding: 0.25rem + } + + .theme-light .tab-group .tab:hover { + border-bottom-color: #9496CA + } + + .theme-light .tab-group .tab:focus { + background-color: #9FA4FE; + color: #FFFFFF + } + + .theme-light .tab-group .tab-active { + border-bottom-color: #5558AF; + color: #5558AF + } + +.theme-light .tab-active:focus { + border-bottom-color: #FFFFFF +} + +.theme-light .hidden-input { + display: none +} + +.theme-light .toggle { + display: inline-block; + line-height: 1 +} + +.theme-light .toggle-ball { + background-color: #F0F2F4; + border: 0; + border-radius: 1.25rem; + cursor: pointer; + height: 1.25rem; + margin: 0.125rem; + outline: none; + padding: 0; + position: relative; + width: 3.75rem +} + + .theme-light .toggle-ball:before { + background-color: #454A92; + border-radius: 50%; + content: ""; + height: 0.875rem; + left: 0.1875rem; + position: absolute; + top: 0.18750000000000003rem; + transition: 0.2s; + width: 0.875rem + } + +.theme-light .hidden-input:checked + .toggle-ball:before { + background-color: #4C509D; + transform: translateX(2.5rem) +} + +.theme-light .toggle-ball:focus { + box-shadow: 0 0 0 0.125rem #5558AF; + outline: none +} + +.theme-light .hidden-input:checked + .toggle-ball { + background-color: #7FBA00 +} + +.theme-light .font-title { + font-size: 1.5rem; + line-height: 2rem +} + +.theme-light .font-title2 { + font-size: 1.125rem; + line-height: 1.5rem +} + +.theme-light .font-base { + font-size: 0.875rem; + line-height: 1.25rem +} + +.theme-light .font-caption { + font-size: 0.75rem; + line-height: 1rem +} + +.theme-light .font-xsmall { + font-size: 0.625rem; + line-height: 0.6875rem +} + +.theme-light .font-semilight { + font-family: 'Segoe UI Light', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 300 +} + +.theme-light .font-regular { + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 400 +} + +.theme-light .font-semibold { + font-family: 'Segoe UI Semibold', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 600 +} + +.theme-light .font-bold { + font-family: 'Segoe UI Bold', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 700 +} + +.theme-light .input-container { + overflow: hidden; + position: relative +} + +.theme-light .input-field { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background: #F0F2F4; + border: 0.125rem solid transparent; + border-radius: 0.1875rem; + box-sizing: border-box; + color: #525C6D; + font: inherit; + height: 2rem; + margin: 0; + outline: none; + padding: 0.5rem 0.75rem; + width: 100% +} + +.theme-light .input-error-icon { + bottom: 0.5625rem; + color: #C50E2E; + position: absolute; + right: 0.75rem +} + +.theme-light .label { + border: 0; + color: #4E586A; + display: inline-block; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.75rem; + font-weight: 400; + line-height: 1rem; + margin-bottom: 0.5rem; + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding: 0 +} + +.theme-light .error-label { + border: 0; + color: #C50E2E; + float: right; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.75rem; + font-weight: 400; + line-height: 1rem; + margin-bottom: 0.5rem; + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding: 0 +} + +.theme-light .textarea-container { + display: flex; + flex-direction: column; + overflow: hidden; + position: relative +} + +.theme-light .textarea-field { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background: #F0F2F4; + border: 0.125rem solid transparent; + border-radius: 0.1875rem; + box-sizing: border-box; + color: #525C6D; + flex: 1; + font: inherit; + margin: 0; + min-height: 3.75rem; + outline: none; + padding: 0.5rem 0.75rem; + resize: none +} + + .theme-light .input-field:hover:inactive:enabled, .theme-light .textarea-field:hover:inactive:enabled { + background: #F0F2F4; + border-bottom-color: transparent + } + + .theme-light .input-field:disabled, .theme-light .textarea-field:disabled { + background: #F3F4F5; + border-bottom-color: transparent; + color: #DEE0E3 + } + + .theme-light .input-field:active:enabled, .theme-light .input-field:focus, .theme-light .textarea-field:active:enabled, .theme-light .textarea-field:focus { + background: #F0F2F4; + border-bottom-color: #5558AF + } + +.theme-light .textarea-error-icon { + color: #C50E2E; + position: absolute; + right: 0.75rem; + top: 50% +} + +.theme-dark .surface { + background-color: #2B2B30; + color: #FFFFFF; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.25rem +} + +.theme-dark .panel { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background-color: #404045; + border-color: transparent; + border-radius: 0.1875rem; + border-style: solid; + border-width: 0.125rem; + box-sizing: border-box; + display: flex; + flex-direction: column; + overflow: hidden +} + +.theme-dark .panel-header { + flex: 0 0 auto; + margin-left: 2rem; + margin-right: 2rem; + margin-top: 2rem +} + +.theme-dark .panel-body { + flex: 1 1 auto; + margin-left: 2rem; + margin-right: 2rem; + overflow: auto +} + +.theme-dark .panel-footer { + flex: 0 0 auto; + margin-bottom: 2rem; + margin-left: 2rem; + margin-right: 2rem +} + +.theme-dark .button-primary { + background: #9FA4FE; + border: 0.125rem solid; + border-color: transparent; + border-radius: 0.1875rem; + color: #2B2B30; + cursor: pointer; + font: inherit; + height: 2rem; + min-width: 6rem; + padding: 0.25rem; + white-space: nowrap +} + + .theme-dark .button-primary:hover:enabled { + background: #AEB2FF; + border-color: transparent; + color: #2B2B30 + } + + .theme-dark .button-primary:active { + background: #B8BBFF; + border-color: transparent; + color: #2B2B30 + } + + .theme-dark .button-primary:disabled { + background: #35353A; + border-color: transparent; + color: #77777A + } + + .theme-dark .button-primary:focus { + background: #9FA4FE; + border-color: transparent; + color: #2B2B30; + outline: 0.125rem solid #2B2B30; + outline-offset: -0.25rem + } + +.theme-dark .button-secondary { + background: #404045; + border: 0.125rem solid; + border-color: #77777A; + border-radius: 0.1875rem; + color: #C8C8C9; + cursor: pointer; + font: inherit; + height: 2rem; + min-width: 6rem; + padding: 0.25rem; + white-space: nowrap +} + + .theme-dark .button-secondary:hover:enabled { + background: #77777A; + border-color: transparent; + color: #FFFFFF + } + + .theme-dark .button-secondary:active { + background: #48484D; + border-color: transparent; + color: #FFFFFF + } + + .theme-dark .button-secondary:disabled { + background: #404045; + border-color: #35353A; + color: #77777A + } + + .theme-dark .button-secondary:focus { + background: #77777A; + border-color: transparent; + color: #FFFFFF; + outline: 0.125rem solid #FFFFFF; + outline-offset: -0.25rem + } + +.theme-dark .radio-container { + align-items: center; + background: transparent; + border: none; + display: flex; + outline: none +} + + .theme-dark .radio-container + .radio-container { + margin-top: 0.5rem + } + +.theme-dark .radio-button { + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + background: transparent; + border: 0.0625rem solid; + border-color: #C8C8C9; + border-radius: 100%; + cursor: pointer; + display: inline-block; + font: inherit; + height: 0.75rem; + margin: 0.125rem; + margin-left: 0.375rem; + padding: 0; + position: relative; + width: 0.75rem +} + + .theme-dark .radio-button:hover { + background: transparent; + border-color: #C8C8C9 + } + + .theme-dark .radio-button:disabled { + background: #404045; + border-color: #77777A + } + + .theme-dark .radio-button:disabled + label { + color: #77777A; + cursor: default + } + + .theme-dark .radio-button:focus { + box-shadow: 0 0 0 0.125rem #5558AF; + outline: none + } + +.theme-dark .hidden-input:checked + .radio-button { + background: #9FA4FE; + border-color: #9FA4FE +} + + .theme-dark .hidden-input:checked + .radio-button + label { + color: #FFFFFF + } + +.theme-dark .radio-label { + color: #C8C8C9; + cursor: pointer; + font-size: 0.75rem; + line-height: 1rem; + margin-left: 0.625rem +} + +.theme-dark .radio-group { + display: inline-block +} + +.theme-dark .tab-group { + border-bottom: 0.0625rem solid #000000; + margin: 0; + padding: 0; + width: 100% +} + + .theme-dark .tab-group .tab { + background: 0; + border: 0; + border-bottom: transparent 0.25rem solid; + color: #C8C8C9; + cursor: pointer; + display: inline-block; + font: inherit; + margin: 0; + margin-right: 1.25rem; + outline: none; + padding: 0.25rem + } + + .theme-dark .tab-group .tab:hover { + border-bottom-color: #7174AA + } + + .theme-dark .tab-group .tab:focus { + background-color: #5558AF; + color: #FFFFFF + } + + .theme-dark .tab-group .tab-active { + border-bottom-color: #9FA4FE; + color: #9FA4FE + } + +.theme-dark .tab-active:focus { + border-bottom-color: #FFFFFF +} + +.theme-dark .hidden-input { + display: none +} + +.theme-dark .toggle { + display: inline-block; + line-height: 1 +} + +.theme-dark .toggle-ball { + background-color: #2B2B30; + border: 0; + border-radius: 1.25rem; + cursor: pointer; + height: 1.25rem; + margin: 0.125rem; + outline: none; + padding: 0; + position: relative; + width: 3.75rem +} + + .theme-dark .toggle-ball:before { + background-color: #C8C8C9; + border-radius: 50%; + content: ""; + height: 0.875rem; + left: 0.1875rem; + position: absolute; + top: 0.18750000000000003rem; + transition: 0.2s; + width: 0.875rem + } + +.theme-dark .hidden-input:checked + .toggle-ball:before { + background-color: #FFFFFF; + transform: translateX(2.5rem) +} + +.theme-dark .toggle-ball:focus { + box-shadow: 0 0 0 0.125rem #9FA4FE; + outline: none +} + +.theme-dark .hidden-input:checked + .toggle-ball { + background-color: #88BC2B +} + +.theme-dark .font-title { + font-size: 1.5rem; + line-height: 2rem +} + +.theme-dark .font-title2 { + font-size: 1.125rem; + line-height: 1.5rem +} + +.theme-dark .font-base { + font-size: 0.875rem; + line-height: 1.25rem +} + +.theme-dark .font-caption { + font-size: 0.75rem; + line-height: 1rem +} + +.theme-dark .font-xsmall { + font-size: 0.625rem; + line-height: 0.6875rem +} + +.theme-dark .font-semilight { + font-family: 'Segoe UI Light', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 300 +} + +.theme-dark .font-regular { + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 400 +} + +.theme-dark .font-semibold { + font-family: 'Segoe UI Semibold', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 600 +} + +.theme-dark .font-bold { + font-family: 'Segoe UI Bold', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 700 +} + +.theme-dark .input-container { + overflow: hidden; + position: relative +} + +.theme-dark .input-field { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background: #2B2B30; + border: 0.125rem solid transparent; + border-radius: 0.1875rem; + box-sizing: border-box; + color: #C8C8C9; + font: inherit; + height: 2rem; + margin: 0; + outline: none; + padding: 0.5rem 0.75rem; + width: 100% +} + +.theme-dark .input-error-icon { + bottom: 0.5625rem; + color: #ED1B3E; + position: absolute; + right: 0.75rem +} + +.theme-dark .label { + border: 0; + color: #FFFFFF; + display: inline-block; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.75rem; + font-weight: 400; + line-height: 1rem; + margin-bottom: 0.5rem; + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding: 0 +} + +.theme-dark .error-label { + border: 0; + color: #ED1B3E; + float: right; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.75rem; + font-weight: 400; + line-height: 1rem; + margin-bottom: 0.5rem; + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding: 0 +} + +.theme-dark .textarea-container { + display: flex; + flex-direction: column; + overflow: hidden; + position: relative +} + +.theme-dark .textarea-field { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background: #2B2B30; + border: 0.125rem solid transparent; + border-radius: 0.1875rem; + box-sizing: border-box; + color: #C8C8C9; + flex: 1; + font: inherit; + margin: 0; + min-height: 3.75rem; + outline: none; + padding: 0.5rem 0.75rem; + resize: none +} + + .theme-dark .input-field:hover:inactive:enabled, .theme-dark .textarea-field:hover:inactive:enabled { + background: #2B2B30; + border-bottom-color: transparent + } + + .theme-dark .input-field:disabled, .theme-dark .textarea-field:disabled { + background: #35353A; + border-bottom-color: transparent; + color: #48484D + } + + .theme-dark .input-field:active:enabled, .theme-dark .input-field:focus, .theme-dark .textarea-field:active:enabled, .theme-dark .textarea-field:focus { + background: #2B2B30; + border-bottom-color: #9FA4FE + } + +.theme-dark .textarea-error-icon { + color: #ED1B3E; + position: absolute; + right: 0.75rem; + top: 50% +} + +.theme-contrast .surface { + background-color: #000000; + color: #FFFFFF; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.25rem +} + +.theme-contrast .panel { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background-color: #000000; + border-color: #FFFFFF; + border-radius: 0.1875rem; + border-style: solid; + border-width: 0.125rem; + box-sizing: border-box; + display: flex; + flex-direction: column; + overflow: hidden +} + +.theme-contrast .panel-header { + flex: 0 0 auto; + margin-left: 2rem; + margin-right: 2rem; + margin-top: 2rem +} + +.theme-contrast .panel-body { + flex: 1 1 auto; + margin-left: 2rem; + margin-right: 2rem; + overflow: auto +} + +.theme-contrast .panel-footer { + flex: 0 0 auto; + margin-bottom: 2rem; + margin-left: 2rem; + margin-right: 2rem +} + +.theme-contrast .button-primary { + background: #FFFFFF; + border: 0.125rem solid; + border-color: transparent; + border-radius: 0.1875rem; + color: #000000; + cursor: pointer; + font: inherit; + height: 2rem; + min-width: 6rem; + padding: 0.25rem; + white-space: nowrap +} + + .theme-contrast .button-primary:disabled { + background: #30F42C; + border-color: transparent; + color: #000000 + } + +.theme-contrast .button-secondary { + background: #000000; + border: 0.125rem solid; + border-color: #FFFFFF; + border-radius: 0.1875rem; + color: #FFFFFF; + cursor: pointer; + font: inherit; + height: 2rem; + min-width: 6rem; + padding: 0.25rem; + white-space: nowrap +} + + .theme-contrast .button-primary:hover:enabled, .theme-contrast .button-primary:active, .theme-contrast .button-secondary:hover:enabled, .theme-contrast .button-secondary:active { + background: #FFFF00; + border-color: transparent; + color: #000000 + } + + .theme-contrast .button-secondary:disabled { + background: #000000; + border-color: #30F42C; + color: #30F42C + } + + .theme-contrast .button-primary:focus, .theme-contrast .button-secondary:focus { + background: #FFFF00; + border-color: transparent; + color: #000000; + outline: 0.125rem solid transparent; + outline-offset: -0.25rem + } + +.theme-contrast .radio-container { + align-items: center; + background: transparent; + border: none; + display: flex; + outline: none +} + + .theme-contrast .radio-container + .radio-container { + margin-top: 0.5rem + } + +.theme-contrast .radio-button { + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + background: transparent; + border: 0.0625rem solid; + border-color: #FFFFFF; + border-radius: 100%; + cursor: pointer; + display: inline-block; + font: inherit; + height: 0.75rem; + margin: 0.125rem; + margin-left: 0.375rem; + padding: 0; + position: relative; + width: 0.75rem +} + + .theme-contrast .radio-button:hover { + background: transparent; + border-color: #FFFFFF + } + + .theme-contrast .radio-button:disabled { + background: transparent; + border-color: #30F42C + } + + .theme-contrast .radio-button:disabled + label { + color: #30F42C; + cursor: default + } + + .theme-contrast .radio-button:focus { + box-shadow: 0 0 0 0.125rem #FFFF00; + outline: none + } + +.theme-contrast .hidden-input:checked + .radio-button { + background: #00EBFF; + border-color: #00EBFF +} + + .theme-contrast .hidden-input:checked + .radio-button + label { + color: #FFFFFF + } + +.theme-contrast .radio-label { + color: #FFFFFF; + cursor: pointer; + font-size: 0.75rem; + line-height: 1rem; + margin-left: 0.625rem +} + +.theme-contrast .radio-group { + display: inline-block +} + +.theme-contrast .tab-group { + border-bottom: 0.0625rem solid #30F42C; + margin: 0; + padding: 0; + width: 100% +} + + .theme-contrast .tab-group .tab { + background: 0; + border: 0; + border-bottom: transparent 0.25rem solid; + color: #FFFFFF; + cursor: pointer; + display: inline-block; + font: inherit; + margin: 0; + margin-right: 1.25rem; + outline: none; + padding: 0.25rem + } + + .theme-contrast .tab-group .tab:hover { + border-bottom-color: #FFFF00 + } + + .theme-contrast .tab-group .tab:focus { + background-color: #FFFF00; + color: #000000 + } + + .theme-contrast .tab-group .tab-active { + border-bottom-color: #00EBFF; + color: #FFFFFF + } + +.theme-contrast .tab-active:focus { + border-bottom-color: #000000 +} + +.theme-contrast .hidden-input { + display: none +} + +.theme-contrast .toggle { + display: inline-block; + line-height: 1 +} + +.theme-contrast .toggle-ball { + background-color: #FFFFFF; + border: 0; + border-radius: 1.25rem; + cursor: pointer; + height: 1.25rem; + margin: 0.125rem; + outline: none; + padding: 0; + position: relative; + width: 3.75rem +} + + .theme-contrast .toggle-ball:before { + background-color: #FFFF00; + border-radius: 50%; + content: ""; + height: 0.875rem; + left: 0.1875rem; + position: absolute; + top: 0.18750000000000003rem; + transition: 0.2s; + width: 0.875rem + } + +.theme-contrast .hidden-input:checked + .toggle-ball:before { + background-color: #4C509D; + transform: translateX(2.5rem) +} + +.theme-contrast .toggle-ball:focus { + box-shadow: 0 0 0 0.125rem #30F42C; + outline: none +} + +.theme-contrast .hidden-input:checked + .toggle-ball { + background-color: #7FBA00 +} + +.theme-contrast .font-title { + font-size: 1.5rem; + line-height: 2rem +} + +.theme-contrast .font-title2 { + font-size: 1.125rem; + line-height: 1.5rem +} + +.theme-contrast .font-base { + font-size: 0.875rem; + line-height: 1.25rem +} + +.theme-contrast .font-caption { + font-size: 0.75rem; + line-height: 1rem +} + +.theme-contrast .font-xsmall { + font-size: 0.625rem; + line-height: 0.6875rem +} + +.theme-contrast .font-semilight { + font-family: 'Segoe UI Light', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 300 +} + +.theme-contrast .font-regular { + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 400 +} + +.theme-contrast .font-semibold { + font-family: 'Segoe UI Semibold', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 600 +} + +.theme-contrast .font-bold { + font-family: 'Segoe UI Bold', 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-weight: 700 +} + +.theme-contrast .input-container { + overflow: hidden; + position: relative +} + +.theme-contrast .input-field { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background: #000000; + border: 0.125rem solid #FFFFFF; + border-radius: 0.1875rem; + box-sizing: border-box; + color: #FFFFFF; + font: inherit; + height: 2rem; + margin: 0; + outline: none; + padding: 0.5rem 0.75rem; + width: 100% +} + +.theme-contrast .input-error-icon { + bottom: 0.5625rem; + color: #FFFF00; + position: absolute; + right: 0.75rem +} + +.theme-contrast .label { + border: 0; + color: #FFFFFF; + display: inline-block; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.75rem; + font-weight: 400; + line-height: 1rem; + margin-bottom: 0.5rem; + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding: 0 +} + +.theme-contrast .error-label { + border: 0; + color: #FFFF00; + float: right; + font-family: 'Segoe UI', Tahoma, Helvetica, Sans-Serif; + font-size: 0.75rem; + font-weight: 400; + line-height: 1rem; + margin-bottom: 0.5rem; + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding: 0 +} + +.theme-contrast .textarea-container { + display: flex; + flex-direction: column; + overflow: hidden; + position: relative +} + +.theme-contrast .textarea-field { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background: #000000; + border: 0.125rem solid #FFFFFF; + border-radius: 0.1875rem; + box-sizing: border-box; + color: #FFFFFF; + flex: 1; + font: inherit; + margin: 0; + min-height: 3.75rem; + outline: none; + padding: 0.5rem 0.75rem; + resize: none +} + + .theme-contrast .input-field:hover:inactive:enabled, .theme-contrast .textarea-field:hover:inactive:enabled { + background: #000000; + border-bottom-color: transparent + } + + .theme-contrast .input-field:disabled, .theme-contrast .textarea-field:disabled { + background: #30F42C; + border-bottom-color: #FFFFFF; + color: #FFFFFF + } + + .theme-contrast .input-field:active:enabled, .theme-contrast .input-field:focus, .theme-contrast .textarea-field:active:enabled, .theme-contrast .textarea-field:focus { + background: #000000; + border-bottom-color: #FFFF00 + } + +.theme-contrast .textarea-error-icon { + color: #FFFF00; + position: absolute; + right: 0.75rem; + top: 50% +} diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/default.html b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/default.html new file mode 100644 index 0000000000..7577fe9a84 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/default.html @@ -0,0 +1,292 @@ + + + + + + + Teams Action Based Messaging Extension + + + + + +
+
+
+
Action Based Messaging Extension
+
+
+
+
+
Your bot is ready!
+
+ You can now test your bot in Teams.
+
+ Visit + Azure + Bot Service + to register your bot and add it to the
+ Teams channel. The bot's endpoint URL typically looks + like this: +
+
https://your_bots_hostname/api/messages
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/profile-image.png b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/profile-image.png new file mode 100644 index 0000000000..48a2de1330 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/csharp/wwwroot/profile-image.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/ActionPreviewOptions.png b/samples/TeamsSDK/Archived/msgext-action/java/Images/ActionPreviewOptions.png new file mode 100644 index 0000000000..186f853978 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/ActionPreviewOptions.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/ActionPreviewWelcome.png b/samples/TeamsSDK/Archived/msgext-action/java/Images/ActionPreviewWelcome.png new file mode 100644 index 0000000000..7eb40a6d9e Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/ActionPreviewWelcome.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/AdaptiveCardPreview.png b/samples/TeamsSDK/Archived/msgext-action/java/Images/AdaptiveCardPreview.png new file mode 100644 index 0000000000..3f997229a0 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/AdaptiveCardPreview.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/AppInstallation.png b/samples/TeamsSDK/Archived/msgext-action/java/Images/AppInstallation.png new file mode 100644 index 0000000000..18dfb04054 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/AppInstallation.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/CardInComposeBox.png b/samples/TeamsSDK/Archived/msgext-action/java/Images/CardInComposeBox.png new file mode 100644 index 0000000000..0d02f205dc Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/CardInComposeBox.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/CardPreview.png b/samples/TeamsSDK/Archived/msgext-action/java/Images/CardPreview.png new file mode 100644 index 0000000000..d71b7a1ea2 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/CardPreview.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/CreateAdaptiveCard.png b/samples/TeamsSDK/Archived/msgext-action/java/Images/CreateAdaptiveCard.png new file mode 100644 index 0000000000..fc9019747f Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/CreateAdaptiveCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/CreateCard.png b/samples/TeamsSDK/Archived/msgext-action/java/Images/CreateCard.png new file mode 100644 index 0000000000..010ac70bf9 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/CreateCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/FetchRoster.PNG b/samples/TeamsSDK/Archived/msgext-action/java/Images/FetchRoster.PNG new file mode 100644 index 0000000000..68e03524c4 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/FetchRoster.PNG differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/MsgExtAction.gif b/samples/TeamsSDK/Archived/msgext-action/java/Images/MsgExtAction.gif new file mode 100644 index 0000000000..8bf471e6f8 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/MsgExtAction.gif differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/StaticPage.PNG b/samples/TeamsSDK/Archived/msgext-action/java/Images/StaticPage.PNG new file mode 100644 index 0000000000..87fc06d424 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/StaticPage.PNG differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Images/WebView.PNG b/samples/TeamsSDK/Archived/msgext-action/java/Images/WebView.PNG new file mode 100644 index 0000000000..d723c888b6 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/Images/WebView.PNG differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/LICENSE b/samples/TeamsSDK/Archived/msgext-action/java/LICENSE new file mode 100644 index 0000000000..21071075c2 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/samples/TeamsSDK/Archived/msgext-action/java/README.md b/samples/TeamsSDK/Archived/msgext-action/java/README.md new file mode 100644 index 0000000000..22ab129b74 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/README.md @@ -0,0 +1,130 @@ +--- +page_type: sample +description: This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality. +products: +- office-teams +- office +- office-365 +languages: +- Java +extensions: + contentType: samples + createdDate: "12/12/2019 13:38:25 PM" +urlFragment: officedev-microsoft-teams-samples-bot-msgext-action-java +--- + +# Teams Message Extension Action Bot + +Explore the capabilities of Action-Based Messaging Extensions in Microsoft Teams with this sample app. It showcases how to implement interactive features, including bots and message extensions, allowing users to create content dynamically through a user-friendly interface. + +There are two basic types of Messaging Extension in Teams: [Search-based](https://docs.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/search-commands/define-search-command) and [Action-based](https://docs.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/action-commands/define-action-command). This sample illustrates how to +build an Action-based Messaging Extension. + +This sample is a Spring Boot app and uses the Azure CLI and azure-webapp Maven plugin to deploy to Azure. + +## Included Features +* Bots +* Message Extensions +* Action Commands + +- **Interaction with Messaging Extension action** +![MsgExtAction](Images/MsgExtAction.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Teams Messaging Extensions Action:** [Manifest](/samples/msgext-action/csharp/demo-manifest/msgext-action.zip) + +## Prerequisites + +- Intall Java 1.8+ [Java](https://www.oracle.com/java/technologies/downloads/#java8-windows) +- Install [Maven](https://maven.apache.org/) +- Setup for Java and Maven [Setup](Setup.md) +- An account on [Azure](https://azure.microsoft.com) if you want to deploy to Azure. +- Microsoft Teams is installed and you have an account +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution + +## Setup + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +the Teams service needs to call into the bot. + +1) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +1) Setup for Bot + + In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration). + - For bot handle, make up a name. + - Select "Use existing app registration" (Create the app registration in Microsoft Entra ID beforehand.) + - Choose "Accounts in any organizational directory (Any Azure AD directory - Multitenant)" in Authentication section in your App Registration to run this sample smoothly. + - __*If you don't have an Azure account*__ create an [Azure free account here](https://azure.microsoft.com/free/) + + In the new Azure Bot resource in the Portal, + - Ensure that you've [enabled the Teams Channel](https://learn.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - In Settings/Configuration/Messaging endpoint, enter the current `https` URL you were given by running the tunnelling application. Append with the path `/api/messages` + +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +1) Update the `resources/application.properties` file configuration in your project, for the bot to use the Microsoft App Id and App Password from the Bot Framework registration. (Note the App Password is referred to as the "client secret" in the azure portal and you can always create a new client secret anytime.) + +1) From the root of this project folder: (`samples/msgext-action/java`) + - Open a terminal and build the sample using `mvn package` command + - Install the packages in the local cache by using `mvn install` command in a terminal + - Run it by using `java -jar .\target\bot-teams-messaging-extensions-action-sample.jar` command in a terminal + +1) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appManifest` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `<>` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` with base Url domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + - **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.) + +## Running the sample + +> Note this `manifest.json` specified that the bot will be called from both the `compose` and `message` areas of Teams. Please refer to Teams documentation for more details. + +1. Selecting the **Create Card** command from the Compose Box command list. The parameters dialog will be displayed and can be submitted to initiate the card creation within the Messaging Extension code. + +![ActionPreviewOptions](Images/ActionPreviewOptions.png) + +![CreateCard](Images/CreateCard.png) + +![AdaptiveCardPreview](Images/AdaptiveCardPreview.png) + +2. Selecting the **Web View** command from the Message command list. +![WebView](Images/WebView.PNG) + +3. Selecting the **FetchRoster** command from the Message command list. *Even though this action is being shown on the contextual menu, it's not implemented and is expected to fail.* +![FetchRoster](Images/FetchRoster.PNG) + +**Note:** Likewise you can try with all other configured commands in your app manifest. + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Messaging extension action](https://learn.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/action-commands/define-action-command) +- [Spring Boot](https://spring.io/projects/spring-boot) +- [Maven Plugin for Azure App Service](https://github.com/microsoft/azure-maven-plugins/tree/develop/azure-webapp-maven-plugin) +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) +- [Azure for Java cloud developers](https://docs.microsoft.com/en-us/azure/java/?view=azure-java-stable) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/java/Setup.md b/samples/TeamsSDK/Archived/msgext-action/java/Setup.md new file mode 100644 index 0000000000..d23a3ce7cf --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/Setup.md @@ -0,0 +1,57 @@ + +## Setup for Maven and Java JDK. + +## Description +This document helps you to setup/configure the Java JDK and Maven (download, install, configure and run) for your Java samples. + +## Steps for Java-JDK setup +1) Install Java JDK **32 bit / 64 bit** as per your PC configuration (Minimum Required version is - Java 1.8+) +[Java-JDK download link](https://www.oracle.com/java/technologies/downloads/#java8-windows). + +1) After Successful installation, search **Environment variable** in pc windows search bar and open system properties window. +![Environment vairable](SetupImages/environment-variables.png) + +1) Open Environment variable configuration and add JAVA_HOME System Variable and it's value as the installed JDK path. +![System vairable](SetupImages/JAVA_HOME.png) + +## Steps for Maven setup +1) Install [Maven](https://maven.apache.org/) + +![Download Maven](SetupImages/download-maven.png) + +2) Once the download has completed, extract the Maven archive to a directory of your choice. + +![extract-maven](SetupImages/extract-maven.png) + +3) Open the Start menu and search for environment variables, click the Edit the system environment variables result. + +![install-maven-edit-environment-variable](SetupImages/install-maven-edit-environment-variable-new.png) + +4) Under the Advanced tab in the System Properties window, click Environment Variables. + +![install-maven-on-edit-environment-variable-path](SetupImages/install-maven-on-edit-environment-variable-path-maven-home.png) + +5) Click the New button under the System variables section to add a new system environment variable + +![install-maven-edit-environment-variable](SetupImages/install-maven-edit-environment-variable-new.png) + +6) Enter MAVEN_HOME as the variable name and the path to the Maven directory as the variable value. Click OK to save the new system variable. + +![install-maven-on-windows-maven-home-variable](SetupImages/install-maven-on-windows-maven-home-variable.png) + +7) Enter MAVEN_HOME as the variable name and the path to the Maven directory as the variable value. Click OK to save the new system variable. + +![install-maven-path-variable](SetupImages/install-maven-path-variable.png) + +8) Enter %MAVEN_HOME%\bin in the new field. Click OK to save changes to the Path variable. + +![install-maven-on-windows](SetupImages/install-maven-on-windows-maven-home-variable.png) + + ## Verify Maven Installation +- In the command prompt, use the following command `mvn -v` to verify the installation by checking the current version of Maven. + +![verifymaveninstallation](SetupImages/verifymaveninstallation.png) + +## Further reading +- [Maven Apache Download](https://phoenixnap.com/kb/install-maven-windows) +- [java JDK](https://www.oracle.com/java/technologies/downloads/#java8-windows) diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/JAVA_HOME.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/JAVA_HOME.png new file mode 100644 index 0000000000..19d8a366c7 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/JAVA_HOME.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/Setup-variables-java-sdk.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/Setup-variables-java-sdk.png new file mode 100644 index 0000000000..7b64f9f1e6 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/Setup-variables-java-sdk.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/download-maven.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/download-maven.png new file mode 100644 index 0000000000..313d2fdc75 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/download-maven.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/environment-variables.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/environment-variables.png new file mode 100644 index 0000000000..031b1ba6a2 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/environment-variables.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/extract-maven.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/extract-maven.png new file mode 100644 index 0000000000..efce0cc9d4 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/extract-maven.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-edit-environment-variable-new.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-edit-environment-variable-new.png new file mode 100644 index 0000000000..5a781f2939 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-edit-environment-variable-new.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-edit-environment-variable-path-maven-home.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-edit-environment-variable-path-maven-home.png new file mode 100644 index 0000000000..5918a2ba70 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-edit-environment-variable-path-maven-home.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-save-changes-to-variables.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-save-changes-to-variables.png new file mode 100644 index 0000000000..de5a393cd0 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-save-changes-to-variables.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-windows-maven-home-variable.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-windows-maven-home-variable.png new file mode 100644 index 0000000000..a7420fee32 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-on-windows-maven-home-variable.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-path-variable.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-path-variable.png new file mode 100644 index 0000000000..2008ff55aa Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/install-maven-path-variable.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/new-system-variable.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/new-system-variable.png new file mode 100644 index 0000000000..507de80356 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/new-system-variable.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/verifymaveninstallation.png b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/verifymaveninstallation.png new file mode 100644 index 0000000000..50d62aa53f Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/SetupImages/verifymaveninstallation.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/appManifest/icon-color.png b/samples/TeamsSDK/Archived/msgext-action/java/appManifest/icon-color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/appManifest/icon-color.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/appManifest/icon-outline.png b/samples/TeamsSDK/Archived/msgext-action/java/appManifest/icon-outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/java/appManifest/icon-outline.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/java/appManifest/manifest.json b/samples/TeamsSDK/Archived/msgext-action/java/appManifest/manifest.json new file mode 100644 index 0000000000..e22745f7b9 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/appManifest/manifest.json @@ -0,0 +1,168 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0", + "id": "<>", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://dev.botframework.com", + "privacyUrl": "https://privacy.microsoft.com", + "termsOfUseUrl": "https://www.microsoft.com/en-us/legal/intellectualproperty/copyright/default.aspx" + }, + "name": { + "short": "Action Messaging Extension", + "full": "Microsoft Teams Action Based Messaging Extension" + }, + "description": { + "short": "This sample app illustrates how to implement Action-Based Messaging Extensions", + "full": "This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality." + }, + "icons": { + "outline": "icon-outline.png", + "color": "icon-color.png" + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "<>", + "needsChannelSelector": false, + "isNotificationOnly": false, + "supportsCalling": false, + "supportsVideo": false, + "supportsFiles": false, + "scopes": [ + "team", + "personal", + "groupChat" + ] + } + ], + "composeExtensions": [ + { + "botId": "<>", + "commands": [ + { + "id": "createCard", + "type": "action", + "context": [ + "compose" + ], + "description": "Command to run action to create a Card from Compose Box", + "title": "Create Card", + "parameters": [ + { + "name": "title", + "title": "Card title", + "description": "Title for the card", + "inputType": "text" + }, + { + "name": "subTitle", + "title": "Subtitle", + "description": "Subtitle for the card", + "inputType": "text" + }, + { + "name": "text", + "title": "Text", + "description": "Text for the card", + "inputType": "textarea" + } + ] + }, + { + "id": "shareMessage", + "type": "action", + "context": [ + "message" + ], + "description": "Test command to run action on message context (message sharing)", + "title": "Share Message", + "parameters": [ + { + "name": "includeImage", + "title": "Include Image", + "description": "Include image in Hero Card", + "inputType": "toggle" + } + ] + }, + { + "id": "FetchRoster", + "description": "Fetch the conversation roster", + "title": "FetchRoster", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + }, + { + "id": "createAdaptiveCard", + "type": "action", + "context": [ + "compose" + ], + "description": "Command to run action to create a Card from Compose Box", + "title": "Adaptive Card", + "parameters": [ + { + "name": "title", + "title": "Name", + "description": "Name of the User", + "inputType": "text" + }, + { + "name": "subTitle", + "title": "Designation", + "description": "Designation of the User", + "inputType": "text" + }, + { + "name": "text", + "title": "Description", + "description": "Description", + "inputType": "textarea" + } + ] + }, + { + "id": "webView", + "description": "Fetch the Web View", + "title": "Web View", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + }, + { + "id": "HTML", + "description": "Fetch the HTML", + "title": "HTML", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + }, + { + "id": "razorView", + "description": "Fetch the Razor View", + "title": "Razor View", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + } + ] + } + ], + "permissions": [ + "identity" + ], + "validDomains": [ + "<>" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/java/assets/sample.json b/samples/TeamsSDK/Archived/msgext-action/java/assets/sample.json new file mode 100644 index 0000000000..0d5a25c176 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-msgext-action-java", + "source": "officeDev", + "title": "Action Based Messaging Extensions", + "shortDescription": "This sample app demonstrates how to build an Action-Based Messaging Extension", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/msgext-action/java", + "longDescription": [ + "This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality." + ], + "creationDateTime": "2019-10-17", + "updateDateTime": "2024-10-11", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "java" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "maven" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot,ME" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/msgext-action/java/Images/MsgExtAction.gif", + "alt": "Solution UX showing action based Messaging Extensions" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/java/deploymentTemplates/template-with-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/java/deploymentTemplates/template-with-new-rg.json new file mode 100644 index 0000000000..c1953fe9c6 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/deploymentTemplates/template-with-new-rg.json @@ -0,0 +1,308 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "S1", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "P1v2", + "tier": "PremiumV2", + "size": "P1v2", + "family": "Pv2", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "newAppServicePlanLocation": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "The location of the App Service Plan. Defaults to \"westus\"." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "appServicePlanName": "[parameters('newAppServicePlanName')]", + "resourcesLocation": "[parameters('newAppServicePlanLocation')]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]", + "publishingUsername": "[concat('$', parameters('newWebAppName'))]", + "resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new Linux App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "perSiteScaling": false, + "maximumElasticWorkerCount": 1, + "isSpot": false, + "reserved": true, + "isXenon": false, + "hyperV": false, + "targetWorkerCount": 0, + "targetWorkerSizeId": 0 + } + }, + { + "comments": "Create a Web App using a Linux App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2018-11-01", + "location": "[variables('resourcesLocation')]", + "kind": "app,linux", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "hostNameSslStates": [ + { + "name": "[concat(parameters('newWebAppName'), '.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Standard" + }, + { + "name": "[concat(parameters('newWebAppName'), '.scm.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Repository" + } + ], + "serverFarmId": "[variables('appServicePlanName')]", + "reserved": true, + "isXenon": false, + "hyperV": false, + "scmSiteAlsoStopped": false, + "clientAffinityEnabled": true, + "clientCertEnabled": false, + "hostNamesDisabled": false, + "containerSize": 0, + "dailyMemoryTimeQuota": 0, + "httpsOnly": false, + "redundancyMode": "None", + "siteConfig": { + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "type": "Microsoft.Web/sites/config", + "apiVersion": "2018-11-01", + "name": "[concat(variables('webAppName'), '/web')]", + "location": "[variables('resourcesLocation')]", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', variables('webAppName'))]" + ], + "properties": { + "numberOfWorkers": 1, + "defaultDocuments": [ + "Default.htm", + "Default.html", + "Default.asp", + "index.htm", + "index.html", + "iisstart.htm", + "default.aspx", + "index.php", + "hostingstart.html" + ], + "netFrameworkVersion": "v4.0", + "linuxFxVersion": "JAVA|8-jre8", + "requestTracingEnabled": false, + "remoteDebuggingEnabled": false, + "httpLoggingEnabled": false, + "logsDirectorySizeLimit": 35, + "detailedErrorLoggingEnabled": false, + "publishingUsername": "[variables('publishingUsername')]", + "scmType": "None", + "use32BitWorkerProcess": true, + "webSocketsEnabled": false, + "alwaysOn": true, + "managedPipelineMode": "Integrated", + "virtualApplications": [ + { + "virtualPath": "/", + "physicalPath": "site\\wwwroot", + "preloadEnabled": true + } + ], + "loadBalancing": "LeastRequests", + "experiments": { + "rampUpRules": [] + }, + "autoHealEnabled": false, + "localMySqlEnabled": false, + "ipSecurityRestrictions": [ + { + "ipAddress": "Any", + "action": "Allow", + "priority": 1, + "name": "Allow all", + "description": "Allow all access" + } + ], + "scmIpSecurityRestrictions": [ + { + "ipAddress": "Any", + "action": "Allow", + "priority": 1, + "name": "Allow all", + "description": "Allow all access" + } + ], + "scmIpSecurityRestrictionsUseMain": false, + "http20Enabled": false, + "minTlsVersion": "1.2", + "ftpsState": "AllAllowed", + "reservedInstanceCount": 0 + } + }, + { + "apiVersion": "2021-03-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "azurebot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + }, + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', variables('webAppName'))]" + ] + }, + { + "type": "Microsoft.BotService/botServices/channels", + "apiVersion": "2021-03-01", + "name": "[concat(parameters('botId'), '/MsTeamsChannel')]", + "location": "global", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.BotService/botServices/', variables('webAppName'))]" + ], + "properties": { + "properties": { + "enableCalling": false, + "isEnabled": true + }, + "channelName": "MsTeamsChannel" + } + } + ], + "outputs": {} + } + } + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-action/java/deploymentTemplates/template-with-preexisting-rg.json b/samples/TeamsSDK/Archived/msgext-action/java/deploymentTemplates/template-with-preexisting-rg.json new file mode 100644 index 0000000000..becb72b7e0 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/deploymentTemplates/template-with-preexisting-rg.json @@ -0,0 +1,276 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "S1", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "P1v2", + "tier": "PremiumV2", + "size": "P1v2", + "family": "Pv2", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "existingAppServicePlan": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", + "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", + "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), parameters('newAppServicePlanName'))]", + "publishingUsername": "[concat('$', parameters('newWebAppName'))]", + "resourcesLocation": "[parameters('appServicePlanLocation')]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" + }, + "resources": [ + { + "comments": "Create a new Linux App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingAppServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "perSiteScaling": false, + "maximumElasticWorkerCount": 1, + "isSpot": false, + "reserved": true, + "isXenon": false, + "hyperV": false, + "targetWorkerCount": 0, + "targetWorkerSizeId": 0 + } + }, + { + "comments": "Create a Web App using a Linux App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2018-11-01", + "location": "[variables('resourcesLocation')]", + "kind": "app,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "hostNameSslStates": [ + { + "name": "[concat(parameters('newWebAppName'), '.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Standard" + }, + { + "name": "[concat(parameters('newWebAppName'), '.scm.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Repository" + } + ], + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]", + "reserved": true, + "isXenon": false, + "hyperV": false, + "scmSiteAlsoStopped": false, + "clientAffinityEnabled": true, + "clientCertEnabled": false, + "hostNamesDisabled": false, + "containerSize": 0, + "dailyMemoryTimeQuota": 0, + "httpsOnly": false, + "redundancyMode": "None", + "siteConfig": { + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "type": "Microsoft.Web/sites/config", + "apiVersion": "2018-11-01", + "name": "[concat(variables('webAppName'), '/web')]", + "location": "[variables('resourcesLocation')]", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ], + "properties": { + "numberOfWorkers": 1, + "defaultDocuments": [ + "Default.htm", + "Default.html", + "Default.asp", + "index.htm", + "index.html", + "iisstart.htm", + "default.aspx", + "index.php", + "hostingstart.html" + ], + "netFrameworkVersion": "v4.0", + "linuxFxVersion": "JAVA|8-jre8", + "requestTracingEnabled": false, + "remoteDebuggingEnabled": false, + "httpLoggingEnabled": false, + "logsDirectorySizeLimit": 35, + "detailedErrorLoggingEnabled": false, + "publishingUsername": "[variables('publishingUsername')]", + "scmType": "None", + "use32BitWorkerProcess": true, + "webSocketsEnabled": false, + "alwaysOn": true, + "managedPipelineMode": "Integrated", + "virtualApplications": [ + { + "virtualPath": "/", + "physicalPath": "site\\wwwroot", + "preloadEnabled": true + } + ], + "loadBalancing": "LeastRequests", + "experiments": { + "rampUpRules": [] + }, + "autoHealEnabled": false, + "localMySqlEnabled": false, + "ipSecurityRestrictions": [ + { + "ipAddress": "Any", + "action": "Allow", + "priority": 1, + "name": "Allow all", + "description": "Allow all access" + } + ], + "scmIpSecurityRestrictions": [ + { + "ipAddress": "Any", + "action": "Allow", + "priority": 1, + "name": "Allow all", + "description": "Allow all access" + } + ], + "scmIpSecurityRestrictionsUseMain": false, + "http20Enabled": false, + "minTlsVersion": "1.2", + "ftpsState": "AllAllowed", + "reservedInstanceCount": 0 + } + }, + { + "apiVersion": "2021-03-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "azurebot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "msaAppId": "[parameters('appId')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ] + }, + { + "type": "Microsoft.BotService/botServices/channels", + "apiVersion": "2021-03-01", + "name": "[concat(parameters('botId'), '/MsTeamsChannel')]", + "location": "global", + "dependsOn": [ + "[resourceId('Microsoft.BotService/botServices', parameters('botId'))]" + ], + "properties": { + "properties": { + "enableCalling": false, + "isEnabled": true + }, + "channelName": "MsTeamsChannel" + } + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-action/java/pom.xml b/samples/TeamsSDK/Archived/msgext-action/java/pom.xml new file mode 100644 index 0000000000..2d788e41b1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/pom.xml @@ -0,0 +1,255 @@ + + + + 4.0.0 + + com.microsoft.bot.sample + bot-teams-messaging-extensions-action + sample + jar + + ${project.groupId}:${project.artifactId} + This package contains a Java Teams Messaging Extensions Action sample using Spring Boot. + http://maven.apache.org + + + org.springframework.boot + spring-boot-starter-parent + 2.4.0 + + + + + + MIT License + http://www.opensource.org/licenses/mit-license.php + + + + + + Bot Framework Development + + Microsoft + https://dev.botframework.com/ + + + + + 1.8 + 1.8 + 1.8 + com.microsoft.bot.sample.teamsaction.Application + + + + + oss-sonatype + oss-sonatype + https://oss.sonatype.org/content/repositories/snapshots/ + + true + + + + + + + junit + junit + 4.13.1 + test + + + org.springframework.boot + spring-boot-starter-test + 2.4.0 + test + + + org.junit.vintage + junit-vintage-engine + test + + + + org.slf4j + slf4j-api + + + org.apache.logging.log4j + log4j-api + 2.17.1 + + + org.apache.logging.log4j + log4j-core + 2.17.1 + + + org.apache.logging.log4j + log4j-to-slf4j + 2.17.1 + test + + + + com.microsoft.bot + bot-integration-spring + 4.14.1 + compile + + + + + + build + + true + + + + + src/main/resources + false + + + + + maven-compiler-plugin + 3.8.1 + + + maven-war-plugin + 3.2.3 + + src/main/webapp + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + com.microsoft.bot.sample.teamsaction.Application + + + + + + com.microsoft.azure + azure-webapp-maven-plugin + 1.12.0 + + V2 + ${groupname} + ${botname} + + + JAVA_OPTS + -Dserver.port=80 + + + + linux + Java 8 + Java SE + + + + + ${project.basedir}/target + + *.jar + + + + + + + + + + + + publish + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + maven-war-plugin + 3.2.3 + + src/main/webapp + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + true + ossrh + https://oss.sonatype.org/ + true + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + 8 + false + + + + attach-javadocs + + jar + + + + + + + + + diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/Application.java b/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/Application.java new file mode 100644 index 0000000000..c8e160336b --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/Application.java @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.bot.sample.teamsaction; + +import com.microsoft.bot.builder.Bot; +import com.microsoft.bot.integration.AdapterWithErrorHandler; +import com.microsoft.bot.integration.BotFrameworkHttpAdapter; +import com.microsoft.bot.integration.Configuration; +import com.microsoft.bot.integration.spring.BotController; +import com.microsoft.bot.integration.spring.BotDependencyConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +// +// This is the starting point of the Sprint Boot Bot application. +// +@SpringBootApplication + +// Use the default BotController to receive incoming Channel messages. A custom +// controller could be used by eliminating this import and creating a new +// org.springframework.web.bind.annotation.RestController. +// The default controller is created by the Spring Boot container using +// dependency injection. The default route is /api/messages. +@Import({BotController.class}) + +/** + * This class extends the BotDependencyConfiguration which provides the default + * implementations for a Bot application. The Application class should + * override methods in order to provide custom implementations. + */ +public class Application extends BotDependencyConfiguration { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + /** + * Returns the Bot for this application. + * + *

+ * The @Component annotation could be used on the Bot class instead of this method + * with the @Bean annotation. + *

+ * + * @return The Bot implementation for this application. + */ + @Bean + public Bot getBot() { + return new TeamsMessagingExtensionsActionBot(); + } + + /** + * Returns a custom Adapter that provides error handling. + * + * @param configuration The Configuration object to use. + * @return An error handling BotFrameworkHttpAdapter. + */ + @Override + public BotFrameworkHttpAdapter getBotFrameworkHttpAdaptor(Configuration configuration) { + return new AdapterWithErrorHandler(configuration); + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/TeamsMessagingExtensionsActionBot.java b/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/TeamsMessagingExtensionsActionBot.java new file mode 100644 index 0000000000..2d8e8f12b1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/TeamsMessagingExtensionsActionBot.java @@ -0,0 +1,120 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.bot.sample.teamsaction; + +import com.microsoft.bot.builder.TurnContext; +import com.microsoft.bot.builder.teams.TeamsActivityHandler; +import com.microsoft.bot.schema.CardImage; +import com.microsoft.bot.schema.HeroCard; +import com.microsoft.bot.schema.teams.MessagingExtensionAction; +import com.microsoft.bot.schema.teams.MessagingExtensionActionResponse; +import com.microsoft.bot.schema.teams.MessagingExtensionAttachment; +import com.microsoft.bot.schema.teams.MessagingExtensionResult; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +/** + * This class implements the functionality of the Bot. + * + *

This is where application specific logic for interacting with the users would be + * added. There are two basic types of Messaging Extension in Teams: Search-based and Action-based. + * This sample illustrates how to build an Action-based Messaging Extension.

+ */ +public class TeamsMessagingExtensionsActionBot extends TeamsActivityHandler { + @Override + protected CompletableFuture onTeamsMessagingExtensionSubmitAction( + TurnContext turnContext, + MessagingExtensionAction action + ) { + switch (action.getCommandId()) { + // These commandIds are defined in the Teams App Manifest. + case "createCard": + return createCardCommand(turnContext, action); + + case "shareMessage": + return shareMessageCommand(turnContext, action); + default: + return notImplemented( + String.format("Invalid CommandId: %s", action.getCommandId())); + } + } + + private CompletableFuture createCardCommand( + TurnContext turnContext, + MessagingExtensionAction action + ) { + // The user has chosen to create a card by choosing the 'Create Card' context menu command. + Map actionData = (Map) action.getData(); + + HeroCard card = new HeroCard(); + card.setTitle(actionData.get("title")); + card.setSubtitle(actionData.get("subTitle")); + card.setText(actionData.get("text")); + + MessagingExtensionAttachment attachment = new MessagingExtensionAttachment(); + attachment.setContent(card); + attachment.setContentType(HeroCard.CONTENTTYPE); + attachment.setPreview(card.toAttachment()); + List attachments = Arrays.asList(attachment); + + MessagingExtensionResult result = new MessagingExtensionResult(); + result.setAttachments(attachments); + result.setAttachmentLayout("list"); + result.setType("result"); + MessagingExtensionActionResponse response = new MessagingExtensionActionResponse(); + response.setComposeExtension(result); + + return CompletableFuture.completedFuture(response); + } + + private CompletableFuture shareMessageCommand( + TurnContext turnContext, + MessagingExtensionAction action + ) { + // The user has chosen to share a message by choosing the 'Share Message' context menu command. + Map actionData = (Map) action.getData(); + + HeroCard card = new HeroCard(); + card.setTitle( + action.getMessagePayload().getFrom() != null && action.getMessagePayload().getFrom().getUser() != null + ? action.getMessagePayload().getFrom().getUser().getDisplayName() : ""); + card.setText(action.getMessagePayload().getBody().getContent()); + + if (action.getMessagePayload().getAttachments() != null && !action.getMessagePayload() + .getAttachments().isEmpty()) { + // This sample does not add the MessagePayload Attachments. This is left as an + // exercise for the user. + card.setSubtitle(String.format("(%d Attachments not included)", + action.getMessagePayload().getAttachments().size())); + } + + // This Messaging Extension example allows the user to check a box to include an image with the + // shared message. This demonstrates sending custom parameters along with the message payload. + boolean includeImage = actionData.get("includeImage") != null ? ( + Boolean.valueOf(actionData.get("includeImage")) + ) : false; + if (includeImage) { + CardImage cardImage = new CardImage(); + cardImage.setUrl("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU"); + card.setImages(Arrays.asList(cardImage)); + } + + MessagingExtensionAttachment attachment = new MessagingExtensionAttachment(); + attachment.setContent(card); + attachment.setContentType(HeroCard.CONTENTTYPE); + attachment.setPreview(card.toAttachment()); + + MessagingExtensionResult result = new MessagingExtensionResult(); + result.setAttachmentLayout("list"); + result.setType("result"); + result.setAttachments(Arrays.asList(attachment)); + + MessagingExtensionActionResponse response = new MessagingExtensionActionResponse(); + response.setComposeExtension(result); + return CompletableFuture.completedFuture(response); + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/package-info.java b/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/package-info.java new file mode 100644 index 0000000000..adad2856cd --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/main/java/com/microsoft/bot/sample/teamsaction/package-info.java @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. + +/** + * This package contains the classes for the Teams Messaging Extension Action sample. + */ +package com.microsoft.bot.sample.teamsaction; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/main/resources/application.properties b/samples/TeamsSDK/Archived/msgext-action/java/src/main/resources/application.properties new file mode 100644 index 0000000000..d7d0ee8643 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/main/resources/application.properties @@ -0,0 +1,3 @@ +MicrosoftAppId= +MicrosoftAppPassword= +server.port=3978 diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/main/resources/log4j2.json b/samples/TeamsSDK/Archived/msgext-action/java/src/main/resources/log4j2.json new file mode 100644 index 0000000000..67c0ad5306 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/main/resources/log4j2.json @@ -0,0 +1,18 @@ +{ + "configuration": { + "name": "Default", + "appenders": { + "Console": { + "name": "Console-Appender", + "target": "SYSTEM_OUT", + "PatternLayout": {"pattern": "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"} + } + }, + "loggers": { + "root": { + "level": "debug", + "appender-ref": {"ref": "Console-Appender","level": "debug"} + } + } + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/META-INF/MANIFEST.MF b/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/WEB-INF/web.xml b/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..383c19004c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,12 @@ + + + dispatcher + + org.springframework.web.servlet.DispatcherServlet + + + contextConfigLocation + /WEB-INF/spring/dispatcher-config.xml + + 1 + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/index.html b/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/index.html new file mode 100644 index 0000000000..a200688b3e --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/main/webapp/index.html @@ -0,0 +1,418 @@ + + + + + + + Teams Action Based Messaging Extension + + + + + +
+
+
+
Spring Boot Bot
+
+
+
+
+
Your bot is ready!
+
You can test your bot in the Bot Framework Emulator
+ by connecting to http://localhost:3978/api/messages.
+ +
Visit Azure + Bot Service to register your bot and add it to
+ various channels. The bot's endpoint URL typically looks + like this:
+
https://your_bots_hostname/api/messages
+
+
+
+
+ +
+ + + diff --git a/samples/TeamsSDK/Archived/msgext-action/java/src/test/java/com/microsoft/bot/sample/teamsaction/ApplicationTest.java b/samples/TeamsSDK/Archived/msgext-action/java/src/test/java/com/microsoft/bot/sample/teamsaction/ApplicationTest.java new file mode 100644 index 0000000000..d76c2bb8de --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/java/src/test/java/com/microsoft/bot/sample/teamsaction/ApplicationTest.java @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.bot.sample.teamsaction; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class ApplicationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/.env b/samples/TeamsSDK/Archived/msgext-action/nodejs/.env new file mode 100644 index 0000000000..f82e9af78d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/.env @@ -0,0 +1,5 @@ +MicrosoftAppType=SingleTenant +MicrosoftAppId= +MicrosoftAppPassword= +MicrosoftAppTenantId= +BaseUrl= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/.eslintrc.js b/samples/TeamsSDK/Archived/msgext-action/nodejs/.eslintrc.js new file mode 100644 index 0000000000..abe49d5995 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/.eslintrc.js @@ -0,0 +1,15 @@ +/* eslint-disable */ +module.exports = { + "extends": "standard", + "rules": { + "semi": [2, "always"], + "indent": [2, 4], + "no-return-await": 0, + "space-before-function-paren": [2, { + "named": "never", + "anonymous": "never", + "asyncArrow": "always" + }], + "template-curly-spacing": [2, "always"] + } +}; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/.gitignore b/samples/TeamsSDK/Archived/msgext-action/nodejs/.gitignore new file mode 100644 index 0000000000..6a16d288f8 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/.gitignore @@ -0,0 +1,17 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appManifest/build +/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store + +# build +lib/ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/extensions.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/extensions.json new file mode 100644 index 0000000000..2d88dee21b --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/launch.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/launch.json new file mode 100644 index 0000000000..d027ed91e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/launch.json @@ -0,0 +1,73 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Local Service", + "type": "node", + "request": "attach", + "port": 9239, + "restart": true, + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/settings.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/settings.json new file mode 100644 index 0000000000..4299620253 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/tasks.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/tasks.json new file mode 100644 index 0000000000..6a9084c0c1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/.vscode/tasks.json @@ -0,0 +1,104 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Teams App Locally", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy", + "Start application" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "nodejs", // Validate if Node.js is installed. + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978 // app service port + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + }, + { + "label": "Start application", + "type": "shell", + "command": "npm run dev:teamsfx", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": { + "pattern": [ + { + "regexp": "^.*$", + "file": 0, + "location": 1, + "message": 2 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "[nodemon] starting", + "endsPattern": "Server listening on http://localhost:3978" + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/1.Install.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/1.Install.png new file mode 100644 index 0000000000..40e8f4c925 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.ActionPreviewOptions.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.ActionPreviewOptions.png new file mode 100644 index 0000000000..a2093891ab Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.ActionPreviewOptions.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.CreateCard.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.CreateCard.png new file mode 100644 index 0000000000..95d78453c9 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.CreateCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.SelectActionMessageExtension.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.SelectActionMessageExtension.png new file mode 100644 index 0000000000..8ce991d923 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/2.SelectActionMessageExtension.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/3.SendCard.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/3.SendCard.png new file mode 100644 index 0000000000..9e388b84ec Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/3.SendCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/4.FetchRoaster.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/4.FetchRoaster.png new file mode 100644 index 0000000000..0e98abd66c Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/4.FetchRoaster.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/5.EnterDetailsCard_WebView.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/5.EnterDetailsCard_WebView.png new file mode 100644 index 0000000000..136b5b495b Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/5.EnterDetailsCard_WebView.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/6.SendEmpDetails.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/6.SendEmpDetails.png new file mode 100644 index 0000000000..e38a87e61f Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/6.SendEmpDetails.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/7.StaticHtml.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/7.StaticHtml.png new file mode 100644 index 0000000000..72b467ee09 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/7.StaticHtml.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/MsgExtAction.gif b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/MsgExtAction.gif new file mode 100644 index 0000000000..5f414fb391 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/Images/MsgExtAction.gif differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/README.md b/samples/TeamsSDK/Archived/msgext-action/nodejs/README.md new file mode 100644 index 0000000000..86659a74c8 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/README.md @@ -0,0 +1,173 @@ +--- +page_type: sample +description: This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality. +products: +- office-teams +- office +- office-365 +languages: +- nodejs +extensions: + contentType: samples + createdDate: "10-04-2022 17:00:25" +urlFragment: officedev-microsoft-teams-samples-msgext-action-nodejs +--- + +# Teams Messaging Extensions Action +Explore the capabilities of Action-Based Messaging Extensions in Microsoft Teams with this sample app. It showcases how to implement interactive features, including bots and message extensions, allowing users to create content dynamically through a user-friendly interface. + +This bot has been created using [Bot Framework](https://dev.botframework.com). This sample shows +how to incorporate basic conversational flow into a Teams application. It also illustrates a few of the Teams specific calls you can make from your bot. + +## Included Features +* Bots +* Message Extensions +* Action Commands + +- **Interaction with bot** +![Messaging Extension](Images/MsgExtAction.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Teams Messaging Extensions Action:** [Manifest](/samples/msgext-action/csharp/demo-manifest/msgext-action.zip) + + +## Prerequisites + +- Microsoft Teams is installed and you have an account +- [NodeJS](https://nodejs.org/en/) +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +# Setup + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +the Teams service needs to call into the bot. + +1) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +## 2) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. +## Setup for bot +In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration). + - For bot handle, make up a name. + - Select "Use existing app registration" (Create the app registration in Microsoft Entra ID beforehand.) + - __*If you don't have an Azure account*__ create an [Azure free account here](https://azure.microsoft.com/free/) + + In the new Azure Bot resource in the Portal, + - Ensure that you've [enabled the Teams Channel](https://learn.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - In Settings/Configuration/Messaging endpoint, enter the current `https` URL you were given by running the tunnelling application. Append with the path `/api/messages` + +## Setup for code + +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +1) In a terminal, navigate to `samples/msgext-action/nodejs` + +1) Install modules + + ```bash + npm install + ``` + +1) Update the `.env` configuration for the bot to use the Microsoft App Id and App Password from the Bot Framework registration. (Note the App Password is referred to as the "client secret" in the azure portal and you can always create a new client secret anytime.) `MicrosoftAppTenantId` will be the id for the tenant where application is registered. + - Set "MicrosoftAppType" in the `env`. (**Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI**) + + - Set "BaseUrl" in the `env` as per your application like the ngrok forwarding url (ie `https://xxxx.ngrok-free.app`) after starting ngrok and if you are using dev tunnels, your URL will be like: https://12345.devtunnels.ms. + +1) Run your bot at the command line: + + ```bash + npm start + ``` + +1) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appManifest` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `<>` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` with base Url domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + - **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.) + - Add the bot to personal/team/groupChat scope (Supported scopes) + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/msgext-action/nodejs/index.js#L47) line and put your debugger for local debug. + +## Running the sample + +> Note this `manifest.json` specified that the bot will be called from both the `compose` and `message` areas of Teams. Please refer to Teams documentation for more details. + +1) Selecting the **Create Card** command from the Compose Box command list. The parameters dialog will be displayed and can be submitted to initiate the card creation within the Messaging Extension code. + +![Install](Images/1.Install.png) + +![ME-Card ](Images/2.SelectActionMessageExtension.png) + +![ME-Card ](Images/2.CreateCard.png) + +![ME-Posted-Card ](Images/3.SendCard.png) + + +2) Selecting the **Fetch Roster** command from the Compose Box command list. You will presented with prompt for Just In Time installation if app is not already added to current team/chat. + +![Roster-Fetch ](Images/4.FetchRoaster.png) + +3) You can try with other supported commands as well like: **Adaptive Card**, **Web View**, **HTML**, **Razor View** + +![Static-Tab ](Images/7.StaticHtml.png) + +![Web-View ](Images/5.EnterDetailsCard_WebView.png) + +![Web-View ](Images/6.SendEmpDetails.png) + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Messaging extension action](https://learn.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/action-commands/define-action-command) +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/aad.manifest.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/aad.manifest.json new file mode 100644 index 0000000000..2a8f8e3749 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/aad.manifest.json @@ -0,0 +1,32 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "msgext-action-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMyOrg", + "oauth2AllowIdTokenImplicitFlow": true, + "oauth2AllowImplicitFlow": true, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/color.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/manifest.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/manifest.json new file mode 100644 index 0000000000..408812b93d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/manifest.json @@ -0,0 +1,130 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://dev.botframework.com", + "privacyUrl": "https://privacy.microsoft.com", + "termsOfUseUrl": "https://www.microsoft.com/en-us/legal/intellectualproperty/copyright/default.aspx" + }, + "name": { + "short": "Action Messaging Extension", + "full": "Microsoft Teams Action Based Messaging Extension" + }, + "description": { + "short": "This sample app illustrates how to implement Action-Based Messaging Extensions.", + "full": "This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "needsChannelSelector": false, + "isNotificationOnly": false, + "supportsCalling": false, + "supportsVideo": false, + "supportsFiles": false, + "scopes": [ + "team", + "personal", + "groupChat" + ] + } + ], + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "commands": [ + { + "id": "createCard", + "type": "action", + "context": [ + "compose" + ], + "description": "Command to run action to create a Card from Compose Box", + "title": "Create Card", + "parameters": [ + { + "name": "title", + "title": "Card title", + "description": "Title for the card", + "inputType": "text" + }, + { + "name": "subTitle", + "title": "Subtitle", + "description": "Subtitle for the card", + "inputType": "text" + }, + { + "name": "text", + "title": "Text", + "description": "Text for the card", + "inputType": "textarea" + } + ] + }, + { + "id": "shareMessage", + "type": "action", + "context": [ + "message" + ], + "description": "Test command to run action on message context (message sharing)", + "title": "Share Message", + "parameters": [ + { + "name": "includeImage", + "title": "Include Image", + "description": "Include image in Hero Card", + "inputType": "toggle" + } + ] + }, + { + "id": "FetchRoster", + "description": "Fetch the conversation roster", + "title": "FetchRoster", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + }, + { + "id": "webView", + "description": "Fetch the Web View", + "title": "Web View", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + }, + { + "id": "Static HTML", + "description": "Fetch the Static HTML", + "title": "Static HTML", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] + } + ] + } + ], + "permissions": [ + "identity" + ], + "validDomains": [ + "{{domain-name}}", + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/outline.png b/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/nodejs/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/assets/sample.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/assets/sample.json new file mode 100644 index 0000000000..939e721a4d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-msgext-action-nodejs", + "source": "officeDev", + "title": "Messaging Extension Action", + "shortDescription": "This sample app illustrates how to implement Action-Based Messaging Extensions.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/msgext-action/nodejs", + "longDescription": [ + "This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality." + ], + "creationDateTime": "2022-10-04", + "updateDateTime": "2024-10-11", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + } + ], + "thumbnails": [ + { + "type": "Image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/msgext-action/nodejs/Images/MsgExtAction.gif", + "alt": "Solution UX showing action based messaging extension" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/bots/teamsMessagingExtensionsActionBot.js b/samples/TeamsSDK/Archived/msgext-action/nodejs/bots/teamsMessagingExtensionsActionBot.js new file mode 100644 index 0000000000..239e702ada --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/bots/teamsMessagingExtensionsActionBot.js @@ -0,0 +1,239 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { TeamsActivityHandler, CardFactory, TeamsInfo, MessageFactory } = require('botbuilder'); +const baseUrl = process.env.BaseUrl; + +/** + * TeamsMessagingExtensionsActionBot handles messaging extension actions in Microsoft Teams. + */ +class TeamsMessagingExtensionsActionBot extends TeamsActivityHandler { + constructor() { + super(); + } + + /** + * Handles the submit action from the messaging extension. + * @param {TurnContext} context - The context object for the turn. + * @param {MessagingExtensionAction} action - The action object. + */ + async handleTeamsMessagingExtensionSubmitAction(context, action) { + switch (action.commandId) { + case 'createCard': + return createCardCommand(action); + case 'shareMessage': + return shareMessageCommand(action); + case 'webView': + return await webViewResponse(action); + } + } + + /** + * Handles the fetch task action from the messaging extension. + * @param {TurnContext} context - The context object for the turn. + * @param {MessagingExtensionAction} action - The action object. + */ + async handleTeamsMessagingExtensionFetchTask(context, action) { + switch (action.commandId) { + case 'webView': + return empDetails(); + case 'Static HTML': + return dateTimeInfo(); + default: + try { + const member = await this.getSingleMember(context); + return { + task: { + type: 'continue', + value: { + card: getAdaptiveCardAttachment(), + height: 400, + title: `Hello ${member}`, + width: 300 + } + } + }; + } catch (e) { + if (e.code === 'BotNotInConversationRoster') { + return { + task: { + type: 'continue', + value: { + card: getJustInTimeCardAttachment(), + height: 400, + title: 'Adaptive Card - App Installation', + width: 300 + } + } + }; + } + throw e; + } + } + } + + /** + * Gets a single member from the conversation. + * @param {TurnContext} context - The context object for the turn. + */ + async getSingleMember(context) { + try { + const member = await TeamsInfo.getMember(context, context.activity.from.id); + return member.name; + } catch (e) { + if (e.code === 'MemberNotFoundInConversation') { + await context.sendActivity(MessageFactory.text('Member not found.')); + return e.code; + } + throw e; + } + } +} + +/** + * Creates a just-in-time card attachment. + */ +function getJustInTimeCardAttachment() { + return CardFactory.adaptiveCard({ + actions: [ + { + type: 'Action.Submit', + title: 'Continue', + data: { msteams: { justInTimeInstall: true } } + } + ], + body: [ + { + text: 'Looks like you have not used Action Messaging Extension app in this team/chat. Please click **Continue** to add this app.', + type: 'TextBlock', + wrap: true + } + ], + type: 'AdaptiveCard', + version: '1.0' + }); +} + +/** + * Creates an adaptive card attachment. + */ +function getAdaptiveCardAttachment() { + return CardFactory.adaptiveCard({ + actions: [{ type: 'Action.Submit', title: 'Close' }], + body: [ + { + text: 'This app is installed in this conversation. You can now use it to do some great stuff!!!', + type: 'TextBlock', + isSubtle: false, + wrap: true + } + ], + type: 'AdaptiveCard', + version: '1.0' + }); +} + +/** + * Handles the create card command. + * @param {MessagingExtensionAction} action - The action object. + */ +function createCardCommand(action) { + const data = action.data; + const heroCard = CardFactory.heroCard(data.title, data.text); + heroCard.content.subtitle = data.subTitle; + const attachment = { contentType: heroCard.contentType, content: heroCard.content, preview: heroCard }; + + return { + composeExtension: { + type: 'result', + attachmentLayout: 'list', + attachments: [attachment] + } + }; +} + +/** + * Handles the share message command. + * @param {MessagingExtensionAction} action - The action object. + */ +function shareMessageCommand(action) { + let userName = 'unknown'; + if (action.messagePayload.from && action.messagePayload.from.user && action.messagePayload.from.user.displayName) { + userName = action.messagePayload.from.user.displayName; + } + + let images = []; + const includeImage = action.data.includeImage; + if (includeImage === 'true') { + images = ['https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU']; + } + const heroCard = CardFactory.heroCard(`${userName} originally sent this message:`, action.messagePayload.body.content, images); + + if (action.messagePayload.attachments && action.messagePayload.attachments.length > 0) { + heroCard.content.subtitle = `(${action.messagePayload.attachments.length} Attachments not included)`; + } + + const attachment = { contentType: heroCard.contentType, content: heroCard.content, preview: heroCard }; + + return { + composeExtension: { + type: 'result', + attachmentLayout: 'list', + attachments: [attachment] + } + }; +} + +/** + * Returns employee details task module. + */ +function empDetails() { + return { + task: { + type: 'continue', + value: { + width: 350, + height: 300, + title: 'Task module WebView', + url: `${baseUrl}/customForm` + } + } + }; +} + +/** + * Returns date and time info task module. + */ +function dateTimeInfo() { + return { + task: { + type: 'continue', + value: { + width: 450, + height: 125, + title: 'Task module Static HTML', + url: `${baseUrl}/staticPage` + } + } + }; +} + +/** + * Handles the web view response. + * @param {MessagingExtensionAction} action - The action object. + */ +async function webViewResponse(action) { + const data = action.data; + const heroCard = CardFactory.heroCard(`ID: ${data.EmpId}`, `E-Mail: ${data.EmpEmail}`); + heroCard.content.subtitle = `Name: ${data.EmpName}`; + const attachment = { contentType: heroCard.contentType, content: heroCard.content, preview: heroCard }; + return { + composeExtension: { + type: 'result', + attachmentLayout: 'list', + attachments: [attachment] + } + }; +} + +module.exports.TeamsMessagingExtensionsActionBot = TeamsMessagingExtensionsActionBot; diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/build.js b/samples/TeamsSDK/Archived/msgext-action/nodejs/build.js new file mode 100644 index 0000000000..a59684a045 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/build.js @@ -0,0 +1,14 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js' +}) + .then((r) => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json new file mode 100644 index 0000000000..4ba1505699 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appType": { + "value": "SingleTenant" + }, + "appId": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json new file mode 100644 index 0000000000..35696a5ff6 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "value": "" + }, + "existingAppServicePlanName": { + "value": "" + }, + "existingAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appType": { + "value": "SingleTenant" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/readme.md b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/readme.md new file mode 100644 index 0000000000..ba81e5b608 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/readme.md @@ -0,0 +1,38 @@ +# Usage +BotApp must be deployed prior to AzureBot. + +### Command line: +`az login`
+`az deployment group create --resource-group --template-file --parameters @` + +## Parameters for template-BotApp-with-rg.json: + +- **appServiceName**: (required) The Name of the Bot App Service. +- (Pick an existing App Service Plan or create a new App Service Plan.) + - **existingAppServicePlanName**: The name of the App Service Plan. + - **existingAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanName**: The name of the App Service Plan. + - **newAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**: (required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. +- **UMSIName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to Subscription Tenant ID. + +More info: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource + +## Parameters for template-AzureBot-with-rg.json: + +- **azureBotId**: (required) The globally unique and immutable bot ID. +- **azureBotSku**: The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default). +- **azureBotRegion**: Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope. +- **botEndpoint**: Use to handle client messages, Such as `https://.azurewebsites.net/api/messages`. +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **UMSIName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to Subscription Tenant ID. + +More info: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json new file mode 100644 index 0000000000..56b91417d6 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json @@ -0,0 +1,121 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default)." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope." + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appType": { + "type": "string", + "defaultValue": "SingleTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"SingleTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]", + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "msiResourceId": "" + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "" + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "[variables('msiResourceId')]" + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "msiResourceId": "[variables('appTypeDef')[parameters('appType')].msiResourceId]" + } + }, + "resources": [ + { + "apiVersion": "2021-05-01-preview", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "msaAppTenantId": "[variables('appType').tenantId]", + "msaAppMSIResourceId": "[variables('appType').msiResourceId]", + "msaAppType": "[parameters('appType')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + }, + "dependsOn": [] + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json new file mode 100644 index 0000000000..7037cd300a --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json @@ -0,0 +1,191 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "existingAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "existingAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appType": { + "type": "string", + "defaultValue": "SingleTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"SingleTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types. Defaults to \"\"." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication. Defaults to \"\"." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. Defaults to \"\"." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "useExistingServicePlan": "[not(empty(parameters('existingAppServicePlanName')))]", + "servicePlanName": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanName'), parameters('newAppServicePlanName'))]", + "servicePlanLocation": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanLocation'), parameters('newAppServicePlanLocation'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "identity": { "type": "None" } + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "identity": { "type": "None" } + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[variables('msiResourceId')]": {} + } + } + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "identity": "[variables('appTypeDef')[parameters('appType')].identity]" + } + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[parameters('newAppServicePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "properties": { + "name": "[variables('servicePlanName')]" + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('servicePlanLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]" + ], + "name": "[parameters('appServiceName')]", + "identity": "[variables('appType').identity]", + "properties": { + "name": "[parameters('appServiceName')]", + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "10.14.1" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + }, + { + "name": "MicrosoftAppTenantId", + "value": "[variables('appType').tenantId]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json new file mode 100644 index 0000000000..e09367570e --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appType": { + "value": "SingleTenant" + }, + "appId": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json new file mode 100644 index 0000000000..e7c002c471 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "appServiceName": { + "value": "" + }, + "appServicePlanName": { + "value": "" + }, + "appServicePlanLocation": { + "value": "" + }, + "appServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appType": { + "value": "SingleTenant" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/readme.md b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/readme.md new file mode 100644 index 0000000000..2f2571d06d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/readme.md @@ -0,0 +1,45 @@ +# Usage +BotApp must be deployed prior to AzureBot. + +### Command line: +`az login`
+`az deployment sub create --template-file --location --parameters @` + +## Parameters for template-BotApp-new-rg.json: + +- **groupName**: (required) The name of the new Resource Group. +- **groupLocation**: (required) The location of the new Resource Group. + +- **appServiceName**: (required) The location of the App Service Plan. +- **appServicePlanName**: (required) The name of the App Service Plan. +- **appServicePlanLocation**: The location of the App Service Plan. Defaults to use groupLocation. +- **appServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**: (required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. +- **UMSIName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +More info: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource + + + +## Parameters for template-AzureBot-new-rg.json: + +- **groupName**: (required) The name of the new Resource Group. +- **groupLocation**: (required) The location of the new Resource Group. + +- **azureBotId**: (required) The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable. +- **azureBotSku**: The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default). +- **azureBotRegion**: Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope. +- **botEndpoint**: Use to handle client messages, Such as `https://.azurewebsites.net/api/messages`. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **UMSIName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to Subscription Tenant ID. + +More info: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json new file mode 100644 index 0000000000..3eb478f5b1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json @@ -0,0 +1,160 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "" + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appType": { + "type": "string", + "defaultValue": "SingleTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"SingleTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]", + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "msiResourceId": "" + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "" + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "[variables('msiResourceId')]" + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "msiResourceId": "[variables('appTypeDef')[parameters('appType')].msiResourceId]" + } + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "apiVersion": "2021-03-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "name": "[parameters('azureBotId')]", + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "msaAppTenantId": "[variables('appType').tenantId]", + "msaAppMSIResourceId": "[variables('appType').msiResourceId]", + "msaAppType": "[parameters('appType')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json new file mode 100644 index 0000000000..1eba298d99 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json @@ -0,0 +1,213 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "appServiceName": { + "type": "string", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "appServicePlanName": { + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "appServicePlanLocation": { + "type": "string", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "appServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + }, + "appType": { + "type": "string", + "defaultValue": "SingleTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"SingleTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "appServicePlanName": "[parameters('appServicePlanName')]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), parameters('groupLocation'), parameters('appServicePlanLocation'))]", + "appServiceName": "[parameters('appServiceName')]", + "resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "identity": { "type": "None" } + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "identity": { "type": "None" } + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[variables('msiResourceId')]": {} + } + } + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "identity": "[variables('appTypeDef')[parameters('appType')].identity]" + } + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('appServicePlanSku')]", + "properties": { + "name": "[variables('appServicePlanName')]" + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('appServiceName')]", + "identity": "[variables('appType').identity]", + "properties": { + "name": "[variables('appServiceName')]", + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "10.14.1" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + }, + { + "name": "MicrosoftAppTenantId", + "value": "[variables('appType').tenantId]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + } + ], + "outputs": {} + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/env/.env.local b/samples/TeamsSDK/Archived/msgext-action/nodejs/env/.env.local new file mode 100644 index 0000000000..6d46e5e348 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/env/.env.local @@ -0,0 +1,22 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +MICROSOFT_APP_TYPE=SingleTenant +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +APP_NAME_SUFFIX=local \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/index.js b/samples/TeamsSDK/Archived/msgext-action/nodejs/index.js new file mode 100644 index 0000000000..157c582221 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/index.js @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const path = require('path'); + +const ENV_FILE = path.join(__dirname, '.env'); +require('dotenv').config({ path: ENV_FILE }); + +const express = require('express'); + +// Import required bot services. +// See https://aka.ms/bot-services to learn more about the different parts of a bot. +const { CloudAdapter, ConfigurationBotFrameworkAuthentication } = require('botbuilder'); + +const { TeamsMessagingExtensionsActionBot } = require('./bots/teamsMessagingExtensionsActionBot'); + +// Create adapter. +// See https://aka.ms/about-bot-adapter to learn more about adapters. +const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env); +const adapter = new CloudAdapter(botFrameworkAuthentication); + +adapter.onTurnError = async (context, error) => { + // This check writes out errors to console log .vs. app insights. + // NOTE: In production environment, you should consider logging this to Azure + // application insights. See https://aka.ms/bottelemetry for telemetry + // configuration instructions. + console.error(`\n [onTurnError] unhandled error: ${error}`); + + // Send a trace activity, which will be displayed in Bot Framework Emulator + await context.sendTraceActivity( + 'OnTurnError Trace', + `${error}`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); + + // Uncomment below commented line for local debugging. + // await context.sendActivity(`Sorry, it looks like something went wrong. Exception Caught: ${error}`); +}; + +// Create the bot that will handle incoming messages. +const bot = new TeamsMessagingExtensionsActionBot(); + +const server = express(); + +// Add this line so req.body is populated +server.use(express.json()); + +server.engine('html', require('ejs').renderFile); +server.set('view engine', 'ejs'); +server.set('views', __dirname); + +const port = process.env.PORT || 3978; +server.listen(port, () => { + console.log(`Server listening on http://localhost:${port}`); +}); + +server.use("/Images", express.static(path.resolve(__dirname, 'Images'))); + +server.get('/customForm', (req, res) => { + res.render('./views/CustomForm'); +}); + +server.get('/staticPage', (req, res) => { + res.render('./views/StaticPage'); +}); + +server.get('*', (req, res) => { + res.json({ error: 'Route not found' }); +}); + +// Listen for incoming requests. +server.post('/api/messages', async (req, res) => { + await adapter.process(req, res, (context) => bot.run(context)); +}); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/infra/azure.bicep b/samples/TeamsSDK/Archived/msgext-action/nodejs/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/infra/azure.parameters.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/infra/azure.parameters.json new file mode 100644 index 0000000000..2ca3c587cf --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "msgext-action" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/m365agents.local.yml b/samples/TeamsSDK/Archived/msgext-action/nodejs/m365agents.local.yml new file mode 100644 index 0000000000..a54415cc88 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/m365agents.local.yml @@ -0,0 +1,97 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-action-nodejs + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: msgext-action-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADandPersonalMicrosoftAccount" # Multitenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: msgext-action${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + # echo "::set-teamsfx-env MICROSOFT_APP_TYPE=MultiTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + - uses: aadApp/update # Apply the AAD manifest to an existing AAD app. Will use the object id in manifest file to determine which AAD app to update. + with: + manifestPath: ./aad.manifest.json # Relative path to teamsfx folder. Environment variables in manifest will be replaced before apply to AAD app + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Run npm command + - uses: cli/runNpmCommand + with: + args: install --no-audit + + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: ${{MICROSOFT_APP_TYPE}} + MicrosoftAppTenantId: ${{MICROSOFT_APP_TENANT_ID}} + BaseUrl: ${{BOT_ENDPOINT}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/m365agents.yml b/samples/TeamsSDK/Archived/msgext-action/nodejs/m365agents.yml new file mode 100644 index 0000000000..703bcaa766 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-action-nodejs + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/package-lock.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/package-lock.json new file mode 100644 index 0000000000..9453944c1b --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/package-lock.json @@ -0,0 +1,6032 @@ +{ + "name": "teams-bot", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "teams-bot", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "botbuilder": "^4.23.3", + "dotenv": "^16.6.1", + "ejs": "^3.1.10", + "express": "^4.22.1" + }, + "devDependencies": { + "esbuild": "^0.28.0", + "eslint": "^8.57.1", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-promise": "^6.6.0", + "nodemon": "^3.1.14" + } + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz", + "integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-http-compat": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.4.0.tgz", + "integrity": "sha512-f1P96IB399YiN2ARYHP7EpZi3Bf3wH4SN2lGzrw7JVwm7bbsVYtf2iKSBwTywD2P62NOPZGHFSZi+6jjb75JuA==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@azure/core-client": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.23.0.tgz", + "integrity": "sha512-Evs1INHo+jUjwHi1T6SG6Ua/LHOQBCLuKEEE6efIpt4ZOoNonaT1kP32GoOcdNDbfqsD2445CPri3MubBy5DEQ==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz", + "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.13.1.tgz", + "integrity": "sha512-5C/2WD5Vb1lHnZS16dNQRPMjN6oV/Upba+C9nBIs15PmOi6A3ZGs4Lr2u60zw4S04gi+u3cEXiqTVP7M4Pz3kw==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^5.5.0", + "@azure/msal-node": "^5.1.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/msal-common": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.4.1.tgz", + "integrity": "sha512-Bl8f+w37xkXsYh7QRkAKCFGYtWMYuOVO7Lv+BxILrvGz3HbIEF22Pt0ugyj0QPOl6NLrHcnNUQ9yeew98P/5iw==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/msal-node": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-5.1.2.tgz", + "integrity": "sha512-DoeSJ9U5KPAIZoHsPywvfEj2MhBniQe0+FSpjLUTdWoIkI999GB5USkW6nNEHnIaLVxROHXvprWA1KzdS1VQ4A==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "16.4.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@azure/identity/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@azure/logger": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz", + "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==", + "license": "MIT", + "dependencies": { + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-5.6.3.tgz", + "integrity": "sha512-sTjMtUm+bJpENU/1WlRzHEsgEHppZDZ1EtNyaOODg/sQBtMxxJzGB+MOCM+T2Q5Qe1fKBrdxUmjyRxm0r7Ez9w==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "16.4.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-browser/node_modules/@azure/msal-common": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.4.1.tgz", + "integrity": "sha512-Bl8f+w37xkXsYh7QRkAKCFGYtWMYuOVO7Lv+BxILrvGz3HbIEF22Pt0ugyj0QPOl6NLrHcnNUQ9yeew98P/5iw==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "14.16.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.1.tgz", + "integrity": "sha512-nyxsA6NA4SVKh5YyRpbSXiMr7oQbwark7JU9LMeg6tJYTSPyAGkdx61wPT4gyxZfxlSxMMEyAsWaubBlNyIa1w==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.16.3.tgz", + "integrity": "sha512-CO+SE4weOsfJf+C5LM8argzvotrXw252/ZU6SM2Tz63fEblhH1uuVaaO4ISYFuN4Q6BhTo7I3qIdi8ydUQCqhw==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "14.16.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@azure/msal-node/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", + "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.19.0" + } + }, + "node_modules/@types/ws": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.5.tgz", + "integrity": "sha512-yURCknZhvywvQItHMMmFSo+fq5arCUIyz/CVk7jD89MSai7dkaX8ufjCWp3NttLojoTVbcE72ri+be/TnEbMHw==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/adaptivecards": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/adaptivecards/-/adaptivecards-1.2.3.tgz", + "integrity": "sha512-amQ5OSW3OpIkrxVKLjxVBPk/T49yuOtnqs1z5ZPfZr0+OpTovzmiHbyoAGDIsu5SNYHwOZFp/3LGOnRaALFa/g==", + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", + "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/botbuilder": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.23.3.tgz", + "integrity": "sha512-1gDIQHHYosYBHGXMjvZEJDrcp3NGy3lzHBml5wn9PFqVuIk/cbsCDZs3KJ3g+aH/GGh4CH/ij9iQ2KbQYHAYKA==", + "license": "MIT", + "dependencies": { + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/msal-node": "^2.13.1", + "axios": "^1.8.2", + "botbuilder-core": "4.23.3", + "botbuilder-stdlib": "4.23.3-internal", + "botframework-connector": "4.23.3", + "botframework-schema": "4.23.3", + "botframework-streaming": "4.23.3", + "dayjs": "^1.11.13", + "filenamify": "^6.0.0", + "fs-extra": "^11.2.0", + "htmlparser2": "^9.0.1", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botbuilder-core": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.23.3.tgz", + "integrity": "sha512-48iW739I24piBH683b/Unvlu1fSzjB69ViOwZ0PbTkN2yW5cTvHJWlW7bXntO8GSqJfssgPaVthKfyaCW457ig==", + "license": "MIT", + "dependencies": { + "botbuilder-dialogs-adaptive-runtime-core": "4.23.3-preview", + "botbuilder-stdlib": "4.23.3-internal", + "botframework-connector": "4.23.3", + "botframework-schema": "4.23.3", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botbuilder-dialogs-adaptive-runtime-core": { + "version": "4.23.3-preview", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs-adaptive-runtime-core/-/botbuilder-dialogs-adaptive-runtime-core-4.23.3-preview.tgz", + "integrity": "sha512-EssyvqK9MobX3gbnUe/jjhLuxpCEeyQeQsyUFMJ236U6vzSQdrAxNH7Jc5DyZw2KKelBdK1xPBdwTYQNM5S0Qw==", + "license": "MIT", + "dependencies": { + "dependency-graph": "^1.0.0" + } + }, + "node_modules/botbuilder-stdlib": { + "version": "4.23.3-internal", + "resolved": "https://registry.npmjs.org/botbuilder-stdlib/-/botbuilder-stdlib-4.23.3-internal.tgz", + "integrity": "sha512-fwvIHnKU8sXo1gTww+m/k8wnuM5ktVBAV/3vWJ+ou40zapy1HYjWQuu6sVCRFgMUngpKwhdmoOQsTXsp58SNtA==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-http-compat": "^2.1.2", + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/core-tracing": "^1.2.0" + } + }, + "node_modules/botframework-connector": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botframework-connector/-/botframework-connector-4.23.3.tgz", + "integrity": "sha512-sChwCFJr3xhcMCYChaOxJoE8/YgdjOPWzGwz5JAxZDwhbQonwYX5O/6Z9EA+wB3TCFNEh642SGeC/rOitaTnGQ==", + "license": "MIT", + "dependencies": { + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/identity": "^4.4.1", + "@azure/msal-node": "^2.13.1", + "@types/jsonwebtoken": "9.0.6", + "axios": "^1.8.2", + "base64url": "^3.0.0", + "botbuilder-stdlib": "4.23.3-internal", + "botframework-schema": "4.23.3", + "buffer": "^6.0.3", + "cross-fetch": "^4.0.0", + "https-proxy-agent": "^7.0.5", + "jsonwebtoken": "^9.0.2", + "node-fetch": "^2.7.0", + "openssl-wrapper": "^0.3.4", + "rsa-pem-from-mod-exp": "^0.8.6", + "zod": "^3.23.8" + } + }, + "node_modules/botframework-schema": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.23.3.tgz", + "integrity": "sha512-/W0uWxZ3fuPLAImZRLnPTbs49Z2xMpJSIzIBxSfvwO0aqv9GsM3bTk3zlNdJ1xr40SshQ7WiH2H1hgjBALwYJw==", + "license": "MIT", + "dependencies": { + "adaptivecards": "1.2.3", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botframework-streaming": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/botframework-streaming/-/botframework-streaming-4.23.3.tgz", + "integrity": "sha512-GMtciQGfZXtAW6syUqFpFJQ2vDyVbpxL3T1DqFzq/GmmkAu7KTZ1zvo7PTww6+IT1kMW0lmL/XZJVq3Rhg4PQA==", + "license": "MIT", + "dependencies": { + "@types/ws": "^6.0.3", + "uuid": "^10.0.0", + "ws": "^7.5.10" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/builtins": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", + "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" + }, + "node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-compat-utils/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-config-standard": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", + "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", + "eslint-plugin-promise": "^6.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-n": { + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "builtins": "^5.0.1", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", + "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", + "is-core-module": "^2.12.1", + "minimatch": "^3.1.2", + "resolve": "^1.22.2", + "semver": "^7.5.3" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", + "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filename-reserved-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/filenamify": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-6.0.0.tgz", + "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemon": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz", + "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^10.2.1", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nodemon/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openssl-wrapper": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/openssl-wrapper/-/openssl-wrapper-0.3.4.tgz", + "integrity": "sha512-iITsrx6Ho8V3/2OVtmZzzX8wQaKAaFXEJQdzoPUZDtyf5jWFlqo+h+OhGT4TATQ47f9ACKHua8nw7Qoy85aeKQ==", + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rsa-pem-from-mod-exp": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.6.tgz", + "integrity": "sha512-c5ouQkOvGHF1qomUUDJGFcXsomeSO2gbEs6hVhMAtlkE1CuaZase/WzoaKFG/EZQuNmq6pw/EMCeEnDvOgCJYQ==", + "license": "MIT" + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/package.json b/samples/TeamsSDK/Archived/msgext-action/nodejs/package.json new file mode 100644 index 0000000000..a8d4a4c1ea --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/package.json @@ -0,0 +1,36 @@ +{ + "name": "teams-bot", + "version": "1.0.0", + "description": "Bot Builder v4 Bot Teams sample", + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev:teamsfx": "npm run dev", + "dev": "nodemon --inspect=9239 --signal SIGINT ./index.js", + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "build": "node build.js", + "lint": "eslint .", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples.git" + }, + "dependencies": { + "botbuilder": "^4.23.3", + "dotenv": "^16.6.1", + "ejs": "^3.1.10", + "express": "^4.22.1" + }, + "devDependencies": { + "esbuild": "^0.28.0", + "eslint": "^8.57.1", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-promise": "^6.6.0", + "nodemon": "^3.1.14" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/views/CustomForm.ejs b/samples/TeamsSDK/Archived/msgext-action/nodejs/views/CustomForm.ejs new file mode 100644 index 0000000000..9fbcccaec9 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/views/CustomForm.ejs @@ -0,0 +1,54 @@ + + + Microsoft Teams ME Action WebView + + + + + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/nodejs/views/StaticPage.ejs b/samples/TeamsSDK/Archived/msgext-action/nodejs/views/StaticPage.ejs new file mode 100644 index 0000000000..93e733f810 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/nodejs/views/StaticPage.ejs @@ -0,0 +1,35 @@ + + + Microsoft Teams ME Action StaticPage + + + + + +
+

+

+
+ + diff --git a/samples/TeamsSDK/Archived/msgext-action/python/.env b/samples/TeamsSDK/Archived/msgext-action/python/.env new file mode 100644 index 0000000000..9d36feb6bd --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/.env @@ -0,0 +1,4 @@ +MicrosoftAppId= +MicrosoftAppPassword= +MicrosoftAppType=SingleTenant +MicrosoftAppTenantId= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/.gitignore b/samples/TeamsSDK/Archived/msgext-action/python/.gitignore new file mode 100644 index 0000000000..e8442994dd --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/.gitignore @@ -0,0 +1,14 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +appManifest/build/ + +# python virtual environment +.venv/ + +# misc +.env +.deployment/ + +# tmp files +__pycache__/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/.pylintrc b/samples/TeamsSDK/Archived/msgext-action/python/.pylintrc new file mode 100644 index 0000000000..a134068ff8 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/.pylintrc @@ -0,0 +1,590 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-whitelist= + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS,build,botbuilder-schema,samples,django_tests,Generator,operations,operations_async,schema + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns=setup.py,azure_bdist_wheel.py + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use. +jobs=1 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=print-statement, + parameter-unpacking, + unpacking-in-except, + old-raise-syntax, + backtick, + long-suffix, + old-ne-operator, + old-octal-literal, + import-star-module-level, + non-ascii-bytes-literal, + raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + xrange-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + raising-string, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + deprecated-string-function, + deprecated-str-translate-call, + deprecated-itertools-function, + deprecated-types-field, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + deprecated-operator-function, + deprecated-urllib-function, + xreadlines-attribute, + deprecated-sys-function, + exception-escape, + comprehension-escape, + bad-continuation, + duplicate-code, + redefined-outer-name, + missing-docstring, + too-many-instance-attributes, + too-few-public-methods, + redefined-builtin, + too-many-arguments, + no-self-use, + fixme, + broad-except, + bare-except, + too-many-public-methods, + cyclic-import, + too-many-locals, + too-many-function-args, + too-many-return-statements, + import-error, + no-name-in-module, + too-many-branches + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit + + +[LOGGING] + +# Format style used to check logging format string. `old` means using % +# formatting, while `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package.. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=120 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. +#class-attribute-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. +#variable-rgx= + + +[STRING] + +# This flag controls whether the implicit-str-concat-in-sequence should +# generate a warning on implicit string concatenation in sequences defined over +# several lines. +check-str-concat-over-line-jumps=no + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules=optparse,tkinter.tix + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled). +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled). +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[DESIGN] + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement. +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "BaseException, Exception". +overgeneral-exceptions=BaseException, + Exception diff --git a/samples/TeamsSDK/Archived/msgext-action/python/.vscode/extensions.json b/samples/TeamsSDK/Archived/msgext-action/python/.vscode/extensions.json new file mode 100644 index 0000000000..bf8c33db9c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension", + "ms-python.python", + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/.vscode/launch.json b/samples/TeamsSDK/Archived/msgext-action/python/.vscode/launch.json new file mode 100644 index 0000000000..607a8fdbdd --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/.vscode/launch.json @@ -0,0 +1,69 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Python: Run App Locally", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/app.py", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/.vscode/settings.json b/samples/TeamsSDK/Archived/msgext-action/python/.vscode/settings.json new file mode 100644 index 0000000000..2e7a56f72f --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "debug.onTaskErrors": "abort" +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/.vscode/tasks.json b/samples/TeamsSDK/Archived/msgext-action/python/.vscode/tasks.json new file mode 100644 index 0000000000..253c1ead76 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/.vscode/tasks.json @@ -0,0 +1,78 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Prepare Teams App Resources", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/Images/1.InstallApp.png b/samples/TeamsSDK/Archived/msgext-action/python/Images/1.InstallApp.png new file mode 100644 index 0000000000..d3f27fc536 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/Images/1.InstallApp.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/Images/2.SelectMsgextAction.png b/samples/TeamsSDK/Archived/msgext-action/python/Images/2.SelectMsgextAction.png new file mode 100644 index 0000000000..a8bf957296 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/Images/2.SelectMsgextAction.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/Images/3.CardMsgextActionDetails.png b/samples/TeamsSDK/Archived/msgext-action/python/Images/3.CardMsgextActionDetails.png new file mode 100644 index 0000000000..93052eebe9 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/Images/3.CardMsgextActionDetails.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/Images/4.CardDetailsMsgextAction.png b/samples/TeamsSDK/Archived/msgext-action/python/Images/4.CardDetailsMsgextAction.png new file mode 100644 index 0000000000..635fbf6f36 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/Images/4.CardDetailsMsgextAction.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/Images/5.CardDetailsMsgextAction1.png b/samples/TeamsSDK/Archived/msgext-action/python/Images/5.CardDetailsMsgextAction1.png new file mode 100644 index 0000000000..6adae96585 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/Images/5.CardDetailsMsgextAction1.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/Images/5.CardDetailsMsgextAction2.png b/samples/TeamsSDK/Archived/msgext-action/python/Images/5.CardDetailsMsgextAction2.png new file mode 100644 index 0000000000..516f52ffc0 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/Images/5.CardDetailsMsgextAction2.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/Images/MsgExtAction.gif b/samples/TeamsSDK/Archived/msgext-action/python/Images/MsgExtAction.gif new file mode 100644 index 0000000000..747fb287f4 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/Images/MsgExtAction.gif differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/README.md b/samples/TeamsSDK/Archived/msgext-action/python/README.md new file mode 100644 index 0000000000..a9a1cdda8f --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/README.md @@ -0,0 +1,155 @@ +--- +page_type: sample +description: This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality. +products: +- office-teams +- office +- office-365 +languages: +- python +extensions: + contentType: samples + createdDate: "12-12-2019 13:38:25" +urlFragment: officedev-microsoft-teams-samples-bot-msgext-action-python +--- + +# Teams Messaging Extensions Action + +Explore the capabilities of Action-Based Messaging Extensions in Microsoft Teams with this sample app. It showcases how to implement interactive features, including bots and message extensions, allowing users to create content dynamically through a user-friendly interface. + +[Messaging Extensions](https://docs.microsoft.com/microsoftteams/platform/messaging-extensions/what-are-messaging-extensions) are a special kind of Microsoft Teams application that is support by the [Bot Framework](https://dev.botframework.com) v4. + +There are two basic types of Messaging Extension in Teams: [Search-based](https://docs.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/search-commands/define-search-command) and [Action-based](https://docs.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/action-commands/define-action-command). This sample illustrates how to +build an Action-based Messaging Extension. + +## Included Features +* Bots +* Message Extensions +* Action Commands + +- **Interaction with Messaging Extension** +![MsgExtAction](Images/MsgExtAction.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app manifest (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Teams Messaging Extensions Action:** [Manifest](/samples/msgext-action/csharp/demo-manifest/msgext-action.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account +- [Python SDK](https://www.python.org/downloads/) version 3.7 +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution +- [Python SDK](https://www.python.org/downloads/) min version 3.11 + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) and [Python Extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Press **CTRL+Shift+P** to open the command box and enter **Python: Create Environment** to create and activate your desired virtual environment. Remember to select `requirements.txt` as dependencies to install when creating the virtual environment. +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Run the app (Manually Uploading to Teams) + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +the Teams service needs to call into the bot. + +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +1) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +2) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +3) Create [Bot Framework registration resource](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration) in Azure + - Use the current `https` URL you were given by running the tunnelling application. Append with the path `/api/messages` used by this sample + - Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - __*If you don't have an Azure account*__ you can use this [Bot Framework registration](https://docs.microsoft.com/microsoftteams/platform/bots/how-to/create-a-bot-for-teams#register-your-web-service-with-the-bot-framework) + +1) Bring up a terminal, navigate to `Microsoft-Teams-Samples\samples\msgext-action\python` folder + +1) Activate your desired virtual environment + +1) Install dependencies by running ```pip install -r requirements.txt``` in the project folder. + +1) Update the `config.py` configuration for the bot to use the Microsoft App Id and App Password from the Bot Framework registration. (Note the App Password is referred to as the "client secret" in the azure portal and you can always create a new client secret anytime.) + +1) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appManifest` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `{{AAD_APP_CLIENT_ID}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` with base Url domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + - **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.) + - Add the bot to personal/team/groupChat scope (Supported scopes) + +1) Run your bot with `python app.py` + +## Running the sample + +> Note this `manifest.json` specified that the bot will be called from both the `compose` and `message` areas of Teams. Please refer to Teams documentation for more details. Also note this bot does not process incoming Messages, but responds only to Messaging Extension commands. + +1) Selecting the **Create Card** command from the Compose Box command list. The parameters dialog will be displayed and can be submitted to initiate the card creation within the Messaging Extension code. + +or + +2) Selecting the **Share Message** command from the Message command list. + +![1.InstallApp](Images/1.InstallApp.png) + +![2.SelectMsgextAction](Images/2.SelectMsgextAction.png) + +![3.CardMsgextActionDetails ](Images/3.CardMsgextActionDetails.png) + +![4.CardDetailsMsgextAction](Images/4.CardDetailsMsgextAction.png) + +![5.CardDetailsMsgextAction1](Images/5.CardDetailsMsgextAction1.png) + +![5.CardDetailsMsgextAction2](Images/5.CardDetailsMsgextAction2.png) + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +# Further reading + +- [Messaging extension action](https://learn.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/action-commands/define-action-command) +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/aad.manifest.json b/samples/TeamsSDK/Archived/msgext-action/python/aad.manifest.json new file mode 100644 index 0000000000..463b6d23f5 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/aad.manifest.json @@ -0,0 +1,100 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "displayName": "msgext-action-aad", + "signInAudience": "AzureADMyOrg", + "api": { + "requestedAccessTokenVersion": 2, + "oauth2PermissionScopes": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ] + }, + "info": {}, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "publicClient": {}, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "web": { + "implicitGrantSettings": {} + }, + "spa": {} +} diff --git a/samples/TeamsSDK/Archived/msgext-action/python/app.py b/samples/TeamsSDK/Archived/msgext-action/python/app.py new file mode 100644 index 0000000000..717f46ed2c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/app.py @@ -0,0 +1,69 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import sys +import traceback +from datetime import datetime, timezone + +from aiohttp import web +from aiohttp.web import Request, Response +from botbuilder.core import ( + TurnContext, +) +from botbuilder.core.integration import aiohttp_error_middleware +from botbuilder.integration.aiohttp import CloudAdapter, ConfigurationBotFrameworkAuthentication +from botbuilder.schema import Activity, ActivityTypes +from bots import TeamsMessagingExtensionsActionBot +from config import DefaultConfig + +CONFIG = DefaultConfig() + +# Create adapter. +# See https://aka.ms/about-bot-adapter to learn more about how bots work. +ADAPTER = CloudAdapter(ConfigurationBotFrameworkAuthentication(CONFIG)) + + +# Catch-all for errors. +async def on_error(context: TurnContext, error: Exception): + # This check writes out errors to console log .vs. app insights. + # NOTE: In production environment, you should consider logging this to Azure + # application insights. + print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr) + traceback.print_exc() + + # Send a message to the user + await context.send_activity("The bot encountered an error or bug.") + await context.send_activity( + "To continue to run this bot, please fix the bot source code." + ) + # Send a trace activity if we're talking to the Bot Framework Emulator + if context.activity.channel_id == "emulator": + # Create a trace activity that contains the error object + trace_activity = Activity( + label="TurnError", + name="on_turn_error Trace", + timestamp=datetime.now(timezone.utc), + type=ActivityTypes.trace, + value=f"{error}", + value_type="https://www.botframework.com/schemas/error", + ) + # Send a trace activity, which will be displayed in Bot Framework Emulator + await context.send_activity(trace_activity) + + +ADAPTER.on_turn_error = on_error + +# Create the Bot +BOT = TeamsMessagingExtensionsActionBot() + + +# Listen for incoming requests on /api/messages +async def messages(req: Request) -> Response: + return await ADAPTER.process(req, BOT) + + +APP = web.Application(middlewares=[aiohttp_error_middleware]) +APP.router.add_post("/api/messages", messages) + +if __name__ == "__main__": + web.run_app(APP, host="localhost", port=CONFIG.PORT) diff --git a/samples/TeamsSDK/Archived/msgext-action/python/appManifest/color.png b/samples/TeamsSDK/Archived/msgext-action/python/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/appManifest/manifest.json b/samples/TeamsSDK/Archived/msgext-action/python/appManifest/manifest.json new file mode 100644 index 0000000000..d7ede745f7 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/appManifest/manifest.json @@ -0,0 +1,80 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.20/MicrosoftTeams.schema.json", + "manifestVersion": "1.20", + "version": "1.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://dev.botframework.com", + "privacyUrl": "https://privacy.microsoft.com", + "termsOfUseUrl": "https://www.microsoft.com/en-us/legal/intellectualproperty/copyright/default.aspx" + }, + "name": { + "short": "Action Messaging Extension", + "full": "Microsoft Teams Action Based Messaging Extension" + }, + "description": { + "short": "This sample app illustrates how to implement Action-Based Messaging Extensions.", + "full": "This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "accentColor": "#FFFFFF", + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "commands": [ + { + "id": "createCard", + "type": "action", + "context": [ "compose" ], + "description": "Command to run action to create a Card from Compose Box", + "title": "Create Card", + "parameters": [ + { + "name": "title", + "title": "Card title", + "description": "Title for the card", + "inputType": "text" + }, + { + "name": "subTitle", + "title": "Subtitle", + "description": "Subtitle for the card", + "inputType": "text" + }, + { + "name": "text", + "title": "Text", + "description": "Text for the card", + "inputType": "textarea" + } + ] + }, + { + "id": "shareMessage", + "type": "action", + "context": [ "message" ], + "description": "Test command to run action on message context (message sharing)", + "title": "Share Message", + "parameters": [ + { + "name": "includeImage", + "title": "Include Image", + "description": "Include image in Hero Card", + "inputType": "toggle" + } + ] + } + ] + } + ], + "permissions": [ + "identity" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/appManifest/outline.png b/samples/TeamsSDK/Archived/msgext-action/python/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-action/python/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/msgext-action/python/assets/sample.json b/samples/TeamsSDK/Archived/msgext-action/python/assets/sample.json new file mode 100644 index 0000000000..87cc80e171 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-msgext-action-csharp", + "source": "officeDev", + "title": "Action Based Messaging Extensions", + "shortDescription": "This sample app illustrates how to implement Action-Based Messaging Extensions.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/msgext-action/python", + "longDescription": [ + "This sample demonstrates how to create Action-Based Messaging Extensions for Microsoft Teams, enabling users to interactively generate content. It features bots, message extensions, and seamless integration with user inputs for enhanced functionality." + ], + "creationDateTime": "2019-10-17", + "updateDateTime": "2024-10-11", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "python" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "python" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot,ME" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/msgext-action/python/Images/MsgExtAction.gif", + "alt": "Solution UX showing action based Messaging Extensions" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/bots/__init__.py b/samples/TeamsSDK/Archived/msgext-action/python/bots/__init__.py new file mode 100644 index 0000000000..daea6bcda7 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/bots/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from .teams_messaging_extensions_action_bot import TeamsMessagingExtensionsActionBot + +__all__ = ["TeamsMessagingExtensionsActionBot"] diff --git a/samples/TeamsSDK/Archived/msgext-action/python/bots/teams_messaging_extensions_action_bot.py b/samples/TeamsSDK/Archived/msgext-action/python/bots/teams_messaging_extensions_action_bot.py new file mode 100644 index 0000000000..b1feecf620 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/bots/teams_messaging_extensions_action_bot.py @@ -0,0 +1,86 @@ +# Copyright (c) Microsoft Corp. All rights reserved. +# Licensed under the MIT License. + +from botbuilder.core import ( + CardFactory, + TurnContext, +) +from botbuilder.schema import HeroCard, CardImage +from botbuilder.schema.teams import ( + MessagingExtensionAction, + MessagingExtensionActionResponse, + MessagingExtensionAttachment, + MessagingExtensionResult, +) +from botbuilder.core.teams import TeamsActivityHandler + + +class TeamsMessagingExtensionsActionBot(TeamsActivityHandler): + async def on_teams_messaging_extension_submit_action_dispatch( + self, turn_context: TurnContext, action: MessagingExtensionAction + ) -> MessagingExtensionActionResponse: + if action.command_id == "createCard": + return await self.create_card_command(turn_context, action) + if action.command_id == "shareMessage": + return await self.share_message_command(turn_context, action) + + raise NotImplementedError(f"Unexpected action.command_id {action.command_id}.") + + async def create_card_command( + self, + turn_context: TurnContext, # pylint: disable=unused-argument + action: MessagingExtensionAction, + ) -> MessagingExtensionActionResponse: + title = action.data["title"] + sub_title = action.data["subTitle"] + text = action.data["text"] + + card = HeroCard(title=title, subtitle=sub_title, text=text) + attachment = MessagingExtensionAttachment( + content=card, + content_type=CardFactory.content_types.hero_card, + preview=CardFactory.hero_card(card), + ) + attachments = [attachment] + + extension_result = MessagingExtensionResult( + attachment_layout="list", type="result", attachments=attachments + ) + return MessagingExtensionActionResponse(compose_extension=extension_result) + + async def share_message_command( + self, + turn_context: TurnContext, # pylint: disable=unused-argument + action: MessagingExtensionAction, + ) -> MessagingExtensionActionResponse: + # The user has chosen to share a message by choosing the 'Share Message' context menu command. + title = f"{action.message_payload.from_property.user.display_name} originally sent this message:" + text = action.message_payload.body.content + card = HeroCard(title=title, text=text) + + if action.message_payload.attachments is not None: + # This sample does not add the MessagePayload Attachments. This is left as an + # exercise for the user. + card.subtitle = ( + f"({len(action.message_payload.attachments)} Attachments not included)" + ) + + # This Messaging Extension example allows the user to check a box to include an image with the + # shared message. This demonstrates sending custom parameters along with the message payload. + include_image = action.data["includeImage"] + if include_image == "true": + image = CardImage( + url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU" + ) + card.images = [image] + + attachment = MessagingExtensionAttachment( + content=card, + content_type=CardFactory.content_types.hero_card, + preview=CardFactory.hero_card(card), + ) + + extension_result = MessagingExtensionResult( + attachment_layout="list", type="result", attachments=[attachment] + ) + return MessagingExtensionActionResponse(compose_extension=extension_result) diff --git a/samples/TeamsSDK/Archived/msgext-action/python/config.py b/samples/TeamsSDK/Archived/msgext-action/python/config.py new file mode 100644 index 0000000000..952cbbe389 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/config.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os + + +class DefaultConfig: + """ Bot Configuration """ + + PORT = 3978 + APP_ID = os.environ.get("MicrosoftAppId", "") + APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "") + APP_TYPE = os.environ.get("MicrosoftAppType", "") + APP_TENANTID = os.environ.get("MicrosoftAppTenantId", "") diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json new file mode 100644 index 0000000000..cc1800c0db --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json new file mode 100644 index 0000000000..54a7d62890 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "value": "" + }, + "existingAppServicePlanName": { + "value": "" + }, + "existingAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanLocation": { + "value": "West US" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/readme.md b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/readme.md new file mode 100644 index 0000000000..c86cbf9db7 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/readme.md @@ -0,0 +1,26 @@ +# Usage +BotApp must be deployed prior to AzureBot. + +### Command line: +`az login`
+`az deployment group create --resource-group --template-file --parameters @` + +## Parameters for template-BotApp-with-rg.json: + +- **appServiceName**: (required) The Name of the Bot App Service. +- (Pick an existing App Service Plan or create a new App Service Plan.) + - **existingAppServicePlanName**: The name of the App Service Plan. + - **existingAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanName**: The name of the App Service Plan. + - **newAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**: (required) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. + +## Parameters for template-AzureBot-with-rg.json: + +- **azureBotId**: (required) The globally unique and immutable bot ID. +- **azureBotSku**: The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default). +- **azureBotRegion**: Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope. +- **botEndpoint**: Use to handle client messages, Such as `https://.azurewebsites.net/api/messages`. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json new file mode 100644 index 0000000000..60c9c1bb6c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default)." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope." + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]" + }, + "resources": [ + { + "apiVersion": "2021-05-01-preview", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "name": "[parameters('azureBotId')]", + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json new file mode 100644 index 0000000000..3a44abf249 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json @@ -0,0 +1,210 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "type": "string", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "existingAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "existingAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types. Defaults to \"\"." + } + } + }, + "variables": { + "useExistingServicePlan": "[not(empty(parameters('existingAppServicePlanName')))]", + "servicePlanName": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanName'), parameters('newAppServicePlanName'))]", + "servicePlanLocation": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanLocation'), parameters('newAppServicePlanLocation'))]" + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[parameters('newAppServicePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('servicePlanName')]", + "perSiteScaling": false, + "reserved": true, + "targetWorkerCount": 0, + "targetWorkerSizeId": 0 + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "name": "[parameters('appServiceName')]", + "location": "[variables('servicePlanLocation')]", + "kind": "app,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]" + ], + "properties": { + "enabled": true, + "hostNameSslStates": [ + { + "name": "[concat(parameters('appServiceName'), '.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Standard" + }, + { + "name": "[concat(parameters('appServiceName'), '.scm.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Repository" + } + ], + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]", + "reserved": true, + "scmSiteAlsoStopped": false, + "clientAffinityEnabled": false, + "clientCertEnabled": false, + "hostNamesDisabled": false, + "containerSize": 0, + "dailyMemoryTimeQuota": 0, + "httpsOnly": false, + "siteConfig": { + "appSettings": [ + { + "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", + "value": "true" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "type": "Microsoft.Web/sites/config", + "apiVersion": "2016-08-01", + "name": "[concat(parameters('appServiceName'), '/web')]", + "location": "[variables('servicePlanLocation')]", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites', parameters('appServiceName'))]" + ], + "properties": { + "numberOfWorkers": 1, + "defaultDocuments": [ + "Default.htm", + "Default.html", + "Default.asp", + "index.htm", + "index.html", + "iisstart.htm", + "default.aspx", + "index.php", + "hostingstart.html" + ], + "netFrameworkVersion": "v4.0", + "phpVersion": "", + "pythonVersion": "", + "nodeVersion": "", + "linuxFxVersion": "PYTHON|3.7", + "requestTracingEnabled": false, + "remoteDebuggingEnabled": false, + "remoteDebuggingVersion": "VS2017", + "httpLoggingEnabled": true, + "logsDirectorySizeLimit": 35, + "detailedErrorLoggingEnabled": false, + "publishingUsername": "[concat('$', parameters('appServiceName'))]", + "scmType": "None", + "use32BitWorkerProcess": true, + "webSocketsEnabled": false, + "alwaysOn": false, + "appCommandLine": "gunicorn --bind 0.0.0.0 --worker-class aiohttp.worker.GunicornWebWorker --timeout 600 app:APP", + "managedPipelineMode": "Integrated", + "virtualApplications": [ + { + "virtualPath": "/", + "physicalPath": "site\\wwwroot", + "preloadEnabled": false, + "virtualDirectories": null + } + ], + "winAuthAdminState": 0, + "winAuthTenantState": 0, + "customAppPoolIdentityAdminState": false, + "customAppPoolIdentityTenantState": false, + "loadBalancing": "LeastRequests", + "routingRules": [], + "experiments": { + "rampUpRules": [] + }, + "autoHealEnabled": false, + "vnetName": "", + "minTlsVersion": "1.2", + "ftpsState": "AllAllowed", + "reservedInstanceCount": 0 + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json new file mode 100644 index 0000000000..f180618138 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json new file mode 100644 index 0000000000..f3f07b4972 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "appServiceName": { + "value": "" + }, + "appServicePlanName": { + "value": "" + }, + "appServicePlanLocation": { + "value": "" + }, + "appServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/readme.md b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/readme.md new file mode 100644 index 0000000000..dbdfabf9a9 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/readme.md @@ -0,0 +1,27 @@ +# Usage +BotApp must be deployed prior to AzureBot. + +### Command line: +`az login`
+`az deployment sub create --template-file --location --parameters @` + +## Parameters for template-BotApp-new-rg.json: + +- **groupName**: (required) The name of the new Resource Group. +- **groupLocation**: (required) The location of the new Resource Group. +- **appServiceName**: (required) The location of the App Service Plan. +- **appServicePlanName**: (required) The name of the App Service Plan. +- **appServicePlanLocation**: The location of the App Service Plan. Defaults to use groupLocation. +- **appServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**: (required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. + +## Parameters for template-AzureBot-new-rg.json: + +- **groupName**: (required) The name of the new Resource Group. +- **groupLocation**: (required) The location of the new Resource Group. +- **azureBotId**: (required) The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable. +- **azureBotSku**: The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default). +- **azureBotRegion**: Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope. +- **botEndpoint**: Use to handle client messages, Such as `https://.azurewebsites.net/api/messages`. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json new file mode 100644 index 0000000000..927307e0fc --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json @@ -0,0 +1,104 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "" + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "apiVersion": "2021-03-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "name": "[parameters('azureBotId')]", + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json new file mode 100644 index 0000000000..612112a32b --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json @@ -0,0 +1,227 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "appServiceName": { + "type": "string", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "appServicePlanName": { + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "appServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "appServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types." + } + } + }, + "variables": { + "appServicePlanName": "[parameters('appServicePlanName')]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), parameters('groupLocation'), parameters('appServicePlanLocation'))]", + "appServiceName": "[parameters('appServiceName')]", + "resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('appServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('appServicePlanName')]", + "perSiteScaling": false, + "reserved": true, + "targetWorkerCount": 0, + "targetWorkerSizeId": 0 + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app,linux", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('appServiceName')]", + "properties": { + "name": "[variables('appServiceName')]", + "hostNameSslStates": [ + { + "name": "[concat(parameters('appServiceName'), '.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Standard" + }, + { + "name": "[concat(parameters('appServiceName'), '.scm.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Repository" + } + ], + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", + "value": "true" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + }, + { + "type": "Microsoft.Web/sites/config", + "apiVersion": "2016-08-01", + "name": "[concat(parameters('appServiceName'), '/web')]", + "location": "[variables('resourcesLocation')]", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', parameters('appServiceName'))]" + ], + "properties": { + "numberOfWorkers": 1, + "defaultDocuments": [ + "Default.htm", + "Default.html", + "Default.asp", + "index.htm", + "index.html", + "iisstart.htm", + "default.aspx", + "index.php", + "hostingstart.html" + ], + "netFrameworkVersion": "v4.0", + "phpVersion": "", + "pythonVersion": "", + "nodeVersion": "", + "linuxFxVersion": "PYTHON|3.7", + "requestTracingEnabled": false, + "remoteDebuggingEnabled": false, + "remoteDebuggingVersion": "VS2017", + "httpLoggingEnabled": true, + "logsDirectorySizeLimit": 35, + "detailedErrorLoggingEnabled": false, + "publishingUsername": "[concat('$', parameters('appServiceName'))]", + "scmType": "None", + "use32BitWorkerProcess": true, + "webSocketsEnabled": false, + "alwaysOn": false, + "appCommandLine": "gunicorn --bind 0.0.0.0 --worker-class aiohttp.worker.GunicornWebWorker --timeout 600 app:APP", + "managedPipelineMode": "Integrated", + "virtualApplications": [ + { + "virtualPath": "/", + "physicalPath": "site\\wwwroot", + "preloadEnabled": false, + "virtualDirectories": null + } + ], + "winAuthAdminState": 0, + "winAuthTenantState": 0, + "customAppPoolIdentityAdminState": false, + "customAppPoolIdentityTenantState": false, + "loadBalancing": "LeastRequests", + "routingRules": [], + "experiments": { + "rampUpRules": [] + }, + "autoHealEnabled": false, + "vnetName": "", + "minTlsVersion": "1.2", + "ftpsState": "AllAllowed", + "reservedInstanceCount": 0 + } + } + ], + "outputs": {} + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/env/.env.local b/samples/TeamsSDK/Archived/msgext-action/python/env/.env.local new file mode 100644 index 0000000000..6cbc235aa2 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/env/.env.local @@ -0,0 +1,22 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +APP_NAME_SUFFIX= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/infra/azure.bicep b/samples/TeamsSDK/Archived/msgext-action/python/infra/azure.bicep new file mode 100644 index 0000000000..98e1027752 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAadAppTenantId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: 'SingleTenant' + msaAppTenantId: botAadAppTenantId + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/msgext-action/python/infra/azure.parameters.json b/samples/TeamsSDK/Archived/msgext-action/python/infra/azure.parameters.json new file mode 100644 index 0000000000..6b3f8124e0 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/infra/azure.parameters.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAadAppTenantId": { + "value": "${{AAD_APP_TENANT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "msgext-action" + } + } + } \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/m365agents.local.yml b/samples/TeamsSDK/Archived/msgext-action/python/m365agents.local.yml new file mode 100644 index 0000000000..f2dca90dae --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/m365agents.local.yml @@ -0,0 +1,88 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-action-python + +provision: + # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + - uses: aadApp/create + with: + name: msgext-action-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # SingleTenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: msgext-action${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + +deploy: + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: SingleTenant + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-action/python/m365agents.yml b/samples/TeamsSDK/Archived/msgext-action/python/m365agents.yml new file mode 100644 index 0000000000..ee992fae84 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-action-python + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/msgext-action/python/requirements.txt b/samples/TeamsSDK/Archived/msgext-action/python/requirements.txt new file mode 100644 index 0000000000..4f83249bb0 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-action/python/requirements.txt @@ -0,0 +1 @@ +botbuilder-integration-aiohttp==4.17.1 diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.env b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.env new file mode 100644 index 0000000000..df5b75c579 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.env @@ -0,0 +1,6 @@ +BotId={TODO: BOT_ID} +BotPassword={TODO: BOT_PASSWORD} +MicrosoftAppId= +MicrosoftAppPassword= +MicrosoftAppTenantId= +MicrosoftAppType=SingleTenant \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.gitignore b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.gitignore new file mode 100644 index 0000000000..8f78731e17 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appManifest/build +/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store + +# build +lib/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/extensions.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/extensions.json new file mode 100644 index 0000000000..2d88dee21b --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/launch.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/launch.json new file mode 100644 index 0000000000..d027ed91e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/launch.json @@ -0,0 +1,73 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Local Service", + "type": "node", + "request": "attach", + "port": 9239, + "restart": true, + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/settings.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/settings.json new file mode 100644 index 0000000000..4299620253 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/tasks.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/tasks.json new file mode 100644 index 0000000000..3356f91c1b --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/.vscode/tasks.json @@ -0,0 +1,105 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Teams App Locally", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy", + "Start application" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "nodejs", // Validate if Node.js is installed. + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + 9239 // app inspector port for Node.js debugger + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + }, + { + "label": "Start application", + "type": "shell", + "command": "npm run dev:teamsfx", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": { + "pattern": [ + { + "regexp": "^.*$", + "file": 0, + "location": 1, + "message": 2 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "[nodemon] starting", + "endsPattern": "Service listening at http://localhost:" + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OpenAppIcon.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OpenAppIcon.png new file mode 100644 index 0000000000..7e7c6363dc Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OpenAppIcon.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OpenNewMail.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OpenNewMail.png new file mode 100644 index 0000000000..e5637b593c Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OpenNewMail.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OutputInOutlook.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OutputInOutlook.png new file mode 100644 index 0000000000..7d4f0bb3ec Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/OutputInOutlook.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/SearchInExtension.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/SearchInExtension.png new file mode 100644 index 0000000000..641bc96033 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/SearchInExtension.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/msgextsearchquickstart.gif b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/msgextsearchquickstart.gif new file mode 100644 index 0000000000..884350a7f7 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/msgextsearchquickstart.gif differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/result.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/result.png new file mode 100644 index 0000000000..5198b9d302 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/result.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/search.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/search.png new file mode 100644 index 0000000000..092ebe8f4b Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/Images/search.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/README.md b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/README.md new file mode 100644 index 0000000000..bca4e59290 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/README.md @@ -0,0 +1,166 @@ +--- +page_type: sample +description: This sample demonstrates a simple JavaScript-based Messaging Extension that accepts search requests and returns results within Microsoft Teams. +products: +- office-teams +- office +- office-365 +languages: +- javascript +- nodejs +extensions: + contentType: samples + createdDate: "07/07/2021 01:38:27 PM" +urlFragment: officedev-microsoft-teams-samples-msgext-search-quickstart-js +--- + +# Messaging Extension quick start + +This comprehensive JavaScript quick start sample illustrates the creation of a Messaging Extension in Microsoft Teams designed to process search requests from users. By enabling interactions through buttons and forms, it facilitates direct communication with your web service, enhancing user experience within the Teams environment. + +*Bots* allow users to interact with your web service through text, interactive cards, and task modules. *Messaging extensions* allow users to interact with your web service through buttons and forms in the Microsoft Teams client. They can search, or initiate actions, in an external system from the compose message area, the command box, or directly from a message. + +## Included Features +* Bots +* Message Extensions +* Search Commands + +## Interaction with app + +![Sample Module](Images/msgextsearchquickstart.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Messaging Extension quick start:** [Manifest](/samples/msgext-search-quickstart/js/demo-manifest/msgext-search-quickstart.zip) + +## Prerequisites + +**Dependencies** +- [NodeJS](https://nodejs.org/en/) +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/download) latest version or equivalent tunneling solution +- [M365 developer account](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the appropriate permissions to install an app. +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + + 1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + + 2. Azure Bot [Azure Bot] (https://learn.microsoft.com/azure/bot-service/abs-quickstart?view=azure-bot-service-4.0&tabs=userassigned) + +- For the Messaging endpoint URL, use the current `https` URL you were given by running the tunnelling application and append it with the path `/api/messages`. It should like something work `https://{subdomain}.ngrok-free.app/api/messages`. + +- Click on the `Bots` menu item from the toolkit and select the bot you are using for this project. Update the messaging endpoint and press enter to save the value in the Bot Framework. + +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + + 3. Setup NGROK + - Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +4) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +5. Setup for code + - Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + + - In a terminal, navigate to `samples/msgext-search-quickstart/js` + + - Update the `.env` configuration for the bot to use the `MicrosoftAppId` and `MicrosoftAppPassword`, `BaseUrl` with application base url. For e.g., your ngrok or dev tunnels url. (Note the MicrosoftAppId is the AppId created in step 1 (Setup for Bot), the MicrosoftAppPassword is referred to as the "client secret" in step 1 (Setup for Bot) and you can always create a new client secret anytime.) + + - Run your app + + ```bash + npm start + ``` + +6. Setup Manifest for Teams +- __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the ./appManifest folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `{{Microsoft-App-Id}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` and replace `{{domain-name}}` with base Url of your domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appManifest folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your app is uploaded to Teams. + +## Running the sample + +![Search](Images/search.png) + +![Result](Images/result.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**After opening Outlook web, click the "New mail" button.** + +![Open New Mail](Images/OpenNewMail.png) + +**on the tool bar on top,select Apps icon. Your uploaded app title appears among your installed apps** + +![OpenAppIcon](Images/OpenAppIcon.png) + +**Select your app icon to launch your app in Office on the web** + +![Search in Extension](Images/SearchInExtension.png) + +![Output in Outlook](Images/OutputInOutlook.png) + +## Deploy to Teams +Start debugging the project by hitting the `F5` key or click the debug icon in Visual Studio Code and click the `Start Debugging` green arrow button. + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) +- [Search based messaging extension](https://learn.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/search-commands/define-search-command) \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/aad.manifest.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/aad.manifest.json new file mode 100644 index 0000000000..e93ee80a1f --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/aad.manifest.json @@ -0,0 +1,32 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "msgext-search-quickstart-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMyOrg", + "oauth2AllowIdTokenImplicitFlow": true, + "oauth2AllowImplicitFlow": true, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/color.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/manifest.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/manifest.json new file mode 100644 index 0000000000..6dbdfa6fa1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/manifest.json @@ -0,0 +1,60 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Teams App, Inc.", + "websiteUrl": "https://${{BOT_DOMAIN}}", + "privacyUrl": "https://${{BOT_DOMAIN}}/privacy", + "termsOfUseUrl": "https://${{BOT_DOMAIN}}/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Messaging Extension Search", + "full": "" + }, + "description": { + "short": "Messaging Extension quick start for handling search requests.", + "full": "This sample demonstrates a simple JavaScript-based Messaging Extension that accepts search requests and returns results within Microsoft Teams." + }, + "accentColor": "#FFFFFF", + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "canUpdateConfiguration": true, + "commands": [ + { + "id": "searchQuery", + "type": "query", + "title": "Search", + "description": "Test command to run query", + "initialRun": false, + "fetchTask": false, + "context": [ + "compose", + "commandBox" + ], + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Your search query", + "inputType": "text" + } + ] + } + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/outline.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/assets/sample.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/assets/sample.json new file mode 100644 index 0000000000..6d0b01da85 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-msgext-search-quickstart-js", + "source": "officeDev", + "title": "Search messaging extension", + "shortDescription": "This sample demonstrates a simple JavaScript-based Messaging Extension that accepts search requests and returns results within Microsoft Teams.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/msgext-search-quickstart/js", + "longDescription": [ + "This JavaScript quick start sample showcases how to create a Messaging Extension in Microsoft Teams that handles user search queries. It allows users to interact with your web service through the Teams client, providing seamless search functionality." + ], + "creationDateTime": "2021-07-07", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "msgext" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/msgext-search-quickstart/js/Images/msgext-search-quickstart.gif", + "alt": "Solution UX showing search messaging extension" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/botActivityHandler.js b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/botActivityHandler.js new file mode 100644 index 0000000000..734b06e450 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/botActivityHandler.js @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { TeamsActivityHandler, CardFactory } = require('botbuilder'); +const axios = require('axios'); + +class BotActivityHandler extends TeamsActivityHandler { + /* Building a messaging extension search command is a two step process. + (1) Define how the messaging extension will look and be invoked in the client. + This can be done from the Configuration tab, or the Manifest Editor. + Learn more: https://aka.ms/teams-me-design-search. + (2) Define how the bot service will respond to incoming search commands. + Learn more: https://aka.ms/teams-me-respond-search. + + NOTE: Ensure the bot endpoint that services incoming messaging extension queries is + registered with Bot Framework. + Learn more: https://aka.ms/teams-register-bot. + */ + + // Invoked when the service receives an incoming search query. + async handleTeamsMessagingExtensionQuery(context, query) { + const searchQuery = query.parameters[0].value; + const queryParams = new URLSearchParams({ text: searchQuery, size: 8 }); + const response = await axios.get(`http://registry.npmjs.com/-/v1/search?${queryParams}`); + + const attachments = []; + response.data.objects.forEach(obj => { + const heroCard = CardFactory.heroCard(obj.package.name); + const preview = CardFactory.heroCard(obj.package.name); // Preview cards are optional for Hero card. You need them for Adaptive Cards. + preview.content.tap = { type: 'invoke', value: { description: obj.package.description } }; + const attachment = { ...heroCard, preview }; + attachments.push(attachment); + }); + + return { + composeExtension: { + type: 'result', + attachmentLayout: 'list', + attachments: attachments + } + }; + } + + // Invoked when the user selects an item from the search result list returned above. + async handleTeamsMessagingExtensionSelectItem(context, obj) { + return { + composeExtension: { + type: 'result', + attachmentLayout: 'list', + attachments: [CardFactory.thumbnailCard(obj.description)] + } + }; + } + + /* Messaging Extension - Unfurling Link */ + handleTeamsAppBasedLinkQuery(context, query) { + const attachment = CardFactory.thumbnailCard('Thumbnail Card', + query.url, + ['https://raw.githubusercontent.com/microsoft/botframework-sdk/master/icon.png']); + + const result = { + attachmentLayout: 'list', + type: 'result', + attachments: [attachment] + }; + + const response = { + composeExtension: result + }; + return response; + } + /* Messaging Extension - Unfurling Link */ +} + +module.exports.BotActivityHandler = BotActivityHandler; + diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/build.js b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/build.js new file mode 100644 index 0000000000..a59684a045 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/build.js @@ -0,0 +1,14 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js' +}) + .then((r) => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/demo-manifest/msgext-search-quickstart.zip b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/demo-manifest/msgext-search-quickstart.zip new file mode 100644 index 0000000000..fee5376e4c Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/demo-manifest/msgext-search-quickstart.zip differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/env/.env.local b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/env/.env.local new file mode 100644 index 0000000000..d1477bbe03 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/env/.env.local @@ -0,0 +1,21 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +MICROSOFT_APP_TYPE=SingleTenant +MICROSOFT_APP_TENANT_ID= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +APP_NAME_SUFFIX=local \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/index.js b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/index.js new file mode 100644 index 0000000000..ce6bab3c47 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/index.js @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// index.js is used to setup and configure your bot + +// Import required packages +const path = require('path'); +const express = require('express'); + +// Import required bot services. +// See https://aka.ms/bot-services to learn more about the different parts of a bot. +const { + CloudAdapter, + ConfigurationBotFrameworkAuthentication +} = require('botbuilder') + +// Import bot definitions +const { BotActivityHandler } = require('./botActivityHandler'); + +// Load environment variables from .env file. +const ENV_FILE = path.join(__dirname, '.env'); +require('dotenv').config({ path: ENV_FILE }); + +// Create adapter. +// See https://aka.ms/about-bot-adapter to learn more about adapters. +const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env); +const adapter = new CloudAdapter(botFrameworkAuthentication); + +adapter.onTurnError = async (context, error) => { + // This check writes out errors to console log .vs. app insights. + // NOTE: In production environment, you should consider logging this to Azure + // application insights. + console.error(`\n [onTurnError] unhandled error: ${ error }`); + + // Send a trace activity, which will be displayed in Bot Framework Emulator + await context.sendTraceActivity( + 'OnTurnError Trace', + `${ error }`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); + + // Uncomment below commented line for local debugging. + // await context.sendActivity(`Sorry, it looks like something went wrong. Exception Caught: ${error}`); + +}; + +// Create bot handlers +const botActivityHandler = new BotActivityHandler(); + +// Create HTTP server. +const server = express(); +server.use(express.json()); +const port = process.env.port || process.env.PORT || 3978; +server.listen(port, () => + console.log(`Service listening at http://localhost:${port}`) +); + +// Listen for incoming requests. +server.post('/api/messages', async (req, res) => { + // Route received a request to adapter for processing + await adapter.process(req, res, (context) => botActivityHandler.run(context)); +}); diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/infra/azure.bicep b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/infra/azure.parameters.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/infra/azure.parameters.json new file mode 100644 index 0000000000..b55a51532d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "msgext-search-quickstart" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/m365agents.local.yml b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/m365agents.local.yml new file mode 100644 index 0000000000..9e79523631 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/m365agents.local.yml @@ -0,0 +1,96 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-search-quickstart-js + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: msgext-search-quickstart-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADandPersonalMicrosoftAccount" # Multitenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: msgext-search-quickstart${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + # echo "::set-teamsfx-env MICROSOFT_APP_TYPE=MultiTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + - uses: aadApp/update # Apply the AAD manifest to an existing AAD app. Will use the object id in manifest file to determine which AAD app to update. + with: + manifestPath: ./aad.manifest.json # Relative path to teamsfx folder. Environment variables in manifest will be replaced before apply to AAD app + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Run npm command + - uses: cli/runNpmCommand + with: + args: install --no-audit + + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} + MicrosoftAppType: SingleTenant diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/m365agents.yml b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/m365agents.yml new file mode 100644 index 0000000000..b5f12cd12c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-search-quickstart-js + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/js/package.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/package.json new file mode 100644 index 0000000000..213cb443bb --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/js/package.json @@ -0,0 +1,26 @@ +{ + "name": "teams-conversation-bot", + "version": "1.0.0", + "msteams": { + "teamsAppId": "ee6d6590-f7b8-4790-b899-c77dfaa08058" + }, + "description": "Microsoft Teams conversation bot quickstart", + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev:teamsfx": "npm run dev", + "dev": "nodemon --inspect=9239 --signal SIGINT ./index.js", + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "build": "node build.js" + }, + "dependencies": { + "axios": "^1.15.0", + "botbuilder": "^4.23.3", + "dotenv": "^17.4.2", + "esbuild": "^0.28.0", + "express": "^5.2.1", + "nodemon": "^3.1.14" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.env b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.env new file mode 100644 index 0000000000..9d36feb6bd --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.env @@ -0,0 +1,4 @@ +MicrosoftAppId= +MicrosoftAppPassword= +MicrosoftAppType=SingleTenant +MicrosoftAppTenantId= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.gitignore b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.gitignore new file mode 100644 index 0000000000..e8442994dd --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.gitignore @@ -0,0 +1,14 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +appManifest/build/ + +# python virtual environment +.venv/ + +# misc +.env +.deployment/ + +# tmp files +__pycache__/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/extensions.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/extensions.json new file mode 100644 index 0000000000..bf8c33db9c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension", + "ms-python.python", + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/launch.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/launch.json new file mode 100644 index 0000000000..6d66d8beb8 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/launch.json @@ -0,0 +1,69 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Python: Run App Locally", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/app.py", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/settings.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/settings.json new file mode 100644 index 0000000000..3014fd9cf0 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "debug.onTaskErrors": "abort" +} diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/tasks.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/tasks.json new file mode 100644 index 0000000000..253c1ead76 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/.vscode/tasks.json @@ -0,0 +1,78 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Prepare Teams App Resources", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/1.Install_App.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/1.Install_App.png new file mode 100644 index 0000000000..6b26b5321a Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/1.Install_App.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/2.Select_App.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/2.Select_App.png new file mode 100644 index 0000000000..ca70b132c9 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/2.Select_App.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/3.Search_Query_With_Results.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/3.Search_Query_With_Results.png new file mode 100644 index 0000000000..1ee96792a9 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/3.Search_Query_With_Results.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/4.Selected_Result_Card.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/4.Selected_Result_Card.png new file mode 100644 index 0000000000..e2b55644f6 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/4.Selected_Result_Card.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/5.Compose_Card.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/5.Compose_Card.png new file mode 100644 index 0000000000..554bf9e588 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/5.Compose_Card.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/6.Search_Results_2.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/6.Search_Results_2.png new file mode 100644 index 0000000000..0bb10c08ec Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/6.Search_Results_2.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/7.Outlook_App.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/7.Outlook_App.png new file mode 100644 index 0000000000..f59f47b43b Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/7.Outlook_App.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/msgextsearchquickstart.gif b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/msgextsearchquickstart.gif new file mode 100644 index 0000000000..fe74593cbd Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/Images/msgextsearchquickstart.gif differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/README.md b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/README.md new file mode 100644 index 0000000000..2b4ed8c141 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/README.md @@ -0,0 +1,148 @@ +--- +page_type: sample +description: This sample demonstrates a simple python-based Messaging Extension that accepts search requests and returns results within Microsoft Teams. +products: +- office-teams +- office +- office-365 +languages: +- python +extensions: + contentType: samples + createdDate: "26/12/2024 01:38:27 PM" +urlFragment: officedev-microsoft-teams-samples-msgext-search-quickstart-python +--- + +# Messaging Extension quick start + +This comprehensive python quick start sample illustrates the creation of a Messaging Extension in Microsoft Teams designed to process search requests from users. By enabling interactions through buttons and forms, it facilitates direct communication with your web service, enhancing user experience within the Teams environment. + +*Messaging extensions* allow users to interact with your web service through buttons and forms in the Microsoft Teams client. They can search, or initiate actions, in an external system from the compose message area, the command box, or directly from a message. + +## Included Features +* Bots +* Message Extensions +* Search Commands + +## Interaction with app + +![Sample Module](Images/msgextsearchquickstart.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Messaging Extension quick start:** [Manifest](/samples/msgext-search-quickstart/js/demo-manifest/msgext-search-quickstart.zip) + +## Prerequisites + +**Dependencies** +- Microsoft Teams is installed and you have an account +- [Python SDK](https://www.python.org/downloads/) min version 3.6 +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) and [Python Extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Press **CTRL+Shift+P** to open the command box and enter **Python: Create Environment** to create and activate your desired virtual environment. Remember to select `requirements.txt` as dependencies to install when creating the virtual environment. +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +1) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + + 2. Azure Bot [Azure Bot] (https://learn.microsoft.com/azure/bot-service/abs-quickstart?view=azure-bot-service-4.0&tabs=userassigned) + +- For the Messaging endpoint URL, use the current `https` URL you were given by running the tunnelling application and append it with the path `/api/messages`. It should like something work `https://{subdomain}.ngrok-free.app/api/messages`. + +- Click on the `Bots` menu item from the toolkit and select the bot you are using for this project. Update the messaging endpoint and press enter to save the value in the Bot Framework. + +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + + 3. Setup NGROK + - Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +4. Setup for code + - Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + + - In a terminal, navigate to `samples/msgext-search-quickstart/python` + + - Activate your desired virtual environment + + - Install dependencies by running ```pip install -r requirements.txt``` in the project folder. + + - Update the `config.py` configuration for the bot to use the Microsoft App Id and App Password from the Bot Framework registration. (Note the App Password is referred to as the "client secret" in the azure portal and you can always create a new client secret anytime.) + + - Run your bot with `python app.py` + +5) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appManifest` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `${{AAD_APP_CLIENT_ID}}` and `${{TEAMS_APP_ID}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` + - **Upload** the `manifest.zip` to Teams (in the Apps view click "Upload a custom app") + +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appManifest folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your app is uploaded to Teams. + +## Running the sample + +![MsgExt Search](Images/1.Install_App.png) + +![MsgExt Search](Images/2.Select_App.png) + +![MsgExt Search](Images/3.Search_Query_With_Results.png) + +![MsgExt Search](Images/4.Selected_Result_Card.png) + +![MsgExt Search](Images/5.Compose_Card.png) + +![MsgExt Search](Images/6.Search_Results_2.png) + +![MsgExt Search](Images/7.Outlook_App.png) + + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) +- [Search based messaging extension](https://learn.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/search-commands/define-search-command) \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/aad.manifest.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/aad.manifest.json new file mode 100644 index 0000000000..0b6558944c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/aad.manifest.json @@ -0,0 +1,32 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "msgext-search-quickstart-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMultipleOrgs", + "oauth2AllowIdTokenImplicitFlow": true, + "oauth2AllowImplicitFlow": true, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/app.py b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/app.py new file mode 100644 index 0000000000..f5ef1f6bd1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/app.py @@ -0,0 +1,69 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import sys +import traceback +from datetime import datetime, timezone +from http import HTTPStatus +from aiohttp import web +from aiohttp.web import Request, Response +from botbuilder.core import TurnContext +from botbuilder.integration.aiohttp import ( + CloudAdapter, + ConfigurationBotFrameworkAuthentication, +) +from botbuilder.core.integration import aiohttp_error_middleware +from botbuilder.schema import Activity, ActivityTypes +from bots import BotActivityHandler +from config import DefaultConfig + +CONFIG = DefaultConfig() + +# Create adapter. +ADAPTER = CloudAdapter(ConfigurationBotFrameworkAuthentication(CONFIG)) + + +# Catch-all for errors. +async def on_error(context: TurnContext, error: Exception): + print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr) + traceback.print_exc() + + await context.send_activity("The bot encountered an error or bug.") + await context.send_activity( + "To continue to run this bot, please fix the bot source code." + ) + + if context.activity.channel_id == "emulator": + trace_activity = Activity( + label="TurnError", + name="on_turn_error Trace", + timestamp=datetime.now(timezone.utc), + type=ActivityTypes.trace, + value=f"{error}", + value_type="https://www.botframework.com/schemas/error", + ) + await context.send_activity(trace_activity) + + +ADAPTER.on_turn_error = on_error + +# Create the Bot +BOT = BotActivityHandler() + + +# Listen for incoming requests on /api/messages. +async def messages(req: Request) -> Response: + try: + return await ADAPTER.process(req, BOT) + except Exception as e: + print(f"Error processing activity: {e}") + traceback.print_exc() + return Response(status=HTTPStatus.INTERNAL_SERVER_ERROR) + + +# Create the main application and routes +APP = web.Application(middlewares=[aiohttp_error_middleware]) +APP.router.add_post("/api/messages", messages) + +if __name__ == "__main__": + web.run_app(APP, host="localhost", port=CONFIG.PORT) diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/color.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/manifest.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/manifest.json new file mode 100644 index 0000000000..b0b71b39d5 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/manifest.json @@ -0,0 +1,60 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.24/MicrosoftTeams.schema.json", + "manifestVersion": "1.24", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Teams App, Inc.", + "websiteUrl": "https://${{BOT_DOMAIN}}", + "privacyUrl": "https://${{BOT_DOMAIN}}/privacy", + "termsOfUseUrl": "https://${{BOT_DOMAIN}}/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "MsgExt Srch Python", + "full": "Messaging Extension Search Python" + }, + "description": { + "short": "Messaging Extension quick start for handling search requests.", + "full": "This sample demonstrates a simple python-based Messaging Extension that accepts search requests and returns results within Microsoft Teams." + }, + "accentColor": "#FFFFFF", + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "canUpdateConfiguration": true, + "commands": [ + { + "id": "searchQuery", + "type": "query", + "title": "Search", + "description": "Test command to run query", + "initialRun": false, + "fetchTask": false, + "context": [ + "compose", + "commandBox" + ], + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Your search query", + "inputType": "text" + } + ] + } + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/outline.png b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/assets/sample.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/assets/sample.json new file mode 100644 index 0000000000..b253f79ed7 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-msgext-search-quickstart-python", + "source": "officeDev", + "title": "Search messaging extension", + "shortDescription": "This sample demonstrates a simple python-based Messaging Extension that accepts search requests and returns results within Microsoft Teams.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/msgext-search-quickstart/python", + "longDescription": [ + "This python quick start sample showcases how to create a Messaging Extension in Microsoft Teams that handles user search queries. It allows users to interact with your web service through the Teams client, providing seamless search functionality." + ], + "creationDateTime": "2024-12-26", + "updateDateTime": "2024-12-26", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "python" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot,MsgExt" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/msgext-search-quickstart/python/Images/msgext-search-quickstart.gif", + "alt": "Solution UX showing search messaging extension- Microsoft 365 Agents Toolkit" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/bots/__init__.py b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/bots/__init__.py new file mode 100644 index 0000000000..cde1f7a4d5 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/bots/__init__.py @@ -0,0 +1,3 @@ +from .botActivityHandler import BotActivityHandler + +__all__ = ["BotActivityHandler"] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/bots/botActivityHandler.py b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/bots/botActivityHandler.py new file mode 100644 index 0000000000..53fd91bf5a --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/bots/botActivityHandler.py @@ -0,0 +1,133 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import requests +from botbuilder.core import TurnContext, CardFactory +from botbuilder.schema import ThumbnailCard, CardAction, CardImage +from botbuilder.core.teams import TeamsActivityHandler +from botbuilder.schema.teams import ( + MessagingExtensionResponse, + MessagingExtensionAttachment, + MessagingExtensionResult, +) + +# A bot activity handler that processes Teams messaging extensions and app link queries +class BotActivityHandler(TeamsActivityHandler): + # Handle search-based messaging extension queries + async def on_teams_messaging_extension_query(self, context, query): + # Get the search query parameter + search_query = query.parameters[0].value + + # Call the npm registry search API + response = requests.get( + "http://registry.npmjs.com/-/v1/search", + params={"text": search_query, "size": 8}, + ) + response.raise_for_status() + data = response.json() + + attachments = [] + + # Build a list of cards for the search results + for obj in data["objects"][:8]: + package = obj.get("package", {}) + package_name = package.get("name", "Unknown Package") + description = package.get("description", "No description available") + homepage = package.get("links", {}).get("homepage", "https://www.npmjs.com") + + # Main card (full view when selected/inserted into conversation) + thumbnail_card = ThumbnailCard( + title=package_name, + text=description, + buttons=[ + CardAction( + type="openUrl", + title="View on NPM", + value=f"https://www.npmjs.com/package/{package_name}", + ), + CardAction( + type="openUrl", + title="Homepage", + value=homepage, + ), + ], + ) + card_attachment = CardFactory.thumbnail_card(thumbnail_card) + + # Preview card (shown in search result list) + preview_card = ThumbnailCard(title=package_name, text=description) + preview_attachment = CardFactory.thumbnail_card(preview_card) + preview_attachment.content.tap = CardAction( + type="invoke", + value={"title": package_name, "description": description}, + ) + + # Messaging Extension attachment + attachment = MessagingExtensionAttachment( + content=card_attachment.content, + content_type=card_attachment.content_type, + preview=preview_attachment, + ) + attachments.append(attachment) + + # Wrap the results in a MessagingExtensionResult + result = MessagingExtensionResult( + type="result", + attachment_layout="list", + attachments=attachments, + ) + + return MessagingExtensionResponse(compose_extension=result) + + # Handle the user's selection of an item from the search results + async def on_teams_messaging_extension_select_item( + self, turn_context: TurnContext, query + ): + # Build a card with the selected package details + selected_card = ThumbnailCard( + title=query.get("title"), + text=query.get("description"), + ) + selected_attachment = CardFactory.thumbnail_card(selected_card) + + me_attachment = MessagingExtensionAttachment( + content=selected_attachment.content, + content_type=selected_attachment.content_type, + ) + + result = MessagingExtensionResult( + type="result", + attachment_layout="list", + attachments=[me_attachment], + ) + + return MessagingExtensionResponse(compose_extension=result) + + # Handle app-based link unfurling (e.g., when a user pastes a link) + async def on_teams_app_based_link_query( + self, turn_context: TurnContext, query + ): + # Create a card with the unfurled link details + link_card = ThumbnailCard( + title="Thumbnail Card", + text=query.url, + images=[ + CardImage( + url="https://raw.githubusercontent.com/microsoft/botframework-sdk/master/icon.png" + ) + ], + ) + link_attachment = CardFactory.thumbnail_card(link_card) + + me_attachment = MessagingExtensionAttachment( + content=link_attachment.content, + content_type=link_attachment.content_type, + ) + + result = MessagingExtensionResult( + type="result", + attachment_layout="list", + attachments=[me_attachment], + ) + + return MessagingExtensionResponse(compose_extension=result) diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/config.py b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/config.py new file mode 100644 index 0000000000..9d7d12aca1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/config.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os + +""" Bot Configuration """ + + +class DefaultConfig: + """ Bot Configuration """ + + PORT = 3978 + APP_ID = os.environ.get("MicrosoftAppId", "<>") + APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "<>") + APP_TYPE = os.environ.get("MicrosoftAppType", "") + APP_TENANTID = os.environ.get("MicrosoftAppTenantId", "") \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/env/.env.local b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/env/.env.local new file mode 100644 index 0000000000..5c612f9173 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/env/.env.local @@ -0,0 +1,19 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +APP_NAME_SUFFIX= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/infra/azure.bicep b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/infra/azure.bicep new file mode 100644 index 0000000000..3ddf3130e9 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/infra/azure.bicep @@ -0,0 +1,42 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string +param botAadAppTenantId string +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: 'SingleTenant' + msaAppTenantId: botAadAppTenantId + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/infra/azure.parameters.json b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/infra/azure.parameters.json new file mode 100644 index 0000000000..def255a116 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/infra/azure.parameters.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAadAppTenantId": { + "value": "${{AAD_APP_TENANT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "MsgextSearchQuickstart" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/m365agents.local.yml b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/m365agents.local.yml new file mode 100644 index 0000000000..9272723011 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/m365agents.local.yml @@ -0,0 +1,85 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-search-quickstart-python + +provision: + # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + - uses: aadApp/create + with: + name: msgextsearchquickstart-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADandPersonalMicrosoftAccount" # SingleTenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: msgextsearchquickstart${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + - uses: aadApp/update # Apply the AAD manifest to an existing AAD app. Will use the object id in manifest file to determine which AAD app to update. + with: + manifestPath: ./aad.manifest.json # Relative path to teamsfx folder. Environment variables in manifest will be replaced before apply to AAD app + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: SingleTenant + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/m365agents.yml b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/m365agents.yml new file mode 100644 index 0000000000..1c2bba62f1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-search-quickstart-python + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/msgext-search-quickstart/python/requirements.txt b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/requirements.txt new file mode 100644 index 0000000000..a85d5a3a83 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-search-quickstart/python/requirements.txt @@ -0,0 +1,2 @@ +requests==2.33.1 +botbuilder-integration-aiohttp>=4.17.1 diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/.gitignore b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/.gitignore new file mode 100644 index 0000000000..7466c01f9c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +appPackage/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/AdapterWithErrorHandler.cs b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/AdapterWithErrorHandler.cs new file mode 100644 index 0000000000..959577598d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/AdapterWithErrorHandler.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Builder.TraceExtensions; +using Microsoft.Bot.Connector.Authentication; + +namespace MsgextUnfurlingAcLoop; + +public class AdapterWithErrorHandler : CloudAdapter +{ + public AdapterWithErrorHandler(BotFrameworkAuthentication auth, ILogger logger) + : base(auth, logger) + { + OnTurnError = async (turnContext, exception) => + { + // Log any leaked exception from the application. + // NOTE: In production environment, you should consider logging this to + // Azure Application Insights. Visit https://aka.ms/bottelemetry to see how + // to add telemetry capture to your bot. + logger.LogError(exception, "[OnTurnError] unhandled error: {Message}", exception.Message); + + // Send a trace activity, which will be displayed in the Bot Framework Emulator + await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError"); + }; + } +} diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Bots/MsgextUnfurlingAcLoopComponents.cs b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Bots/MsgextUnfurlingAcLoopComponents.cs new file mode 100644 index 0000000000..55e391fa2c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Bots/MsgextUnfurlingAcLoopComponents.cs @@ -0,0 +1,117 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using AdaptiveCards; +using Microsoft.Agents.Builder; +using Microsoft.Agents.Core.Models; +using Microsoft.Agents.Extensions.Teams.Compat; +using Microsoft.Agents.Extensions.Teams.Models; +using System.Text.Json; + +namespace MsgextUnfurlingAcLoop.Bots; + +public class MsgextUnfurlingAcLoopComponents : TeamsActivityHandler +{ + /// + /// Reads the adaptive card JSON from the Resources folder. + /// + private static string GetAdaptiveCardJson() + { + var paths = new[] { ".", "Resources", "adaptiveCard.json" }; + return File.ReadAllText(Path.Combine(paths)); + } + + /// + /// Invoked when an app based link query activity is received from the connector. + /// + protected override Task OnTeamsAppBasedLinkQueryAsync( + ITurnContext turnContext, + AppBasedLinkQuery query, + CancellationToken cancellationToken) + { + AdaptiveCardParseResult result = AdaptiveCard.FromJson(GetAdaptiveCardJson()); + + var attachments = new MessagingExtensionAttachment + { + Content = result.Card, + ContentType = AdaptiveCard.ContentType + }; + + return Task.FromResult(new MessagingExtensionResponse + { + ComposeExtension = new MessagingExtensionResult + { + AttachmentLayout = "list", + Type = "result", + Attachments = new List + { + new() + { + Content = result.Card, + ContentType = AdaptiveCard.ContentType, + Preview = attachments, + }, + }, + }, + }); + } + + /// + /// Invoked when an adaptive card action invoke activity is received. + /// + protected override Task OnAdaptiveCardInvokeAsync( + ITurnContext turnContext, + AdaptiveCardInvokeValue adaptiveCardInvokeValue, + CancellationToken cancellationToken) + { + if (turnContext.Activity.Name == "adaptiveCard/action") + { + var paths = new[] { ".", "Resources", "adaptiveCardSuccess.json" }; + var adaptiveCardJson = File.ReadAllText(Path.Combine(paths)); + + return Task.FromResult(new AdaptiveCardInvokeResponse + { + StatusCode = 200, + Type = AdaptiveCard.ContentType, + Value = JsonSerializer.Deserialize(adaptiveCardJson) + }); + } + + return Task.FromResult(null!); + } + + /// + /// Invoked when the user is searching in the messaging extension query. + /// + protected override Task OnTeamsMessagingExtensionQueryAsync( + ITurnContext turnContext, + MessagingExtensionQuery query, + CancellationToken cancellationToken) + { + var card = new ThumbnailCard + { + Title = "Adaptive Card-based Loop component", + Text = "These samples are designed to help understand Microsoft Teams platform capabilities and scenarios(Bots,Tabs,Message extensions,Meeting extensions,Personal apps,Webhooks and connectors)", + }; + + AdaptiveCardParseResult result = AdaptiveCard.FromJson(GetAdaptiveCardJson()); + + return Task.FromResult(new MessagingExtensionResponse + { + ComposeExtension = new MessagingExtensionResult + { + AttachmentLayout = "list", + Type = "result", + Attachments = new List + { + new() + { + Content = result.Card, + ContentType = AdaptiveCard.ContentType, + Preview = card.ToAttachment(), + }, + }, + }, + }); + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Controllers/BotController.cs b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Controllers/BotController.cs new file mode 100644 index 0000000000..3ca11cf0ba --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Controllers/BotController.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; + +namespace MsgextUnfurlingAcLoop.Controllers; + +[Route("api/messages")] +[ApiController] +public class BotController(IBotFrameworkHttpAdapter adapter, IBot bot) : ControllerBase +{ + [HttpPost] + public async Task PostAsync() => + await adapter.ProcessAsync(Request, Response, bot); +} diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/1.InstallApp.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/1.InstallApp.png new file mode 100644 index 0000000000..e1bc74efb4 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/1.InstallApp.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/1.OutlookClickmail.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/1.OutlookClickmail.png new file mode 100644 index 0000000000..d54ec1db6e Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/1.OutlookClickmail.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/10.SuccessfullyExecute.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/10.SuccessfullyExecute.png new file mode 100644 index 0000000000..0351bcb4aa Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/10.SuccessfullyExecute.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/2.OutlookOpenApp.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/2.OutlookOpenApp.png new file mode 100644 index 0000000000..70ab72bbc3 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/2.OutlookOpenApp.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/2.SelectAddToChat.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/2.SelectAddToChat.png new file mode 100644 index 0000000000..e72fb3bd35 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/2.SelectAddToChat.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/3.GroupChat.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/3.GroupChat.png new file mode 100644 index 0000000000..7ca781cccf Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/3.GroupChat.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/3.OutlookSelectApp.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/3.OutlookSelectApp.png new file mode 100644 index 0000000000..526c49c379 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/3.OutlookSelectApp.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/4.AdaptiveCardLoopComponent.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/4.AdaptiveCardLoopComponent.png new file mode 100644 index 0000000000..6db99ebf15 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/4.AdaptiveCardLoopComponent.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/4.OutlookMsgext.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/4.OutlookMsgext.png new file mode 100644 index 0000000000..000ab5f712 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/4.OutlookMsgext.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/5.OutlookSearchCard.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/5.OutlookSearchCard.png new file mode 100644 index 0000000000..8add395501 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/5.OutlookSearchCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/5.SelectACloopComponent.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/5.SelectACloopComponent.png new file mode 100644 index 0000000000..4e49f3b5d6 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/5.SelectACloopComponent.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/6.MsgextSearch.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/6.MsgextSearch.png new file mode 100644 index 0000000000..59db1aae01 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/6.MsgextSearch.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/6.OutlookClickCard.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/6.OutlookClickCard.png new file mode 100644 index 0000000000..1c94084d4e Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/6.OutlookClickCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/7.MsgextSearchResults.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/7.MsgextSearchResults.png new file mode 100644 index 0000000000..9f3c767810 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/7.MsgextSearchResults.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/7.OutlookClickEx.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/7.OutlookClickEx.png new file mode 100644 index 0000000000..6dcb03f575 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/7.OutlookClickEx.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/8.AdaptiveCardLoopComponentMsgextSearch.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/8.AdaptiveCardLoopComponentMsgextSearch.png new file mode 100644 index 0000000000..5aa9fa2701 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/8.AdaptiveCardLoopComponentMsgextSearch.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/8.OutlookOutput.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/8.OutlookOutput.png new file mode 100644 index 0000000000..221bad4314 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/8.OutlookOutput.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/9.ClickExecute.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/9.ClickExecute.png new file mode 100644 index 0000000000..0f668d96db Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/9.ClickExecute.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/9.OutlookAClink.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/9.OutlookAClink.png new file mode 100644 index 0000000000..315a0bb8fb Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/9.OutlookAClink.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/OutlookChannelEnabled.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/OutlookChannelEnabled.png new file mode 100644 index 0000000000..3e778b991d Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/OutlookChannelEnabled.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/msgext-unfurling-ac-loop-components.gif b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/msgext-unfurling-ac-loop-components.gif new file mode 100644 index 0000000000..6a11808475 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Images/msgext-unfurling-ac-loop-components.gif differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/M365Agent.ttkproj b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/M365Agent.ttkproj new file mode 100644 index 0000000000..ab60e6b19a --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/M365Agent.ttkproj @@ -0,0 +1,14 @@ + + + + 9576200e-6b5e-4dbf-a34b-6e2575f10af9 + + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/aad.manifest.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/aad.manifest.json new file mode 100644 index 0000000000..1e3c8bb8e8 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/aad.manifest.json @@ -0,0 +1,100 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "displayName": "msgext-unfurling-ac-loop-components-aad", + "signInAudience": "AzureADMultipleOrgs", + "api": { + "requestedAccessTokenVersion": 2, + "oauth2PermissionScopes": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ] + }, + "info": {}, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "publicClient": {}, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "web": { + "implicitGrantSettings": {} + }, + "spa": {} +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/color.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/color.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/manifest.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/manifest.json new file mode 100644 index 0000000000..44a53e43b6 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/manifest.json @@ -0,0 +1,80 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Teams App, Inc.", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "AC Loop Component", + "full": "Adaptive Card based loop components." + }, + "description": { + "short": "C# Messaging Extension with adaptive card-based loop components functionality.", + "full": "This sample demonstrates a C# Messaging Extension for Microsoft Teams that utilizes adaptive card-based loop components, enabling link unfurling and dynamic interactions within the compose area." + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "groupChat" + ], + "supportsFiles": false, + "isNotificationOnly": false + } + ], + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "commands": [ + { + "id": "searchQuery", + "context": [ + "compose", + "commandBox" + ], + "description": "Messaging extension with adaptive card-based loop components functionality", + "title": "Search", + "type": "query", + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Messaging extension with adaptive card-based loop components functionality", + "inputType": "text" + } + ] + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "${{BOT_DOMAIN}}", + "*.github.com/OfficeDev/Microsoft-Teams-Samples/tree/main" + ] + } + } + ] + } + ], + "configurableTabs": [], + "staticTabs": [], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/outline.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/appPackage/outline.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/env/.env.local b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/env/.env.local new file mode 100644 index 0000000000..e090c08c34 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/env/.env.local @@ -0,0 +1,25 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local +APP_NAME_SUFFIX=local + +# Generated during provision, you can also add your own variables. +BOT_ID= +TEAMS_APP_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE=SingleTenant +MICROSOFT_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +TEAMSFX_M365_USER_NAME= + +BOT_ENDPOINT= +BOT_DOMAIN= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/infra/azure.bicep b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/infra/azure.parameters.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/infra/azure.parameters.json new file mode 100644 index 0000000000..3ee5f6e631 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "msgext-unfurling-ac-loop-components" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/launchSettings.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/launchSettings.json new file mode 100644 index 0000000000..8c76c70d9e --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/launchSettings.json @@ -0,0 +1,17 @@ +{ + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } + }, + // Launch project within Teams without prepare app dependencies + "Microsoft Teams (browser) (skip update app)": { + "commandName": "Project", + "environmentVariables": { + "UPDATE_TEAMS_APP": "false" + }, + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/m365agents.local.yml b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/m365agents.local.yml new file mode 100644 index 0000000000..40191d3b84 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/m365agents.local.yml @@ -0,0 +1,92 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-unfurling-ac-loop-components-csharp + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: msgext-unfurling-ac-loop-components-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMultipleOrgs" # Multitenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: msgext-unfurling-ac-loop-components-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ../appsettings.json + content: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: ${{MICROSOFT_APP_TYPE}} + MicrosoftAppTenantId: ${{MICROSOFT_APP_TENANT_ID}} + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appPackage/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/m365agents.yml b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/m365agents.yml new file mode 100644 index 0000000000..e18fda16d5 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/M365Agent/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-unfurling-ac-loop-components-csharp + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/MsgextUnfurlingAcLoop.csproj b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/MsgextUnfurlingAcLoop.csproj new file mode 100644 index 0000000000..fe3a774b9a --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/MsgextUnfurlingAcLoop.csproj @@ -0,0 +1,46 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + Always + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/MsgextUnfurlingAcLoop.sln b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/MsgextUnfurlingAcLoop.sln new file mode 100644 index 0000000000..b4dd5a2be0 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/MsgextUnfurlingAcLoop.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32901.215 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MsgextUnfurlingAcLoop", "MsgextUnfurlingAcLoop.csproj", "{25A8E103-5D11-4E86-8386-02EA05268130}" +EndProject +Project("{A9E3F50B-275E-4AF7-ADCE-8BE12D41E305}") = "M365Agent", "M365Agent\M365Agent.ttkproj", "{9576200E-6B5E-4DBF-A34B-6E2575F10AF9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{75C1DD92-1CF9-42CE-9FD0-2CED48A2FD87}" + ProjectSection(SolutionItems) = preProject + MsgextUnfurlingAcLoop.slnLaunch.user = MsgextUnfurlingAcLoop.slnLaunch.user + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {25A8E103-5D11-4E86-8386-02EA05268130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25A8E103-5D11-4E86-8386-02EA05268130}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25A8E103-5D11-4E86-8386-02EA05268130}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25A8E103-5D11-4E86-8386-02EA05268130}.Release|Any CPU.Build.0 = Release|Any CPU + {9576200E-6B5E-4DBF-A34B-6E2575F10AF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9576200E-6B5E-4DBF-A34B-6E2575F10AF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9576200E-6B5E-4DBF-A34B-6E2575F10AF9}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {9576200E-6B5E-4DBF-A34B-6E2575F10AF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9576200E-6B5E-4DBF-A34B-6E2575F10AF9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0689A0FF-D565-4242-B00D-99AA952C82D1} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Program.cs b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Program.cs new file mode 100644 index 0000000000..db081eb369 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Program.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Agents.Hosting.AspNetCore; +using MsgextUnfurlingAcLoop.Bots; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddHttpClient(); + +// Add AgentApplicationOptions from appsettings section "AgentApplication". +builder.AddAgentApplicationOptions(); + +// Add the Agent, which contains the logic for responding to user messages. +builder.AddAgent(); + +// Configure the HTTP request pipeline. + +// Add AspNet token validation for Azure Bot Service and Entra. +builder.Services.AddControllers(); + +var app = builder.Build(); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.UseDefaultFiles() + .UseStaticFiles(); + +app.MapGet("/", () => "Microsoft Agents SDK Sample"); + +// This receives incoming messages and routes them to the registered AgentApplication. +app.MapAgentApplicationEndpoints(requireAuth: !app.Environment.IsDevelopment()); + +app.Run(); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Properties/launchSettings.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Properties/launchSettings.json new file mode 100644 index 0000000000..889e9ad51f --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "Start Project": { + "commandName": "Project", + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7130;http://localhost:5130", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/README.md b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/README.md new file mode 100644 index 0000000000..b82175c5f7 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/README.md @@ -0,0 +1,216 @@ +--- +page_type: sample +description: This sample demonstrates a C# Messaging Extension for Microsoft Teams that utilizes adaptive card-based loop components, enabling link unfurling and dynamic interactions within the compose area. +products: +- office-teams +- office +- office-365 +languages: +- csharp +extensions: + contentType: samples + createdDate: "09-20-2023 20:32:25" +urlFragment: officedev-microsoft-teams-samples-msgext-unfurling-ac-loop-components-csharp +--- + +# Messaging Extension with Adaptive Card Loop Components + +This C# sample illustrates the development of a Messaging Extension for Microsoft Teams, featuring adaptive card-based loop components that facilitate link unfurling and user interaction. By allowing users to copy and paste URLs from platforms like GitHub, the extension enhances the messaging experience with rich previews and dynamic functionality, making it easier to engage with shared content. + +If you copy and paste a link from `https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main` or your ngrok base url, it wil unfurl inside compose area. + +## Included Features +* Message Extensions +* Search Commands +* Link Unfurling +* Adaptive card based loop component + +## Interaction with teams +![msgext-unfurling-ac-loop-components](Images/msgext-unfurling-ac-loop-components.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Msgext-Unfurling-Adaptive-Card-Loop-Components:** [Manifest](/samples/msgext-unfurling-ac-loop-components/csharp/demo-manifest/msgext-unfurling-ac-loop-components.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account +- [.NET SDK](https://dotnet.microsoft.com/download) version 6.0 +- [dev tunnel](https://learn.microsoft.com/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution +- [Microsoft 365 Agents Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.14 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Microsoft 365 Agents Toolkit for Visual Studio [Microsoft 365 Agents Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In the debug dropdown menu of Visual Studio, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel. +1. In the debug dropdown menu of Visual Studio, select default startup project > **Microsoft Teams (browser)** +1. Right-click the 'M365Agent' project in Solution Explorer and select **Microsoft 365 Agents Toolkit > Select Microsoft 365 Account** +1. Sign in to Microsoft 365 Agents Toolkit with a **Microsoft 365 work or school account** +1. Set `Startup Item` as `Microsoft Teams (browser)`. +1. Press F5, or select Debug > Start Debugging menu in Visual Studio to start your app +
![image](https://raw.githubusercontent.com/OfficeDev/TeamsFx/dev/docs/images/visualstudio/debug/debug-button.png) +1. In the opened web browser, select Add button to install the app in Teams + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + + +## Run the sample locally + +### 1. Register you app with Azure AD + + 1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + 2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. + 3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You’ll need those later when updating your Teams application manifest and in the appsettings.json. + 4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + 5. Navigate to the **Certificates & secrets**. In the Client secrets section, click on "+ New client secret". Add a description(Name of the secret) for the secret and select “Never” for Expires. Click "Add". Once the client secret is created, copy its value, it need to be placed in the appsettings.json. + +### 2. Setup + +1) Setup for Bot + + In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration). + - For bot handle, make up a name. + - Select "Use existing app registration" (Create the app registration in Microsoft Entra ID beforehand.) + - __*If you don't have an Azure account*__ create an [Azure free account here](https://azure.microsoft.com/free/) + + In the new Azure Bot resource in the Portal, + - Ensure that you've [enabled the Teams Channel](https://learn.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - Ensure that you've [enabled the Outlook Channel](https://learn.microsoft.com/azure/bot-service/bot-service-channel-connect-actionable-email?view=azure-bot-service-4.0) + ![Outlook Channel enabled](Images/OutlookChannelEnabled.png) + - In Settings/Configuration/Messaging endpoint, enter the current `https` URL you were given by running the tunnelling application. Append with the path `/api/messages` + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +the Teams service needs to call into the bot. + +1) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +### 3. Setup for code +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +1) If you are using Visual Studio + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `samples/msgext-unfurling-ac-loop-components/csharp` folder + - Select `MsgextUnfurlingAcLoop.csproj` or `MsgextUnfurlingAcLoop.sln`file + +1) Modify the `/appsettings.json` and fill in the following details: + - `{{Microsoft-App-Type}}` - (**Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI**) + - `{{Microsoft-App-Id}}` - Generated from Step 1 is the application app id + - `{{Microsoft-App-Password}}` - Generated from Step 1, also referred to as Client secret + - `{{Microsoft-App-TenantId}}` - Generated from Step 1 is the tenantId id + +1) Run your bot, either from Visual Studio with `F5` or using `dotnet run` in the appropriate folder. + +1) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appPackage` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `{{Microsoft-App-Id}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `{{domain-name}}` with base Url domain. E.g. if you are using ngrok it would be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be `12345.devtunnels.ms`. + - **Zip** up the contents of the `appPackage` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + - **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.) + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/msgext-unfurling-ac-loop-components/csharp/AdapterWithErrorHandler.cs#L25) line and put your debugger for local debug. + +### 4. Running the sample + +> Note the Teams `manifest.json` for this sample also includes a Search Query. This Messaging Extension is only introduced in order to enable installation, because there is no mechanism for installing a link unfurling feature in isolation. + +**Install App:** +![1.InstallApp](Images/1.InstallApp.png) + +**Add to a chat:** +![2.SelectAddToChat](Images/2.SelectAddToChat.png) + +**Add to a group chat:** +![3.GroupChat](Images/3.GroupChat.png) + +**If you copy and paste a link from https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main into the compose message area the link will unfurl:** +![4.AdaptiveCardLoopComponent](Images/4.AdaptiveCardLoopComponent.png) + +**Search for actions and apps:** +![5.SelectACloopComponent](Images/5.SelectACloopComponent.png) + +**Search:** +![6.MsgextSearch ](Images/6.MsgextSearch.png) + +**Search Results:** +![7.MsgextSearchResults ](Images/7.MsgextSearchResults.png) + +**Adaptive Card Based Loop Components:** +![8.AdaptiveCardLoopComponentMsgextSearch](Images/8.AdaptiveCardLoopComponentMsgextSearch.png) + +**Click Execute:** +![9.ClickExecute](Images/9.ClickExecute.png) + +**Successfully Execute:** +![10.SuccessfullyExecute](Images/10.SuccessfullyExecute.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**After opening Outlook web, click the "New mail" button:** +![1.OutlookClickmail](Images/1.OutlookClickmail.png) + +**On the tool bar on top,select Apps icon. Your uploaded app title appears among your installed apps:** +![2.OutlookOpenApp](Images/2.OutlookOpenApp.png) + +**Select your app icon:** +![3.OutlookSelectApp](Images/3.OutlookSelectApp.png) + +**Search for actions and apps:** +![4.OutlookMsgext](Images/4.OutlookMsgext.png) + +**Search Results:** +![5.OutlookSearchCard ](Images/5.OutlookSearchCard.png) + +**Adaptive Card Based Loop Components:** +![6.OutlookClickCard](Images/6.OutlookClickCard.png) + +**Click Execute:** +![7.OutlookClickEx](Images/7.OutlookClickEx.png) + +**Successfully Execute:** +![8.OutlookOutput](Images/8.OutlookOutput.png) + +**If you copy and paste a link from https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main into the compose message area the link will unfurl:** +![9.OutlookAClink](Images/9.OutlookAClink.png) + + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Adaptive Card-based Loop components](https://learn.microsoft.com/microsoftteams/platform/m365-apps/cards-loop-component?branch=pr-9230) +- [Build message extensions](https://learn.microsoft.com/microsoftteams/platform/messaging-extensions/what-are-messaging-extensions) +- [Azure Bot Service Introduction](https://learn.microsoft.com/microsoftteams/platform/messaging-extensions/how-to/link-unfurling) +- [Universal Actions for Adaptive Cards](https://learn.microsoft.com/microsoftteams/platform/task-modules-and-cards/cards/universal-actions-for-adaptive-cards/work-with-universal-actions-for-adaptive-cards) +- [Extend a Teams message extension across Microsoft 365](https://learn.microsoft.com/microsoftteams/platform/m365-apps/extend-m365-teams-message-extension) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Resources/adaptiveCard.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Resources/adaptiveCard.json new file mode 100644 index 0000000000..3e72fe273e --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Resources/adaptiveCard.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.5", + "metadata": { + "webUrl": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main" + }, + "body": [ + { + "type": "TextBlock", + "text": "Adaptive Card-based Loop component", + "size": "Large", + "weight": "Bolder" + }, + + { + "type": "Container", + "items": [ + { + "type": "TextBlock", + "text": "These samples are designed to help understand Microsoft Teams platform capabilities and scenarios(Bots,Tabs,Message extensions,Meeting extensions,Personal apps,Webhooks and connectors)", + "weight": "bolder", + "size": "medium" + } + ] + } + ], + "actions": [ + { + "type": "Action.Execute", + "title": "Execute!", + "verb": "userExecute" + }, + + { + "type": "Action.OpenUrl", + "title": "Universal Actions for Adaptive Cards", + "url": "https://learn.microsoft.com/microsoftteams/platform/task-modules-and-cards/cards/universal-actions-for-adaptive-cards/work-with-universal-actions-for-adaptive-cards" + }, + + { + "type": "Action.OpenUrl", + "title": "Adaptive Card-based Loop components", + "url": "https://learn.microsoft.com/microsoftteams/platform/m365-apps/cards-loop-component?branch=pr-9230" + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Resources/adaptiveCardSuccess.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Resources/adaptiveCardSuccess.json new file mode 100644 index 0000000000..b18d23b283 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/Resources/adaptiveCardSuccess.json @@ -0,0 +1,22 @@ +{ + "type": "AdaptiveCard", + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.5", + "body": [ + { + "type": "TextBlock", + "size": "Default", + "text": "Adaptive Card-based Loop component Successfully Execute!! ", + "style": "heading" + }, + { + "type": "Image", + "url": "https://raw.githubusercontent.com/microsoft/botframework-sdk/master/icon.png", + "height": "auto", + "size": "Medium", + "horizontalAlignment": "left", + "spacing": "None", + "width": "0px" + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/appsettings.Development.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/appsettings.Development.json new file mode 100644 index 0000000000..0c208ae918 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/appsettings.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/appsettings.json new file mode 100644 index 0000000000..bca5414231 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/appsettings.json @@ -0,0 +1,39 @@ +{ + "TokenValidation": { + "Audiences": [ + "" + ], + "TenantId": "" + }, + "Connections": { + "ServiceConnection": { + "Assembly": "Microsoft.Agents.Authentication.Msal", + "Type": "MsalAuth", + "Settings": { + "AuthType": "ClientSecret", + "AuthorityEndpoint": "https://login.microsoftonline.com/", + "ClientId": "", + "ClientSecret": "", + "Scopes": [ + "https://api.botframework.com/.default" + ] + } + } + }, + "ConnectionsMap": [ + { + "ServiceUrl": "*", + "Connection": "ServiceConnection" + } + ], + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "MicrosoftAppId": "", + "MicrosoftAppPassword": "", + "MicrosoftAppType": "SingleTenant", + "MicrosoftAppTenantId": "" +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/assets/sample.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/assets/sample.json new file mode 100644 index 0000000000..a955301635 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-msgext-unfurling-ac-loop-components-csharp", + "source": "officeDev", + "title": "Adaptive Card based loop components", + "shortDescription": "This sample demonstrates a C# Messaging Extension for Microsoft Teams that utilizes adaptive card-based loop components, enabling link unfurling and dynamic interactions within the compose area.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/msgext-unfurling-ac-loop-components/csharp", + "longDescription": [ + "This C# sample showcases a Messaging Extension for Microsoft Teams that incorporates adaptive card loop components, allowing users to interact with links directly in the compose area. Users can copy and paste links from GitHub or other sources to see rich previews and dynamic content, enhancing their messaging experience." + ], + "creationDateTime": "2023-09-20", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "csharp" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "netframework" + }, + { + "key": "TEAMS-FEATURES", + "value": "ME and Adaptive Card" + } + ], + "thumbnails": [ + { + "type": "Image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/msgext-unfurling-ac-loop-components/csharp/Images/msgext-unfurling-ac-loop-components.gif", + "alt": "Solution UX showing Adaptive Card Loop Component Using Messaging Extension" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/demo-manifest/msgext-unfurling-ac-loop-components.zip b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/demo-manifest/msgext-unfurling-ac-loop-components.zip new file mode 100644 index 0000000000..5df68f8bc2 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/demo-manifest/msgext-unfurling-ac-loop-components.zip differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/wwwroot/default.html b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/wwwroot/default.html new file mode 100644 index 0000000000..256217b2d2 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/csharp/wwwroot/default.html @@ -0,0 +1,300 @@ + + + + + + + Teams Msgext Unfurling AC Loop Components + + + + + +
+
+
+
Msgext Unfurling AC Loop Components
+
+
+
+
+
Your bot is ready!
+
+ You can now test your bot in Teams.
+
+ Visit + Azure + Bot Service + to register your bot and add it to the
+ Teams channel. The bot's endpoint URL typically looks + like this: +
+
https://your_bots_hostname/api/messages
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.gitignore b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.gitignore new file mode 100644 index 0000000000..a253c8f5ca --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.gitignore @@ -0,0 +1,13 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appManifest/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.localConfigs b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.localConfigs new file mode 100644 index 0000000000..1534515c1a --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.localConfigs @@ -0,0 +1,2 @@ +BOT_ID= +BOT_PASSWORD= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/launch.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/launch.json new file mode 100644 index 0000000000..d027ed91e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/launch.json @@ -0,0 +1,73 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Local Service", + "type": "node", + "request": "attach", + "port": 9239, + "restart": true, + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/settings.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/settings.json new file mode 100644 index 0000000000..4299620253 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ] +} diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/tasks.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/tasks.json new file mode 100644 index 0000000000..8b5e5698eb --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.vscode/tasks.json @@ -0,0 +1,105 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Teams App Locally", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy", + "Start application" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "nodejs", // Validate if Node.js is installed. + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + 9239 // app inspector port for Node.js debugger + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + }, + { + "label": "Start application", + "type": "shell", + "command": "npm run dev:teamsfx", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": { + "pattern": [ + { + "regexp": "^.*$", + "file": 0, + "location": 1, + "message": 2 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "[nodemon] starting", + "endsPattern": "restify listening to|Bot/ME service listening at|[nodemon] app crashed" + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.webappignore b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.webappignore new file mode 100644 index 0000000000..a30456bb74 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/.webappignore @@ -0,0 +1,26 @@ +.webappignore +.fx +.deployment +.localConfigs +.vscode +*.js.map +*.ts.map +*.ts +.git* +.tsbuildinfo +CHANGELOG.md +readme.md +local.settings.json +test +tsconfig.json +.DS_Store +teamsapp.yml +teamsapp.*.yml +/env/ +/script/ +/node_modules/.bin +/node_modules/ts-node +/node_modules/typescript +/appManifest/ +/infra/ +/teamsfx/ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/1.InstallApp.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/1.InstallApp.png new file mode 100644 index 0000000000..e1bc74efb4 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/1.InstallApp.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/1.OutlookClickmail.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/1.OutlookClickmail.png new file mode 100644 index 0000000000..d54ec1db6e Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/1.OutlookClickmail.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/10.SuccessfullyExecute.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/10.SuccessfullyExecute.png new file mode 100644 index 0000000000..0351bcb4aa Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/10.SuccessfullyExecute.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/2.OutlookOpenApp.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/2.OutlookOpenApp.png new file mode 100644 index 0000000000..70ab72bbc3 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/2.OutlookOpenApp.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/2.SelectAddToChat.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/2.SelectAddToChat.png new file mode 100644 index 0000000000..e72fb3bd35 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/2.SelectAddToChat.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/3.GroupChat.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/3.GroupChat.png new file mode 100644 index 0000000000..7ca781cccf Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/3.GroupChat.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/3.OutlookSelectApp.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/3.OutlookSelectApp.png new file mode 100644 index 0000000000..526c49c379 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/3.OutlookSelectApp.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/4.AdaptiveCardLoopComponent.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/4.AdaptiveCardLoopComponent.png new file mode 100644 index 0000000000..6db99ebf15 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/4.AdaptiveCardLoopComponent.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/4.OutlookMsgext.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/4.OutlookMsgext.png new file mode 100644 index 0000000000..000ab5f712 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/4.OutlookMsgext.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/5.OutlookSearchCard.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/5.OutlookSearchCard.png new file mode 100644 index 0000000000..8add395501 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/5.OutlookSearchCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/5.SelectACloopComponent.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/5.SelectACloopComponent.png new file mode 100644 index 0000000000..4e49f3b5d6 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/5.SelectACloopComponent.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/6.MsgextSearch.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/6.MsgextSearch.png new file mode 100644 index 0000000000..59db1aae01 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/6.MsgextSearch.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/6.OutlookClickCard.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/6.OutlookClickCard.png new file mode 100644 index 0000000000..1c94084d4e Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/6.OutlookClickCard.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/7.MsgextSearchResults.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/7.MsgextSearchResults.png new file mode 100644 index 0000000000..9f3c767810 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/7.MsgextSearchResults.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/7.OutlookClickEx.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/7.OutlookClickEx.png new file mode 100644 index 0000000000..6dcb03f575 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/7.OutlookClickEx.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/8.AdaptiveCardLoopComponentMsgextSearch.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/8.AdaptiveCardLoopComponentMsgextSearch.png new file mode 100644 index 0000000000..5aa9fa2701 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/8.AdaptiveCardLoopComponentMsgextSearch.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/8.OutlookOutput.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/8.OutlookOutput.png new file mode 100644 index 0000000000..221bad4314 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/8.OutlookOutput.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/9.ClickExecute.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/9.ClickExecute.png new file mode 100644 index 0000000000..0f668d96db Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/9.ClickExecute.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/9.OutlookAClink.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/9.OutlookAClink.png new file mode 100644 index 0000000000..315a0bb8fb Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/9.OutlookAClink.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/msgext-unfurling-ac-loop-components.gif b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/msgext-unfurling-ac-loop-components.gif new file mode 100644 index 0000000000..6a11808475 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/Images/msgext-unfurling-ac-loop-components.gif differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/README.md b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/README.md new file mode 100644 index 0000000000..095490319d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/README.md @@ -0,0 +1,203 @@ +--- +page_type: sample +description: This sample demonstrates a Node.js Messaging Extension for Microsoft Teams that utilizes adaptive card-based loop components, enabling link unfurling and dynamic interactions within the compose area. +products: +- office-teams +- office +- office-365 +languages: +- nodejs +extensions: + contentType: samples + createdDate: "08-21-2023 20:32:25" +urlFragment: officedev-microsoft-teams-samples-msgext-unfurling-ac-loop-components-nodejs +--- + +# Messaging Extension with Adaptive Card Loop Components + +This comprehensive Node.js sample illustrates the development of a Messaging Extension for Microsoft Teams, featuring adaptive card-based loop components that facilitate link unfurling and user interaction. By enabling users to copy and paste URLs from platforms like GitHub, the extension enriches the messaging experience with rich previews and dynamic functionality, making it easier to engage with shared content. + +If you copy and paste a link from `https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main` or your ngrok base url, it wil unfurl inside compose area. + +## Included Features +* Message Extensions +* Search Commands +* Link Unfurling +* Adaptive card based loop component + +## Interaction with teams +![msgext-unfurling-ac-loop-components](Images/msgext-unfurling-ac-loop-components.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Msgext-Unfurling-Adaptive-Card-Loop-Components:** [Manifest](/samples/msgext-unfurling-ac-loop-components/nodejs/demo-manifest/msgext-unfurling-ac-loop-components.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account +- [NodeJS](https://nodejs.org/en/) +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution. +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Run the sample locally + +### 1. Register you app with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + 2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. + 3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You’ll need those later when updating your Teams application manifest and in the .env. + 4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + + 5. Navigate to the **Certificates & secrets**. In the Client secrets section, click on "+ New client secret". Add a description(Name of the secret) for the secret and select “Never” for Expires. Click "Add". Once the client secret is created, copy its value, it need to be placed in the .env. + +### 2. Setup + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +the Teams service needs to call into the bot. + +1) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +### 3. Setup for code +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +1) In a terminal, navigate to `samples/msgext-unfurling-ac-loop-components/nodejs` + +1) Install modules + + ```bash + npm install + ``` + +1) Open .env file from this path folder `samples/msgext-unfurling-ac-loop-components/nodejs` and update + - `{{BOT_ID}}` - Generated from Step 1 (Application (client) ID)is the application app id + - `{{BOT_PASSWORD}}` - Generated from Step 1.4, also referred to as Client secret + +1) Run your bot at the command line: + + ```bash + npm start + ``` + +1) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appManifest` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `{{BOT_ID}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `<>` - Your application's base url domain. E.g. for https://12345.ngrok-free.app the base url domain will be 12345.ngrok-free.app if you are using ngrok and if you are using dev tunnel then your domain will be like: `12345.devtunnels.ms`. + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + - **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.) + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/msgext-unfurling-ac-loop-components/nodejs/index.js#L39) line and put your debugger for local debug. + +### 4. Running the sample + +> Note the Teams `manifest.json` for this sample also includes a Search Query. This Messaging Extension is only introduced in order to enable installation, because there is no mechanism for installing a link unfurling feature in isolation. + +**Install App:** +![1.InstallApp](Images/1.InstallApp.png) + +**Add to a chat:** +![2.SelectAddToChat](Images/2.SelectAddToChat.png) + +**Add to a group chat:** +![3.GroupChat](Images/3.GroupChat.png) + +**If you copy and paste a link from https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main into the compose message area the link will unfurl:** +![4.AdaptiveCardLoopComponent](Images/4.AdaptiveCardLoopComponent.png) + +**Search for actions and apps:** +![5.SelectACloopComponent](Images/5.SelectACloopComponent.png) + +**Search:** +![6.MsgextSearch ](Images/6.MsgextSearch.png) + +**Search Results:** +![7.MsgextSearchResults ](Images/7.MsgextSearchResults.png) + +**Adaptive Card Based Loop Components:** +![8.AdaptiveCardLoopComponentMsgextSearch](Images/8.AdaptiveCardLoopComponentMsgextSearch.png) + +**Click Execute:** +![9.ClickExecute](Images/9.ClickExecute.png) + +**Successfully Execute:** +![10.SuccessfullyExecute](Images/10.SuccessfullyExecute.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**After opening Outlook web, click the "New mail" button:** +![1.OutlookClickmail](Images/1.OutlookClickmail.png) + +**On the tool bar on top,select Apps icon. Your uploaded app title appears among your installed apps:** +![2.OutlookOpenApp](Images/2.OutlookOpenApp.png) + +**Select your app icon:** +![3.OutlookSelectApp](Images/3.OutlookSelectApp.png) + +**Search for actions and apps:** +![4.OutlookMsgext](Images/4.OutlookMsgext.png) + +**Search Results:** +![5.OutlookSearchCard ](Images/5.OutlookSearchCard.png) + +**Adaptive Card Based Loop Components:** +![6.OutlookClickCard](Images/6.OutlookClickCard.png) + +**Click Execute:** +![7.OutlookClickEx](Images/7.OutlookClickEx.png) + +**Successfully Execute:** +![8.OutlookOutput](Images/8.OutlookOutput.png) + +**If you copy and paste a link from https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main into the compose message area the link will unfurl:** +![9.OutlookAClink](Images/9.OutlookAClink.png) + + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Adaptive Card-based Loop components](https://learn.microsoft.com/en-us/microsoftteams/platform/m365-apps/cards-loop-component?branch=pr-en-us-9230) +- [Build message extensions](https://learn.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/what-are-messaging-extensions) +- [Azure Bot Service Introduction](https://learn.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/how-to/link-unfurling) +- [Universal Actions for Adaptive Cards](https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/universal-actions-for-adaptive-cards/work-with-universal-actions-for-adaptive-cards) +- [Extend a Teams message extension across Microsoft 365](https://learn.microsoft.com/en-us/microsoftteams/platform/m365-apps/extend-m365-teams-message-extension) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/color.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/manifest.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/manifest.json new file mode 100644 index 0000000000..c007791f5d --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/manifest.json @@ -0,0 +1,82 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Teams App, Inc.", + "websiteUrl": "https://${{BOT_DOMAIN}}", + "privacyUrl": "https://${{BOT_DOMAIN}}/termofuse", + "termsOfUseUrl": "https://${{BOT_DOMAIN}}/privacy" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "AC Loop Component", + "full": "Adaptive Card based loop components." + }, + "description": { + "short": "Messaging Extension with adaptive card-based loop components functionality", + "full": "This sample demonstrates a Node.js Messaging Extension for Microsoft Teams that utilizes adaptive card-based loop components, enabling link unfurling and dynamic interactions within the compose area." + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "${{BOT_ID}}", + "scopes": [ + "groupChat" + ], + "supportsFiles": false, + "isNotificationOnly": false + } + ], + "composeExtensions": [ + { + "botId": "${{BOT_ID}}", + "commands": [ + { + "id": "searchQuery", + "context": [ + "compose", + "commandBox" + ], + "description": "Messaging extension with adaptive card-based loop components functionality", + "title": "Search", + "type": "query", + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Messaging extension with adaptive card-based loop components functionality", + "inputType": "text" + } + ] + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "${{BOT_DOMAIN}}", + "*.github.com/OfficeDev/Microsoft-Teams-Samples/tree/main", + "<>" + ] + } + } + ] + } + ], + "configurableTabs": [], + "staticTabs": [], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{BOT_DOMAIN}}", + "<>" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/outline.png b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/assets/sample.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/assets/sample.json new file mode 100644 index 0000000000..881b14910a --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-msgext-unfurling-ac-loop-components-nodejs", + "source": "officeDev", + "title": "Adaptive Card based loop components", + "shortDescription": "This sample demonstrates a Node.js Messaging Extension for Microsoft Teams that utilizes adaptive card-based loop components, enabling link unfurling and dynamic interactions within the compose area.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/msgext-unfurling-ac-loop-components/nodejs", + "longDescription": [ + "This Node.js sample showcases a Messaging Extension for Microsoft Teams that incorporates adaptive card loop components, allowing users to interact with links directly in the compose area. By copying and pasting URLs from GitHub or other sources, users can see rich previews and dynamic content, enhancing their messaging experience." + ], + "creationDateTime": "2023-08-21", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "restify" + }, + { + "key": "TEAMS-FEATURES", + "value": "ME, Adaptive Card" + } + ], + "thumbnails": [ + { + "type": "Image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/msgext-unfurling-ac-loop-components/nodejs/Images/msgext-unfurling-ac-loop-components.gif", + "alt": "Solution UX showing Adaptive Card Loop Component Using ME" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/bots/teamsBot.js b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/bots/teamsBot.js new file mode 100644 index 0000000000..4b45526ad4 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/bots/teamsBot.js @@ -0,0 +1,148 @@ +const { TeamsActivityHandler, CardFactory } = require("botbuilder"); + +const card = CardFactory.adaptiveCard({ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.6", + "metadata": { + "webUrl": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main" + }, + "body": [ + { + "type": "TextBlock", + "text": "Adaptive Card-based Loop component", + "size": "Large", + "weight": "Bolder" + }, + { + "type": "Container", + "items": [ + { + "type": "TextBlock", + "text": "These samples are designed to help understand Microsoft Teams platform capabilities and scenarios(Bots,Tabs,Message extensions,Meeting extensions,Personal apps,Webhooks and connectors)", + "weight": "bolder", + "size": "medium" + } + ] + } + ], + "actions": [ + { + "type": "Action.Execute", + "title": "Execute!", + "verb": "userExecute", + "fallback": "Action.Submit" + }, + { + "type": "Action.OpenUrl", + "title": "Universal Actions for Adaptive Cards", + "url": "https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/universal-actions-for-adaptive-cards/work-with-universal-actions-for-adaptive-cards" + }, + { + "type": "Action.OpenUrl", + "title": "Adaptive Card-based Loop components", + "url": "https://learn.microsoft.com/en-us/microsoftteams/platform/m365-apps/cards-loop-component?branch=pr-en-us-9230" + } + ] +}); + +class TeamsBot extends TeamsActivityHandler { + // Invoked when an action is taken on an Adaptive Card. The Adaptive Card sends an event to the Bot and this + // method handles that event. + async onAdaptiveCardInvoke(context, invokeValue) { + // The verb "userExecute" is sent from the Adaptive Card defined in adaptiveCards/learn.json + if (invokeValue.action.verb === "userExecute") { + const card = { + "type": "AdaptiveCard", + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.5", + "body": [ + { + "type": "TextBlock", + "size": "Default", + "text": "Adaptive Card-based Loop component Successfully Execute!! ", + "style": "heading" + }, + { + "type": "Image", + "url": "https://raw.githubusercontent.com/microsoft/botframework-sdk/master/icon.png", + "height": "auto", + "size": "Medium", + "horizontalAlignment": "left", + "spacing": "None", + "width": "0px" + } + ] + }; + return { + statusCode: 200, + type: "application/vnd.microsoft.card.adaptive", + value: card + }; + } + } + + // Msgext-link-unfurling + handleTeamsAppBasedLinkQuery() { + + const attachment = JSON.parse(JSON.stringify(card)); + + attachment.preview = { + content: { + title: "Adaptive Card-based Loop component", + text:"These samples are designed to help understand Microsoft Teams platform capabilities and scenarios(Bots,Tabs,Message extensions,Meeting extensions,Personal apps,Webhooks and connectors)", + }, + contentType: "application/vnd.microsoft.card.thumbnail", + } + + const result = { + attachmentLayout: 'list', + type: 'result', + attachments: [attachment] + }; + + const response = { + composeExtension: result + }; + + return response; +} + + // Message extension Code Search + // Used in creating a Search-based Message Extension + async handleTeamsMessagingExtensionQuery(context, query) { + + const attachment = JSON.parse(JSON.stringify(card)); + + attachment.preview = { + content: { + title: "Adaptive Card-based Loop component", + text:"These samples are designed to help understand Microsoft Teams platform capabilities and scenarios(Bots,Tabs,Message extensions,Meeting extensions,Personal apps,Webhooks and connectors)", + }, + contentType: "application/vnd.microsoft.card.thumbnail", + } + + return { + composeExtension: { + type: "result", + attachmentLayout: "list", + attachments: [attachment], + }, + }; + } + + // Receives invoke activities with the name 'selectItem'. + //Used in creating a Search-based Message Extension. + async handleTeamsMessagingExtensionSelectItem(context, obj) { + + return { + composeExtension: { + type: "result", + attachmentLayout: "list", + attachments: [JSON.parse(JSON.stringify(card))], + }, + }; + } +} + +module.exports.TeamsBot = TeamsBot; diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/build.js b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/build.js new file mode 100644 index 0000000000..af1ca8cb3c --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/build.js @@ -0,0 +1,15 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js', + external: ['dtrace-provider'], +}) + .then(() => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/config.js b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/config.js new file mode 100644 index 0000000000..df88c39871 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/config.js @@ -0,0 +1,6 @@ +const config = { + botId: process.env.BOT_ID, + botPassword: process.env.BOT_PASSWORD, +}; + +module.exports = config; diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/demo-manifest/msgext-unfurling-ac-loop-components-node.zip b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/demo-manifest/msgext-unfurling-ac-loop-components-node.zip new file mode 100644 index 0000000000..b467f15b19 Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/demo-manifest/msgext-unfurling-ac-loop-components-node.zip differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/demo-manifest/msgext-unfurling-ac-loop-components.zip b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/demo-manifest/msgext-unfurling-ac-loop-components.zip new file mode 100644 index 0000000000..b0cc4b10ca Binary files /dev/null and b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/demo-manifest/msgext-unfurling-ac-loop-components.zip differ diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/env/.env.dev b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/env/.env.dev new file mode 100644 index 0000000000..3e4398dbf1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/env/.env.dev @@ -0,0 +1,15 @@ +# This file includes environment variables that will be committed to git by default. + +# Built-in environment variables +TEAMSFX_ENV=dev +APP_NAME_SUFFIX=dev +# Updating AZURE_SUBSCRIPTION_ID or AZURE_RESOURCE_GROUP_NAME after provision may also require an update to RESOURCE_SUFFIX, because some services require a globally unique name across subscriptions/resource groups. +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +RESOURCE_SUFFIX=ac-loop-components + +# Generated during provision, you can also add your own variables. +BOT_ID= +TEAMS_APP_ID= +BOT_AZURE_APP_SERVICE_RESOURCE_ID= +BOT_DOMAIN= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/env/.env.local b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/env/.env.local new file mode 100644 index 0000000000..42b87b3009 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/env/.env.local @@ -0,0 +1,14 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. +BOT_ID= +TEAMS_APP_ID= +BOT_DOMAIN= +BOT_ENDPOINT= +TEAMS_APP_TENANT_ID= +M365_TITLE_ID= +M365_APP_ID= +APP_NAME_SUFFIX=local \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/index.js b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/index.js new file mode 100644 index 0000000000..4008cd63a0 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/index.js @@ -0,0 +1,61 @@ +// index.js is used to setup and configure your bot + +// Import required packages +const restify = require("restify"); + +// Import required bot services. +// See https://aka.ms/bot-services to learn more about the different parts of a bot. +const { + CloudAdapter, + ConfigurationBotFrameworkAuthentication, +} = require("botbuilder"); +const { TeamsBot } = require("./bots/teamsBot"); +const config = require("./config"); + +// Create adapter. +// See https://aka.ms/about-bot-adapter to learn more about adapters. +const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication({ + MicrosoftAppId: config.botId, + MicrosoftAppPassword: config.botPassword, + MicrosoftAppType: "MultiTenant", +}); + +const adapter = new CloudAdapter(botFrameworkAuthentication); + +adapter.onTurnError = async (context, error) => { + // This check writes out errors to console log .vs. app insights. + // NOTE: In production environment, you should consider logging this to Azure + // application insights. See https://aka.ms/bottelemetry for telemetry + // configuration instructions. + console.error(`\n [onTurnError] unhandled error: ${error}`); + + // Uncomment below commented line for local debugging. + // await context.sendActivity(`Sorry, it looks like something went wrong. Exception Caught: ${error}`); + + // Note: Since this Messaging Extension does not have the messageTeamMembers permission + // in the manifest, the bot will not be allowed to message users. +}; + +// Create the bot that will handle incoming messages. +const bot = new TeamsBot(); + +// Create HTTP server. +const server = restify.createServer(); +server.use(restify.plugins.bodyParser()); +server.listen(process.env.port || process.env.PORT || 3978, function () { + console.log(`\nBot started, ${server.name} listening to ${server.url}`); +}); + +// Listen for incoming requests. +server.post("/api/messages", async (req, res) => { + await adapter.process(req, res, async (context) => { + await bot.run(context); + }); +}); + +// Gracefully shutdown HTTP server +["exit", "uncaughtException", "SIGINT", "SIGTERM", "SIGUSR1", "SIGUSR2"].forEach((event) => { + process.on(event, () => { + server.close(); + }); +}); diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/azure.bicep b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/azure.bicep new file mode 100644 index 0000000000..41cf99a692 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/azure.bicep @@ -0,0 +1,82 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +@secure() +@description('Required by Bot Framework package in your bot project') +param botAadAppClientSecret string + +param webAppSKU string + +@maxLength(42) +param botDisplayName string + +param serverfarmsName string = resourceBaseName +param webAppName string = resourceBaseName +param location string = resourceGroup().location + +// Compute resources for your Web App +resource serverfarm 'Microsoft.Web/serverfarms@2021-02-01' = { + kind: 'app' + location: location + name: serverfarmsName + sku: { + name: webAppSKU + } +} + +// Web App that hosts your bot +resource webApp 'Microsoft.Web/sites@2021-02-01' = { + kind: 'app' + location: location + name: webAppName + properties: { + serverFarmId: serverfarm.id + httpsOnly: true + siteConfig: { + alwaysOn: true + appSettings: [ + { + name: 'WEBSITE_RUN_FROM_PACKAGE' + value: '1' // Run Azure APP Service from a package file + } + { + name: 'WEBSITE_NODE_DEFAULT_VERSION' + value: '~18' // Set NodeJS version to 18.x for your site + } + { + name: 'RUNNING_ON_AZURE' + value: '1' + } + { + name: 'BOT_ID' + value: botAadAppClientId + } + { + name: 'BOT_PASSWORD' + value: botAadAppClientSecret + } + ] + ftpsState: 'FtpsOnly' + } + } +} + +// Register your web service as a bot with the Bot Framework +module azureBotRegistration './botRegistration/azurebot.bicep' = { + name: 'Azure-Bot-registration' + params: { + resourceBaseName: resourceBaseName + botAadAppClientId: botAadAppClientId + botAppDomain: webApp.properties.defaultHostName + botDisplayName: botDisplayName + } +} + +// The output will be persisted in .env.{envName}. Visit https://aka.ms/teamsfx-actions/arm-deploy for more details. +output BOT_AZURE_APP_SERVICE_RESOURCE_ID string = webApp.id +output BOT_DOMAIN string = webApp.properties.defaultHostName diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/azure.parameters.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/azure.parameters.json new file mode 100644 index 0000000000..00c1291644 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/azure.parameters.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "ME${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{BOT_ID}}" + }, + "botAadAppClientSecret": { + "value": "${{SECRET_BOT_PASSWORD}}" + }, + "webAppSKU": { + "value": "B1" + }, + "botDisplayName": { + "value": "AdaptiveCardLoopComponents" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/azurebot.bicep b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/azurebot.bicep new file mode 100644 index 0000000000..4450c8dfe6 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/azurebot.bicep @@ -0,0 +1,47 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param botAadAppClientId string +param botAppDomain string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} + +// Connect the bot service to Outlook, and other Microsoft 365 applications +resource botServiceM365ExtensionsChannel 'Microsoft.BotService/botServices/channels@2022-06-15-preview' = { + parent: botService + location: 'global' + name: 'M365Extensions' + properties: { + channelName: 'M365Extensions' + } +} diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/readme.md b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/readme.md new file mode 100644 index 0000000000..d5416243cd --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/readme.md @@ -0,0 +1 @@ +The `azurebot.bicep` module is provided to help you create Azure Bot service when you don't use Azure to host your app. If you use Azure as infrastrcture for your app, `azure.bicep` under infra folder already leverages this module to create Azure Bot service for you. You don't need to deploy `azurebot.bicep` again. \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/m365agents.local.yml b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/m365agents.local.yml new file mode 100644 index 0000000000..2f1200dbc1 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/m365agents.local.yml @@ -0,0 +1,92 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-unfurling-ac-loop-components-nodejs + +provision: + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: AdaptiveCardLoopComponents${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Create or reuse an existing Azure Active Directory application for bot. + - uses: botAadApp/create + with: + # The Azure Active Directory application's display name + name: AdaptiveCardLoopComponents${{APP_NAME_SUFFIX}} + writeToEnvironmentFile: + # The Azure Active Directory application's client id created for bot. + botId: BOT_ID + # The Azure Active Directory application's client secret created for bot. + botPassword: SECRET_BOT_PASSWORD + + # Create or update the bot registration on dev.botframework.com + - uses: botFramework/create + with: + botId: ${{BOT_ID}} + name: AdaptiveCardLoopComponents + messagingEndpoint: ${{BOT_ENDPOINT}}/api/messages + description: "" + channels: + - name: msteams + - name: m365extensions + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Extend your Teams app to Outlook and the Microsoft 365 app + - uses: teamsApp/extendToM365 + with: + # Relative path to the build app package. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + titleId: M365_TITLE_ID + appId: M365_APP_ID + +deploy: + # Run npm command + - uses: cli/runNpmCommand + with: + args: install --no-audit + + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.localConfigs + envs: + BOT_ID: ${{BOT_ID}} + BOT_PASSWORD: ${{SECRET_BOT_PASSWORD}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/m365agents.yml b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/m365agents.yml new file mode 100644 index 0000000000..93206c16ae --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:msgext-unfurling-ac-loop-components-nodejs + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/package.json b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/package.json new file mode 100644 index 0000000000..e29dbfff09 --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/package.json @@ -0,0 +1,30 @@ +{ + "name": "msgext-unfurling-ac-loop-components", + "version": "1.0.0", + "msteams": { + "teamsAppId": null + }, + "description": "Messaging Extension For Adaptive Card Based Loop Components", + "engines": { + "node": "18 || 20 || 22" + }, + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev:teamsfx": "env-cmd --silent -f .localConfigs npm run dev", + "dev": "nodemon --inspect=9239 --signal SIGINT ./index.js", + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "build": "node build.js" + }, + "dependencies": { + "botbuilder": "^4.23.3", + "restify": "^11.1.0" + }, + "devDependencies": { + "env-cmd": "^11.0.0", + "nodemon": "^3.1.14", + "esbuild": "^0.28.0" + } +} diff --git a/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/web.config b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/web.config new file mode 100644 index 0000000000..be6103596f --- /dev/null +++ b/samples/TeamsSDK/Archived/msgext-unfurling-ac-loop-components/nodejs/web.config @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot.sln b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot.sln new file mode 100644 index 0000000000..47b813ec4e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35004.147 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeepLinkBot", "DeepLinkBot\DeepLinkBot.csproj", "{B18CD866-7E29-498F-88EA-C3B48C96CA7C}" +EndProject +Project("{A9E3F50B-275E-4AF7-ADCE-8BE12D41E305}") = "M365Agent", "M365Agent\M365Agent.ttkproj", "{BD528DA9-F03F-4914-9EAC-97C61793CC67}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0A362977-2104-4668-A5BA-0E4670FEE7B1}" + ProjectSection(SolutionItems) = preProject + DeepLinkBot.slnLaunch.user = DeepLinkBot.slnLaunch.user + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B18CD866-7E29-498F-88EA-C3B48C96CA7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B18CD866-7E29-498F-88EA-C3B48C96CA7C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B18CD866-7E29-498F-88EA-C3B48C96CA7C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B18CD866-7E29-498F-88EA-C3B48C96CA7C}.Release|Any CPU.Build.0 = Release|Any CPU + {BD528DA9-F03F-4914-9EAC-97C61793CC67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD528DA9-F03F-4914-9EAC-97C61793CC67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD528DA9-F03F-4914-9EAC-97C61793CC67}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {BD528DA9-F03F-4914-9EAC-97C61793CC67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD528DA9-F03F-4914-9EAC-97C61793CC67}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7075E508-599E-421A-A431-696A3E92B2F9} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/.gitignore b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/.gitignore new file mode 100644 index 0000000000..7466c01f9c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +appPackage/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AdapterWithErrorHandler.cs b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AdapterWithErrorHandler.cs new file mode 100644 index 0000000000..c2be81a17f --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AdapterWithErrorHandler.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Builder.TraceExtensions; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace Microsoft.BotBuilderSamples +{ + public class AdapterWithErrorHandler : CloudAdapter + { + public AdapterWithErrorHandler(IConfiguration configuration, ILogger logger) + : base(configuration, null, logger) + { + OnTurnError = async (turnContext, exception) => + { + // Log any leaked exception from the application. + // NOTE: In production environment, you should consider logging this to + // Azure Application Insights. Visit https://aka.ms/bottelemetry to see how + // to add telemetry capture to your bot. + logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}"); + + // Uncomment below commented line for local debugging. + // await turnContext.SendActivityAsync($"Sorry, it looks like something went wrong. Exception Caught: {exception.Message}"); + + // Send a trace activity, which will be displayed in the Bot Framework Emulator + await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError"); + }; + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/color.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/manifest.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/manifest.json new file mode 100644 index 0000000000..1832288363 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/manifest.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "<>", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Deep Link Bot", + "full": "Bot for Deep linking to tab" + }, + "description": { + "short": "DeepLinkBot for Microsoft Teams", + "full": "This sample DeepLink app which demos to navigate to required item in tab." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "accentColor": "#60A18E", + "staticTabs": [ + { + "contentUrl": "https://{{domain-name}}/DeepLink", + "websiteUrl": "https://{{domain-name}}", + "entityId": "com.contoso.DeeplLinkBot.help", + "name": "Deep Link Tab", + "scopes": [ + "personal" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "{{domain-name}}", + "{{domain-name}}" + ], + "authorization": { + "permissions": { + "resourceSpecific": [ + { + "name": "MeetingStage.Write.Chat", + "type": "Delegated" + }, + { + "name": "ChannelMeetingStage.Write.Group", + "type": "Delegated" + } + ] + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/outline.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/AppManifest_Hub/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Bots/DeepLinkBot.cs b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Bots/DeepLinkBot.cs new file mode 100644 index 0000000000..ea95953e96 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Bots/DeepLinkBot.cs @@ -0,0 +1,231 @@ +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AdaptiveCards; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Schema; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.BotBuilderSamples.Bots +{ + public class DeepLinkBot : ActivityHandler + { + public readonly IConfiguration _configuration; + public DeepLinkBot(IConfiguration configuration) + { + _configuration = configuration; + } + + public static string channelID = ""; + public string teamsUrl = "https://teams.microsoft.com/l/entity/"; + public string tabUrlTask1; + public string tabUrlTask2; + public string tabUrlTask3; + public string callingDeeplink; + public string extendedDeepLink; + public string sidePanelLink; + + DeeplinkHelper deeplinkHelper = new DeeplinkHelper(); + protected override async Task OnMessageActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) + { + var attachment = AdaptiveDeepLinkCard(turnContext.Activity.From.Name, turnContext); + await turnContext.SendActivityAsync(MessageFactory.Attachment(attachment), cancellationToken); + } + + protected override async Task OnMembersAddedAsync(IList membersAdded, ITurnContext turnContext, CancellationToken cancellationToken) + { + var welcomeText = "Hello and welcome!"; + foreach (var member in membersAdded) + { + if (member.Id != turnContext.Activity.Recipient.Id) + { + await turnContext.SendActivityAsync(MessageFactory.Text(welcomeText, welcomeText), cancellationToken); + } + } + } + public Attachment AdaptiveDeepLinkCard(string userName, ITurnContext turnContext) + { + if (turnContext.Activity.Conversation.ConversationType == "channel") + { + channelID = turnContext.Activity.Conversation.Id.Split(';')[0]; + tabUrlTask1 = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], "bot1"); + tabUrlTask2 = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], "bot2"); + tabUrlTask3 = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], "bot3"); + extendedDeepLink = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], ""); + } + else + { + tabUrlTask1 = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["TeamsAppId"], _configuration["TabEntityId"], "topic1"); + tabUrlTask2 = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["TeamsAppId"], _configuration["TabEntityId"], "topic2"); + tabUrlTask3 = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["TeamsAppId"], _configuration["TabEntityId"], "topic3"); + extendedDeepLink = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["TeamsAppId"], _configuration["TabEntityId"], ""); + sidePanelLink = deeplinkHelper.GetDeepLinkToMeetingSidePanel(teamsUrl, _configuration["TeamsAppId"], _configuration["BaseURL"], _configuration["ChannelEntityId"], turnContext.Activity.Conversation.Id, "chat"); + } + + var DeepLinkCard = new AdaptiveCard(new AdaptiveSchemaVersion("1.0")) + { + Body = new List() + { + new AdaptiveContainer + { + Items = new List() + { + new AdaptiveTextBlock() + { + Text = $"Hey {userName}! Please click on below buttons to navigate to a tab!", + Size = AdaptiveTextSize.Large, + Wrap = true + }, + new AdaptiveColumnSet() + { + Columns = new List() + { + new AdaptiveColumn() + { + Width = AdaptiveColumnWidth.Auto, + Items = new List() + { + new AdaptiveTextBlock() + { + Text = "Bots in Teams", + Color = AdaptiveTextColor.Accent, + Size = AdaptiveTextSize.Medium, + HorizontalAlignment = AdaptiveHorizontalAlignment.Center, + Spacing = AdaptiveSpacing.None + } + }, + SelectAction = new AdaptiveOpenUrlAction() + { + Url = new Uri(tabUrlTask1), + Title = "Bots in Teams" + } + } + } + }, + new AdaptiveColumnSet() + { + Columns = new List() + { + new AdaptiveColumn() + { + Width = AdaptiveColumnWidth.Auto, + Items = new List() + { + new AdaptiveTextBlock() + { + Text ="Bot Framework SDK", + Color = AdaptiveTextColor.Accent, + Size = AdaptiveTextSize.Medium, + HorizontalAlignment = AdaptiveHorizontalAlignment.Center, + Spacing = AdaptiveSpacing.None + } + }, + SelectAction = new AdaptiveOpenUrlAction() + { + Url = new Uri(tabUrlTask2), + Title = "Bot Framework SDK" + } + } + } + }, + new AdaptiveColumnSet() + { + Columns = new List() + { + new AdaptiveColumn() + { + Width = AdaptiveColumnWidth.Auto, + Items = new List() + { + new AdaptiveTextBlock() + { + Text = "Teams Apps", + Color = AdaptiveTextColor.Accent, + Size = AdaptiveTextSize.Medium, + HorizontalAlignment = AdaptiveHorizontalAlignment.Center, + Spacing = AdaptiveSpacing.None + } + }, + SelectAction = new AdaptiveOpenUrlAction() + { + Url = new Uri(tabUrlTask3), + Title = "Teams Apps" + } + } + } + }, + new AdaptiveColumnSet() + { + Columns = new List() + { + new AdaptiveColumn() + { + Width = AdaptiveColumnWidth.Auto, + Items = new List() + { + new AdaptiveTextBlock() + { + Text = "Extended Deeplink features", + Color = AdaptiveTextColor.Accent, + Size = AdaptiveTextSize.Medium, + HorizontalAlignment = AdaptiveHorizontalAlignment.Center, + Spacing = AdaptiveSpacing.None + } + }, + SelectAction = new AdaptiveOpenUrlAction() + { + Url = new Uri(extendedDeepLink), + Title = "Extended Deeplink features" + } + } + } + } + }.Concat(!string.IsNullOrEmpty(sidePanelLink) ? new[] + { + new AdaptiveColumnSet() + { + Columns = new List() + { + new AdaptiveColumn() + { + Width = AdaptiveColumnWidth.Auto, + Items = new List() + { + new AdaptiveTextBlock() + { + Text = "Side Panel Deeplink", + Color = AdaptiveTextColor.Accent, + Size = AdaptiveTextSize.Medium, + HorizontalAlignment = AdaptiveHorizontalAlignment.Center, + Spacing = AdaptiveSpacing.None + } + }, + SelectAction = new AdaptiveOpenUrlAction() + { + Url = new Uri(sidePanelLink), + Title = "Deeplink to sidepanel" + } + } + } + } + } : new AdaptiveElement[0]).ToList() + } + } + }; + + var acard = new Attachment() + { + ContentType = AdaptiveCard.ContentType, + Content = Newtonsoft.Json.JsonConvert.DeserializeObject(DeepLinkCard.ToJson()) + }; + return acard; + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Controllers/BotController.cs b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Controllers/BotController.cs new file mode 100644 index 0000000000..f08f008003 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Controllers/BotController.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; + +namespace Microsoft.BotBuilderSamples.Controllers +{ + // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot + // implementation at runtime. Multiple different IBot implementations running at different endpoints can be + // achieved by specifying a more specific type for the bot constructor argument. + [Route("api/messages")] + [ApiController] + public class BotController : ControllerBase + { + private readonly CloudAdapter Adapter; + private readonly IBot Bot; + + public BotController(CloudAdapter adapter, IBot bot) + { + Adapter = adapter; + Bot = bot; + } + + [HttpPost, HttpGet] + public async Task PostAsync() + { + // Delegate the processing of the HTTP POST to the adapter. + // The adapter will invoke the bot. + await Adapter.ProcessAsync(Request, Response, Bot); + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Controllers/HomeController.cs b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Controllers/HomeController.cs new file mode 100644 index 0000000000..b876ef78b4 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Controllers/HomeController.cs @@ -0,0 +1,210 @@ +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// + +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Mvc; +using Microsoft.BotBuilderSamples.Bots; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.BotBuilderSamples.Controllers +{ + public class HomeController : Controller + { + public readonly IConfiguration _configuration; + public HomeController(IConfiguration configuration) + { + _configuration = configuration; + } + public string channelID = DeepLinkBot.channelID; + public string teamsUrl = "https://teams.microsoft.com/l/entity/"; + + public static List deeplinks = new List(); + public DeepLinksModel task1Link; + public DeepLinksModel task2Link; + public DeepLinksModel task3Link; + + public static List channelDeeplinks = new List(); + public DeepLinkChannelModel task1ChannelLink; + public DeepLinkChannelModel task2ChannelLink; + public DeepLinkChannelModel task3ChannelLink; + + DeeplinkHelper deeplinkHelper = new DeeplinkHelper(); + public IActionResult Index() + { + return View(); + } + + [Route("DeepLink")] + public ActionResult DeepLink() + { + if (deeplinks.Count == 0) + { + task1Link = new DeepLinksModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["TabEntityId"], "topic1"), + ID = 1, + linkTitle = "Bots in Teams" + }; + + task2Link = new DeepLinksModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["TabEntityId"], "topic2"), + ID = 2, + linkTitle = "Bot Frawework SDK" + }; + + task3Link = new DeepLinksModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["TabEntityId"], "topic3"), + ID = 3, + linkTitle = "Teams Apps" + }; + + deeplinks.Add(task1Link); + deeplinks.Add(task2Link); + deeplinks.Add(task3Link); + } + + return View(deeplinks); + } + + + [Route("DeepLinkChannel")] + public ActionResult DeepLinkChannel() + { + if (channelDeeplinks.Count == 0) + { + task1ChannelLink = new DeepLinkChannelModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"],_configuration["BaseURL"],channelID,_configuration["ChannelEntityId"], "bot1"), + ID = 1, + linkTitle = "Bots in Teams" + }; + + task2ChannelLink = new DeepLinkChannelModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], "bot2"), + ID = 2, + linkTitle = "Bot Frawework SDK" + + }; + + task3ChannelLink = new DeepLinkChannelModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], "bot3"), + ID = 3, + linkTitle = "Teams Apps" + }; + + channelDeeplinks.Add(task1ChannelLink); + channelDeeplinks.Add(task2ChannelLink); + channelDeeplinks.Add(task3ChannelLink); + } + ViewBag.AppId = _configuration["TeamsAppId"]; + return View(channelDeeplinks); + } + + + [Route("ChannelView")] + public ActionResult ChannelView() + { + if (channelDeeplinks.Count == 0) + { + task1ChannelLink = new DeepLinkChannelModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], "bot1"), + ID = 1, + linkTitle = "Bots in Teams" + }; + + task2ChannelLink = new DeepLinkChannelModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], "bot2"), + ID = 2, + linkTitle = "Bot Frawework SDK" + + }; + + task3ChannelLink = new DeepLinkChannelModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToChannelTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["BaseURL"], channelID, _configuration["ChannelEntityId"], "bot3"), + ID = 3, + linkTitle = "Teams Apps" + }; + + channelDeeplinks.Add(task1ChannelLink); + channelDeeplinks.Add(task2ChannelLink); + channelDeeplinks.Add(task3ChannelLink); + } + + return View(channelDeeplinks); + } + + [Route("Configure")] + public ActionResult Configure() + + { + return View(); + } + + [Route("TaskList")] + public ActionResult TaskList() + { + if (deeplinks.Count == 0) + { + task1Link = new DeepLinksModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["TabEntityId"], "topic1"), + ID = 1, + linkTitle = "Bots in Teams" + }; + + task2Link = new DeepLinksModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["TabEntityId"], "topic2"), + ID = 2, + linkTitle = "Bot Frawework SDK" + }; + + task3Link = new DeepLinksModel() + { + linkUrl = deeplinkHelper.GetDeepLinkToTabTask(teamsUrl, _configuration["MicrosoftAppId"], _configuration["TabEntityId"], "topic3"), + ID = 3, + linkTitle = "Teams Apps" + }; + + deeplinks.Add(task1Link); + deeplinks.Add(task2Link); + deeplinks.Add(task3Link); + } + + return View(deeplinks); + } + + [Route("Detail/{id}")] + public ActionResult Detail(int id) + { + return View(deeplinks.FirstOrDefault(i => i.ID == id)); + } + + [Route("DetailChannel/{id}")] + public ActionResult DetailChannel(int id) + { + var model = new DeepLinkChannelModel + { + ID = id + }; + + return View(model); + } + + [Route("ExtendedDeepLinks")] + public PartialViewResult ExtendedDeepLinks() + { + return PartialView(); + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/DeepLinkBot.csproj b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/DeepLinkBot.csproj new file mode 100644 index 0000000000..8ed722947c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/DeepLinkBot.csproj @@ -0,0 +1,21 @@ + + + + net10.0 + enable + latest + + + + + + + + + + + Always + + + + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Models/DeepLinkChannelModel.cs b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Models/DeepLinkChannelModel.cs new file mode 100644 index 0000000000..b47e0380e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Models/DeepLinkChannelModel.cs @@ -0,0 +1,9 @@ +namespace Microsoft.BotBuilderSamples.Controllers +{ + public class DeepLinkChannelModel + { + public string linkUrl { get; set; } + public int ID { get; set; } + public string linkTitle { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Models/DeepLinksModel.cs b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Models/DeepLinksModel.cs new file mode 100644 index 0000000000..712730180c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Models/DeepLinksModel.cs @@ -0,0 +1,9 @@ +namespace Microsoft.BotBuilderSamples.Controllers +{ + public class DeepLinksModel + { + public string linkUrl { get; set; } + public int ID { get; set; } + public string linkTitle { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Program.cs b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Program.cs new file mode 100644 index 0000000000..f5409fee9c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Program.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.BotBuilderSamples; +using Microsoft.BotBuilderSamples.Bots; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers().AddNewtonsoftJson(); +builder.Services.AddRazorPages(); + +// Create the Bot Framework Adapter with error handling enabled. +builder.Services.AddSingleton(); + +// Create the bot as a transient. In this case the ASP Controller is expecting an IBot. +builder.Services.AddTransient(); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +} + +app.UseDefaultFiles(); +app.UseStaticFiles(); +app.UseWebSockets(); +app.UseRouting(); +app.UseAuthorization(); + +app.MapControllerRoute("default", "{controller=Home}/{action=Index}"); + +app.Run(); + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Properties/launchSettings.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Properties/launchSettings.json new file mode 100644 index 0000000000..ff9d8fe153 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "Start Project": { + "commandName": "Project", + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7130;http://localhost:5130", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Services/DeeplinkHelper.cs b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Services/DeeplinkHelper.cs new file mode 100644 index 0000000000..8fb85938b3 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Services/DeeplinkHelper.cs @@ -0,0 +1,84 @@ +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// + +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Text; +using System.Web; + +namespace Microsoft.BotBuilderSamples.Bots +{ + public class DeeplinkHelper + { + /// + /// Method to generate deeplink to tab. + /// + /// Teams deeplink url. + /// Application id of the app. + /// Entity id of the tab. + /// Sub entity id of the tab. + public string GetDeepLinkToTabTask(string teamsUrl, string appID, string entityId, string subEntityID) + { + Dictionary task1Values = new Dictionary + { + {"subEntityId",subEntityID } + }; + string jsoncontext = JsonConvert.SerializeObject(task1Values); + string taskContext = HttpUtility.UrlEncode(jsoncontext); + string deepLinkURL = teamsUrl + appID + "/" + entityId + "?context="; + string channelDeepLink = deepLinkURL + taskContext; + return channelDeepLink; + } + + /// + /// Method to generate deeplink to meeting sidepanel. + /// + /// Teams deeplink url. + /// Application id of the app. + /// Base url of the application. + /// Entity id of the tab. + /// Chat id of the meeting group chat. + /// Chat context where app is installed. + public string GetDeepLinkToMeetingSidePanel(string teamsUrl, string appID, string baseUrl, string entityId, string chatId, string contextType) + { + StringBuilder sb = new StringBuilder(); + sb.Append("{"); + sb.Append("\"chatId\":\"" + chatId + "\","); + sb.Append("\"contextType\":\"" + contextType + "\""); + sb.Append("}"); + + string jsoncontext = sb.ToString(); + string taskContext = HttpUtility.UrlEncode(jsoncontext); + string encodedUrl = HttpUtility.UrlEncode(baseUrl + "/appInMeeting"); + string deepLinkURL = teamsUrl + appID + "/" + entityId + "?webUrl=" + encodedUrl + "&context="; + string sidePanelDeepLink = deepLinkURL + taskContext; + return sidePanelDeepLink; + } + + /// + /// Method to generate deeplink to channel tab. + /// + /// Teams deeplink url. + /// Application id of the app. + /// Base url of the application. + /// Channel id of teams channel where app is installed. + /// Entity id of the tab. + /// Sub entity id of the tab. + public string GetDeepLinkToChannelTask(string teamsUrl, string appID, string baseUrl, string channelId, string entityId, string subEntityID) + { + StringBuilder sb = new StringBuilder(); + sb.Append("{"); + sb.Append("\"subEntityId\":\"" + subEntityID + "\","); + sb.Append("\"channelId\":\"" + channelId + "\""); + sb.Append("}"); + string channelContext = sb.ToString(); + string encodedUrl = HttpUtility.UrlEncode(baseUrl + "/DeepLinkChannel"); + string taskContext = HttpUtility.UrlEncode(channelContext); + string deepLinkURL = teamsUrl + appID + "/" + entityId + "?webUrl=" + encodedUrl + "&label=Topic&context="; + string channelDeepLink = deepLinkURL + taskContext; + return channelDeepLink; + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/ChannelView.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/ChannelView.cshtml new file mode 100644 index 0000000000..6cbc77ceff --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/ChannelView.cshtml @@ -0,0 +1,38 @@ +@model IEnumerable + + + + + + + + + @foreach (var item in Model) + { + + + + + + } +
+ @Html.ActionLink(item.linkTitle, "DetailChannel", new { id = item.ID }) +
+ +
+ + Extended Deep link features + + @{ + Html.RenderPartial("ExtendedDeepLinks"); + } +
\ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/Configure.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/Configure.cshtml new file mode 100644 index 0000000000..f81cf82b02 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/Configure.cshtml @@ -0,0 +1,20 @@ + + +

Click on save to configure the tab.

+ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DeepLink.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DeepLink.cshtml new file mode 100644 index 0000000000..b879dd259c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DeepLink.cshtml @@ -0,0 +1,72 @@ +@model IEnumerable + + + + + + +
+
+ +Back To List + + + + @foreach (var item in Model) + { + + + + + + } +
+ @Html.ActionLink(item.linkTitle, "Detail", new { id = item.ID }) +
+ +
+ + Extended Deep link features + + @{ + Html.RenderPartial("ExtendedDeepLinks"); + } +
\ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DeepLinkChannel.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DeepLinkChannel.cshtml new file mode 100644 index 0000000000..b95584bc0a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DeepLinkChannel.cshtml @@ -0,0 +1,155 @@ +@model IEnumerable + + + + + + +
+
+ +
@Html.ActionLink("Back to List", "ChannelView")
+ + + + @foreach (var item in Model) + { + + + + + + } +
+ @Html.ActionLink(item.linkTitle, "DetailChannel", new { id = item.ID }) +
+ +
+ + + + + + +
\ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/Detail.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/Detail.cshtml new file mode 100644 index 0000000000..28cccb0305 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/Detail.cshtml @@ -0,0 +1,18 @@ + +@{ ViewBag.Title = "Detail"; } +@model Microsoft.BotBuilderSamples.Controllers.DeepLinksModel + + + + + +

+ @Html.ActionLink("Back to List", "TaskList") +

+ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DetailChannel.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DetailChannel.cshtml new file mode 100644 index 0000000000..66b8d13133 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/DetailChannel.cshtml @@ -0,0 +1,36 @@ + +@{ ViewBag.Title = "DetailChannel"; } +@model Microsoft.BotBuilderSamples.Controllers.DeepLinkChannelModel + + + + +
+
+ +

+ @Html.ActionLink("Back to List", "ChannelView") +

+ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/ExtendedDeepLinks.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/ExtendedDeepLinks.cshtml new file mode 100644 index 0000000000..32c399050f --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/ExtendedDeepLinks.cshtml @@ -0,0 +1,247 @@ +@{ + ViewBag.Title = "Detail"; +} + + + + + + +
+
+
+
+
+
+
+ Add this app in meeting side panel and stage this tab to experience deeplink to meeting side panel. +
+
+
+
+
+
+
+
+
+
+ Audio call members using the v2.0 SDK method +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.call.startCall({ targets: usersEmailArray,
+        requestedModalities: [microsoftTeams.call.CallModalities.Audio]})
+    .then((result) => {
+        console.log(result);
+    }).catch((error) => {
+            console.log(error);
+    });
+                            
+
+
Select members and make a call.
+
+ +
+
+
+
+
+
+ Video call members using the v2.0 SDK method +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.call.startCall({ targets: usersEmailArray,
+    requestedModalities: [microsoftTeams.call.CallModalities.Video]})
+.then((result) => {
+    console.log(result);
+}).catch((error) => {
+        console.log(error);
+});
+                            
+
+
Select members and make a call.
+
+ +
+
+
+
+
+
+
+
Open a scheduling dialog
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink("https://teams.microsoft.com/l/meeting/new?subject=Meeting Subject"
++ "&startTime=2022-07-24T10:30:00"
++ "&endTime=2022-07-24T11:30:00"
++ "&content=Meeting Content"
++ "&attendees=abc@ms.com,bcd@ms.com")
+                            
+
+
+
+ Add Details for scheduling dialog +
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ +
+
+
+
+
+
+ Open a Polly app install dialog +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink("https://teams.microsoft.com/l/app/1542629c-01b3-4a6d-8f76-1938b779e48d")
+                            
+
+
+ +
+
+
+
+
+
+
+
+ Start new chat +
+
+ To use this option, configure the function using following + parameters + +
+const chatPromise = chat.openGroupChat({ users: [user] });
+    chatPromise.
+        then((result) => { console.log(result) }).
+        catch((error) => { console.log(error) });
+                            
+
+
+ +
+
+
+
+
+
+ Navigate to chat (Personal chat with bot) +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink(`https://teams.microsoft.com/l/entity{appId}/conversations`);
+                            
+
+
+ +
+
+
+
+
+
+
+
+ Navigate to teams chat (Works in teams chat only) +
+
+ To use this option, configure the function using following + parameters + +
+const queryParameters = {
+    channelId: context.channel.id,
+    tenantId: context.user.tenant.id,
+    groupId: context.team.groupId,
+    parentMessageId: context.app.parentMessageId,
+    teamName: context.team.displayName,
+    channelName: context.channel.displayName
+            }
+
+microsoftTeams.app.openLink(`https://teams.microsoft.com/l/message/${queryParameters.channelId}/tenantId=${queryParameters.tenantId}&groupId=${queryParameters.groupId}&parentMessageId=${queryParameters.parentMessageId}&teamName=${queryParameters.teamName}&channelName=${queryParameters.channelName}`)
+                            
+
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/TaskList.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/TaskList.cshtml new file mode 100644 index 0000000000..4f163d4362 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Home/TaskList.cshtml @@ -0,0 +1,41 @@ +@model IEnumerable + + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + } +
+ @Html.ActionLink(item.linkTitle, "Detail", new { id = item.ID }) +
+ +
+ + Extended Deep link features + + @{ + Html.RenderPartial("ExtendedDeepLinks"); + } +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Shared/_Layout.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..5fb3e77d19 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/Shared/_Layout.cshtml @@ -0,0 +1,18 @@ + + + + Microsoft Teams Hello World Sample App + + + @RenderSection("scripts", required: false) + + +
+
+ @RenderBody() +
+
+ + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/_ViewStart.cshtml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/appsettings.Development.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/appsettings.Development.json new file mode 100644 index 0000000000..e203e9407e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/appsettings.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/appsettings.json new file mode 100644 index 0000000000..97cfe864ce --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/appsettings.json @@ -0,0 +1,11 @@ +{ + "TeamsAppId": "", + "MicrosoftAppId": "", + "MicrosoftAppPassword": "", + "MicrosoftAppType": "SingleTenant", + "MicrosoftAppTenantId": "", + "BaseURL": "", + "ChannelEntityId": "DeepLinkApp", + "TabEntityId": "com.contoso.DeeplLinkBot.help", + "ManifestAppId": "" +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_Chat_Addapp.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_Chat_Addapp.png new file mode 100644 index 0000000000..5694703367 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_Chat_Addapp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_P_app.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_P_app.png new file mode 100644 index 0000000000..02b098f5e5 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_P_app.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_Team_selection.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_Team_selection.png new file mode 100644 index 0000000000..a02e39c3f7 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_Team_selection.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_meeting_appopen.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_meeting_appopen.png new file mode 100644 index 0000000000..94c758f834 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/01_meeting_appopen.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Chat_Addmember.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Chat_Addmember.png new file mode 100644 index 0000000000..547fa58542 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Chat_Addmember.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Meeting_selectapp.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Meeting_selectapp.png new file mode 100644 index 0000000000..4b9dcf01f1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Meeting_selectapp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_P_Welecomecard.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_P_Welecomecard.png new file mode 100644 index 0000000000..a3783a95eb Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_P_Welecomecard.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Team_AddtoTeam.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Team_AddtoTeam.png new file mode 100644 index 0000000000..d57241c574 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/02_Team_AddtoTeam.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_Chat_appopen.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_Chat_appopen.png new file mode 100644 index 0000000000..ce258397d6 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_Chat_appopen.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_P_Welcomemsg.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_P_Welcomemsg.png new file mode 100644 index 0000000000..a3783a95eb Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_P_Welcomemsg.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_Team_SelectTeam.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_Team_SelectTeam.png new file mode 100644 index 0000000000..3a89902674 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_Team_SelectTeam.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_meeting_configuretab.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_meeting_configuretab.png new file mode 100644 index 0000000000..ce258397d6 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/03_meeting_configuretab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Chat_defaultapp.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Chat_defaultapp.png new file mode 100644 index 0000000000..31f77ca53f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Chat_defaultapp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Meeting_defaultpage.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Meeting_defaultpage.png new file mode 100644 index 0000000000..196b8ba011 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Meeting_defaultpage.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_P_text.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_P_text.png new file mode 100644 index 0000000000..4a1428fc5a Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_P_text.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Team_AppSetupforTeam.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Team_AppSetupforTeam.png new file mode 100644 index 0000000000..727c51bbe1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/04_Team_AppSetupforTeam.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/05_P_ResponseCard.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/05_P_ResponseCard.png new file mode 100644 index 0000000000..056195f502 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/05_P_ResponseCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/05_Team_AppLoad.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/05_Team_AppLoad.png new file mode 100644 index 0000000000..84bee8db22 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/05_Team_AppLoad.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/06_P_BotTeamDeeplink.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/06_P_BotTeamDeeplink.png new file mode 100644 index 0000000000..213d48a2f2 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/06_P_BotTeamDeeplink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/06_Team_Page.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/06_Team_Page.png new file mode 100644 index 0000000000..971bd7988d Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/06_Team_Page.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/07_P_BotSDKLink.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/07_P_BotSDKLink.png new file mode 100644 index 0000000000..3781152012 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/07_P_BotSDKLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/07_Team_DeeplinBotTeam.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/07_Team_DeeplinBotTeam.png new file mode 100644 index 0000000000..971bd7988d Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/07_Team_DeeplinBotTeam.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/08_P_Teamappslink.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/08_P_Teamappslink.png new file mode 100644 index 0000000000..5798dfbd60 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/08_P_Teamappslink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/08_Team_PostBotTeam.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/08_Team_PostBotTeam.png new file mode 100644 index 0000000000..db910dffef Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/08_Team_PostBotTeam.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/09_P_DeepLinkTab.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/09_P_DeepLinkTab.png new file mode 100644 index 0000000000..31f77ca53f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/09_P_DeepLinkTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/09_Team_BotSDKClick.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/09_Team_BotSDKClick.png new file mode 100644 index 0000000000..0d93e3fbda Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/09_Team_BotSDKClick.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/10_Team_postBotSDK.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/10_Team_postBotSDK.png new file mode 100644 index 0000000000..bcc797f122 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/10_Team_postBotSDK.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/11_Team_Postteamsapp.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/11_Team_Postteamsapp.png new file mode 100644 index 0000000000..2605787719 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/11_Team_Postteamsapp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/12_Audioclick.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/12_Audioclick.png new file mode 100644 index 0000000000..f574b904e8 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/12_Audioclick.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/13_Team_Selectpeopleaudio.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/13_Team_Selectpeopleaudio.png new file mode 100644 index 0000000000..8755141fd8 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/13_Team_Selectpeopleaudio.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/14_Team_StartaudioCall.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/14_Team_StartaudioCall.png new file mode 100644 index 0000000000..162d34f259 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/14_Team_StartaudioCall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/15_Team_Postaudiostartcall.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/15_Team_Postaudiostartcall.png new file mode 100644 index 0000000000..353e33448b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/15_Team_Postaudiostartcall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/16_Team_AudiocallScreen.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/16_Team_AudiocallScreen.png new file mode 100644 index 0000000000..fa15f5763b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/16_Team_AudiocallScreen.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/17_Team_Endaudiocall.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/17_Team_Endaudiocall.png new file mode 100644 index 0000000000..0f0dc9d374 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/17_Team_Endaudiocall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/18_Team_postclickVedioCall.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/18_Team_postclickVedioCall.png new file mode 100644 index 0000000000..164d173e11 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/18_Team_postclickVedioCall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/19_Team_VideoStart.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/19_Team_VideoStart.png new file mode 100644 index 0000000000..e20b3d4700 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/19_Team_VideoStart.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/20_Teams_VedioStart.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/20_Teams_VedioStart.png new file mode 100644 index 0000000000..6ba5158e00 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/20_Teams_VedioStart.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/21_Team_SechuleMeeting.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/21_Team_SechuleMeeting.png new file mode 100644 index 0000000000..51828c7f33 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/21_Team_SechuleMeeting.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/22_Team_PostScheduleMeeting.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/22_Team_PostScheduleMeeting.png new file mode 100644 index 0000000000..5cadb192f1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/22_Team_PostScheduleMeeting.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/24_Team_AddApp.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/24_Team_AddApp.png new file mode 100644 index 0000000000..4f877e2e34 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/24_Team_AddApp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/AppOffice.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/AppOffice.png new file mode 100644 index 0000000000..2934c4221b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/AppOutlook.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/AppOutlook.png new file mode 100644 index 0000000000..b818081205 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/BotAdaptiveCard.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/BotAdaptiveCard.png new file mode 100644 index 0000000000..ff0d6022d1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/BotAdaptiveCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/BotCard.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/BotCard.png new file mode 100644 index 0000000000..11468116fb Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/BotCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/ChannelTab.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/ChannelTab.png new file mode 100644 index 0000000000..9a13908c5e Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/ChannelTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab.png new file mode 100644 index 0000000000..51828c7f33 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab2.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab2.png new file mode 100644 index 0000000000..45bbddd4ed Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab2.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab2Polly.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab2Polly.png new file mode 100644 index 0000000000..da098d5602 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTab2Polly.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTabVideo.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTabVideo.png new file mode 100644 index 0000000000..9a6925e89c Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/DeepLinkTabVideo.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/GroupChat.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/GroupChat.png new file mode 100644 index 0000000000..034f8efeb3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/GroupChat.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/GroupChatDeepLink.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/GroupChatDeepLink.png new file mode 100644 index 0000000000..abd245be20 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/GroupChatDeepLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/InstallOffice.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/InstallOffice.png new file mode 100644 index 0000000000..92f4255c74 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/InstallOutlook.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/InstallOutlook.png new file mode 100644 index 0000000000..81ea427e9e Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/MeetingStageView.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/MeetingStageView.png new file mode 100644 index 0000000000..2252dc1268 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/MeetingStageView.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Personal_CardDeeplink.gif b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Personal_CardDeeplink.gif new file mode 100644 index 0000000000..fecea29d89 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Personal_CardDeeplink.gif differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/RedirectTab.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/RedirectTab.png new file mode 100644 index 0000000000..213d48a2f2 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/RedirectTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/SidePanelTab.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/SidePanelTab.png new file mode 100644 index 0000000000..b2a5ab4d74 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/SidePanelTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Sidepanel.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Sidepanel.png new file mode 100644 index 0000000000..b2a5ab4d74 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Sidepanel.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/StartChatDeepLink.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/StartChatDeepLink.png new file mode 100644 index 0000000000..bb242a0a25 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/StartChatDeepLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/StartNewChat.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/StartNewChat.png new file mode 100644 index 0000000000..5faca00956 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/StartNewChat.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Tab_DeepLink.gif b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Tab_DeepLink.gif new file mode 100644 index 0000000000..782199506b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Tab_DeepLink.gif differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Tab_Deeplink_Team.gif b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Tab_Deeplink_Team.gif new file mode 100644 index 0000000000..4e4e05d8fb Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/Tab_Deeplink_Team.gif differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/TeamsAdminPortal.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/TeamsAdminPortal.png new file mode 100644 index 0000000000..c9d8df047f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/images/TeamsAdminPortal.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/default.html b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/default.html new file mode 100644 index 0000000000..aea493b517 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/default.html @@ -0,0 +1,418 @@ + + + + + + + EchoBot + + + + + +
+
+
+
EchoBot
+
+
+
+
+
Your bot is ready!
+
You can test your bot in the Bot Framework Emulator
+ by connecting to http://localhost:3978/api/messages.
+ +
Visit Azure + Bot Service to register your bot and add it to
+ various channels. The bot's endpoint URL typically looks + like this:
+
https://your_bots_hostname/api/messages
+
+
+
+
+ +
+ + + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/js/DeeplinkFeatures.js b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/js/DeeplinkFeatures.js new file mode 100644 index 0000000000..154155d265 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/js/DeeplinkFeatures.js @@ -0,0 +1,114 @@ +// Initialize the library. +microsoftTeams.app.initialize(); + +// Select people for fetching the attendees. +function selectPeople() { + microsoftTeams.people.selectPeople({ setSelected: [], openOrgWideSearchInChatOrChannel: true, singleSelect: false }).then((people) => { + if (people) { + document.getElementById("Attendee").value = (people.map((p) => p.email)).join(","); + } + }).catch((error) => { + console.log(error); + }); +} + +// function which redirects the user to start new chat. +function startNewChat() { + // Declare microsoftTeams chat + var chat = microsoftTeams.chat; + + // Declare microsoftTeams.app + var app = microsoftTeams.app; + + app.initialize().then(app.getContext).then((context) => { + + // get the current user. + let user = context.user.loginHint; + + if (chat.isSupported()) { + const chatPromise = chat.openGroupChat({ users: [user] }); + chatPromise. + then((result) => { console.log(result) }). + catch((error) => { console.log(error) }); + } + else { + console.log("openGroupChat isn't supported"); + } + + }); +} + +// function to navigate chat with application +function navigateToChatWithApplication() { + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/entity/${env.AppId}/conversations`); +} + +// navigates to teams chat window. +function navigateToTeamsChat() { + let app = microsoftTeams.app; + + app.initialize().then(app.getContext).then((context) => { + const queryParameters = { + channelId: context.channel.id, + tenantId: context.user.tenant.id, + groupId: context.team.groupId, + parentMessageId: context.app.parentMessageId, + teamName: context.team.displayName, + channelName: context.channel.displayName + } + + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/message/${queryParameters.channelId}/tenantId=${queryParameters.tenantId}&groupId=${queryParameters.groupId}&parentMessageId=${queryParameters.parentMessageId}&teamName=${queryParameters.teamName}&channelName=${queryParameters.channelName}`) + }); +} + +// function to navigate chat with application +function onCallDeepLinkButtonClick(callModalities) { + microsoftTeams.people.selectPeople({ setSelected: [], openOrgWideSearchInChatOrChannel: true, singleSelect: false }).then((people) => { + if (people) { + if (microsoftTeams.call.isSupported()) { + microsoftTeams.call.startCall({ + targets: people.map((p) => p.email), + requestedModalities: [callModalities] + }) + .then((result) => { + console.log(result); + }).catch((error) => { + console.log(error); + }); + } + else { + alert("Call isn't supported"); + } + } + }).catch((error) => { + console.log(error); + }); +} + +// function to open scheduling dialog workflow +function onSchedulingDialogClick() { + var subjectInput = document.getElementById("Subject"); + var startTimeInput = document.getElementById("StartTime"); + var endTimeInput = document.getElementById("EndTime"); + var contentInput = document.getElementById("Content"); + var attendeeInput = document.getElementById("Attendee"); + + if (subjectInput.value.trim() !== "" && startTimeInput.value !== "" && endTimeInput.value !== "" && attendeeInput.value !== "") { + var meetingDetails = + { + attendees: attendeeInput.value, + content: contentInput.value.trim(), + endTime: endTimeInput.value, + startTime: startTimeInput.value, + subject: subjectInput.value.trim(), + }; + + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/meeting/new?subject=${meetingDetails.subject}&startTime=${meetingDetails.startTime}&endTime=${meetingDetails.endTime}&content=${meetingDetails.content}&attendees=${meetingDetails.attendees}`) + } +} + +// function to open app installation dialog workflow +// Below app id is for harcoded for polly app which is already available in store. +function onAppInstallDialogClick() { + microsoftTeams.app.openLink("https://teams.microsoft.com/l/app/1542629c-01b3-4a6d-8f76-1938b779e48d"); +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/js/env.js b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/js/env.js new file mode 100644 index 0000000000..728c0506d0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/js/env.js @@ -0,0 +1,3 @@ +env = { + AppId: "<>" +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/style.css b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/style.css new file mode 100644 index 0000000000..ea4b9bd181 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/DeepLinkBot/wwwroot/style.css @@ -0,0 +1,65 @@ +pre { + overflow-x: scroll; +} + +.callDeeplinkButton { + font-family: "Segoe UI","Apple Color Emoji","Segoe UI Emoji","Segoe UI Web"; + font-weight: 700; + background-color: #444791; + cursor: pointer; + color: white; + width: 50px; + border-radius: 8px; + border: none; + margin-top: 1rem; + padding: 10px 0px; + text-align: center; + text-decoration: none; +} + + .callDeeplinkButton:hover { + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); + } + +.inputContainer { + margin-top: 10px; +} + +.container { + font-family: "Segoe UI","Apple Color Emoji","Segoe UI Emoji","Segoe UI Web"; + font-size: 14px; +} + +.card { + box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%); + width: 27rem; + min-height: 18rem; + overflow: hidden; + margin-left: 2rem; + margin-top: 0.5rem; +} + +.card-container-div { + padding-bottom: 2rem; + display: flex; +} + +.card-header { + margin-left: 1rem; + margin-right: 1rem; + margin-top: 1rem; + padding-top: 0.5rem; + font-size: 16px !important; +} + +button { + margin: 1rem 8.5rem 1rem 11.5rem; +} + +.form-container { + margin-left: 1rem; +} + +.card-body { + margin-left: 0.5rem; +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/M365Agent.ttkproj b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/M365Agent.ttkproj new file mode 100644 index 0000000000..b0be8d6f13 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/M365Agent.ttkproj @@ -0,0 +1,14 @@ + + + + bd528da9-f03f-4914-9eac-97c61793cc67 + + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/aad.manifest.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/aad.manifest.json new file mode 100644 index 0000000000..155d4390d7 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/aad.manifest.json @@ -0,0 +1,100 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "displayName": "tab-deeplink-aad", + "signInAudience": "AzureADMultipleOrgs", + "api": { + "requestedAccessTokenVersion": 2, + "oauth2PermissionScopes": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ] + }, + "info": {}, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "publicClient": {}, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "web": { + "implicitGrantSettings": {} + }, + "spa": {} +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/color.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/manifest.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/manifest.json new file mode 100644 index 0000000000..19093bae70 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/manifest.json @@ -0,0 +1,87 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Deep Link Bot", + "full": "Bot for Deep linking to tab" + }, + "description": { + "short": "Sample Teams app showcasing deeplinks for calls, chats, and navigation.", + "full": "This Teams sample application highlights deeplinks for various functionalities, such as initiating calls, chats, and navigating within tabs and apps. It features a comprehensive setup guide and supports interactions with both bots and tabs for enhanced user engagement." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "accentColor": "#60A18E", + "configurableTabs": [ + { + "configurationUrl": "${{BOT_ENDPOINT}}/Configure", + "canUpdateConfiguration": true, + "scopes": [ + "groupChat", + "team" + ], + "context": [ + "channelTab", + "privateChatTab", + "meetingSidePanel", + "meetingStage", + "meetingChatTab", + "meetingDetailsTab" + ] + } + ], + "staticTabs": [ + { + "contentUrl": "${{BOT_ENDPOINT}}/DeepLink", + "websiteUrl": "${{BOT_ENDPOINT}}", + "entityId": "com.contoso.DeeplLinkBot.help", + "name": "Deep Link Tab", + "scopes": [ + "personal" + ] + } + ], + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "needsChannelSelector": false, + "isNotificationOnly": false, + "scopes": [ + "groupChat", + "personal", + "team" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{BOT_DOMAIN}}" + ], + "authorization": { + "permissions": { + "resourceSpecific": [ + { + "name": "MeetingStage.Write.Chat", + "type": "Delegated" + }, + { + "name": "ChannelMeetingStage.Write.Group", + "type": "Delegated" + } + ] + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/outline.png b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/appPackage/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/env/.env.local b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/env/.env.local new file mode 100644 index 0000000000..0024c338a7 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/env/.env.local @@ -0,0 +1,26 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local +APP_NAME_SUFFIX=local + +# Generated during provision, you can also add your own variables. +BOT_ID= +TEAMS_APP_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= +M365_TITLE_ID= +M365_APP_ID= +TEAMSFX_M365_USER_NAME= + +BOT_ENDPOINT= +BOT_DOMAIN= diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/infra/azure.bicep b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/infra/azure.parameters.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/infra/azure.parameters.json new file mode 100644 index 0000000000..1f27d78ac7 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "tab-deeplink" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/launchSettings.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/launchSettings.json new file mode 100644 index 0000000000..a750f7154e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/launchSettings.json @@ -0,0 +1,21 @@ +{ + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + }, + "Outlook (browser)": { + "commandName": "Project", + "launchUrl": "https://outlook.office.com/host/${{M365_APP_ID}}?login_hint=${{TEAMSFX_M365_USER_NAME}}" + } + }, + // Launch project within Teams without prepare app dependencies + "Microsoft Teams (browser) (skip update app)": { + "commandName": "Project", + "environmentVariables": { + "UPDATE_TEAMS_APP": "false" + }, + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/m365agents.local.yml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/m365agents.local.yml new file mode 100644 index 0000000000..2f219fbff8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/m365agents.local.yml @@ -0,0 +1,106 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-deeplink-csharp + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: tab-deeplink-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMultipleOrgs" # Multitenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-deeplink-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ../DeepLinkBot/appsettings.json + content: + TeamsAppId: ${{TEAMS_APP_ID}} + MicrosoftAppType: ${{MICROSOFT_APP_TYPE}} + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + BaseURL: ${{BOT_DOMAIN}} + ManifestAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appPackage/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Extend your Teams app to Outlook and the Microsoft 365 app + - uses: teamsApp/extendToM365 + with: + # Relative path to the build app package. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + titleId: M365_TITLE_ID + appId: M365_APP_ID \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/m365agents.yml b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/m365agents.yml new file mode 100644 index 0000000000..1eb2df44c9 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/M365Agent/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-deeplink-csharp + +environmentFolderPath: ./env \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/README.md b/samples/TeamsSDK/Archived/tab-deeplink/csharp/README.md new file mode 100644 index 0000000000..4202319b70 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/README.md @@ -0,0 +1,320 @@ +--- +page_type: sample +description: This Teams sample application highlights deeplinks for various functionalities, such as initiating calls, chats, and navigating within tabs and apps. It features a comprehensive setup guide and supports interactions with both bots and tabs for enhanced user engagement. +products: +- office-teams +- office +- office-365 +languages: +- csharp +extensions: + contentType: samples + createdDate: "07/07/2021 01:38:27 PM" +urlFragment: officedev-microsoft-teams-samples-tab-deeplink-csharp +--- + # DeepLink + +Discover this Microsoft Teams sample app designed to demonstrate deeplinks for seamless interactions, including calls, chats, and navigation within tabs and applications. With robust features such as bot integration, a welcome card flow, and detailed setup instructions, this app empowers developers to enhance user experiences and streamline communication within Teams. + + ## Included Features +* Tabs +* Bots +* Deep Links + +## Interaction with bot + + ##### Welcome Card Flow + + ![bot-conversations](DeepLinkBot/images/Personal_CardDeeplink.gif) + + ##### Deeplink Tab Flow + + ![bot-conversations ](DeepLinkBot/images/Tab_DeepLink.gif) + + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant; [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading).). + +**Tab Deeplink:** [Manifest](/samples/tab-deeplink/csharp/demo-manifest/tab-deeplink.zip) + + ## Prerequisites + +- Microsoft Teams is installed and you have an account (not a guest account) +- [.NET Core SDK](https://dotnet.microsoft.com/download) version 6.0 + + ```bash + # determine dotnet version + dotnet --version + ``` +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunneling solution +- [M365 developer account](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the +- [Microsoft 365 Agents Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.14 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Microsoft 365 Agents Toolkit for Visual Studio [Microsoft 365 Agents Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In the debug dropdown menu of Visual Studio, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel. +1. In the debug dropdown menu of Visual Studio, select default startup project > **Microsoft Teams (browser)** +1. Right-click the 'M365Agent' project in Solution Explorer and select **Microsoft 365 Agents Toolkit > Select Microsoft 365 Account** +1. Sign in to Microsoft 365 Agents Toolkit with a **Microsoft 365 work or school account** +1. Set `Startup Item` as `Microsoft Teams (browser)`. +1. Press F5, or select Debug > Start Debugging menu in Visual Studio to start your app +
![image](https://raw.githubusercontent.com/OfficeDev/TeamsFx/dev/docs/images/visualstudio/debug/debug-button.png) +1. In the opened web browser, select Add button to install the app in Teams + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + + ## Setup + + > Note these instructions are for running the sample on your local machine, the tunnelling solution is required because + the Teams service needs to call into the bot. + +1) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +2) Setup for Bot + - Register a Microsoft Entra ID aap registration in Azure portal. + - Also, register a bot with Azure Bot Service, following the instructions [here](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration?view=azure-bot-service-3.0). + - Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/en-us/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - While registering the bot, use `https:///api/messages` as the messaging endpoint. + + > NOTE: When you create your app registration, you will create an App ID and App password - make sure you keep these for later. + +3. Setup NGROK + - Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +4. Setup for code + + - Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + - Update channelID placeholer `` value in your `DeepLinkBot.cs` file with your particular channel id from any Team in Teams. (You can get it manually by clicking on 3 dots in any team's channel and fetch it's link and extract the channel id ) like `General` channel) Example: `19:cbe3683f25094106b826c9cada3afbe0@thread.skype` + + - Navigate to `wwwroot/js/env.js` file and update your AppId at placeholder `<>` (You can get it manually frrm [teams admin portal](https://admin.teams.microsoft.com/). + - ![personal-AddedBot ](DeepLinkBot/images/TeamsAdminPortal.png) + + - Update the `appsettings.json` configuration for the bot to use the MicrosoftAppId, MicrosoftAppPassword, BaseURL , + ChannelEntityId is a unique identifier ,TabEntityId as EntityId from Manifest file ,MannifestAppId as manifest ID from manifest file, + generated in Step 1 (App Registration creation). (Note the App Password is referred to as the "client secret" + in the azure portal and you can always create a new client secret anytime.) + - Also, set MicrosoftAppType in the `appsettings.json`. (**Allowed values are: SingleTenant, UserAssignedMSI**) + + - If you are using Visual Studio + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `samples/Tab-deeplink/csharp` folder + - Select `DeeplinkBot.csproj` or `DeeplinkBot.sln`file + - Run your bot, either from Visual Studio with `F5` or using `dotnet run` in the appropriate folder. + +5. __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appPackage` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* + you see the place holder string `<>` value(depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json` and `${{BOT_DOMAIN}}` with base Url domain. E.g. if you are using ngrok it would be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be `12345.devtunnels.ms`. + - **Edit** the `manifest.json` for `validDomains` with base Url domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + **Note:** If you want to test your app across multi hub like: Outlook/Office.com, please update the `manifest.json` in the `tab-deeplink\csharp\DeepLinkBot\AppManifest_Hub` folder with the required values. + - **Zip** up the contents of the `Manifest` folder to create a `Manifest.zip` or `AppManifest_Hub` folder into a `AppManifest_Hub.zip`. (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + - **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.) + - Add the app to personal/team/groupChat scope (Supported scopes) + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/tab-deeplink/csharp/DeepLinkBot/AdapterWithErrorHandler.cs#L26) line and put your debugger for local debug. + + ## Running the sample + +You can interact with this bot in Teams by sending it a message, or selecting a command from the command list. The bot will respond to the following strings. + +1. **Show Welcome** + + - **Result:** The bot will send the welcome card for you to interact with + - **Valid Scopes:** personal, Team, chat, Meeting + + - **Personal Scope Interactions:** + + **Adding bot UI:** + + ![personal-AddBot ](DeepLinkBot/images/01_P_app.png) + + **Added bot UI:** + + ![personal-AddedBot ](DeepLinkBot/images/02_P_Welecomecard.png) + + **Show Welcome command interaction:** + + ![personal-WelcomeCard-Interaction ](DeepLinkBot/images/05_P_ResponseCard.png) + + **Show Deeplink Tab:** + + ![personal-WelcomeCard-Interaction ](DeepLinkBot/images/08_P_Teamappslink.png) + + + - **Teams Scope Interactions:** + + **Adding bot UI:** + + ![Team-AddBot ](DeepLinkBot/images/02_Team_AddtoTeam.png) + + **Team Selection for app:** + + ![Team-AddedBot ](DeepLinkBot/images/03_Team_SelectTeam.png) + + **App Setup for the specific Team:** + + ![Team-AddedBot ](DeepLinkBot/images/04_Team_AppSetupforTeam.png) + + **Show instraction for the team:** + + ![Team-WelcomeCard-Interaction ](DeepLinkBot/images/06_Team_Page.png) + + **Show Deeplink Tab:** + + ![Team-WelcomeCard-Interaction ](DeepLinkBot/images/08_P_Teamappslink.png) + + + - **Chat Scope Interactions:** + + **Adding bot UI:** + + ![Chat-AddBot ](DeepLinkBot/images/01_Chat_Addapp.png) + + **Chat User Selection:** + + ![Chat-AddedBot ](DeepLinkBot/images/02_Chat_Addmember.png) + + **App setup for the specific chat user:** + + ![Chat-AddedBot ](DeepLinkBot/images/03_Chat_appopen.png) + + **Show user instraction tab:** + + ![Chat-WelcomeCard-Interaction ](DeepLinkBot/images/04_Chat_defaultapp.png) + + + - **Meeting Scope Interactions:** + + **Adding tab UI:** + + ![Meeting-AddBot ](DeepLinkBot/images/01_meeting_appopen.png) + + **Meeting Selection:** + + ![Meeting-AddedBot ](DeepLinkBot/images/02_Meeting_selectapp.png) + + **App setup for the specific chat user:** + + ![Meeting-AddedBot ](DeepLinkBot/images/03_meeting_configuretab.png) + + **Show user instraction tab:** + + ![Meeting-WelcomeCard-Interaction ](DeepLinkBot/images/04_Meeting_defaultpage.png) + + - **Deeplink to meeting side panel:** + + `@mention` bot in meeting chat to get adaptive card. + + ![Bot-Adaptive-Card](DeepLinkBot/images/BotAdaptiveCard.png) + + Click on `Side Panel Deeplink` which will redirect to meeting side panel. + + ![Meeting-Sidepanel](DeepLinkBot/images/Sidepanel.PNG) + + - **Tab Interactions:** + + **Deeplink to Audio Call:** + + ![Audio-Deeplink](DeepLinkBot/images/16_Team_AudiocallScreen.png) + + **Deeplink to Video Call:** + + ![Video-Deeplink](DeepLinkBot/images/19_Team_VideoStart.png) + + **Deeplink to Meeting schedule:** + + ![Meeting-Schedule](DeepLinkBot/images/22_Team_PostScheduleMeeting.png) + + **Deeplink to Polly app install dialog:** + + ![App-Install-Dialog](DeepLinkBot/images/24_Team_AddApp.png) + + **Deeplink to start new chat:** + + ![Start-New-Chat](DeepLinkBot/images/StartChatDeeplink.png) + + ![New-Chat](DeepLinkBot/images/StartNewChat.png) + + **Deeplink to channel conversation:** + + ![Show-Channel-Conversation ](DeepLinkBot/images/GroupChatDeeplink.png) + + ![channel-Conversation](DeepLinkBot/images/GroupChat.png) + + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**On the side bar, select More Apps. Your uploaded app title appears among your installed apps** + +![InstallOutlook](DeepLinkBot/images/InstallOutlook.png) + +**Select your app icon to launch and preview your app running in Outlook on the web** + +![AppOutlook](DeepLinkBot/images/AppOutlook.png) + +**Note:** Similarly, you can test your application in the Outlook desktop app as well. + +## Office on the web + +- To preview your app running in Office on the web. + +- Log into office.com with test tenant credentials + +**Select the Apps icon on the side bar. Your uploaded app title appears among your installed apps** + +![InstallOffice](DeepLinkBot/images/InstallOffice.png) + +**Select your app icon to launch your app in Office on the web** + +![AppOffice](DeepLinkBot/images/AppOffice.png) + +**Note:** Similarly, you can test your application in the Office 365 desktop app as well. + + ## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + + ## Further reading + +- [How Microsoft Teams bots work](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-basics-teams?view=azure-bot-service-4.0&tabs=javascript) + +- [Extend Teams apps across Microsoft 365](https://learn.microsoft.com/en-us/microsoftteams/platform/m365-apps/overview) + + + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/csharp/assets/sample.json b/samples/TeamsSDK/Archived/tab-deeplink/csharp/assets/sample.json new file mode 100644 index 0000000000..3c8b0b7475 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/csharp/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-tab-deeplink-csharp", + "source": "officeDev", + "title": "DeepLink", + "shortDescription": "This Microsoft Teams sample app demonstrates deeplinks for calls, video, chat, and navigation within tabs and apps.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-deeplink/csharp", + "longDescription": [ + "This Teams sample application highlights deeplinks for various functionalities, such as initiating calls, chats, and navigating within tabs and apps. It features a comprehensive setup guide and supports interactions with both bots and tabs for enhanced user engagement." + ], + "creationDateTime": "2021-07-07", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "csharp" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "netframework" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab,bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/tab-deeplink/csharp/DeepLinkBot/images/Team_DeepLink.gif", + "alt": "Solution UX showing deeplink" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.env b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.env new file mode 100644 index 0000000000..be24a50e1f --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.env @@ -0,0 +1,8 @@ +MicrosoftAppId= +MicrosoftAppPassword= +Base_URL= +Tab_Entity_Id=com.contoso.DeeplLinkBot.help +Channel_Entity_Id=DeepLinkApp +TeamsAppId= +MicrosoftAppType=SingleTenant +MicrosoftAppTenantId= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.eslintrc.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.eslintrc.js new file mode 100644 index 0000000000..43b3d45dd2 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.eslintrc.js @@ -0,0 +1,15 @@ +/* eslint-disable */ +module.exports = { + "extends": "standard", + "rules": { + "semi": [2, "always"], + "indent": [2, 4], + "no-return-await": 0, + "space-before-function-paren": [2, { + "named": "never", + "anonymous": "never", + "asyncArrow": "always" + }], + "template-curly-spacing": [2, "always"] + } +}; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.gitignore b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.gitignore new file mode 100644 index 0000000000..6a16d288f8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.gitignore @@ -0,0 +1,17 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appManifest/build +/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store + +# build +lib/ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/extensions.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/extensions.json new file mode 100644 index 0000000000..2d88dee21b --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/launch.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/launch.json new file mode 100644 index 0000000000..d027ed91e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/launch.json @@ -0,0 +1,73 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Local Service", + "type": "node", + "request": "attach", + "port": 9239, + "restart": true, + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/settings.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/settings.json new file mode 100644 index 0000000000..4299620253 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ] +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/tasks.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/tasks.json new file mode 100644 index 0000000000..b79f108ff5 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/.vscode/tasks.json @@ -0,0 +1,105 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Teams App Locally", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy", + "Start application" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "nodejs", // Validate if Node.js is installed. + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + 9239 // app inspector port for Node.js debugger + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + }, + { + "label": "Start application", + "type": "shell", + "command": "npm run dev:teamsfx", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": { + "pattern": [ + { + "regexp": "^.*$", + "file": 0, + "location": 1, + "message": 2 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "[nodemon] starting", + "endsPattern": "Server listening on port:" + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Bots/DeepLinkTabsnode.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Bots/DeepLinkTabsnode.js new file mode 100644 index 0000000000..7037bd7563 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Bots/DeepLinkTabsnode.js @@ -0,0 +1,75 @@ +const fs = require('fs'); +const path = require('path'); +const { TeamsActivityHandler, MessageFactory, CardFactory } = require('botbuilder'); +const AdaptiveCardData = require('adaptivecards-templating'); +const DeepLinkTabHelper = require('../pages/DeepLinkTabHelper.js'); + +// Load the Adaptive Card template once at module load. +const adaptiveCardTemplate = JSON.parse( + fs.readFileSync(path.join(__dirname, '..', 'resources', 'AdaptiveCard.json'), 'utf8') +); + +class DeepLinkTabsnode extends TeamsActivityHandler { + constructor() { + super(); + + this.onMessage(async (context, next) => { + const conversationType = context.activity.conversation.conversationType; + let BotsDeepLink, MessagingDeepLink, AdaptiveCardDeepLink; + let ExtendedDeepLink = ''; + let sidePanelLink = ''; + + if (conversationType === 'channel') { + const channelId = context.activity.channelData.teamsChannelId; + BotsDeepLink = DeepLinkTabHelper.GetDeepLinkTabChannel('topic1', 1, 'Bots', channelId, process.env.TeamsAppId, process.env.Channel_Entity_Id); + MessagingDeepLink = DeepLinkTabHelper.GetDeepLinkTabChannel('topic2', 2, 'Messaging Extension', channelId, process.env.TeamsAppId, process.env.Channel_Entity_Id); + AdaptiveCardDeepLink = DeepLinkTabHelper.GetDeepLinkTabChannel('topic3', 3, 'Adaptive Card', channelId, process.env.TeamsAppId, process.env.Channel_Entity_Id); + ExtendedDeepLink = DeepLinkTabHelper.GetDeepLinkTabChannel('', 4, 'Extended Deeplink features', channelId, process.env.TeamsAppId, process.env.Channel_Entity_Id); + } else { + BotsDeepLink = DeepLinkTabHelper.GetDeepLinkTabStatic('topic1', 1, 'Bots', process.env.TeamsAppId); + MessagingDeepLink = DeepLinkTabHelper.GetDeepLinkTabStatic('topic2', 2, 'Messaging Extension', process.env.TeamsAppId); + AdaptiveCardDeepLink = DeepLinkTabHelper.GetDeepLinkTabStatic('topic3', 3, 'Adaptive Card', process.env.TeamsAppId); + ExtendedDeepLink = DeepLinkTabHelper.GetDeepLinkTabStatic('', 4, 'Extended Deeplink features', process.env.TeamsAppId); + sidePanelLink = DeepLinkTabHelper.GetDeepLinkToMeetingSidePanel(5, 'Side pannel Deeplink', process.env.TeamsAppId, process.env.Base_URL, context.activity.conversation.id, 'chat'); + } + + await context.sendActivity({ + attachments: [this.createAdaptiveCard(BotsDeepLink, MessagingDeepLink, AdaptiveCardDeepLink, ExtendedDeepLink, sidePanelLink)] + }); + + await next(); + }); + + this.onMembersAdded(async (context, next) => { + const membersAdded = context.activity.membersAdded; + const welcomeText = 'Hello and welcome!'; + for (let cnt = 0; cnt < membersAdded.length; ++cnt) { + if (membersAdded[cnt].id !== context.activity.recipient.id) { + await context.sendActivity(MessageFactory.text(welcomeText, welcomeText)); + } + } + await next(); + }); + } + + createAdaptiveCard(BotsDeepLink, MessagingDeepLink, AdaptiveCardDeepLink, ExtendedDeepLink, sidePanelLink) { + const template = new AdaptiveCardData.Template(adaptiveCardTemplate); + const cardPayload = template.expand({ + $root: { + BotsDeepLink: BotsDeepLink.linkUrl, + MEDeepLink: MessagingDeepLink.linkUrl, + CardsDeepLink: AdaptiveCardDeepLink.linkUrl, + BotsTitle: BotsDeepLink.TaskText, + METitle: MessagingDeepLink.TaskText, + CardsTitle: AdaptiveCardDeepLink.TaskText, + ExtendedDeepLink: ExtendedDeepLink.linkUrl, + ExtendedDeepLinkTitle: ExtendedDeepLink.TaskText, + sidePanelLink: sidePanelLink ? sidePanelLink.linkUrl : '', + sidePanelLinkTitle: sidePanelLink ? sidePanelLink.TaskText : '' + } + }); + return CardFactory.adaptiveCard(cardPayload); + } +} + +module.exports = DeepLinkTabsnode; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppInstall.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppInstall.png new file mode 100644 index 0000000000..4f877e2e34 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppInstall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppOffice.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppOffice.png new file mode 100644 index 0000000000..bf341d072e Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppOutlook.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppOutlook.png new file mode 100644 index 0000000000..55228d004c Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AudioCall.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AudioCall.png new file mode 100644 index 0000000000..fa15f5763b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/AudioCall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/BotAdaptiveCard.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/BotAdaptiveCard.png new file mode 100644 index 0000000000..ff0d6022d1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/BotAdaptiveCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/BotCard.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/BotCard.png new file mode 100644 index 0000000000..11468116fb Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/BotCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/DeepLinkTab.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/DeepLinkTab.png new file mode 100644 index 0000000000..51828c7f33 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/DeepLinkTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/DeepLinkTab2.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/DeepLinkTab2.png new file mode 100644 index 0000000000..45bbddd4ed Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/DeepLinkTab2.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/GroupChat.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/GroupChat.png new file mode 100644 index 0000000000..034f8efeb3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/GroupChat.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/GroupChatDeepLink.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/GroupChatDeepLink.png new file mode 100644 index 0000000000..abd245be20 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/GroupChatDeepLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/InstallOffice.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/InstallOffice.png new file mode 100644 index 0000000000..380d1381d6 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/InstallOutlook.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/InstallOutlook.png new file mode 100644 index 0000000000..45e8a64bd0 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/MeetingSchedule.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/MeetingSchedule.png new file mode 100644 index 0000000000..5cadb192f1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/MeetingSchedule.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/MeetingStageView.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/MeetingStageView.png new file mode 100644 index 0000000000..2252dc1268 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/MeetingStageView.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/PresentNow_Button.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/PresentNow_Button.png new file mode 100644 index 0000000000..f7f76fa6f7 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/PresentNow_Button.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/RedirectTab.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/RedirectTab.png new file mode 100644 index 0000000000..213d48a2f2 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/RedirectTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamWebApps.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamWebApps.png new file mode 100644 index 0000000000..ca6079b7dd Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamWebApps.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_1.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_1.png new file mode 100644 index 0000000000..e1bfdcfbd8 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_1.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_2.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_2.png new file mode 100644 index 0000000000..14b6a27b51 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_2.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_3.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_3.png new file mode 100644 index 0000000000..aa666c3b78 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_3.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_4.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_4.png new file mode 100644 index 0000000000..35054664a6 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_4.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_5.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_5.png new file mode 100644 index 0000000000..cc35e01a21 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsEDU_5.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsForEDU_1.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsForEDU_1.png new file mode 100644 index 0000000000..4ab70a039f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeamsForEDU_1.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeams_LinkSharedFromWebApp.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeams_LinkSharedFromWebApp.png new file mode 100644 index 0000000000..a9756843dc Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeams_LinkSharedFromWebApp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeams_UseWebApp.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeams_UseWebApp.png new file mode 100644 index 0000000000..d60e5e3554 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/ShareToTeams_UseWebApp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/SidePanelTab.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/SidePanelTab.png new file mode 100644 index 0000000000..b2a5ab4d74 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/SidePanelTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/Sidepanel.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/Sidepanel.png new file mode 100644 index 0000000000..b2a5ab4d74 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/Sidepanel.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/StartChatDeepLink.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/StartChatDeepLink.png new file mode 100644 index 0000000000..bb242a0a25 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/StartChatDeepLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/StartNewChat.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/StartNewChat.png new file mode 100644 index 0000000000..5faca00956 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/StartNewChat.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/TabDeepLink.gif b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/TabDeepLink.gif new file mode 100644 index 0000000000..782199506b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/TabDeepLink.gif differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/TeamsAdminPortal.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/TeamsAdminPortal.png new file mode 100644 index 0000000000..c9d8df047f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/TeamsAdminPortal.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/VideoCall.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/VideoCall.png new file mode 100644 index 0000000000..e20b3d4700 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/Images/VideoCall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/README.md b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/README.md new file mode 100644 index 0000000000..32a36f743d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/README.md @@ -0,0 +1,261 @@ +--- +page_type: sample +description: This Teams sample application illustrates how to use deeplinks for initiating calls, video chats, and navigating within various app tabs. It includes detailed setup instructions and supports interactions with bots and tabs to enhance user experience. +products: +- office-teams +- office +- office-365 +languages: +- nodejs +extensions: + contentType: samples + createdDate: "07-07-2021 13:38:27" +urlFragment: officedev-microsoft-teams-samples-tab-deeplink-nodejs +--- + +# DeepLink + +Explore this Microsoft Teams sample app designed to demonstrate the use of deeplinks for seamless interactions, including calls, chats, and navigation across tabs and applications. Featuring bot integration and comprehensive setup guidance, this app empowers developers to create engaging and efficient communication experiences within Teams.[DeepLink](https://learn.microsoft.com/microsoftteams/platform/concepts/build-and-test/deep-links) + + ## Included Features +* Tabs +* Bots +* Deep Links + +## Interaction with app. + +![Preview Image](Images/TabDeepLink.gif) + +## Prerequisites +- Microsoft Teams is installed and you have an account (not a guest account) +- To test locally, [NodeJS](https://nodejs.org/en/download/) must be installed on your development machine (version 16.14.2 or higher) +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunneling solution +- [M365 developer account](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup. + +1) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose **Accounts in this organizational directory only (single tenant)** as the supported account type. + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +2) Setup for Bot +- In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp%2Caadv2). +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/en-us/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) +- While registering the bot, use `https:///api/messages` as the messaging endpoint. +**NOTE:** When you create app registration, you will create an App ID and App password - make sure you keep these for later. + +3. Setup NGROK + - Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +4. Setup for code + + - Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + - Update the `.env` configuration for the bot to use the `YOUR-MICROSOFT-APP-ID`, `YOUR-MICROSOFT-APP-PASSWORD` and `BASE-URL` is tunnel url eg. 124.ngrok-free.app. (Note the MicrosoftAppId is the AppId created in step 1 (Setup for Bot), the MicrosoftAppPassword is referred to as the "client secret" in step 1 (Setup for Bot) and you can always create a new client secret anytime.) + + - navigate to `Deeplink.html` page at line number `58` Update the `data-app-id` attribute with your application id. + + ```bash + data-app-id="{{Your-App-Id}}" + ``` + + - In a terminal, navigate to `samples/tab-deeplink/nodejs` + + ```bash + cd samples/tab-deeplink/nodejs + ``` + + - Install modules + + ```bash + npm install + ``` + + - Navigate to `env.js` file and update your AppId at placeholder `<>` (You can get it manually frrm [teams admin portal](https://admin.teams.microsoft.com/). + - ![TeamsAdminPortal-AppID](Images/TeamsAdminPortal.png) + + - Start the bot + + ```bash + npm start + ``` + - If you are using Visual Studio code + - Launch Visual Studio code + - Folder -> Open -> Project/Solution + - Navigate to ```samples/tab-deeplink/nodejs``` folder + - Select ```nodejs``` Folder + + - To run the application required node modules.Please use this command to install modules npm i. + +5. Setup Manifest for Teams +- __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the ./appManifest folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `<>` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` and replace `{{domain-name}}` with base Url of your domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + **Note:** If you want to test your app across multi hub like: Outlook/Office.com, please update the `manifest.json` in the `tab-deeplink\nodejs\appManifest_Hub` folder with the required values. + - **Zip** up the contents of the `appManifest` folder to create a `appManifest.zip` or `appManifest_Hub` folder to create a `appManifest_Hub.zip`(Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appManifest folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your app is uploaded to Teams. + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/tab-deeplink/nodejs/index.js#L62) line and put your debugger for local debug. + +## Interacting with the bot + +Enter text in the emulator. The text will be echoed back by the bot. +1. Interact with DeepLink bot by pinging it in personal or channel scope. + +![Deep link card](Images/BotCard.png) + +2. Select the option from the options displayed in the adaptive card. This will redirect to the respective Task in the Tab. + +![Redirect Tab](Images/RedirectTab.png) + +3. Click on Back to List to view all the options and additional features of deep link using Microsoft teams SDK v2.0.0. User can select an option which will redirect to the respective Task in the Tab. + +![Additional features](Images/DeepLinkTab.png) + +![Additional features](Images/DeepLinkTab2.png) + +4. Add this application in live meeting and stage the content. + +![Meeting side panel](Images/SidePanelTab.png) + +5. While it's in stage view, using same [deeplink to open tab](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/deep-links?tabs=teamsjs-v2#generate-a-deep-link-to-your-tab) will open the meeting side panel tab. + +![Meeting stage view](Images/MeetingStageView.png) + +6. **Deeplink to meeting side panel:** + +`@mention` bot in meeting chat to get an adaptive card. + +![Bot-Adaptive-Card](Images/BotAdaptiveCard.png) + +Click on `Side Panel Deeplink` which will redirect to the meeting side panel. +**Note:** When the deeplink is opened outside meeting, it will redirect to meeting details tab. +![Meeting-Sidepanel](Images/Sidepanel.PNG) + + +**Tab interaction:** + +**Deeplink to Audio Call:** + +![Audio-Deeplink](Images/AudioCall.png) + +**Deeplink to Video Call:** + +![Video-Deeplink](Images/VideoCall.png) + +**Deeplink to Meeting schedule:** + +![Meeting-Schedule](Images/MeetingSchedule.png) + +**Deeplink to Polly app install dialog:** + +![App-Install-Dialog](Images/AppInstall.png) + +**Deeplink to start new chat:** + +![Start-New-Chat](Images/StartChatDeeplink.png) + +![New-Chat](Images/StartNewChat.png) + +**Deeplink to channel conversation:** + +![Show-Channel-Conversation ](Images/GroupChatDeeplink.png) + +![channel-Conversation](Images/GroupChat.png) + +**Share To Teams Web Apps:** + +![Teams Button](Images/ShareToTeamWebApps.png) + +![Present Now Feature](Images/PresentNow_Button.png) + +![OpensInNewBrowser](Images/ShareToTeams_UseWebApp.png) + +![SharedFromWebApp](Images/ShareToTeams_LinkSharedFromWebApp.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**On the side bar, select More Apps. Your uploaded app title appears among your installed apps** + +![InstallOutlook](Images/InstallOutlook.png) + +**Select your app icon to launch and preview your app running in Outlook on the web** + +![AppOutlook](Images/AppOutlook.png) + +**Note:** Similarly, you can test your application in the Outlook desktop app as well. + +## Office on the web + +- To preview your app running in Office on the web. + +- Log into office.com with test tenant credentials + +**Select the Apps icon on the side bar. Your uploaded app title appears among your installed apps** + +![InstallOffice](Images/InstallOffice.png) + +**Select your app icon to launch your app in Office on the web** + +![AppOffice](Images/AppOffice.png) + +**Note:** Similarly, you can test your application in the Office 365 desktop app as well. + + ## Further reading + +- [Extend Teams apps across Microsoft 365](https://learn.microsoft.com/en-us/microsoftteams/platform/m365-apps/overview) + +- [Share to teams web apps](https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/share-to-teams-from-web-apps?branch=pr-en-us-10824&tabs=method1) + + + + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/aad.manifest.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/aad.manifest.json new file mode 100644 index 0000000000..78eedb19ec --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/aad.manifest.json @@ -0,0 +1,32 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "tab-deeplink-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMyOrg", + "oauth2AllowIdTokenImplicitFlow": true, + "oauth2AllowImplicitFlow": true, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/icon-color.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/icon-color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/icon-color.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/icon-outline.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/icon-outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/icon-outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/manifest.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/manifest.json new file mode 100644 index 0000000000..9d3a2a7b20 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest/manifest.json @@ -0,0 +1,88 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Deep Link Bot", + "full": "Bot for Deep linking to tab" + }, + "description": { + "short": "Teams sample app showcasing deeplinks for calls, chats, and navigation.", + "full": "This Teams sample application illustrates how to use deeplinks for initiating calls, video chats, and navigating within various app tabs. It includes detailed setup instructions and supports interactions with bots and tabs to enhance user experience." + }, + "icons": { + "outline": "icon-outline.png", + "color": "icon-color.png" + }, + "accentColor": "#ffffff", + "configurableTabs": [ + { + "configurationUrl": "https://${{BOT_DOMAIN}}/Configure.html", + "canUpdateConfiguration": true, + "scopes": [ + "groupChat", + "team" + ], + "context": [ + "channelTab", + "privateChatTab", + "meetingSidePanel", + "meetingStage", + "meetingChatTab", + "meetingDetailsTab" + ] + } + ], + "staticTabs": [ + { + "contentUrl": "https://${{BOT_DOMAIN}}/DeepLink.html", + "websiteUrl": "https://${{BOT_DOMAIN}}", + "entityId": "com.contoso.DeeplLinkBot.help", + "name": "Deep Link Tab", + "scopes": [ + "personal" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "{{domain-name}}", + "${{BOT_DOMAIN}}" + ], + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "groupChat", + "personal", + "team" + ], + "isNotificationOnly": false, + "supportsFiles": false + } + ], + "authorization": { + "permissions": { + "resourceSpecific": [ + { + "name": "MeetingStage.Write.Chat", + "type": "Delegated" + }, + { + "name": "ChannelMeetingStage.Write.Group", + "type": "Delegated" + } + ] + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/icon-color.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/icon-color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/icon-color.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/icon-outline.png b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/icon-outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/icon-outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/manifest.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/manifest.json new file mode 100644 index 0000000000..b85539fec1 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/appManifest_Hub/manifest.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0", + "id": "<>", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Deep Link Bot", + "full": "Bot for Deep linking to tab" + }, + "description": { + "short": "DeepLinkBot for Microsoft Teams", + "full": "This sample DeepLink app which demos to navigate to required item in tab." + }, + "icons": { + "outline": "icon-outline.png", + "color": "icon-color.png" + }, + "accentColor": "#ffffff", + "staticTabs": [ + { + "contentUrl": "https://{{domain-name}}/DeepLink.html", + "websiteUrl": "https://{{domain-name}}", + "entityId": "com.contoso.DeeplLinkBot.help", + "name": "Deep Link Tab", + "scopes": [ + "personal" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "{{domain-name}}", + "{{domain-name}}" + ], + "authorization": { + "permissions": { + "resourceSpecific": [ + { + "name": "MeetingStage.Write.Chat", + "type": "Delegated" + }, + { + "name": "ChannelMeetingStage.Write.Group", + "type": "Delegated" + } + ] + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/assets/sample.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/assets/sample.json new file mode 100644 index 0000000000..171890b9c0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-tab-deeplink-nodejs", + "source": "officeDev", + "title": "DeepLink", + "shortDescription": "This Microsoft Teams sample app demonstrates deeplinks for calls, video, chat, and navigation within tabs and apps.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-deeplink/nodejs", + "longDescription": [ + "This Teams sample application illustrates how to use deeplinks for initiating calls, video chats, and navigating within various app tabs. It includes detailed setup instructions and supports interactions with bots and tabs to enhance user experience." + ], + "creationDateTime": "2021-07-07", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab,bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-deeplink/nodejs/Images/Preview.gif", + "alt": "Solution UX showing deeplink" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/build.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/build.js new file mode 100644 index 0000000000..a59684a045 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/build.js @@ -0,0 +1,14 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js' +}) + .then((r) => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/env/.env.local b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/env/.env.local new file mode 100644 index 0000000000..ef1cabe7de --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/env/.env.local @@ -0,0 +1,21 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/index.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/index.js new file mode 100644 index 0000000000..0103bd665e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/index.js @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const path = require('path'); +const dotenv = require('dotenv'); +const express = require('express'); +const cors = require('cors'); +const { + CloudAdapter, + ConfigurationBotFrameworkAuthentication +} = require('botbuilder'); + +const DeepLinkTabsnode = require('./Bots/DeepLinkTabsnode'); + +// Load bot configuration from .env file. +const ENV_FILE = path.join(__dirname, '.env'); +dotenv.config({ path: ENV_FILE }); + +const PORT = process.env.PORT || 3978; + +// Create HTTP server. +const server = express(); +server.use(cors()); +server.use(express.json()); +server.use(express.urlencoded({ extended: true })); + +server.listen(PORT, () => { + console.log('Server listening on port: ' + PORT); +}); + +// Create the bot framework authentication and adapter. +// See https://aka.ms/about-bot-adapter to learn more about how bots work. +const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env); +const adapter = new CloudAdapter(botFrameworkAuthentication); + +// Catch-all error handler. In production, consider logging to Application Insights. +// See https://aka.ms/bottelemetry for telemetry configuration instructions. +adapter.onTurnError = async (context, error) => { + console.error(`\n [onTurnError] unhandled error: ${error}`); + + // Send a trace activity, which will be displayed in Bot Framework Emulator. + await context.sendTraceActivity( + 'OnTurnError Trace', + `${error}`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); +}; + +// Create the bot. +const myBot = new DeepLinkTabsnode(); + +// Listen for incoming bot requests. +server.post('/api/messages', async (req, res) => { + await adapter.process(req, res, (context) => myBot.run(context)); +}); + +// Expose the Microsoft App Id to client-side pages that need it (e.g. for deep links). +server.get('/api/getAppId', (req, res) => { + res.send({ microsoftAppId: process.env.MicrosoftAppId }); +}); + +// Serve the static page assets. +server.use(express.static(path.join(__dirname, './pages'))); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/infra/azure.bicep b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/infra/azure.parameters.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/infra/azure.parameters.json new file mode 100644 index 0000000000..1f27d78ac7 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "tab-deeplink" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/m365agents.local.yml b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/m365agents.local.yml new file mode 100644 index 0000000000..d70ff02727 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/m365agents.local.yml @@ -0,0 +1,92 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-deeplink-nodejs + +provision: + # Creates a new Microsoft Entra (AAD) app for authenticating users locally. + - uses: aadApp/create + with: + name: tab-deeplink-aad + generateClientSecret: true + signInAudience: "AzureADMyOrg" # Single-tenant + writeToEnvironmentFile: + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + name: tab-deeplink${{APP_NAME_SUFFIX}} + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Configure single-tenant bot identity values used by the bot service. + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + # Register the local bot with Bot Framework using the AAD app. + - uses: botFramework/create + with: + botId: ${{AAD_APP_CLIENT_ID}} + name: tab-deeplink + messagingEndpoint: ${{BOT_ENDPOINT}}/api/messages + description: "" + channels: + - name: msteams + + # Apply the AAD manifest to update the created AAD app + - uses: aadApp/update + with: + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate the manifest schema + - uses: teamsApp/validateManifest + with: + manifestPath: ./appManifest/manifest.json + + # Build the Teams app package with latest env values + - uses: teamsApp/zipAppPackage + with: + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + + # Validate the built app package + - uses: teamsApp/validateAppPackage + with: + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in Developer Portal. + - uses: teamsApp/update + with: + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Install npm dependencies + - uses: cli/runNpmCommand + with: + args: install --no-audit + + # Generate runtime environment variables for the local run. + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + TeamsAppId: ${{TEAMS_APP_ID}} + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: SingleTenant + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} + Base_URL: ${{BOT_ENDPOINT}} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/m365agents.yml b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/m365agents.yml new file mode 100644 index 0000000000..bb58481958 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/m365agents.yml @@ -0,0 +1,94 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-deeplink-nodejs + +environmentFolderPath: ./env + +provision: + # Creates a new Microsoft Entra (AAD) app to authenticate users when needed. + - uses: aadApp/create + with: + name: tab-deeplink-aad + generateClientSecret: true + signInAudience: "AzureADMyOrg" # Single-tenant + writeToEnvironmentFile: + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + name: tab-deeplink${{APP_NAME_SUFFIX}} + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Configure single-tenant bot identity values used by the bot service. + - uses: script + with: + run: echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; echo + "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + # Deploy the Azure resources required for the bot. + - uses: arm/deploy + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 + + # Apply the AAD manifest to update the created AAD app + - uses: aadApp/update + with: + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate the manifest schema + - uses: teamsApp/validateManifest + with: + manifestPath: ./appManifest/manifest.json + + # Build the Teams app package with latest env values + - uses: teamsApp/zipAppPackage + with: + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + + # Validate the built app package using validation rules + - uses: teamsApp/validateAppPackage + with: + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in Developer Portal. + - uses: teamsApp/update + with: + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Install npm dependencies + - uses: cli/runNpmCommand + with: + args: install --no-audit + + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + TeamsAppId: ${{TEAMS_APP_ID}} + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: SingleTenant + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} + Base_URL: ${{BOT_ENDPOINT}} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/package-lock.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/package-lock.json new file mode 100644 index 0000000000..a8ff39dba6 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/package-lock.json @@ -0,0 +1,3057 @@ +{ + "name": "tab-deeplink", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tab-deeplink", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "adaptivecards-templating": "^2.3.1", + "botbuilder": "^4.23.2", + "cors": "^2.8.5", + "dotenv": "^16.4.7", + "express": "^4.21.2" + }, + "devDependencies": { + "esbuild": "^0.24.2", + "nodemon": "^3.1.9" + } + }, + "node_modules/@azure/abort-controller": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz", + "integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.3.tgz", + "integrity": "sha512-/wGw8fJ4mdpJ1Cum7s1S+VQyXt1ihwKLzfabS1O/RDADnmzVc01dHn44qD0BvGH6KlZNzOMW95tEpKqhkCChPA==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client/node_modules/@azure/core-tracing": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", + "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-http": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.5.tgz", + "integrity": "sha512-T8r2q/c3DxNu6mEJfPuJtptUVqwchxzjj32gKcnMi06rdiVONS9rar7kT9T2Am+XvER7uOzpsP79WsqNbdgdWg==", + "deprecated": "This package is no longer supported. Please refer to https://github.com/Azure/azure-sdk-for-js/blob/490ce4dfc5b98ba290dee3b33a6d0876c5f138e2/sdk/core/README.md", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", + "@azure/logger": "^1.0.0", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.5.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-http/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.1.tgz", + "integrity": "sha512-zHeoI3NCs53lLBbWNzQycjnYKsA1CVKlnzSNuSFcUDwBp8HHVObePxrM7HaX+Ha5Ks639H7chNC9HOaIhNS03w==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.8.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/@azure/core-tracing": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", + "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "dependencies": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz", + "integrity": "sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.8.0.tgz", + "integrity": "sha512-l9ALUGHtFB/JfsqmA+9iYAp2a+cCwdNO/cyIr2y7nJLJsz1aae6qVP8XxT7Kbudg0IQRSIMXj0+iivFdbD1xPA==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^4.2.0", + "@azure/msal-node": "^3.2.3", + "events": "^3.0.0", + "jws": "^4.0.0", + "open": "^10.1.0", + "stoppable": "^1.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/core-tracing": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", + "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/msal-common": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.2.1.tgz", + "integrity": "sha512-eZHtYE5OHDN0o2NahCENkczQ6ffGc0MoUSAI3hpwGpZBHJXaEQMMZPWtIx86da2L9w7uT+Tr/xgJbGwIkvTZTQ==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/msal-node": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.3.0.tgz", + "integrity": "sha512-ulsT3EHF1RQ29X55cxBLgKsIKWni9JdbUqG7sipGVP4uhWcBpmm/vhKOMH340+27Acm9+kHGnN/5XmQ5LrIDgA==", + "dependencies": { + "@azure/msal-common": "15.2.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@azure/identity/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@azure/logger": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz", + "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.7.0.tgz", + "integrity": "sha512-H4AIPhIQVe1qW4+BJaitqod6UGQiXE3juj7q2ZBsOPjuZicQaqcbnBp2gCroF/icS0+TJ9rGuyCBJbjlAqVOGA==", + "dependencies": { + "@azure/msal-common": "15.2.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-browser/node_modules/@azure/msal-common": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.2.1.tgz", + "integrity": "sha512-eZHtYE5OHDN0o2NahCENkczQ6ffGc0MoUSAI3hpwGpZBHJXaEQMMZPWtIx86da2L9w7uT+Tr/xgJbGwIkvTZTQ==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "14.16.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.0.tgz", + "integrity": "sha512-1KOZj9IpcDSwpNiQNjt0jDYZpQvNZay7QAEi/5DLubay40iGYtLzya/jbjRPLyOTZhEKyL1MzPuw2HqBCjceYA==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.16.2.tgz", + "integrity": "sha512-An7l1hEr0w1HMMh1LU+rtDtqL7/jw74ORlc9Wnh06v7TU/xpG39/Zdr1ZJu3QpjUfKJ+E0/OXMW8DRSWTlh7qQ==", + "dependencies": { + "@azure/msal-common": "14.16.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@azure/msal-node/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@microsoft/recognizers-text-data-types-timex-expression": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-data-types-timex-expression/-/recognizers-text-data-types-timex-expression-1.3.1.tgz", + "integrity": "sha512-jarJIFIJZBqeofy3hh0vdQo1yOmTM+jCjj6/zmo9JunsQ6LO750eZHCg9eLptQhsvq321XCt5xdRNLCwU8YeNA==", + "peer": true, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@types/atob-lite": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/atob-lite/-/atob-lite-2.0.2.tgz", + "integrity": "sha512-BbCDWqZzlBBq8czVNYPiQNnHPrdPmR1mcyv3c8autpLEDmBMJY4hjziedi4RlXC+jnquD6Ba/yFU6bboZ3ZKVA==", + "peer": true + }, + "node_modules/@types/btoa-lite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.2.tgz", + "integrity": "sha512-ZYbcE2x7yrvNFJiU7xJGrpF/ihpkM7zKgw8bha3LNJSesvTtUNxbpzaT7WXBIryf6jovisrxTBvymxMeLLj1Mg==", + "peer": true + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", + "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "peer": true + }, + "node_modules/@types/node": { + "version": "22.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", + "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/tunnel": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", + "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/xmldom": { + "version": "0.1.34", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.34.tgz", + "integrity": "sha512-7eZFfxI9XHYjJJuugddV6N5YNeXgQE1lArWOcd1eCOKWb/FGs5SIjacSYuEJuwhsGS3gy4RuZ5EUIcqYscuPDA==", + "peer": true + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/adaptive-expressions": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/adaptive-expressions/-/adaptive-expressions-4.23.2.tgz", + "integrity": "sha512-L4A74wiDs/PSYF60CAw79jD1gBX7TXkNvBh/wYD/XIRAEBRi2Sb7sMZTbOzRGeYzGSD5wQZllynYXS+SDr31Lg==", + "peer": true, + "dependencies": { + "@microsoft/recognizers-text-data-types-timex-expression": "~1.3.1", + "@types/atob-lite": "^2.0.2", + "@types/btoa-lite": "^1.0.2", + "@types/lru-cache": "^5.1.1", + "@types/xmldom": "^0.1.34", + "@xmldom/xmldom": "^0.8.6", + "antlr4ts": "0.5.0-alpha.4", + "atob-lite": "^2.0.0", + "big-integer": "^1.6.52", + "btoa-lite": "^1.0.0", + "d3-format": "^3.1.0", + "dayjs": "^1.11.13", + "fast-xml-parser": "^4.4.1", + "jspath": "^0.4.0", + "lodash": "^4.17.21", + "lru-cache": "^5.1.1", + "uuid": "^10.0.0", + "xpath": "^0.0.34" + } + }, + "node_modules/adaptivecards": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/adaptivecards/-/adaptivecards-1.2.3.tgz", + "integrity": "sha512-amQ5OSW3OpIkrxVKLjxVBPk/T49yuOtnqs1z5ZPfZr0+OpTovzmiHbyoAGDIsu5SNYHwOZFp/3LGOnRaALFa/g==" + }, + "node_modules/adaptivecards-templating": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/adaptivecards-templating/-/adaptivecards-templating-2.3.1.tgz", + "integrity": "sha512-rYN1tCb+4NeWUCbo7xzGhwuOG3XllpGWCtgdl/drSJA32tljAvDrMeBO/eUk7uwXx8/1hSc5WJvzbAZQWMd35Q==", + "peerDependencies": { + "adaptive-expressions": "^4.11.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "peer": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/atob-lite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha512-LEeSAWeh2Gfa2FtlQE1shxQ8zi5F9GHarrGKz08TMdODD5T4eH6BMsvtnhbWZ+XQn+Gb6om/917ucvRu7l7ukw==", + "peer": true + }, + "node_modules/axios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/botbuilder": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.23.2.tgz", + "integrity": "sha512-E3UjkPlAmT8TidZIAW1ucVRejz0KBbWEn0wNxJ37GncPl8txhmWvs21xn3hBrifSR4++Y6q/hp/A5cHFQcFGJw==", + "dependencies": { + "@azure/core-http": "^3.0.4", + "@azure/msal-node": "^2.13.1", + "axios": "^1.7.7", + "botbuilder-core": "4.23.2", + "botbuilder-stdlib": "4.23.2-internal", + "botframework-connector": "4.23.2", + "botframework-schema": "4.23.2", + "botframework-streaming": "4.23.2", + "dayjs": "^1.11.13", + "filenamify": "^6.0.0", + "fs-extra": "^11.2.0", + "htmlparser2": "^9.0.1", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botbuilder-core": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.23.2.tgz", + "integrity": "sha512-GwrfkfbEJqCLnhDVc6uKlzKtrptfYTxQxHYfF22s1AxTKdTiA9vsDN9rXq8We7QUPXFOF1ylF1e87k0fQ3Sf+A==", + "dependencies": { + "botbuilder-dialogs-adaptive-runtime-core": "4.23.2-preview", + "botbuilder-stdlib": "4.23.2-internal", + "botframework-connector": "4.23.2", + "botframework-schema": "4.23.2", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botbuilder-dialogs-adaptive-runtime-core": { + "version": "4.23.2-preview", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs-adaptive-runtime-core/-/botbuilder-dialogs-adaptive-runtime-core-4.23.2-preview.tgz", + "integrity": "sha512-+b5oHSDNodYXPnQbub+hTNmQLtBB4hj/ZW73g4Sqv5oAdqHoK/dX181UpiFAvDpHGe8Kx3SNYtRHJIj71u4t0Q==", + "dependencies": { + "dependency-graph": "^1.0.0" + } + }, + "node_modules/botbuilder-stdlib": { + "version": "4.23.2-internal", + "resolved": "https://registry.npmjs.org/botbuilder-stdlib/-/botbuilder-stdlib-4.23.2-internal.tgz", + "integrity": "sha512-5WAu59gCZX3lz2NNw28q+IlAAFIQjXij0wXmN8qh+Tg4PQOCl+5P3hoYqcHIWtGd5Kgn+dpaHtBIewl2LaOXKQ==" + }, + "node_modules/botframework-connector": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/botframework-connector/-/botframework-connector-4.23.2.tgz", + "integrity": "sha512-G4gDpEHhA8AUKbgHMJ1LUjsuDlRPFEcXnH8ouxLI0opT2p1LcUSAAgS4hoOrkaylr04zxrUI0nEWkuWDiWDwzw==", + "dependencies": { + "@azure/core-http": "^3.0.4", + "@azure/identity": "^4.4.1", + "@azure/msal-node": "^2.13.1", + "@types/jsonwebtoken": "9.0.6", + "axios": "^1.7.7", + "base64url": "^3.0.0", + "botbuilder-stdlib": "4.23.2-internal", + "botframework-schema": "4.23.2", + "buffer": "^6.0.3", + "cross-fetch": "^4.0.0", + "https-proxy-agent": "^7.0.5", + "jsonwebtoken": "^9.0.2", + "node-fetch": "^2.7.0", + "openssl-wrapper": "^0.3.4", + "rsa-pem-from-mod-exp": "^0.8.6", + "zod": "^3.23.8" + } + }, + "node_modules/botframework-schema": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.23.2.tgz", + "integrity": "sha512-eO1fmvfCEVJfnqNNAerQU8CHp0FMYTyE459ztNx2k1QJYMl/ds+LNNkGIUlQQFsdVbi2umadK+6hL2a9kqXMqQ==", + "dependencies": { + "adaptivecards": "1.2.3", + "uuid": "^10.0.0", + "zod": "^3.23.8" + } + }, + "node_modules/botframework-streaming": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/botframework-streaming/-/botframework-streaming-4.23.2.tgz", + "integrity": "sha512-UBF0puC2RX8Z0dkN/ag9BuSNWdB5MUtobZLzeaH1h5t7QAYAVNk/SrsUgkBwUsqWpwaZqU+vrGOeByLShDcvaQ==", + "dependencies": { + "@types/node": "18.19.47", + "@types/ws": "^6.0.3", + "uuid": "^10.0.0", + "ws": "^7.5.10" + } + }, + "node_modules/botframework-streaming/node_modules/@types/node": { + "version": "18.19.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.47.tgz", + "integrity": "sha512-1f7dB3BL/bpd9tnDJrrHb66Y+cVrhxSOTGorRNdHwYTUlTay3HuTDPKo9a/4vX9pMQkhYBcAbL4jQdNlhCFP9A==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/botframework-streaming/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/btoa-lite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", + "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==", + "peer": true + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "peer": true, + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/filename-reserved-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/filenamify": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-6.0.0.tgz", + "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", + "dependencies": { + "filename-reserved-regex": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jspath": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/jspath/-/jspath-0.4.0.tgz", + "integrity": "sha512-2/R8wkot8NCXrppBT/onp+4mcAUAZqtPxsW6aSJU3hrFAVqKqtFYcat2XJZ7inN4RtATUxfv0UQSYOmvJKiIGA==", + "peer": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "peer": true + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "peer": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemon": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz", + "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^10.2.1", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nodemon/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openssl-wrapper": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/openssl-wrapper/-/openssl-wrapper-0.3.4.tgz", + "integrity": "sha512-iITsrx6Ho8V3/2OVtmZzzX8wQaKAaFXEJQdzoPUZDtyf5jWFlqo+h+OhGT4TATQ47f9ACKHua8nw7Qoy85aeKQ==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rsa-pem-from-mod-exp": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.6.tgz", + "integrity": "sha512-c5ouQkOvGHF1qomUUDJGFcXsomeSO2gbEs6hVhMAtlkE1CuaZase/WzoaKFG/EZQuNmq6pw/EMCeEnDvOgCJYQ==" + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "peer": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xpath": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", + "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", + "peer": true, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "peer": true + }, + "node_modules/zod": { + "version": "3.24.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", + "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/package.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/package.json new file mode 100644 index 0000000000..5233520aeb --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/package.json @@ -0,0 +1,30 @@ +{ + "name": "tab-deeplink", + "version": "1.0.0", + "description": "Microsoft Teams sample demonstrating deep links across tabs, chats, calls, and meetings.", + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev:teamsfx": "npm run dev", + "dev": "nodemon --inspect=9239 --signal SIGINT ./index.js", + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "build": "node build.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples" + }, + "dependencies": { + "adaptivecards-templating": "^2.3.1", + "botbuilder": "^4.23.2", + "cors": "^2.8.5", + "dotenv": "^16.4.7", + "express": "^4.21.2" + }, + "devDependencies": { + "esbuild": "^0.24.2", + "nodemon": "^3.1.9" + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelDeepLink.html b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelDeepLink.html new file mode 100644 index 0000000000..be833f0a28 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelDeepLink.html @@ -0,0 +1,95 @@ + + + + + + + + + + + + + +
+
+
+
+ + + + Back To List + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelDetails.html b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelDetails.html new file mode 100644 index 0000000000..8214b0ec92 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelDetails.html @@ -0,0 +1,47 @@ + + + + + + + + +
+
+
+ Back To List + +
+ + Extended Deep link features + +
+
+ + +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelTasklist.html b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelTasklist.html new file mode 100644 index 0000000000..09a6288db6 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ChannelTasklist.html @@ -0,0 +1,45 @@ + + + + + + + + + + + +
+
+ + Extended Deep link features + +
+
+ + +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/Configure.html b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/Configure.html new file mode 100644 index 0000000000..4757227137 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/Configure.html @@ -0,0 +1,30 @@ + + + + + + + + + +

Click on save to configure the tab.

+ + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLink.html b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLink.html new file mode 100644 index 0000000000..f32e2dd64b --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLink.html @@ -0,0 +1,73 @@ + + + + + + + + + + + +
+
+
+
+
+
+

Share to Teams using a web page

+

Click below Teams button to open popup

+ +
+
+
+ + Extended Deep link features + +
+
+ + +
+ Back To List + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkFeatures.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkFeatures.js new file mode 100644 index 0000000000..625e9a7466 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkFeatures.js @@ -0,0 +1,115 @@ +// Initialize the library. +microsoftTeams.app.initialize().then(() => { +}); + +// Select people for fetching the attendees. +function selectPeople() { + microsoftTeams.people.selectPeople({ setSelected: [], openOrgWideSearchInChatOrChannel: true, singleSelect: false }).then((people) => { + if (people) { + document.getElementById("Attendee").value = (people.map((p) => p.email)).join(","); + } + }).catch((error) => { + console.log(error); + }); +} + +// function which redirects the user to start new chat. +function startNewChat() { + // Declare microsoftTeams chat + var chat = microsoftTeams.chat; + + // Declare microsoftTeams.app + var app = microsoftTeams.app; + + app.initialize().then(app.getContext).then((context) => { + + // get the current user. + let user = context.user.loginHint; + + if (chat.isSupported()) { + const chatPromise = chat.openGroupChat({ users: [user] }); + chatPromise. + then((result) => { console.log(result) }). + catch((error) => { console.log(error) }); + } + else { + console.log("openGroupChat isn't supported"); + } + + }); +} + +// function to navigate chat with application +function navigateToChatWithApplication() { + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/entity/${env.AppId}/conversations`); +} + +// navigates to teams chat window. +function navigateToTeamsChat() { + let app = microsoftTeams.app; + + app.initialize().then(app.getContext).then((context) => { + const queryParameters = { + channelId: context.channel.id, + tenantId: context.user.tenant.id, + groupId: context.team.groupId, + parentMessageId: context.app.parentMessageId, + teamName: context.team.displayName, + channelName: context.channel.displayName + } + + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/message/${queryParameters.channelId}/tenantId=${queryParameters.tenantId}&groupId=${queryParameters.groupId}&parentMessageId=${queryParameters.parentMessageId}&teamName=${queryParameters.teamName}&channelName=${queryParameters.channelName}`) + }); +} + +// function to navigate chat with application +function onCallDeepLinkButtonClick(callModalities) { + microsoftTeams.people.selectPeople({ setSelected: [], openOrgWideSearchInChatOrChannel: true, singleSelect: false }).then((people) => { + if (people) { + if (microsoftTeams.call.isSupported()) { + microsoftTeams.call.startCall({ + targets: people.map((p) => p.email), + requestedModalities: [callModalities] + }) + .then((result) => { + console.log(result); + }).catch((error) => { + console.log(error); + }); + } + else { + alert("Call isn't supported"); + } + } + }).catch((error) => { + console.log(error); + }); +} + +// function to open scheduling dialog workflow +function onSchedulingDialogClick() { + var subjectInput = document.getElementById("Subject"); + var startTimeInput = document.getElementById("StartTime"); + var endTimeInput = document.getElementById("EndTime"); + var contentInput = document.getElementById("Content"); + var attendeeInput = document.getElementById("Attendee"); + + if (subjectInput.value.trim() !== "" && startTimeInput.value !== "" && endTimeInput.value !== "" && attendeeInput.value !== "") { + var meetingDetails = + { + attendees: attendeeInput.value, + content: contentInput.value.trim(), + endTime: endTimeInput.value, + startTime: startTimeInput.value, + subject: subjectInput.value.trim(), + }; + + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/meeting/new?subject=${meetingDetails.subject}&startTime=${meetingDetails.startTime}&endTime=${meetingDetails.endTime}&content=${meetingDetails.content}&attendees=${meetingDetails.attendees}`) + } +} + +// function to open app installation dialog workflow +// Below app id is for harcoded for polly app which is already available in store. +function onAppInstallDialogClick() { + microsoftTeams.app.openLink("https://teams.microsoft.com/l/app/1542629c-01b3-4a6d-8f76-1938b779e48d"); +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkModel.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkModel.js new file mode 100644 index 0000000000..c2e81f8720 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkModel.js @@ -0,0 +1,7 @@ +var Task1Link ={ ID:1, Desc: "Bots"} +var Task2Link ={ ID:2, Desc:"Messaging Extension"} +var Task3Link ={ ID:3, Desc: "Adaptive Card"} + +var DeepLinkModel =[Task1Link,Task2Link,Task3Link] + + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkTabHelper.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkTabHelper.js new file mode 100644 index 0000000000..9719b03952 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/DeepLinkTabHelper.js @@ -0,0 +1,45 @@ +// Helpers for building Microsoft Teams deep link URLs. +// See https://learn.microsoft.com/microsoftteams/platform/concepts/build-and-test/deep-links + +const buildChannelWebUrl = () => + encodeURIComponent(`${process.env.Base_URL || ''}/ChannelDeepLink.html&label=DeepLink`); + +const GetDeepLinkTabChannel = (subEntityId, ID, Desc, channelId, AppID, EntityID) => { + const taskContext = encodeURIComponent(`{"subEntityId": "${subEntityId}","channelId":"${channelId}"}`); + + return { + linkUrl: `https://teams.microsoft.com/l/entity/${AppID}/${EntityID}?webUrl=${buildChannelWebUrl()}&context=${taskContext}`, + ID: ID, + TaskText: Desc + }; +}; + +const GetDeepLinkTabStatic = (subEntityId, ID, Desc, AppID) => { + const taskContext = encodeURI(`{"subEntityId": "${subEntityId}"}`); + + return { + linkUrl: `https://teams.microsoft.com/l/entity/${AppID}/${process.env.Tab_Entity_Id}?context=${taskContext}`, + ID: ID, + TaskText: Desc + }; +}; + +// Builds a deeplink that opens the meeting side panel for an active meeting chat. +const GetDeepLinkToMeetingSidePanel = (ID, Desc, AppID, baseUrl, chatId, contextType) => { + const taskContext = encodeURI(`{"chatId":"${chatId}","contextType":"${contextType}"}`); + const encodedUrl = encodeURIComponent(`${baseUrl}/ChannelDeepLink.html`); + + return { + linkUrl: `https://teams.microsoft.com/l/entity/${AppID}/${process.env.Channel_Entity_Id}?webUrl=${encodedUrl}&context=${taskContext}`, + ID: ID, + TaskText: Desc + }; +}; + +module.exports = { + GetDeepLinkTabChannel, + GetDeepLinkTabStatic, + GetDeepLinkToMeetingSidePanel +}; + + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/Details.html b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/Details.html new file mode 100644 index 0000000000..389216e98b --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/Details.html @@ -0,0 +1,50 @@ + + + + + + + + + + +
+
+
+ Back To List +
+ + Extended Deep link features + +
+
+ + +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ExtendedDeepLink.html b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ExtendedDeepLink.html new file mode 100644 index 0000000000..3c6e4d7c91 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/ExtendedDeepLink.html @@ -0,0 +1,238 @@ + + + + + + +
+
+
+
+
+
+
+ Add this app in meeting side panel and stage this tab to experience deeplink to meeting + side panel. +
+
+
+
+
+
+
+
+
+
+ Audio call members using the v2.0 SDK method +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.call.startCall({ targets: usersEmailArray,
+        requestedModalities: [microsoftTeams.call.CallModalities.Audio]})
+    .then((result) => {
+        console.log(result);
+    }).catch((error) => {
+            console.log(error);
+    });
+                            
+
+
Select members and make a call.
+
+ +
+
+
+
+
+
+ Video call members using the v2.0 SDK method +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.call.startCall({ targets: usersEmailArray,
+    requestedModalities: [microsoftTeams.call.CallModalities.Video]})
+.then((result) => {
+    console.log(result);
+}).catch((error) => {
+        console.log(error);
+});
+                            
+
+
Select members and make a call.
+
+ +
+
+
+
+
+
+
+
Open a scheduling dialog
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink("https://teams.microsoft.com/l/meeting/new?subject=Meeting Subject"
++ "&startTime=2022-07-24T10:30:00"
++ "&endTime=2022-07-24T11:30:00"
++ "&content=Meeting Content"
++ "&attendees=abc@ms.com,bcd@ms.com")
+                            
+
+
+
+ Add Details for scheduling dialog +
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ +
+
+
+
+
+
+ Open a Polly app install dialog +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink("https://teams.microsoft.com/l/app/1542629c-01b3-4a6d-8f76-1938b779e48d");
+                            
+
+
+ +
+
+
+
+
+
+
+
+ Start new chat +
+
+ To use this option, configure the function using following + parameters + +
+const chatPromise = chat.openGroupChat({ users: [user] });
+    chatPromise.
+        then((result) => { console.log(result) }).
+        catch((error) => { console.log(error) });
+                            
+
+
+ +
+
+
+
+
+
+ Navigate to chat (Personal chat with bot) +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink(`https://teams.microsoft.com/l/entity/{appId}/conversations`);
+                            
+
+
+ +
+
+
+
+
+
+
+
+ Navigate to teams chat (Works in teams chat only) +
+
+ To use this option, configure the function using following + parameters + +
+const queryParameters = {
+    channelId: context.channel.id,
+    tenantId: context.user.tenant.id,
+    groupId: context.team.groupId,
+    parentMessageId: context.app.parentMessageId,
+    teamName: context.team.displayName,
+    channelName: context.channel.displayName
+            }
+
+microsoftTeams.app.openLink(`https://teams.microsoft.com/l/message/${queryParameters.channelId}/tenantId=${queryParameters.tenantId}&groupId=${queryParameters.groupId}&parentMessageId=${queryParameters.parentMessageId}&teamName=${queryParameters.teamName}&channelName=${queryParameters.channelName}`)
+                            
+
+
+ +
+
+
+
+ + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/LinkDescription.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/LinkDescription.js new file mode 100644 index 0000000000..580794a523 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/LinkDescription.js @@ -0,0 +1,51 @@ +microsoftTeams.app.initialize().then(() => { + microsoftTeams.app.getContext().then((context) => { + if (context.page.frameContext === "sidePanel") { + document.getElementById("side-panel-content").style.display = "block"; + document.getElementById('list-content').style.display = "none"; + document.getElementById('taskList').style.display = "none"; + document.getElementById("extended-deeplink").style.display = "none"; + document.getElementById("side-panel-deeplink").style.display = "none"; + } + else if (context.page.frameContext === "meetingStage") { + + fetch(`${window.location.origin}/api/getAppId`).then(response => response.json()).then(data => { + deepLinkString = `https://teams.microsoft.com/l/entity/${data.microsoftAppId}/DeepLinkApp?context={"chatId": "${context.chat.id}","contextType":"chat"}`; + + document.getElementById("side-panel-deeplink").style.display = "block"; + document.getElementById('list-content').style.display = "none"; + document.getElementById('taskList').style.display = "none"; + document.getElementById("extended-deeplink").style.display = "none"; + }); + } + else if (context.page.subPageId === "topic1") { + document.getElementById("taskDiv").innerHTML = "Bots"; + document.getElementById("taskContent").innerHTML = "A bot also referred to as a chatbot or conversational bot is an app that runs simple and repetitive automated tasks performed by the users, such as customer service or support staff. Examples of bots in everyday use include, bots that provide information about the weather, make dinner reservations, or provide travel information. A bot interaction can be a quick question and answer, or it can be a complex conversation that provides access to services.For more details Click here"; + } + + else if (context.page.subPageId === "topic2") { + document.getElementById("taskDiv").innerHTML = "Messaging Extension"; + document.getElementById("taskContent").innerHTML = "Messaging extensions allow the users to interact with your web service through buttons and forms in the Microsoft Teams client. They can search or initiate actions in an external system from the compose message area, the command box, or directly from a message. You can send back the results of that interaction to the Microsoft Teams client in the form of a richly formatted card. This document gives an overview of the messaging extension, tasks performed under different scenarios, working of messaging extension, action and search commands, and link unfurling.For more details Click here"; + } + + else if (context.page.subPageId === "topic3") { + document.getElementById("taskDiv").innerHTML = "Adaptive Card"; + document.getElementById("taskContent").innerHTML ="Adaptive cards are a new cross product specification for cards in Microsoft products including Bots, Cortana, Outlook, and Windows. They are the recommended card type for new Teams development. For general information from the Adaptive cards team see Adaptive Cards Overview. You can use adaptive cards anywhere you can use existing Hero cards, Office365 cards, and Thumbnail cards.For more details Click here"; + } + else{ + var s=DeepLinkModel; + var html =''; + s.forEach(x=> { + var uri = "ChannelDetails.html?id="+x.ID; + let listContent = document.getElementById("list-content"); + let anchorTag = document.createElement("a"); + let lineBreakTag = document.createElement("br"); + anchorTag.href = uri; + anchorTag.innerHTML = x.Desc; + + listContent.appendChild(anchorTag); + listContent.appendChild(lineBreakTag); + }); + } + }); +}); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/TaskList.html b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/TaskList.html new file mode 100644 index 0000000000..e836b87cc6 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/TaskList.html @@ -0,0 +1,42 @@ + + + + + + + + + +
+
+ + Extended Deep link features + +
+
+ + +
+ + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/env.js b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/env.js new file mode 100644 index 0000000000..728c0506d0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/env.js @@ -0,0 +1,3 @@ +env = { + AppId: "<>" +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/style.css b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/style.css new file mode 100644 index 0000000000..f4b73069c8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/pages/style.css @@ -0,0 +1,65 @@ +pre { + overflow-x: scroll; +} + +.callDeeplinkButton { + font-family: "Segoe UI","Apple Color Emoji","Segoe UI Emoji","Segoe UI Web"; + font-weight: 700; + background-color: #444791; + cursor: pointer; + color: white; + width: 50px; + border-radius: 8px; + border: none; + margin-top: 1rem; + padding: 10px 0px; + text-align: center; + text-decoration: none; +} + + .callDeeplinkButton:hover { + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); + } + +.inputContainer { + margin-top: 10px; +} + +.container { + font-family: "Segoe UI","Apple Color Emoji","Segoe UI Emoji","Segoe UI Web"; + font-size: 14px; +} + +.card { + box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%); + width: 33rem; + min-height: 18rem; + overflow: hidden; + margin-left: 2rem; + margin-top: 0.5rem; +} + +.card-container-div { + padding-bottom: 2rem; + display: flex; +} + +.card-header { + margin-left: 1rem; + margin-right: 1rem; + margin-top: 1rem; + padding-top: 0.5rem; + font-size: 16px !important; +} + +button { + margin: 1rem 8.5rem 1rem 11.5rem; +} + +.form-container { + margin-left: 1rem; +} + +.card-body { + margin-left: 0.5rem; +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/nodejs/resources/AdaptiveCard.json b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/resources/AdaptiveCard.json new file mode 100644 index 0000000000..9992badf14 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/nodejs/resources/AdaptiveCard.json @@ -0,0 +1,39 @@ +{ + "type": "AdaptiveCard", + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.0", + "body": [ + { + "type": "TextBlock", + "text": "Please click on below buttons to navigate to a tab!", + "wrap": true + } + ], + "actions": [ + { + "type": "Action.OpenUrl", + "title": "${BotsTitle}", + "url": "${BotsDeepLink}" + }, + { + "type": "Action.OpenUrl", + "title": "${METitle}", + "url": "${MEDeepLink}" + }, + { + "type": "Action.OpenUrl", + "title": "${CardsTitle}", + "url": "${CardsDeepLink}" + }, + { + "type": "Action.OpenUrl", + "title": "${ExtendedDeepLinkTitle}", + "url": "${ExtendedDeepLink}" + }, + { + "type": "Action.OpenUrl", + "title": "${sidePanelLinkTitle}", + "url": "${sidePanelLink}" + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/.env b/samples/TeamsSDK/Archived/tab-deeplink/python/.env new file mode 100644 index 0000000000..d3fd8ef3fb --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/.env @@ -0,0 +1,7 @@ +MicrosoftAppId= +MicrosoftAppPassword= +TeamsAppId= +Tab_Entity_Id=com.contoso.DeeplLinkBot.help +Channel_Entity_Id=DeepLinkApp +MicrosoftAppType=SingleTenant +MicrosoftAppTenantId= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/.gitignore b/samples/TeamsSDK/Archived/tab-deeplink/python/.gitignore new file mode 100644 index 0000000000..e8442994dd --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/.gitignore @@ -0,0 +1,14 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +appManifest/build/ + +# python virtual environment +.venv/ + +# misc +.env +.deployment/ + +# tmp files +__pycache__/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/extensions.json b/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/extensions.json new file mode 100644 index 0000000000..bf8c33db9c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension", + "ms-python.python", + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/launch.json b/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/launch.json new file mode 100644 index 0000000000..6d66d8beb8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/launch.json @@ -0,0 +1,69 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Python: Run App Locally", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/app.py", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/settings.json b/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/settings.json new file mode 100644 index 0000000000..3014fd9cf0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "debug.onTaskErrors": "abort" +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/tasks.json b/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/tasks.json new file mode 100644 index 0000000000..253c1ead76 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/.vscode/tasks.json @@ -0,0 +1,78 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Prepare Teams App Resources", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppInstall.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppInstall.png new file mode 100644 index 0000000000..4f877e2e34 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppInstall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppOffice.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppOffice.png new file mode 100644 index 0000000000..bf341d072e Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppOutlook.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppOutlook.png new file mode 100644 index 0000000000..55228d004c Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AudioCall.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AudioCall.png new file mode 100644 index 0000000000..fa15f5763b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/AudioCall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/BotAdaptiveCard.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/BotAdaptiveCard.png new file mode 100644 index 0000000000..ff0d6022d1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/BotAdaptiveCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/BotCard.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/BotCard.png new file mode 100644 index 0000000000..11468116fb Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/BotCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/DeepLinkTab.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/DeepLinkTab.png new file mode 100644 index 0000000000..51828c7f33 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/DeepLinkTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/DeepLinkTab2.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/DeepLinkTab2.png new file mode 100644 index 0000000000..45bbddd4ed Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/DeepLinkTab2.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/GroupChat.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/GroupChat.png new file mode 100644 index 0000000000..034f8efeb3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/GroupChat.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/GroupChatDeepLink.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/GroupChatDeepLink.png new file mode 100644 index 0000000000..abd245be20 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/GroupChatDeepLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/InstallOffice.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/InstallOffice.png new file mode 100644 index 0000000000..380d1381d6 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/InstallOutlook.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/InstallOutlook.png new file mode 100644 index 0000000000..45e8a64bd0 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/MeetingSchedule.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/MeetingSchedule.png new file mode 100644 index 0000000000..5cadb192f1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/MeetingSchedule.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/MeetingStageView.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/MeetingStageView.png new file mode 100644 index 0000000000..2252dc1268 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/MeetingStageView.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/PresentNow_Button.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/PresentNow_Button.png new file mode 100644 index 0000000000..f7f76fa6f7 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/PresentNow_Button.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/RedirectTab.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/RedirectTab.png new file mode 100644 index 0000000000..213d48a2f2 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/RedirectTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamWebApps.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamWebApps.png new file mode 100644 index 0000000000..ca6079b7dd Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamWebApps.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_1.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_1.png new file mode 100644 index 0000000000..e1bfdcfbd8 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_1.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_2.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_2.png new file mode 100644 index 0000000000..14b6a27b51 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_2.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_3.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_3.png new file mode 100644 index 0000000000..aa666c3b78 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_3.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_4.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_4.png new file mode 100644 index 0000000000..35054664a6 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_4.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_5.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_5.png new file mode 100644 index 0000000000..cc35e01a21 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsEDU_5.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsForEDU_1.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsForEDU_1.png new file mode 100644 index 0000000000..4ab70a039f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeamsForEDU_1.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeams_LinkSharedFromWebApp.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeams_LinkSharedFromWebApp.png new file mode 100644 index 0000000000..05e2c002e3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeams_LinkSharedFromWebApp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeams_UseWebApp.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeams_UseWebApp.png new file mode 100644 index 0000000000..d60e5e3554 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/ShareToTeams_UseWebApp.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/SidePanelTab.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/SidePanelTab.png new file mode 100644 index 0000000000..b2a5ab4d74 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/SidePanelTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/Sidepanel.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/Sidepanel.png new file mode 100644 index 0000000000..b2a5ab4d74 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/Sidepanel.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/StartChatDeepLink.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/StartChatDeepLink.png new file mode 100644 index 0000000000..bb242a0a25 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/StartChatDeepLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/StartNewChat.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/StartNewChat.png new file mode 100644 index 0000000000..5faca00956 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/StartNewChat.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/TabDeepLink.gif b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/TabDeepLink.gif new file mode 100644 index 0000000000..782199506b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/TabDeepLink.gif differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/TeamsAdminPortal.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/TeamsAdminPortal.png new file mode 100644 index 0000000000..c9d8df047f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/TeamsAdminPortal.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/Images/VideoCall.png b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/VideoCall.png new file mode 100644 index 0000000000..e20b3d4700 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/Images/VideoCall.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/README.md b/samples/TeamsSDK/Archived/tab-deeplink/python/README.md new file mode 100644 index 0000000000..c27ac587b8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/README.md @@ -0,0 +1,229 @@ +--- +page_type: sample +description: This Teams sample application illustrates how to use deeplinks for initiating calls, video chats, and navigating within various app tabs. It includes detailed setup instructions and supports interactions with bots and tabs to enhance user experience. +products: +- office-teams +- office +- office-365 +languages: +- python +extensions: + contentType: samples + createdDate: "05-03-2025 13:38:25" +urlFragment: officedev-microsoft-teams-samples-tab-deeplink-python +--- + +# DeepLink + +Explore this Microsoft Teams sample app designed to demonstrate the use of deeplinks for seamless interactions, including calls, chats, and navigation across tabs and applications. Featuring bot integration and comprehensive setup guidance, this app empowers developers to create engaging and efficient communication experiences within Teams.[DeepLink](https://learn.microsoft.com/microsoftteams/platform/concepts/build-and-test/deep-links) + + ## Included Features +* Tabs +* Bots +* Deep Links + +## Interaction with app. + +![Preview Image](Images/TabDeepLink.gif) + +## Prerequisites + +- Microsoft Teams is installed and you have an account +- [Python SDK](https://www.python.org/downloads/) min version 3.6 +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution + + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) and [Python Extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Press **CTRL+Shift+P** to open the command box and enter **Python: Create Environment** to create and activate your desired virtual environment. Remember to select `requirements.txt` as dependencies to install when creating the virtual environment. +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Run the app (Manually Uploading to Teams) + +> Note these instructions are for running the sample on your local machine, the tunnelling solution is required because +the Teams service needs to call into the bot. + +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +2) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +3) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +4) Create [Azure Bot resource resource](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration) in Azure + - Use the current `https` URL you were given by running the tunneling application. Append with the path `/api/messages` used by this sample + - Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - __*If you don't have an Azure account*__ you can use this [Azure free account here](https://azure.microsoft.com/free/) + +5) In a terminal, go to `samples\tab-deeplink` + +6) Activate your desired virtual environment + +7) Install dependencies by running ```pip install -r requirements.txt``` in the project folder. + +8) Update the `config.py` configuration for the bot to use the Microsoft App Id and App Password from the Bot Framework registration. (Note the App Password is referred to as the "client secret" in the azure portal and you can always create a new client secret anytime.) + +9) - navigate to `Deeplink.html` page at line number `58` Update the `data-app-id` attribute with your application id. + - Navigate to `env.js` file and update your AppId at placeholder `<>` (You can get it manually from [teams admin portal](https://admin.teams.microsoft.com/). + - ![TeamsAdminPortal-AppID](Images/TeamsAdminPortal.png) + + +10) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appManifest` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `${{AAD_APP_CLIENT_ID}}` and `${{TEAMS_APP_ID}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` + - **Upload** the `manifest.zip` to Teams (in the Apps view click "Upload a custom app") + +11) Run your bot with `python app.py` + +## Interacting with the bot + +Enter text in the emulator. The text will be echoed back by the bot. +1. Interact with DeepLink bot by pinging it in personal or channel scope. + +![Deep link card](Images/BotCard.png) + +2. Select the option from the options displayed in the adaptive card. This will redirect to the respective Task in the Tab. + +![Redirect Tab](Images/RedirectTab.png) + +3. Click on Back to List to view all the options and additional features of deep link using Microsoft teams SDK v2.0.0. User can select an option which will redirect to the respective Task in the Tab. + +![Additional features](Images/DeepLinkTab.png) + +![Additional features](Images/DeepLinkTab2.png) + +4. Add this application in live meeting and stage the content. + +![Meeting side panel](Images/SidePanelTab.png) + +5. While it's in stage view, using same [deeplink to open tab](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/deep-links?tabs=teamsjs-v2#generate-a-deep-link-to-your-tab) will open the meeting side panel tab. + +![Meeting stage view](Images/MeetingStageView.png) + +6. **Deeplink to meeting side panel:** + +`@mention` bot in meeting chat to get an adaptive card. + +![Bot-Adaptive-Card](Images/BotAdaptiveCard.png) + +Click on `Side Panel Deeplink` which will redirect to the meeting side panel. +**Note:** When the deeplink is opened outside meeting, it will redirect to meeting details tab. +![Meeting-Sidepanel](Images/Sidepanel.PNG) + + +**Tab interaction:** + +**Deeplink to Audio Call:** + +![Audio-Deeplink](Images/AudioCall.png) + +**Deeplink to Video Call:** + +![Video-Deeplink](Images/VideoCall.png) + +**Deeplink to Meeting schedule:** + +![Meeting-Schedule](Images/MeetingSchedule.png) + +**Deeplink to Polly app install dialog:** + +![App-Install-Dialog](Images/AppInstall.png) + +**Deeplink to start new chat:** + +![Start-New-Chat](Images/StartChatDeeplink.png) + +![New-Chat](Images/StartNewChat.png) + +**Deeplink to channel conversation:** + +![Show-Channel-Conversation ](Images/GroupChatDeeplink.png) + +![channel-Conversation](Images/GroupChat.png) + +**Share To Teams Web Apps:** + +![Teams Button](Images/ShareToTeamWebApps.png) + +![Present Now Feature](Images/PresentNow_Button.png) + +![OpensInNewBrowser](Images/ShareToTeams_UseWebApp.png) + +![SharedFromWebApp](Images/ShareToTeams_LinkSharedFromWebApp.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**On the side bar, select More Apps. Your uploaded app title appears among your installed apps** + +![InstallOutlook](Images/InstallOutlook.png) + +**Select your app icon to launch and preview your app running in Outlook on the web** + +![AppOutlook](Images/AppOutlook.png) + +**Note:** Similarly, you can test your application in the Outlook desktop app as well. + +## Office on the web + +- To preview your app running in Office on the web. + +- Log into office.com with test tenant credentials + +**Select the Apps icon on the side bar. Your uploaded app title appears among your installed apps** + +![InstallOffice](Images/InstallOffice.png) + +**Select your app icon to launch your app in Office on the web** + +![AppOffice](Images/AppOffice.png) + +**Note:** Similarly, you can test your application in the Office 365 desktop app as well. + + ## Further reading + +- [Extend Teams apps across Microsoft 365](https://learn.microsoft.com/en-us/microsoftteams/platform/m365-apps/overview) + +- [Share to teams web apps](https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/share-to-teams-from-web-apps?branch=pr-en-us-10824&tabs=method1) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/aad.manifest.json b/samples/TeamsSDK/Archived/tab-deeplink/python/aad.manifest.json new file mode 100644 index 0000000000..c330b8a3ba --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/aad.manifest.json @@ -0,0 +1,32 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "tab-deeplink-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMyOrg", + "oauth2AllowIdTokenImplicitFlow": true, + "oauth2AllowImplicitFlow": true, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ] +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/app.py b/samples/TeamsSDK/Archived/tab-deeplink/python/app.py new file mode 100644 index 0000000000..9434c8bad0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/app.py @@ -0,0 +1,66 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os +import logging +import asyncio +from flask import Flask, request, jsonify, send_from_directory, Response +from botbuilder.core import TurnContext +from botbuilder.schema import Activity +from botbuilder.integration.aiohttp import ( + CloudAdapter, + ConfigurationBotFrameworkAuthentication, +) + +from bots import DeepLinkTabsBot +from config import DefaultConfig + +CONFIG = DefaultConfig() + +app = Flask(__name__) + +PORT = int(os.getenv("PORT", CONFIG.PORT)) +MICROSOFT_APP_ID = os.getenv("MicrosoftAppId", "") + +logging.basicConfig(level=logging.INFO) + +adapter = CloudAdapter(ConfigurationBotFrameworkAuthentication(CONFIG)) +bot = DeepLinkTabsBot() + +async def on_turn_error(context: TurnContext, error: Exception): + logging.error(f"\n [on_turn_error] unhandled error: {error}") + await context.send_activity("Sorry, it looks like something went wrong.") + +adapter.on_turn_error = on_turn_error + +@app.route("/api/messages", methods=["POST"]) +def messages(): + body = request.json + activity = Activity().deserialize(body) + auth_header = request.headers.get("Authorization", "") + + async def aux_func(turn_context: TurnContext): + await bot.on_turn(turn_context) + + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + loop.run_until_complete(adapter.process_activity(auth_header, activity, aux_func)) + finally: + loop.close() + + return Response(status=200) + +@app.route("/api/getAppId", methods=["GET"]) +def get_app_id(): + return jsonify({"microsoftAppId": MICROSOFT_APP_ID}) + +@app.route("/") +def redirect_static(filename): + return send_from_directory("static", filename) + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=PORT) \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/color.png b/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/manifest.json b/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/manifest.json new file mode 100644 index 0000000000..caa56becc6 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/manifest.json @@ -0,0 +1,88 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json", + "manifestVersion": "1.16", + "version": "1.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Deep Link Bot", + "full": "Bot for Deep linking to tab" + }, + "description": { + "short": "Teams sample app showcasing deeplinks for calls, chats, and navigation.", + "full": "This Teams sample application illustrates how to use deeplinks for initiating calls, video chats, and navigating within various app tabs. It includes detailed setup instructions and supports interactions with bots and tabs to enhance user experience." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "accentColor": "#ffffff", + "configurableTabs": [ + { + "configurationUrl": "https://${{BOT_DOMAIN}}/Configure.html", + "canUpdateConfiguration": true, + "scopes": [ + "groupchat", + "team" + ], + "context": [ + "channelTab", + "privateChatTab", + "meetingSidePanel", + "meetingStage", + "meetingChatTab", + "meetingDetailsTab" + ] + } + ], + "staticTabs": [ + { + "contentUrl": "https://${{BOT_DOMAIN}}/DeepLink.html", + "websiteUrl": "https://${{BOT_DOMAIN}}", + "entityId": "com.contoso.DeeplLinkBot.help", + "name": "Deep Link Tab", + "scopes": [ + "personal" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "{{domain-name}}", + "${{BOT_DOMAIN}}" + ], + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "groupChat", + "personal", + "team" + ], + "isNotificationOnly": false, + "supportsFiles": false + } + ], + "authorization": { + "permissions": { + "resourceSpecific": [ + { + "name": "MeetingStage.Write.Chat", + "type": "Delegated" + }, + { + "name": "ChannelMeetingStage.Write.Group", + "type": "Delegated" + } + ] + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/outline.png b/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-deeplink/python/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/assets/sample.json b/samples/TeamsSDK/Archived/tab-deeplink/python/assets/sample.json new file mode 100644 index 0000000000..472d711f4b --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-tab-deeplink-python", + "source": "officeDev", + "title": "DeepLink Bot", + "shortDescription": "This Microsoft Teams sample app demonstrates deeplinks for calls, video, chat, and navigation within tabs and apps.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-deeplink/python", + "longDescription": [ + "This Teams sample application illustrates how to use deeplinks for initiating calls, video chats, and navigating within various app tabs. It includes detailed setup instructions and supports interactions with bots and tabs to enhance user experience." + ], + "creationDateTime": "2025-03-05", + "updateDateTime": "2025-03-05", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "python" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "python" + }, + { + "key": "TEAMS-FEATURES", + "value": "bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/tab-deeplink/python/Images/Preview.gif", + "alt": "Solution UX showing deeplink" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/bots/__init__.py b/samples/TeamsSDK/Archived/tab-deeplink/python/bots/__init__.py new file mode 100644 index 0000000000..6d0118302e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/bots/__init__.py @@ -0,0 +1,3 @@ +from .bot_activity_handler import DeepLinkTabsBot + +__all__ = ["DeepLinkTabsBot"] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/bots/bot_activity_handler.py b/samples/TeamsSDK/Archived/tab-deeplink/python/bots/bot_activity_handler.py new file mode 100644 index 0000000000..b0937cb99e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/bots/bot_activity_handler.py @@ -0,0 +1,83 @@ +import os +import json +from botbuilder.core import ActivityHandler, TurnContext, MessageFactory, CardFactory +from botbuilder.schema import Attachment +from .deep_link_tab_helper import DeepLinkTabHelper + +class DeepLinkTabsBot(ActivityHandler): + def __init__(self): + super().__init__() + + async def on_message_activity(self, turn_context: TurnContext): + conversation_type = turn_context.activity.conversation.conversation_type + extended_deep_link = "" + side_panel_link = "" + + if conversation_type == "channel": + bots_deep_link = DeepLinkTabHelper.get_deep_link_tab_channel( + "topic1", 1, "Bots", turn_context.activity.channel_data["teamsChannelId"], + os.getenv("TeamsAppId"), os.getenv("Channel_Entity_Id") + ) + messaging_deep_link = DeepLinkTabHelper.get_deep_link_tab_channel( + "topic2", 2, "Messaging Extension", turn_context.activity.channel_data["teamsChannelId"], + os.getenv("TeamsAppId"), os.getenv("Channel_Entity_Id") + ) + adaptive_card_deep_link = DeepLinkTabHelper.get_deep_link_tab_channel( + "topic3", 3, "Adaptive Card", turn_context.activity.channel_data["teamsChannelId"], + os.getenv("TeamsAppId"), os.getenv("Channel_Entity_Id") + ) + extended_deep_link = DeepLinkTabHelper.get_deep_link_tab_channel( + "", 4, "Extended Deeplink features", turn_context.activity.channel_data["teamsChannelId"], + os.getenv("TeamsAppId"), os.getenv("Channel_Entity_Id") + ) + else: + bots_deep_link = DeepLinkTabHelper.get_deep_link_tab_static("topic1", 1, "Bots", os.getenv("TeamsAppId")) + messaging_deep_link = DeepLinkTabHelper.get_deep_link_tab_static("topic2", 2, "Messaging Extension", os.getenv("TeamsAppId")) + adaptive_card_deep_link = DeepLinkTabHelper.get_deep_link_tab_static("topic3", 3, "Adaptive Card", os.getenv("TeamsAppId")) + extended_deep_link = DeepLinkTabHelper.get_deep_link_tab_static("", 4, "Extended Deeplink features", os.getenv("TeamsAppId")) + side_panel_link = DeepLinkTabHelper.get_deep_link_to_meeting_side_panel( + 5, "Side panel Deeplink", os.getenv("TeamsAppId"), os.getenv("Base_URL"), + turn_context.activity.conversation.id, "chat" + ) + + adaptive_card = self.create_adaptive_card( + conversation_type, bots_deep_link, messaging_deep_link, adaptive_card_deep_link, extended_deep_link, side_panel_link + ) + + await turn_context.send_activity(MessageFactory.attachment(adaptive_card)) + + async def on_members_added_activity(self, members_added, turn_context: TurnContext): + welcome_text = "Hello and welcome!" + for member in members_added: + if member.id != turn_context.activity.recipient.id: + await turn_context.send_activity(MessageFactory.text(welcome_text)) + + def create_adaptive_card(self, conversation_type, bots_deep_link, messaging_deep_link, adaptive_card_deep_link, extended_deep_link, side_panel_link) -> Attachment: + with open("resources/AdaptiveCard.json", "r", encoding="utf-8") as json_file: + template_payload = json.load(json_file) + + # Define replacement data + card_data = { + "BotsDeepLink": bots_deep_link["linkUrl"], + "MEDeepLink": messaging_deep_link["linkUrl"], + "CardsDeepLink": adaptive_card_deep_link["linkUrl"], + "BotsTitle": bots_deep_link["TaskText"], + "METitle": messaging_deep_link["TaskText"], + "CardsTitle": adaptive_card_deep_link["TaskText"], + "ExtendedDeepLink": extended_deep_link["linkUrl"], + "ExtendedDeepLinkTitle": extended_deep_link["TaskText"], + "sidePanelLink": side_panel_link["linkUrl"] if side_panel_link else "", + "sidePanelLinkTitle": side_panel_link["TaskText"] if side_panel_link else "" + } + + # Convert template to string for manual replacement + adaptive_card_json = json.dumps(template_payload) + + # Replace placeholders manually + for key, value in card_data.items(): + adaptive_card_json = adaptive_card_json.replace(f"${{{key}}}", value) + + # Convert back to dictionary + adaptive_card = json.loads(adaptive_card_json) + + return CardFactory.adaptive_card(adaptive_card) \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/bots/deep_link_tab_helper.py b/samples/TeamsSDK/Archived/tab-deeplink/python/bots/deep_link_tab_helper.py new file mode 100644 index 0000000000..4c478a0b0a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/bots/deep_link_tab_helper.py @@ -0,0 +1,36 @@ +import os +import urllib.parse + +class DeepLinkTabHelper: + @staticmethod + def get_deep_link_tab_channel(sub_entity_id, ID, desc, channel_id, app_id, entity_id): + task_context = urllib.parse.quote(f'{{"subEntityId": "{sub_entity_id}","channelId":"{channel_id}"}}') + encoded_web_url = urllib.parse.quote(f'{os.getenv("Base_URL")}/ChannelDeepLink.html&label=DeepLink') + + return { + "linkUrl": f"https://teams.microsoft.com/l/entity/{app_id}/{entity_id}?webUrl={encoded_web_url}&context={task_context}", + "ID": ID, + "TaskText": desc + } + + @staticmethod + def get_deep_link_tab_static(sub_entity_id, ID, desc, app_id): + task_context = urllib.parse.quote(f'{{"subEntityId": "{sub_entity_id}"}}') + + return { + "linkUrl": f"https://teams.microsoft.com/l/entity/{app_id}/{os.getenv('Tab_Entity_Id')}?context={task_context}", + "ID": ID, + "TaskText": desc + } + + @staticmethod + def get_deep_link_to_meeting_side_panel(ID, desc, app_id, base_url, chat_id, context_type): + json_context = f'{{"chatId": "{chat_id}", "contextType": "{context_type}"}}' + task_context = urllib.parse.quote(json_context) + encoded_url = urllib.parse.quote(f"{base_url}/ChannelDeepLink.html") + + return { + "linkUrl": f"https://teams.microsoft.com/l/entity/{app_id}/{os.getenv('Channel_Entity_Id')}?webUrl={encoded_url}&context={task_context}", + "ID": ID, + "TaskText": desc + } \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/config.py b/samples/TeamsSDK/Archived/tab-deeplink/python/config.py new file mode 100644 index 0000000000..5528d4bcd1 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/config.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os + +""" Bot Configuration """ + + +class DefaultConfig: + """ Bot Configuration """ + + PORT = 3978 + APP_ID = os.environ.get("MicrosoftAppId", "<>") + APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "<>") + BOT_ENDPOINT = os.environ.get("BaseUrl", "<>") + TEAMS_APP_ID = os.environ.get("TeamsAppId", "<>") + Tab_Entity_Id = os.environ.get("Tab_Entity_Id", "<>") + Channel_Entity_Id = os.environ.get("Channel_Entity_Id", "<>") + APP_TYPE = os.environ.get("MicrosoftAppType", "") + APP_TENANTID = os.environ.get("MicrosoftAppTenantId", "") \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/env/.env.local b/samples/TeamsSDK/Archived/tab-deeplink/python/env/.env.local new file mode 100644 index 0000000000..553698b86a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/env/.env.local @@ -0,0 +1,21 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +APP_NAME_SUFFIX=local \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/infra/azure.bicep b/samples/TeamsSDK/Archived/tab-deeplink/python/infra/azure.bicep new file mode 100644 index 0000000000..98e1027752 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAadAppTenantId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: 'SingleTenant' + msaAppTenantId: botAadAppTenantId + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/infra/azure.parameters.json b/samples/TeamsSDK/Archived/tab-deeplink/python/infra/azure.parameters.json new file mode 100644 index 0000000000..c7abf15b3b --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/infra/azure.parameters.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAadAppTenantId": { + "value": "${{AAD_APP_TENANT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "tab-deeplink" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/m365agents.local.yml b/samples/TeamsSDK/Archived/tab-deeplink/python/m365agents.local.yml new file mode 100644 index 0000000000..4d65351338 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/m365agents.local.yml @@ -0,0 +1,87 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-deeplink-python + +provision: + # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + - uses: aadApp/create + with: + name: tab-deeplink-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # Single tenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-deeplink${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + - uses: aadApp/update # Apply the AAD manifest to an existing AAD app. Will use the object id in manifest file to determine which AAD app to update. + with: + manifestPath: ./aad.manifest.json # Relative path to teamsfx folder. Environment variables in manifest will be replaced before apply to AAD app + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + TeamsAppId: ${{TEAMS_APP_ID}} + MicrosoftAppType: SingleTenant + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/m365agents.yml b/samples/TeamsSDK/Archived/tab-deeplink/python/m365agents.yml new file mode 100644 index 0000000000..5885cf926f --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-deeplink-python + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/requirements.txt b/samples/TeamsSDK/Archived/tab-deeplink/python/requirements.txt new file mode 100644 index 0000000000..4ce0d9edb7 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/requirements.txt @@ -0,0 +1,3 @@ +requests==2.33.1 +botbuilder-integration-aiohttp==4.17.1 +flask==3.1.3 \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/resources/AdaptiveCard.json b/samples/TeamsSDK/Archived/tab-deeplink/python/resources/AdaptiveCard.json new file mode 100644 index 0000000000..9992badf14 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/resources/AdaptiveCard.json @@ -0,0 +1,39 @@ +{ + "type": "AdaptiveCard", + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.0", + "body": [ + { + "type": "TextBlock", + "text": "Please click on below buttons to navigate to a tab!", + "wrap": true + } + ], + "actions": [ + { + "type": "Action.OpenUrl", + "title": "${BotsTitle}", + "url": "${BotsDeepLink}" + }, + { + "type": "Action.OpenUrl", + "title": "${METitle}", + "url": "${MEDeepLink}" + }, + { + "type": "Action.OpenUrl", + "title": "${CardsTitle}", + "url": "${CardsDeepLink}" + }, + { + "type": "Action.OpenUrl", + "title": "${ExtendedDeepLinkTitle}", + "url": "${ExtendedDeepLink}" + }, + { + "type": "Action.OpenUrl", + "title": "${sidePanelLinkTitle}", + "url": "${sidePanelLink}" + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelDeepLink.html b/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelDeepLink.html new file mode 100644 index 0000000000..01e0665f7e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelDeepLink.html @@ -0,0 +1,95 @@ + + + + + + + + + + + + + +
+
+
+
+ + + + Back To List + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelDetails.html b/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelDetails.html new file mode 100644 index 0000000000..4f769c2a98 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelDetails.html @@ -0,0 +1,47 @@ + + + + + + + + +
+
+
+ Back To List + +
+ + Extended Deep link features + +
+
+ + +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelTasklist.html b/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelTasklist.html new file mode 100644 index 0000000000..8c2d7886f4 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/ChannelTasklist.html @@ -0,0 +1,45 @@ + + + + + + + + + + + +
+
+ + Extended Deep link features + +
+
+ + +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/Configure.html b/samples/TeamsSDK/Archived/tab-deeplink/python/static/Configure.html new file mode 100644 index 0000000000..ea695d9880 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/Configure.html @@ -0,0 +1,30 @@ + + + + + + + + + +

Click on save to configure the tab.

+ + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLink.html b/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLink.html new file mode 100644 index 0000000000..8f56607eef --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLink.html @@ -0,0 +1,73 @@ + + + + + + + + + + + +
+
+
+
+
+
+

Share to Teams using a web page

+

Click below Teams button to open popup

+ +
+
+
+ + Extended Deep link features + +
+
+ + +
+ Back To List + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLinkFeatures.js b/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLinkFeatures.js new file mode 100644 index 0000000000..625e9a7466 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLinkFeatures.js @@ -0,0 +1,115 @@ +// Initialize the library. +microsoftTeams.app.initialize().then(() => { +}); + +// Select people for fetching the attendees. +function selectPeople() { + microsoftTeams.people.selectPeople({ setSelected: [], openOrgWideSearchInChatOrChannel: true, singleSelect: false }).then((people) => { + if (people) { + document.getElementById("Attendee").value = (people.map((p) => p.email)).join(","); + } + }).catch((error) => { + console.log(error); + }); +} + +// function which redirects the user to start new chat. +function startNewChat() { + // Declare microsoftTeams chat + var chat = microsoftTeams.chat; + + // Declare microsoftTeams.app + var app = microsoftTeams.app; + + app.initialize().then(app.getContext).then((context) => { + + // get the current user. + let user = context.user.loginHint; + + if (chat.isSupported()) { + const chatPromise = chat.openGroupChat({ users: [user] }); + chatPromise. + then((result) => { console.log(result) }). + catch((error) => { console.log(error) }); + } + else { + console.log("openGroupChat isn't supported"); + } + + }); +} + +// function to navigate chat with application +function navigateToChatWithApplication() { + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/entity/${env.AppId}/conversations`); +} + +// navigates to teams chat window. +function navigateToTeamsChat() { + let app = microsoftTeams.app; + + app.initialize().then(app.getContext).then((context) => { + const queryParameters = { + channelId: context.channel.id, + tenantId: context.user.tenant.id, + groupId: context.team.groupId, + parentMessageId: context.app.parentMessageId, + teamName: context.team.displayName, + channelName: context.channel.displayName + } + + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/message/${queryParameters.channelId}/tenantId=${queryParameters.tenantId}&groupId=${queryParameters.groupId}&parentMessageId=${queryParameters.parentMessageId}&teamName=${queryParameters.teamName}&channelName=${queryParameters.channelName}`) + }); +} + +// function to navigate chat with application +function onCallDeepLinkButtonClick(callModalities) { + microsoftTeams.people.selectPeople({ setSelected: [], openOrgWideSearchInChatOrChannel: true, singleSelect: false }).then((people) => { + if (people) { + if (microsoftTeams.call.isSupported()) { + microsoftTeams.call.startCall({ + targets: people.map((p) => p.email), + requestedModalities: [callModalities] + }) + .then((result) => { + console.log(result); + }).catch((error) => { + console.log(error); + }); + } + else { + alert("Call isn't supported"); + } + } + }).catch((error) => { + console.log(error); + }); +} + +// function to open scheduling dialog workflow +function onSchedulingDialogClick() { + var subjectInput = document.getElementById("Subject"); + var startTimeInput = document.getElementById("StartTime"); + var endTimeInput = document.getElementById("EndTime"); + var contentInput = document.getElementById("Content"); + var attendeeInput = document.getElementById("Attendee"); + + if (subjectInput.value.trim() !== "" && startTimeInput.value !== "" && endTimeInput.value !== "" && attendeeInput.value !== "") { + var meetingDetails = + { + attendees: attendeeInput.value, + content: contentInput.value.trim(), + endTime: endTimeInput.value, + startTime: startTimeInput.value, + subject: subjectInput.value.trim(), + }; + + microsoftTeams.app.openLink(`https://teams.microsoft.com/l/meeting/new?subject=${meetingDetails.subject}&startTime=${meetingDetails.startTime}&endTime=${meetingDetails.endTime}&content=${meetingDetails.content}&attendees=${meetingDetails.attendees}`) + } +} + +// function to open app installation dialog workflow +// Below app id is for harcoded for polly app which is already available in store. +function onAppInstallDialogClick() { + microsoftTeams.app.openLink("https://teams.microsoft.com/l/app/1542629c-01b3-4a6d-8f76-1938b779e48d"); +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLinkModel.js b/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLinkModel.js new file mode 100644 index 0000000000..c2e81f8720 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/DeepLinkModel.js @@ -0,0 +1,7 @@ +var Task1Link ={ ID:1, Desc: "Bots"} +var Task2Link ={ ID:2, Desc:"Messaging Extension"} +var Task3Link ={ ID:3, Desc: "Adaptive Card"} + +var DeepLinkModel =[Task1Link,Task2Link,Task3Link] + + diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/Details.html b/samples/TeamsSDK/Archived/tab-deeplink/python/static/Details.html new file mode 100644 index 0000000000..2345dba868 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/Details.html @@ -0,0 +1,50 @@ + + + + + + + + + + +
+
+
+ Back To List +
+ + Extended Deep link features + +
+
+ + +
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/ExtendedDeepLink.html b/samples/TeamsSDK/Archived/tab-deeplink/python/static/ExtendedDeepLink.html new file mode 100644 index 0000000000..d25c73759f --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/ExtendedDeepLink.html @@ -0,0 +1,238 @@ + + + + + + +
+
+
+
+
+
+
+ Add this app in meeting side panel and stage this tab to experience deeplink to meeting + side panel. +
+
+
+
+
+
+
+
+
+
+ Audio call members using the v2.0 SDK method +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.call.startCall({ targets: usersEmailArray,
+        requestedModalities: [microsoftTeams.call.CallModalities.Audio]})
+    .then((result) => {
+        console.log(result);
+    }).catch((error) => {
+            console.log(error);
+    });
+                            
+
+
Select members and make a call.
+
+ +
+
+
+
+
+
+ Video call members using the v2.0 SDK method +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.call.startCall({ targets: usersEmailArray,
+    requestedModalities: [microsoftTeams.call.CallModalities.Video]})
+.then((result) => {
+    console.log(result);
+}).catch((error) => {
+        console.log(error);
+});
+                            
+
+
Select members and make a call.
+
+ +
+
+
+
+
+
+
+
Open a scheduling dialog
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink("https://teams.microsoft.com/l/meeting/new?subject=Meeting Subject"
++ "&startTime=2022-07-24T10:30:00"
++ "&endTime=2022-07-24T11:30:00"
++ "&content=Meeting Content"
++ "&attendees=abc@ms.com,bcd@ms.com")
+                            
+
+
+
+ Add Details for scheduling dialog +
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ +
+
+
+
+
+
+ Open a Polly app install dialog +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink("https://teams.microsoft.com/l/app/1542629c-01b3-4a6d-8f76-1938b779e48d");
+                            
+
+
+ +
+
+
+
+
+
+
+
+ Start new chat +
+
+ To use this option, configure the function using following + parameters + +
+const chatPromise = chat.openGroupChat({ users: [user] });
+    chatPromise.
+        then((result) => { console.log(result) }).
+        catch((error) => { console.log(error) });
+                            
+
+
+ +
+
+
+
+
+
+ Navigate to chat (Personal chat with bot) +
+
+ To use this option, configure the function using following + parameters + +
+microsoftTeams.app.openLink(`https://teams.microsoft.com/l/entity/{appId}/conversations`);
+                            
+
+
+ +
+
+
+
+
+
+
+
+ Navigate to teams chat (Works in teams chat only) +
+
+ To use this option, configure the function using following + parameters + +
+const queryParameters = {
+    channelId: context.channel.id,
+    tenantId: context.user.tenant.id,
+    groupId: context.team.groupId,
+    parentMessageId: context.app.parentMessageId,
+    teamName: context.team.displayName,
+    channelName: context.channel.displayName
+            }
+
+microsoftTeams.app.openLink(`https://teams.microsoft.com/l/message/${queryParameters.channelId}/tenantId=${queryParameters.tenantId}&groupId=${queryParameters.groupId}&parentMessageId=${queryParameters.parentMessageId}&teamName=${queryParameters.teamName}&channelName=${queryParameters.channelName}`)
+                            
+
+
+ +
+
+
+
+ + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/LinkDescription.js b/samples/TeamsSDK/Archived/tab-deeplink/python/static/LinkDescription.js new file mode 100644 index 0000000000..580794a523 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/LinkDescription.js @@ -0,0 +1,51 @@ +microsoftTeams.app.initialize().then(() => { + microsoftTeams.app.getContext().then((context) => { + if (context.page.frameContext === "sidePanel") { + document.getElementById("side-panel-content").style.display = "block"; + document.getElementById('list-content').style.display = "none"; + document.getElementById('taskList').style.display = "none"; + document.getElementById("extended-deeplink").style.display = "none"; + document.getElementById("side-panel-deeplink").style.display = "none"; + } + else if (context.page.frameContext === "meetingStage") { + + fetch(`${window.location.origin}/api/getAppId`).then(response => response.json()).then(data => { + deepLinkString = `https://teams.microsoft.com/l/entity/${data.microsoftAppId}/DeepLinkApp?context={"chatId": "${context.chat.id}","contextType":"chat"}`; + + document.getElementById("side-panel-deeplink").style.display = "block"; + document.getElementById('list-content').style.display = "none"; + document.getElementById('taskList').style.display = "none"; + document.getElementById("extended-deeplink").style.display = "none"; + }); + } + else if (context.page.subPageId === "topic1") { + document.getElementById("taskDiv").innerHTML = "Bots"; + document.getElementById("taskContent").innerHTML = "A bot also referred to as a chatbot or conversational bot is an app that runs simple and repetitive automated tasks performed by the users, such as customer service or support staff. Examples of bots in everyday use include, bots that provide information about the weather, make dinner reservations, or provide travel information. A bot interaction can be a quick question and answer, or it can be a complex conversation that provides access to services.For more details Click here"; + } + + else if (context.page.subPageId === "topic2") { + document.getElementById("taskDiv").innerHTML = "Messaging Extension"; + document.getElementById("taskContent").innerHTML = "Messaging extensions allow the users to interact with your web service through buttons and forms in the Microsoft Teams client. They can search or initiate actions in an external system from the compose message area, the command box, or directly from a message. You can send back the results of that interaction to the Microsoft Teams client in the form of a richly formatted card. This document gives an overview of the messaging extension, tasks performed under different scenarios, working of messaging extension, action and search commands, and link unfurling.For more details Click here"; + } + + else if (context.page.subPageId === "topic3") { + document.getElementById("taskDiv").innerHTML = "Adaptive Card"; + document.getElementById("taskContent").innerHTML ="Adaptive cards are a new cross product specification for cards in Microsoft products including Bots, Cortana, Outlook, and Windows. They are the recommended card type for new Teams development. For general information from the Adaptive cards team see Adaptive Cards Overview. You can use adaptive cards anywhere you can use existing Hero cards, Office365 cards, and Thumbnail cards.For more details Click here"; + } + else{ + var s=DeepLinkModel; + var html =''; + s.forEach(x=> { + var uri = "ChannelDetails.html?id="+x.ID; + let listContent = document.getElementById("list-content"); + let anchorTag = document.createElement("a"); + let lineBreakTag = document.createElement("br"); + anchorTag.href = uri; + anchorTag.innerHTML = x.Desc; + + listContent.appendChild(anchorTag); + listContent.appendChild(lineBreakTag); + }); + } + }); +}); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/TaskList.html b/samples/TeamsSDK/Archived/tab-deeplink/python/static/TaskList.html new file mode 100644 index 0000000000..acea9d110a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/TaskList.html @@ -0,0 +1,42 @@ + + + + + + + + + +
+
+ + Extended Deep link features + +
+
+ + +
+ + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/env.js b/samples/TeamsSDK/Archived/tab-deeplink/python/static/env.js new file mode 100644 index 0000000000..95259d9bfb --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/env.js @@ -0,0 +1,3 @@ +env = { + AppId: "" +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-deeplink/python/static/style.css b/samples/TeamsSDK/Archived/tab-deeplink/python/static/style.css new file mode 100644 index 0000000000..f4b73069c8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-deeplink/python/static/style.css @@ -0,0 +1,65 @@ +pre { + overflow-x: scroll; +} + +.callDeeplinkButton { + font-family: "Segoe UI","Apple Color Emoji","Segoe UI Emoji","Segoe UI Web"; + font-weight: 700; + background-color: #444791; + cursor: pointer; + color: white; + width: 50px; + border-radius: 8px; + border: none; + margin-top: 1rem; + padding: 10px 0px; + text-align: center; + text-decoration: none; +} + + .callDeeplinkButton:hover { + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); + } + +.inputContainer { + margin-top: 10px; +} + +.container { + font-family: "Segoe UI","Apple Color Emoji","Segoe UI Emoji","Segoe UI Web"; + font-size: 14px; +} + +.card { + box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%); + width: 33rem; + min-height: 18rem; + overflow: hidden; + margin-left: 2rem; + margin-top: 0.5rem; +} + +.card-container-div { + padding-bottom: 2rem; + display: flex; +} + +.card-header { + margin-left: 1rem; + margin-right: 1rem; + margin-top: 1rem; + padding-top: 0.5rem; + font-size: 16px !important; +} + +button { + margin: 1rem 8.5rem 1rem 11.5rem; +} + +.form-container { + margin-left: 1rem; +} + +.card-body { + margin-left: 0.5rem; +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/M365Agent.ttkproj b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/M365Agent.ttkproj new file mode 100644 index 0000000000..90126e2918 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/M365Agent.ttkproj @@ -0,0 +1,13 @@ + + + + 0d2b7f18-ecc2-4e73-844a-a4b28d4446c9 + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/aad.manifest.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/aad.manifest.json new file mode 100644 index 0000000000..e23e2fe555 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/aad.manifest.json @@ -0,0 +1,100 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "displayName": "tab-stage-view-aad", + "signInAudience": "AzureADMultipleOrgs", + "api": { + "requestedAccessTokenVersion": 2, + "oauth2PermissionScopes": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ] + }, + "info": {}, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "publicClient": {}, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "web": { + "implicitGrantSettings": {} + }, + "spa": {} +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/color.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/manifest.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/manifest.json new file mode 100644 index 0000000000..4a40114fa2 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/manifest.json @@ -0,0 +1,90 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.1", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Tab SV C#", + "full": "Tab in stage view" + }, + "description": { + "short": "Microsoft Teams tab sample app showcasing stage view functionality.", + "full": "This sample app demonstrates the use of Teams tab in stage view using C#, showcasing collaborative features and interactive elements." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "staticTabs": [ + { + "entityId": "stageViewTask", + "scopes": [ + "personal" + ], + "context": [ + "personalTab", + "channelTab" + ], + "name": "Stage View", + "contentUrl": "https://${{BOT_DOMAIN}}/sampleTab", + "websiteUrl": "https://${{BOT_DOMAIN}}/sampleTab", + "searchUrl": "https://${{BOT_DOMAIN}}/sampleTab" + } + ], + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "team", + "personal", + "groupChat" + ], + "isNotificationOnly": false + } + ], + "accentColor": "#60A18E", + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "commands": [ + { + "id": "searchQuery", + "context": [ "commandBox" ], + "description": "Test command to run query", + "title": "Search Command", + "type": "query", + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Your search query", + "inputType": "text" + } + ] + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "tabstageview.com/card", + "${{BOT_DOMAIN}}" + ] + } + } + ] + } + ], + "permissions": [ "identity", "messageTeamMembers" ], + "validDomains": [ + "${{BOT_DOMAIN}}", + "token.botframework.com" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/outline.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/appPackage/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/env/.env.local b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/env/.env.local new file mode 100644 index 0000000000..ae4c5f84cf --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/env/.env.local @@ -0,0 +1,25 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local +APP_NAME_SUFFIX=local + +# Generated during provision, you can also add your own variables. +BOT_ID= +TEAMS_APP_ID= +TEAMSFX_M365_USER_NAME= + +BOT_ENDPOINT= +BOT_DOMAIN= + +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/infra/azure.bicep b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/infra/azure.parameters.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/infra/azure.parameters.json new file mode 100644 index 0000000000..0c8b50260d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "tab-stage-view" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/launchSettings.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/launchSettings.json new file mode 100644 index 0000000000..d6491ef52c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/launchSettings.json @@ -0,0 +1,15 @@ +{ + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + }, + // Launch project within Teams without prepare app dependencies + "Microsoft Teams (browser) (skip update app)": { + "commandName": "Project", + "environmentVariables": { "UPDATE_TEAMS_APP": "false" }, + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/m365agents.local.yml b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/m365agents.local.yml new file mode 100644 index 0000000000..402ecb3790 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/m365agents.local.yml @@ -0,0 +1,84 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-stage-view-csharp + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: tab-stage-view-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMultipleOrgs" # Multitenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-stage-view-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ../TabInStageView/appsettings.json + content: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + ApplicationBaseURL: ${{BOT_ENDPOINT}} + TeamsAppId: ${{TEAMS_APP_ID}} + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appPackage/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/m365agents.yml b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/m365agents.yml new file mode 100644 index 0000000000..3ea258d325 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/M365Agent/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-stage-view-csharp + +environmentFolderPath: ./env \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/README.md b/samples/TeamsSDK/Archived/tab-stage-view/csharp/README.md new file mode 100644 index 0000000000..ba9abe529d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/README.md @@ -0,0 +1,252 @@ +--- +page_type: sample +description: This sample app demonstrates the use of Teams tab in stage view using C#, showcasing collaborative features and interactive elements. +products: +- office-teams +- office +- office-365 +languages: +- csharp +extensions: + contentType: samples + createdDate: "06/10/2021 01:48:56 AM" +urlFragment: officedev-microsoft-teams-samples-tab-stage-view-csharp +--- + +# Stage View + +This sample app illustrates the capabilities of Microsoft Teams tabs in stage view using C#. It demonstrates collaborative features, such as multi-window support and deep linking, allowing users to engage interactively through adaptive cards and links that enhance the overall user experience in Teams. +This App talks about the Teams tab in stage view with CSharp. +For reference please check [Tabs link unfurling and Stage View](https://docs.microsoft.com/microsoftteams/platform/tabs/tabs-link-unfurling) + +## Included Features +* Bots +* Stage View (tabs) +* Collaborative Stageview +* Stageview Multi-window (PopOut) +* Stageview Modal + +## Interaction with app + +![TabStageView Modules](TabInStageView/Images/TabStageView.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app manifest (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Stage View:** [Manifest](/samples/tab-stage-view/csharp/demo-manifest/tab-stage-view.zip) + +## Prerequisites + +- [.NET Core SDK](https://dotnet.microsoft.com/download) version 6.0 + + determine dotnet version + ```bash + dotnet --version + ``` +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [Ngrok](https://ngrok.com/download) (For local environment testing) latest version (any other tunneling software can also be used) + +- [Teams](https://teams.microsoft.com) Microsoft Teams is installed and you have an account + +- [Microsoft 365 Agents Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.14 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Microsoft 365 Agents Toolkit for Visual Studio [Microsoft 365 Agents Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In the debug dropdown menu of Visual Studio, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel. +1. Right-click the 'M365Agent' project in Solution Explorer and select **Microsoft 365 Agents Toolkit > Select Microsoft 365 Account** +1. Sign in to Microsoft 365 Agents Toolkit with a **Microsoft 365 work or school account** +1. Set `Startup Item` as `Microsoft Teams (browser)`. +1. Press F5, or select Debug > Start Debugging menu in Visual Studio to start your app +
![image](https://raw.githubusercontent.com/OfficeDev/TeamsFx/dev/docs/images/visualstudio/debug/debug-button.png) +1. In the opened web browser, select Add button to install the app in Teams +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +2) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +2. Setup for Bot + - Register a Microsoft Entra ID aap registration in Azure portal. + - Also, register a bot with Azure Bot Service, following the instructions [here](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration?view=azure-bot-service-3.0). + - Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - While registering the bot, use `https:///api/messages` as the messaging endpoint. + + > NOTE: When you create your app registration, you will create an App ID and App password - make sure you keep these for later. + +3. Setup NGROK + - Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +4. Setup for code + +- Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +- Modify the `/appsettings.json` and fill in the following details: + - `{{Bot Id}}` - Generated from Step 1 while doing Microsoft Entra ID app registration in Azure portal. + - `{{ Bot Password}}` - Generated from Step 1, also referred to as Client secret + - `{{ Application Base URL }}` - Your application's base url. E.g. https://12345.ngrok-free.app if you are using ngrok and if you are using dev tunnels, your URL will be like: https://12345.devtunnels.ms. + +- In a terminal, navigate to `TabInStageView` + + ```bash + # change into project folder + cd # TabInStageView + ``` + +- Run the bot from a terminal or from Visual Studio, choose option A or B. + + A) From a terminal + + ```bash + # run the bot + dotnet run + ``` + + B) Or from Visual Studio + + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `TabInStageView` folder + - Select `TabInStageView.csproj` file + - Press `F5` to run the project + +5. Setup Manifest for Teams +- __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the ./appPackage folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `{{Microsoft-App-Id or Bot-id}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` and replace `{{domain-name}}` with base Url of your domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + **Note:** If you want to test your app across multi hub like: Outlook/Office.com, please update the `manifest.json` in the `TabInStageView\AppManifest_Hub` folder with the required values. + - **Zip** up the contents of the `Manifest` folder to create a `Manifest.zip` or `AppManifest_Hub` folder to create a `AppManifest_Hub.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appPackage folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your app is uploaded to Teams. + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/tab-stage-view/csharp/TabInStageView/AdapterWithErrorHandler.cs#L26) line and put your debugger for local debug. + +## Interacting with the bot in Teams + You can use this tab by following the below steps: + - In the navigation bar located at the far left in Teams, select the ellipses ●●● and choose your app from the list. + +## Running the sample +- In the navigation bar located at the far left in Teams, select the ellipses ●●● and choose your app from the list. + +**Install App:** + +![InstallApp](TabInStageView/Images/1.Install.png) + +**Welcome message with feature explanation and Adaptive Card with actions:** + +![Welcome Message](TabInStageView/Images/2.WelcomeCard.png) + +**Open the URL in tab stage view:** + +![InstallApp](TabInStageView/Images/3.Bot-ViewViaCardAction.png) + +**Opening Collaborative Stage View**. Please refer [Collaborative Stage view](https://review.learn.microsoft.com/en-us/microsoftteams/platform/tabs/tabs-link-unfurling?branch=pr-en-us-7891#collaborative-stage-view) for more details + +![Stage View in tab](TabInStageView/Images/7.Tab-PopOutWithChat.png) + +**Opening stage view from Adaptive card via deep link:** + +![Stage View Deep Link](TabInStageView/Images/4.Bot-OpenViaDeeplinkLinkButton.png) + +![LinkUnfurlingStageView](TabInStageView/Images/LinkUnfurlingStageView.png) + +**Opening stage view from unfurling link. If you copy and paste a link from https://tabstageview.com/card into the compose message area the link will unfurl.** + +![LinkUnfurlingText](TabInStageView/Images/LinkUnfurlingText.png) + +**Tab with execute deep link action to open stage view:** + +![OpenMode Model](TabInStageView/Images/5.Tab-Model.png) + +![OpenMode PopOut](TabInStageView/Images/6.Tab-PopOut.png) + + + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**On the side bar, select More Apps. Your uploaded app title appears among your installed apps** + +![InstallOutlook](TabInStageView/Images/InstallOutlook.png) + +**Select your app icon to launch and preview your app running in Outlook on the web** + +![AppOutlook](TabInStageView/Images/AppOutlook.png) + +**After opening Outlook web, click the "New mail" button.** + +![Open New Mail](TabInStageView/Images/OpenNewMail.png) + +**On the tool bar on top, select Apps icon. Your uploaded app title appears among your installed apps** + +![OpenAppIcon](TabInStageView/Images/OpenAppIcon.png) + +**Opening the stage view from unfurling link. If you copy and paste a link from https://tabstageview.com/card into the compose message area the link will unfurl.** + +![Outlook Unfurling](TabInStageView/Images/OutlookUnfurling.png) + +**Note:** Similarly, you can test your application in the Outlook desktop app as well. + +## Office on the web + +- To preview your app running in Office on the web. + +- Log into office.com with test tenant credentials + +**Select the Apps icon on the side bar. Your uploaded app title appears among your installed apps** + +![InstallOffice](TabInStageView/Images/InstallOffice.png) + +**Select your app icon to launch your app in Office on the web** + +![AppOffice](TabInStageView/Images/AppOffice.png) + +**Note:** Similarly, you can test your application in the Office 365 desktop app as well. + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Tabs](https://learn.microsoft.com/microsoftteams/platform/tabs/what-are-tabs) +- [Stage view](https://learn.microsoft.com/microsoftteams/platform/tabs/tabs-link-unfurling#stage-view) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView.sln b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView.sln new file mode 100644 index 0000000000..65b9cea941 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35004.147 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TabInStageView", "TabInStageView\TabInStageView.csproj", "{9595A32B-E860-4EC2-8DA4-FDBDD7FADD80}" +EndProject +Project("{A9E3F50B-275E-4AF7-ADCE-8BE12D41E305}") = "M365Agent", "M365Agent\M365Agent.ttkproj", "{0D2B7F18-ECC2-4E73-844A-A4B28D4446C9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CACA9F3C-6049-492B-B408-F3539F373299}" + ProjectSection(SolutionItems) = preProject + TabInStageView.slnLaunch.user = TabInStageView.slnLaunch.user + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9595A32B-E860-4EC2-8DA4-FDBDD7FADD80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9595A32B-E860-4EC2-8DA4-FDBDD7FADD80}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9595A32B-E860-4EC2-8DA4-FDBDD7FADD80}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9595A32B-E860-4EC2-8DA4-FDBDD7FADD80}.Release|Any CPU.Build.0 = Release|Any CPU + {0D2B7F18-ECC2-4E73-844A-A4B28D4446C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D2B7F18-ECC2-4E73-844A-A4B28D4446C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D2B7F18-ECC2-4E73-844A-A4B28D4446C9}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {0D2B7F18-ECC2-4E73-844A-A4B28D4446C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0D2B7F18-ECC2-4E73-844A-A4B28D4446C9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C5077745-2506-4C60-B687-E59153064F36} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/.gitignore b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/.gitignore new file mode 100644 index 0000000000..7466c01f9c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +appPackage/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AdapterWithErrorHandler.cs b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AdapterWithErrorHandler.cs new file mode 100644 index 0000000000..cc62bc2029 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AdapterWithErrorHandler.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Builder.TraceExtensions; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Extensions.Logging; + +namespace TabInStageView +{ + public class AdapterWithErrorHandler : CloudAdapter + { + public AdapterWithErrorHandler(BotFrameworkAuthentication auth, ILogger logger) + : base(auth, logger) + { + OnTurnError = async (turnContext, exception) => + { + // Log any leaked exception from the application. + logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}"); + + // Uncomment below commented line for local debugging. + // await turnContext.SendActivityAsync($"Sorry, it looks like something went wrong. Exception Caught: {exception.Message}"); + + // Send a trace activity, which will be displayed in the Bot Framework Emulator + await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError"); + }; + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/color.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/manifest.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/manifest.json new file mode 100644 index 0000000000..e7f5a61fa5 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/manifest.json @@ -0,0 +1,79 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.1", + "id": "<>", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Tab Stage View", + "full": "Tab in stage view" + }, + "description": { + "short": "View Tab in stage view", + "full": "This sample demos the tab in stage view" + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "staticTabs": [ + { + "entityId": "stageViewTask", + "scopes": [ + "personal" + ], + "context": [ + "personalTab", + "channelTab" + ], + "name": "Stage View", + "contentUrl": "https://{{domain-name}}/sampleTab", + "websiteUrl": "https://{{domain-name}}/sampleTab", + "searchUrl": "https://{{domain-name}}/sampleTab" + } + ], + "accentColor": "#60A18E", + "composeExtensions": [ + { + "botId": "<>", + "commands": [ + { + "id": "searchQuery", + "context": [ "commandBox" ], + "description": "Test command to run query", + "title": "Search Command", + "type": "query", + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Your search query", + "inputType": "text" + } + ] + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "*.botframework.com", + "{{domain-name}}" + ] + } + } + ] + } + ], + "permissions": [ "identity", "messageTeamMembers" ], + "validDomains": [ + "{{domain-name}}", + "token.botframework.com" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/outline.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/AppManifest_Hub/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Bots/ActivityBot.cs b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Bots/ActivityBot.cs new file mode 100644 index 0000000000..b8431b9287 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Bots/ActivityBot.cs @@ -0,0 +1,210 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using AdaptiveCards; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Teams; +using Microsoft.Bot.Schema; +using Microsoft.Bot.Schema.Teams; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using TabInStageView.Models; + +namespace TabInStageView.Bots +{ + /// + /// Bot Activity handler class. + /// + public class ActivityBot : TeamsActivityHandler + { + private readonly string _appId; + private readonly string _applicationBaseURL; + public static string? _threadId; + + /// + /// Initializes a new instance of the class. + /// + /// configuration of application. + public ActivityBot(IConfiguration configuration) + { + _appId = configuration["TeamsAppId"] ?? throw new NullReferenceException("MicrosoftAppId"); + _applicationBaseURL = configuration["ApplicationBaseURL"] ?? throw new NullReferenceException("ApplicationBaseURL"); + } + + // + /// Overriding to send welcome card once Bot/ME is installed in team. + /// + /// A list of all the members added to the conversation, as described by the conversation update activity. + /// Provides context for a turn of a bot. + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Welcome card when bot is added first time by user. + protected override async Task OnMembersAddedAsync(IList membersAdded, ITurnContext turnContext, CancellationToken cancellationToken) + { + var welcomeText = "Hello and welcome!, Please type any bot command to see the stage view feature"; + + // Set thread Id + _threadId = turnContext.Activity.Conversation.Id; + + foreach (var member in membersAdded) + { + if (member.Id != turnContext.Activity.Recipient.Id) + { + await turnContext.SendActivityAsync(MessageFactory.Text(welcomeText, welcomeText), cancellationToken); + } + } + } + + /// + /// Handle when a message is addressed to the bot. + /// + /// Context object containing information cached for a single turn of conversation with a user. + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// A task that represents the work queued to execute. + /// + /// For more information on bot messaging in Teams, see the documentation + /// https://docs.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/conversation-basics?tabs=dotnet#receive-a-message . + /// + protected override async Task OnMessageActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) + { + await turnContext.SendActivityAsync(MessageFactory.Attachment(GetAdaptiveCardForStageView())); + } + + /// + /// Overriding to invoke when an app based link query activity is received. + /// + protected override Task OnTeamsAppBasedLinkQueryAsync(ITurnContext turnContext, AppBasedLinkQuery query, CancellationToken cancellationToken) + { + AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion("1.5")) + { + Body = new List + { + new AdaptiveTextBlock + { + Text = "Click the button to open the Url in tab stage view", + Weight = AdaptiveTextWeight.Bolder, + Spacing = AdaptiveSpacing.Medium, + }, + }, + Actions = new List + { + new AdaptiveSubmitAction + { + Title = "View via card action", + Data = new AdaptiveCardAction + { + MsteamsCardAction = new CardAction + { + Type = "invoke", + Value = new TabInfoAction + { + Type = "tab/tabInfoAction", + TabInfo = new TabInfo + { + ContentUrl = $"{_applicationBaseURL}", + WebsiteUrl = $"{_applicationBaseURL}", + Name = "Stage view", + EntityId = "entityId" + } + } + }, + }, + } + }, + }; + + var cardContent = JObject.Parse(card.ToJson()); + var attachments = new MessagingExtensionAttachment() + { + Content = cardContent, + ContentType = AdaptiveCard.ContentType + }; + return Task.FromResult(new MessagingExtensionResponse + { + ComposeExtension = new MessagingExtensionResult + { + AttachmentLayout = "list", + Type = "result", + Attachments = new List + { + new MessagingExtensionAttachment + { + Content = cardContent, + ContentType = AdaptiveCard.ContentType, + Preview = attachments, + }, + }, + }, + }); + } + + /// + /// Sample Adaptive card for Stage view. + /// + private Attachment GetAdaptiveCardForStageView() + { + AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion("1.2")) + { + Body = new List + { + new AdaptiveTextBlock + { + Text = "Click the button to open the Url in tab stage view", + Weight = AdaptiveTextWeight.Bolder, + Spacing = AdaptiveSpacing.Medium, + }, + }, + Actions = new List + { + new AdaptiveSubmitAction + { + Title = "View via card action", + Data = new AdaptiveCardAction + { + MsteamsCardAction = new CardAction + { + Type = "invoke", + Value = new TabInfoAction + { + Type = "tab/tabInfoAction", + TabInfo = new TabInfo + { + ContentUrl = $"{_applicationBaseURL}", + WebsiteUrl = $"{_applicationBaseURL}", + Name = "Stage view", + EntityId = "entityId" + } + } + }, + }, + }, + new AdaptiveOpenUrlAction + { + Title = "View via deeplink", + Url = new Uri(GetDeeplinkForStageView()), + }, + }, + }; + + return new Attachment() + { + ContentType = AdaptiveCard.ContentType, + Content = JObject.Parse(card.ToJson()), + }; + } + + /// + /// Create deeplink for stage view. + /// + private string GetDeeplinkForStageView() + { + var deepLinkUrl = "https://teams.microsoft.com/l/stage/" + _appId + "/0?context=" + HttpUtility.UrlEncode("{\"contentUrl\":\""+_applicationBaseURL+"\",\"websiteUrl\":\""+_applicationBaseURL+"\",\"name\":\"DemoStageView\"}"); + return deepLinkUrl; + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Controllers/BotController.cs b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Controllers/BotController.cs new file mode 100644 index 0000000000..35694e4117 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Controllers/BotController.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; + +namespace TabInStageView.Controllers +{ + [Route("api/messages")] + [ApiController] + public class BotController : ControllerBase + { + private readonly IBotFrameworkHttpAdapter _adapter; + private readonly IBot _bot; + + public BotController(IBotFrameworkHttpAdapter adapter, IBot bot) + { + _adapter = adapter; + _bot = bot; + } + + [HttpPost, HttpGet] + public async Task PostAsync() + { + await _adapter.ProcessAsync(Request, Response, _bot); + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Controllers/HomeController.cs b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Controllers/HomeController.cs new file mode 100644 index 0000000000..28ec852fd7 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Controllers/HomeController.cs @@ -0,0 +1,34 @@ +namespace TabInStageView.Controllers +{ + using System; + using Microsoft.AspNetCore.Mvc; + using Microsoft.Extensions.Configuration; + + public class HomeController : Controller + { + private readonly string _appId; + + /// + /// Initializes a new instance of the class. + /// + /// configuration of application. + public HomeController(IConfiguration configuration) + { + _appId = configuration["TeamsAppId"] ?? throw new NullReferenceException("TeamsAppId"); + } + + [Route("")] + public IActionResult Index() + { + return View(); + } + + [Route("sampleTab")] + public ActionResult SampleTab() + { + // Setting client id to be used in deep link in tab + ViewBag.AppId = _appId; + return View(); + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/1.Install.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/1.Install.png new file mode 100644 index 0000000000..a08502c3e3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/2.WelcomeCard.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/2.WelcomeCard.png new file mode 100644 index 0000000000..093bd4a822 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/2.WelcomeCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/3.Bot-ViewViaCardAction.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/3.Bot-ViewViaCardAction.png new file mode 100644 index 0000000000..2bd6a6429a Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/3.Bot-ViewViaCardAction.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/4.Bot-OpenViaDeeplinkLinkButton.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/4.Bot-OpenViaDeeplinkLinkButton.png new file mode 100644 index 0000000000..dc7bcea295 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/4.Bot-OpenViaDeeplinkLinkButton.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/5.Tab-Model.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/5.Tab-Model.png new file mode 100644 index 0000000000..23f477ee94 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/5.Tab-Model.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/6.Tab-PopOut.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/6.Tab-PopOut.png new file mode 100644 index 0000000000..b60960fcaf Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/6.Tab-PopOut.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/7.Tab-PopOutWithChat.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/7.Tab-PopOutWithChat.png new file mode 100644 index 0000000000..8b1317f428 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/7.Tab-PopOutWithChat.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/AppOffice.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/AppOffice.png new file mode 100644 index 0000000000..d2345526f6 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/AppOutlook.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/AppOutlook.png new file mode 100644 index 0000000000..66675a4c73 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/InstallOffice.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/InstallOffice.png new file mode 100644 index 0000000000..ac3fb79bfc Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/InstallOutlook.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/InstallOutlook.png new file mode 100644 index 0000000000..e80183d13b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/LinkUnfurlingStageView.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/LinkUnfurlingStageView.png new file mode 100644 index 0000000000..ee518b6c81 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/LinkUnfurlingStageView.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/LinkUnfurlingText.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/LinkUnfurlingText.png new file mode 100644 index 0000000000..f438544aab Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/LinkUnfurlingText.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OpenAppIcon.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OpenAppIcon.png new file mode 100644 index 0000000000..53a44c14e3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OpenAppIcon.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OpenNewMail.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OpenNewMail.png new file mode 100644 index 0000000000..e1e768258d Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OpenNewMail.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OutlookUnfurling.png b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OutlookUnfurling.png new file mode 100644 index 0000000000..dbd12892bf Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/OutlookUnfurling.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/TabStageView.gif b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/TabStageView.gif new file mode 100644 index 0000000000..ef315431e2 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Images/TabStageView.gif differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/AdaptiveCardAction.cs b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/AdaptiveCardAction.cs new file mode 100644 index 0000000000..480d7b6501 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/AdaptiveCardAction.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace TabInStageView.Models +{ + using Microsoft.Bot.Schema; + using Newtonsoft.Json; + + /// + /// Adaptive card action model class. + /// + public class AdaptiveCardAction + { + /// + /// Gets or sets Ms Teams card action. + /// + [JsonProperty("msteams")] + public required CardAction MsteamsCardAction { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/TabInfo.cs b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/TabInfo.cs new file mode 100644 index 0000000000..00e07673f0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/TabInfo.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace TabInStageView.Models +{ + using Newtonsoft.Json; + + /// + /// Tab info model class. + /// + public class TabInfo + { + /// + /// Gets or sets content url. + /// + [JsonProperty("contentUrl")] + public required string ContentUrl { get; set; } + + /// + /// Gets or sets website url. + /// + [JsonProperty("websiteUrl")] + public required string WebsiteUrl { get; set; } + + /// + /// Gets or sets name. + /// + [JsonProperty("name")] + public required string Name { get; set; } + + /// + /// Gets or sets entity id. + /// + [JsonProperty("entityId")] + public required string EntityId { get; set; } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/TabInfoAction.cs b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/TabInfoAction.cs new file mode 100644 index 0000000000..f4fbe3dc68 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Models/TabInfoAction.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace TabInStageView.Models +{ + using Newtonsoft.Json; + + /// + /// Tab info action model class. + /// + public class TabInfoAction + { + /// + /// Gets or sets type of tab. + /// + [JsonProperty("type")] + public required string Type { get; set; } + + /// + /// Gets or sets tab info. + /// + [JsonProperty("tabInfo")] + public required TabInfo TabInfo { get; set; } + + /// + /// Gets or sets tab info. + /// + [JsonProperty("threadId")] + public string? ThreadId { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Program.cs b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Program.cs new file mode 100644 index 0000000000..5c63d3fc51 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Program.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Connector.Authentication; +using TabInStageView; +using TabInStageView.Bots; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers().AddNewtonsoftJson(); +builder.Services.AddRazorPages(); + +// Create the Bot Framework Authentication to be used with the Bot Adapter. +builder.Services.AddSingleton(); + +// Create the Bot Framework Adapter with error handling enabled. +builder.Services.AddSingleton(); + +// Create the bot as a transient. In this case the ASP Controller is expecting an IBot. +builder.Services.AddTransient(); + +var app = builder.Build(); + +app.UseHttpsRedirection(); +app.UseStaticFiles(); +app.UseRouting(); +app.MapControllers(); +app.MapControllerRoute( + name: "default", + pattern: "{controller}/{action=Index}/{id?}"); + +app.Run(); diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Properties/launchSettings.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Properties/launchSettings.json new file mode 100644 index 0000000000..ff9d8fe153 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "Start Project": { + "commandName": "Project", + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7130;http://localhost:5130", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/TabInStageView.csproj b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/TabInStageView.csproj new file mode 100644 index 0000000000..0e136b7933 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/TabInStageView.csproj @@ -0,0 +1,21 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + Always + + + + diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Views/Home/Index.cshtml b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Views/Home/Index.cshtml new file mode 100644 index 0000000000..0e1462550a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Views/Home/Index.cshtml @@ -0,0 +1,34 @@ +@{ + Layout = null; +} + + + + + + + + +
+

Tab in Stage View

+

Learn about building Web apps with ASP.NET Core.

+ +
+ + + + diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Views/Home/SampleTab.cshtml b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Views/Home/SampleTab.cshtml new file mode 100644 index 0000000000..800d888de1 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/Views/Home/SampleTab.cshtml @@ -0,0 +1,121 @@ +@page +@model TabInStageView.Models.TabInfoAction + + + + + + + + + + +
+
+
+ Click on the button to view the stage view from deeplink: + + + +
+
+
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/appsettings.Development.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/appsettings.Development.json new file mode 100644 index 0000000000..b49abfc201 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } + } diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/appsettings.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/appsettings.json new file mode 100644 index 0000000000..86475f47bd --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/TabInStageView/appsettings.json @@ -0,0 +1,8 @@ +{ + "MicrosoftAppType": "SingleTenant", + "MicrosoftAppId": "{{ Bot Id }}", + "MicrosoftAppPassword": "{{ Bot Password }}", + "MicrosoftAppTenantId": "{{ Tenant Id }}", + "TeamsAppId": "{{ Teams App Id }}", + "ApplicationBaseURL": "{{ Application Base URL }}" +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/assets/sample.json b/samples/TeamsSDK/Archived/tab-stage-view/csharp/assets/sample.json new file mode 100644 index 0000000000..4835735273 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/csharp/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-tab-stage-view-csharp", + "source": "officeDev", + "title": "Stage View", + "shortDescription": "This sample app demonstrates the use of Teams tab in stage view using C#, showcasing collaborative features and interactive elements.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-stage-view/csharp", + "longDescription": [ + "The Stage View sample app provides a C# implementation that highlights the functionality of Teams tabs in stage view, including features like collaborative stage view and multi-window support. Users can interact with various elements such as adaptive cards and deep links, enhancing their experience within Microsoft Teams." + ], + "creationDateTime": "2021-06-10", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "csharp" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "netframework" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab,bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/tab-stage-view/csharp/TabInStageView/Images/TabStageView.gif", + "alt": "Solution UX showing stage view" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/csharp/demo-manifest/tab-stage-view.zip b/samples/TeamsSDK/Archived/tab-stage-view/csharp/demo-manifest/tab-stage-view.zip new file mode 100644 index 0000000000..5f7a6d0366 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/csharp/demo-manifest/tab-stage-view.zip differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.env b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.env new file mode 100644 index 0000000000..2e212f14ab --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.env @@ -0,0 +1,6 @@ +MicrosoftAppId="" +MicrosoftAppPassword="" +BaseUrl="" +MicrosoftAppType=SingleTenant +MicrosoftAppTenantId= +TeamsAppId= diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.eslintignore b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.eslintignore new file mode 100644 index 0000000000..30bc162798 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.eslintignore @@ -0,0 +1 @@ +/node_modules \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.eslintrc.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.eslintrc.js new file mode 100644 index 0000000000..bc3769aad4 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.eslintrc.js @@ -0,0 +1,18 @@ +/* eslint-disable */ +module.exports = { + "extends": "standard", + "rules": { + "semi": [2, "always"], + "indent": [2, 4], + "no-return-await": 0, + "space-before-function-paren": [2, { + "named": "never", + "anonymous": "never", + "asyncArrow": "always" + }], + "template-curly-spacing": [2, "always"] + }, + "parserOptions": { + "ecmaVersion": 2022 + } +}; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.gitignore b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.gitignore new file mode 100644 index 0000000000..8f78731e17 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appManifest/build +/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store + +# build +lib/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/extensions.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/extensions.json new file mode 100644 index 0000000000..2d88dee21b --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/launch.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/launch.json new file mode 100644 index 0000000000..d027ed91e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/launch.json @@ -0,0 +1,73 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Local Service", + "type": "node", + "request": "attach", + "port": 9239, + "restart": true, + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/settings.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/settings.json new file mode 100644 index 0000000000..4299620253 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ] +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/tasks.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/tasks.json new file mode 100644 index 0000000000..b79f108ff5 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/.vscode/tasks.json @@ -0,0 +1,105 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Teams App Locally", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy", + "Start application" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "nodejs", // Validate if Node.js is installed. + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + 9239 // app inspector port for Node.js debugger + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + }, + { + "label": "Start application", + "type": "shell", + "command": "npm run dev:teamsfx", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": { + "pattern": [ + { + "regexp": "^.*$", + "file": 0, + "location": 1, + "message": 2 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "[nodemon] starting", + "endsPattern": "Server listening on port:" + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/1.Install.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/1.Install.png new file mode 100644 index 0000000000..a08502c3e3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/2.HelloAndWelcomeCard.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/2.HelloAndWelcomeCard.png new file mode 100644 index 0000000000..a5da67af42 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/2.HelloAndWelcomeCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/3.Bot-ViewViaCardAction.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/3.Bot-ViewViaCardAction.png new file mode 100644 index 0000000000..3463856dea Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/3.Bot-ViewViaCardAction.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/4.Bot-OpenViaDeeplinkLinkButton.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/4.Bot-OpenViaDeeplinkLinkButton.png new file mode 100644 index 0000000000..dc7bcea295 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/4.Bot-OpenViaDeeplinkLinkButton.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/5.Tab-PopOutWithChat.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/5.Tab-PopOutWithChat.png new file mode 100644 index 0000000000..a397a90d46 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/5.Tab-PopOutWithChat.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/6.Tab-PopOut.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/6.Tab-PopOut.png new file mode 100644 index 0000000000..b7216b4b5d Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/6.Tab-PopOut.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/7.Tab-Model.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/7.Tab-Model.png new file mode 100644 index 0000000000..9075209d0d Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/7.Tab-Model.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/AppOffice.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/AppOffice.png new file mode 100644 index 0000000000..61491e2555 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/AppOutlook.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/AppOutlook.png new file mode 100644 index 0000000000..eaf7f6e445 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/InstallOffice.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/InstallOffice.png new file mode 100644 index 0000000000..eb6449d7d5 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/InstallOutlook.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/InstallOutlook.png new file mode 100644 index 0000000000..0328041f5e Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/LinkUnfurlingStageView.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/LinkUnfurlingStageView.png new file mode 100644 index 0000000000..ee518b6c81 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/LinkUnfurlingStageView.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/LinkUnfurlingText.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/LinkUnfurlingText.png new file mode 100644 index 0000000000..f438544aab Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/LinkUnfurlingText.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OpenAppIcon.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OpenAppIcon.png new file mode 100644 index 0000000000..53a44c14e3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OpenAppIcon.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OpenNewMail.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OpenNewMail.png new file mode 100644 index 0000000000..e1e768258d Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OpenNewMail.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OutlookUnfurling.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OutlookUnfurling.png new file mode 100644 index 0000000000..dbd12892bf Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/OutlookUnfurling.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/TabStageView.gif b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/TabStageView.gif new file mode 100644 index 0000000000..3c74dec834 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Images/TabStageView.gif differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Readme.md b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Readme.md new file mode 100644 index 0000000000..3c50e6b6fe --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/Readme.md @@ -0,0 +1,265 @@ +--- +page_type: sample +description: This sample app demonstrates the use of Teams tab in stage view using Node.js, featuring collaborative elements and interactive capabilities. +products: +- office-teams +- office +- office-365 +languages: +- nodejs +extensions: + contentType: samples + createdDate: "10/06/2021 01:48:56 AM" +urlFragment: officedev-microsoft-teams-samples-tab-stage-view-nodejs +--- + +# Stage View + +This sample app showcases the capabilities of Microsoft Teams tabs in stage view using Node.js. It demonstrates collaborative features such as multi-window support and interactive elements, allowing users to engage dynamically through adaptive cards and deep linking for a richer experience in Teams. +This App talks about the Teams tab in stage view with Nodejs. + +For reference please check [Tabs link unfurling and Stage View](https://docs.microsoft.com/microsoftteams/platform/tabs/tabs-link-unfurling) + +## Included Features +* Bots +* Stage View (tabs) +* Collaborative Stageview +* Stageview Multi-window (PopOut) +* Stageview Modal + +## Interaction with app + +![Tab Stage ViewGif](Images/TabStageView.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Stage View:** [Manifest](/samples/tab-stage-view/csharp/demo-manifest/tab-stage-view.zip) + +## Prerequisites + +- Office 365 tenant. You can get a free tenant for development use by signing up for the [Office 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program). + +- To test locally, [NodeJS](https://nodejs.org/en/download/) must be installed on your development machine (version 16.14.2 or higher). + + ```bash + # determine node version + node --version + ``` + +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [Ngrok](https://ngrok.com/download) (For local environment testing) latest version (any other tunneling software can also be used) + If you using Ngrok to test locally, you'll need [Ngrok](https://ngrok.com/) installed on your development machine. +Make sure you've downloaded and installed Ngrok on your local machine. ngrok will tunnel requests from the Internet to your local computer and terminate the SSL connection from Teams. + +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +> NOTE: The free ngrok plan will generate a new URL every time you run it, which requires you to update your Azure AD registration, the Teams app manifest, and the project configuration. A paid account with a permanent ngrok URL is recommended. + +1) Setup for Bot + - Register a bot with Azure Bot Service, following the instructions [here](https://docs.microsoft.coms/azure/bot-service/bot-service-quickstart-registration?view=azure-bot-service-3.0). + - While registering the bot, use `https:///api/messages` as the messaging endpoint. + + > NOTE: When you create your app registration in Azure portal, you will create an App ID and App password - make sure you keep these for later. + +2) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +3) Setup NGROK +1) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +4) Setup for code +- Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +- In a console, navigate to `samples/tab-stage-view/nodejs` folder + +- Install modules + + ```bash + npm install + ``` + +- Update the `.env` configuration for the bot to use the `MicrosoftAppId` (Microsoft App Id) and `MicrosoftAppPassword` (App Password) from the Azure bot registration in Azure portal or Bot Framework registration. +Also update `BaseUrl` according to your code runtime environment. +> NOTE: the App Password is referred to as the `client secret` in the azure portal and you can always create a new client secret anytime. + +- Run your bot at the command line: + + ```bash + npm start + ``` +- Install modules & Run the NodeJS Server + - Server will run on PORT: 3978 + - Open a terminal and navigate to project root directory + + ```bash + npm run server + ``` +- This command is equivalent to: npm install > npm start + +- Setup Manifest for Teams +5) **This step is specific to Teams.** + + - Edit the `manifest.json` in the `appManifest` folder and replace the following details: + - `<>` with some unique GUID or `MicrosoftAppId` + - `<>` with your application's base url, e.g. https://1234.ngrok-free.app + - `<>` with the `MicrosoftAppId` received from Microsoft Entra ID app registration in Azure portal. + - `<>` with the ngrok URL or app hosted base url. + **Note:** If you want to test your app across multi hub like: Outlook/Office.com, please update the `manifest.json` in the `tab-stage-view\nodejs\appManifest_Hub` folder with the required values. + - **Zip** up the contents of the `appManifest` folder to create a `Manifest.zip` or `appManifest_Hub` folder to create a `appManifest_Hub.zip` + - **Upload** the `manifest.zip` to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appManifest folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your tab is uploaded to Teams. + +**Note**: If you are facing any issue in your app, please uncomment [this](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/tab-stage-view/nodejs/server/api/botController.js#L24) line and put your debugger for local debug.. + +## Running the sample +- From Teams left side bar, select the ellipses ●●● and choose your app from the list. + +**Install App:** + +![InstallApp](Images/1.Install.png) + +**Welcome message with feature explanation and Adaptive Card with actions:** + +![Welcome Message](Images/2.HelloAndWelcomeCard.png) + +**Open the URL in tab stage view:** + +![InstallApp](Images/3.Bot-ViewViaCardAction.png) + + **Click view via card action:** + +![Stage View in tab](Images/4.Bot-OpenViaDeeplinkLinkButton.png) + + **Click view via deeplink:** + + ![Tab View](Images/viaDeeplink.png) + +**Opening Collaborative- Desktop Stage View**. Please refer [Collaborative Stage view](https://review.learn.microsoft.com/en-us/microsoftteams/platform/tabs/tabs-link-unfurling?branch=pr-en-us-7891#collaborative-stage-view) for more details. + + ![Stage View in tab](Images/5.Tab-PopOutWithChat.png) + + ![OpenMode Model](Images/6.Tab-PopOut.png) + + ![OpenMode PopOut](Images/7.Tab-Model.png) + +**Opening stage view from Adaptive card via deep link:** + +![Stage View Deep Link](Images/4.Bot-OpenViaDeeplinkLinkButton.png) + +**Web Stage View:** + +![LinkUnfurlingStageView](Images/LinkUnfurlingStageView.png) + +**Opening stage view from unfurling link. If you copy and paste a link from https://tabstageview.com/card into the compose message area, the link will unfurl.** + +![LinkUnfurlingText](Images/LinkUnfurlingText.png) + +**Tab with execute deep link action to open stage view:** + +![Tab View](Images/viaTabDeeplink.png) + +**Click deep-link:** + +![Tab View](Images/viaDeeplink.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**On the side bar, select More Apps. Your uploaded app title appears among your installed apps** + +![InstallOutlook](Images/InstallOutlook.png) + +**Select your app icon to launch and preview your app running in Outlook on the web** + +![AppOutlook](Images/AppOutlook.png) + +**Note:** Similarly, you can test your application in the Outlook desktop app as well. + +## Office on the web + +- To preview your app running in Office on the web. + +- Log into office.com with test tenant credentials + +**Select the Apps icon on the side bar. Your uploaded app title appears among your installed apps** + +![InstallOffice](Images/InstallOffice.png) + +**Select your app icon to launch your app in Office on the web** + +![AppOffice](Images/AppOffice.png) + +**After opening Outlook web, click the "New mail" button.** + +![Open New Mail](Images/OpenNewMail.png) + +**On the tool bar on top, select Apps icon. Your uploaded app title appears among your installed apps** + +![OpenAppIcon](Images/OpenAppIcon.png) + +**Opening stage view from unfurling link. If you copy and paste a link from https://tabstageview.com/card into the compose message area the link will unfurl.** + +![Outlook Unfurling](Images/OutlookUnfurling.png) + +**Note:** Similarly, you can test your application in the Office 365 desktop app as well. + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + +## Further reading + +- [Tabs](https://learn.microsoft.com/microsoftteams/platform/tabs/what-are-tabs) +- [Stage view](https://learn.microsoft.com/microsoftteams/platform/tabs/tabs-link-unfurling#stage-view) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/aad.manifest.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/aad.manifest.json new file mode 100644 index 0000000000..9c252ab414 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/aad.manifest.json @@ -0,0 +1,100 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "displayName": "tab-stage-view-aad", + "signInAudience": "AzureADMyOrg", + "api": { + "requestedAccessTokenVersion": 2, + "oauth2PermissionScopes": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "delegatedPermissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ] + }, + "info": {}, + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "publicClient": {}, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "web": { + "implicitGrantSettings": {} + }, + "spa": {} +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/color.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/manifest.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/manifest.json new file mode 100644 index 0000000000..53a7d6538d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/manifest.json @@ -0,0 +1,90 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Tab SV_Nodejs", + "full": "Tab in stage view" + }, + "description": { + "short": "Microsoft Teams tab sample app showcasing stage view functionality.", + "full": "This sample app demonstrates the use of Teams tab in stage view using Node.js, featuring collaborative elements and interactive capabilities." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "staticTabs": [ + { + "entityId": "stageViewTask", + "scopes": [ + "personal" + ], + "context": [ + "personalTab", + "channelTab" + ], + "name": "Stage View", + "contentUrl": "https://${{BOT_DOMAIN}}/tab", + "websiteUrl": "https://${{BOT_DOMAIN}}/tab", + "searchUrl": "https://${{BOT_DOMAIN}}/tab" + } + ], + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "team", + "personal", + "groupchat" + ], + "isNotificationOnly": false + } + ], + "accentColor": "#60A18E", + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "commands": [ + { + "id": "searchQuery", + "context": [ "commandBox" ], + "description": "Test command to run query", + "title": "Search Command", + "type": "query", + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Your search query", + "inputType": "text" + } + ] + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "tabstageview.com/card", + "${{BOT_DOMAIN}}" + ] + } + } + ] + } + ], + "permissions": [ "identity", "messageTeamMembers" ], + "validDomains": [ + "${{BOT_DOMAIN}}", + "token.botframework.com" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/outline.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/color.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/manifest.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/manifest.json new file mode 100644 index 0000000000..a090a22813 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/manifest.json @@ -0,0 +1,79 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "<>", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Tab Stage View", + "full": "Tab in stage view" + }, + "description": { + "short": "View Tab in stage view", + "full": "This sample demos the tab in stage view" + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "staticTabs": [ + { + "entityId": "stageViewTask", + "scopes": [ + "personal" + ], + "context": [ + "personalTab", + "channelTab" + ], + "name": "Stage View", + "contentUrl": "https://<>/tab", + "websiteUrl": "https://<>/tab", + "searchUrl": "https://<>/tab" + } + ], + "accentColor": "#60A18E", + "composeExtensions": [ + { + "botId": "<>", + "commands": [ + { + "id": "searchQuery", + "context": [ "commandBox" ], + "description": "Test command to run query", + "title": "Search Command", + "type": "query", + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Your search query", + "inputType": "text" + } + ] + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "*.botframework.com", + "{{domain-name}}" + ] + } + } + ] + } + ], + "permissions": [ "identity", "messageTeamMembers" ], + "validDomains": [ + "<>", + "token.botframework.com" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/outline.png b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/appManifest_Hub/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/assets/sample.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/assets/sample.json new file mode 100644 index 0000000000..a35bf2210c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-tab-stage-view-nodejs", + "source": "officeDev", + "title": "Stage View", + "shortDescription": "This sample app demonstrates the use of Teams tab in stage view using Node.js, featuring collaborative elements and interactive capabilities.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-stage-view/nodejs", + "longDescription": [ + "The Stage View sample app illustrates the functionality of Microsoft Teams tabs in stage view with a Node.js implementation, highlighting features like multi-window support and collaborative interactions. Users can engage through adaptive cards and deep links, enhancing their experience within Teams." + ], + "creationDateTime": "2021-06-10", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab,bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/tab-stage-view/nodejs/Images/TabStageView.gif", + "alt": "Solution UX showing stage view" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/build.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/build.js new file mode 100644 index 0000000000..59a6ff881e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/build.js @@ -0,0 +1,14 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['server/index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js' +}) + .then((r) => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/dist/index.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/dist/index.js new file mode 100644 index 0000000000..0d0074979a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/dist/index.js @@ -0,0 +1,119635 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; +}; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// node_modules/depd/index.js +var require_depd = __commonJS({ + "node_modules/depd/index.js"(exports2, module2) { + var relative = require("path").relative; + module2.exports = depd; + var basePath = process.cwd(); + function containsNamespace(str, namespace) { + var vals = str.split(/[ ,]+/); + var ns = String(namespace).toLowerCase(); + for (var i = 0; i < vals.length; i++) { + var val = vals[i]; + if (val && (val === "*" || val.toLowerCase() === ns)) { + return true; + } + } + return false; + } + function convertDataDescriptorToAccessor(obj, prop, message) { + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); + var value = descriptor.value; + descriptor.get = function getter() { + return value; + }; + if (descriptor.writable) { + descriptor.set = function setter(val) { + return value = val; + }; + } + delete descriptor.value; + delete descriptor.writable; + Object.defineProperty(obj, prop, descriptor); + return descriptor; + } + function createArgumentsString(arity) { + var str = ""; + for (var i = 0; i < arity; i++) { + str += ", arg" + i; + } + return str.substr(2); + } + function createStackString(stack) { + var str = this.name + ": " + this.namespace; + if (this.message) { + str += " deprecated " + this.message; + } + for (var i = 0; i < stack.length; i++) { + str += "\n at " + stack[i].toString(); + } + return str; + } + function depd(namespace) { + if (!namespace) { + throw new TypeError("argument namespace is required"); + } + var stack = getStack(); + var site = callSiteLocation(stack[1]); + var file = site[0]; + function deprecate(message) { + log.call(deprecate, message); + } + deprecate._file = file; + deprecate._ignored = isignored(namespace); + deprecate._namespace = namespace; + deprecate._traced = istraced(namespace); + deprecate._warned = /* @__PURE__ */ Object.create(null); + deprecate.function = wrapfunction; + deprecate.property = wrapproperty; + return deprecate; + } + function eehaslisteners(emitter, type) { + var count = typeof emitter.listenerCount !== "function" ? emitter.listeners(type).length : emitter.listenerCount(type); + return count > 0; + } + function isignored(namespace) { + if (process.noDeprecation) { + return true; + } + var str = process.env.NO_DEPRECATION || ""; + return containsNamespace(str, namespace); + } + function istraced(namespace) { + if (process.traceDeprecation) { + return true; + } + var str = process.env.TRACE_DEPRECATION || ""; + return containsNamespace(str, namespace); + } + function log(message, site) { + var haslisteners = eehaslisteners(process, "deprecation"); + if (!haslisteners && this._ignored) { + return; + } + var caller; + var callFile; + var callSite; + var depSite; + var i = 0; + var seen = false; + var stack = getStack(); + var file = this._file; + if (site) { + depSite = site; + callSite = callSiteLocation(stack[1]); + callSite.name = depSite.name; + file = callSite[0]; + } else { + i = 2; + depSite = callSiteLocation(stack[i]); + callSite = depSite; + } + for (; i < stack.length; i++) { + caller = callSiteLocation(stack[i]); + callFile = caller[0]; + if (callFile === file) { + seen = true; + } else if (callFile === this._file) { + file = this._file; + } else if (seen) { + break; + } + } + var key = caller ? depSite.join(":") + "__" + caller.join(":") : void 0; + if (key !== void 0 && key in this._warned) { + return; + } + this._warned[key] = true; + var msg = message; + if (!msg) { + msg = callSite === depSite || !callSite.name ? defaultMessage(depSite) : defaultMessage(callSite); + } + if (haslisteners) { + var err = DeprecationError(this._namespace, msg, stack.slice(i)); + process.emit("deprecation", err); + return; + } + var format = process.stderr.isTTY ? formatColor : formatPlain; + var output = format.call(this, msg, caller, stack.slice(i)); + process.stderr.write(output + "\n", "utf8"); + } + function callSiteLocation(callSite) { + var file = callSite.getFileName() || ""; + var line = callSite.getLineNumber(); + var colm = callSite.getColumnNumber(); + if (callSite.isEval()) { + file = callSite.getEvalOrigin() + ", " + file; + } + var site = [file, line, colm]; + site.callSite = callSite; + site.name = callSite.getFunctionName(); + return site; + } + function defaultMessage(site) { + var callSite = site.callSite; + var funcName = site.name; + if (!funcName) { + funcName = ""; + } + var context = callSite.getThis(); + var typeName = context && callSite.getTypeName(); + if (typeName === "Object") { + typeName = void 0; + } + if (typeName === "Function") { + typeName = context.name || typeName; + } + return typeName && callSite.getMethodName() ? typeName + "." + funcName : funcName; + } + function formatPlain(msg, caller, stack) { + var timestamp = (/* @__PURE__ */ new Date()).toUTCString(); + var formatted = timestamp + " " + this._namespace + " deprecated " + msg; + if (this._traced) { + for (var i = 0; i < stack.length; i++) { + formatted += "\n at " + stack[i].toString(); + } + return formatted; + } + if (caller) { + formatted += " at " + formatLocation(caller); + } + return formatted; + } + function formatColor(msg, caller, stack) { + var formatted = "\x1B[36;1m" + this._namespace + "\x1B[22;39m \x1B[33;1mdeprecated\x1B[22;39m \x1B[0m" + msg + "\x1B[39m"; + if (this._traced) { + for (var i = 0; i < stack.length; i++) { + formatted += "\n \x1B[36mat " + stack[i].toString() + "\x1B[39m"; + } + return formatted; + } + if (caller) { + formatted += " \x1B[36m" + formatLocation(caller) + "\x1B[39m"; + } + return formatted; + } + function formatLocation(callSite) { + return relative(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2]; + } + function getStack() { + var limit = Error.stackTraceLimit; + var obj = {}; + var prep = Error.prepareStackTrace; + Error.prepareStackTrace = prepareObjectStackTrace; + Error.stackTraceLimit = Math.max(10, limit); + Error.captureStackTrace(obj); + var stack = obj.stack.slice(1); + Error.prepareStackTrace = prep; + Error.stackTraceLimit = limit; + return stack; + } + function prepareObjectStackTrace(obj, stack) { + return stack; + } + function wrapfunction(fn, message) { + if (typeof fn !== "function") { + throw new TypeError("argument fn must be a function"); + } + var args = createArgumentsString(fn.length); + var stack = getStack(); + var site = callSiteLocation(stack[1]); + site.name = fn.name; + var deprecatedfn = new Function( + "fn", + "log", + "deprecate", + "message", + "site", + '"use strict"\nreturn function (' + args + ") {log.call(deprecate, message, site)\nreturn fn.apply(this, arguments)\n}" + )(fn, log, this, message, site); + return deprecatedfn; + } + function wrapproperty(obj, prop, message) { + if (!obj || typeof obj !== "object" && typeof obj !== "function") { + throw new TypeError("argument obj must be object"); + } + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); + if (!descriptor) { + throw new TypeError("must call property on owner object"); + } + if (!descriptor.configurable) { + throw new TypeError("property must be configurable"); + } + var deprecate = this; + var stack = getStack(); + var site = callSiteLocation(stack[1]); + site.name = prop; + if ("value" in descriptor) { + descriptor = convertDataDescriptorToAccessor(obj, prop, message); + } + var get = descriptor.get; + var set = descriptor.set; + if (typeof get === "function") { + descriptor.get = function getter() { + log.call(deprecate, message, site); + return get.apply(this, arguments); + }; + } + if (typeof set === "function") { + descriptor.set = function setter() { + log.call(deprecate, message, site); + return set.apply(this, arguments); + }; + } + Object.defineProperty(obj, prop, descriptor); + } + function DeprecationError(namespace, message, stack) { + var error = new Error(); + var stackString; + Object.defineProperty(error, "constructor", { + value: DeprecationError + }); + Object.defineProperty(error, "message", { + configurable: true, + enumerable: false, + value: message, + writable: true + }); + Object.defineProperty(error, "name", { + enumerable: false, + configurable: true, + value: "DeprecationError", + writable: true + }); + Object.defineProperty(error, "namespace", { + configurable: true, + enumerable: false, + value: namespace, + writable: true + }); + Object.defineProperty(error, "stack", { + configurable: true, + enumerable: false, + get: function() { + if (stackString !== void 0) { + return stackString; + } + return stackString = createStackString.call(this, stack); + }, + set: function setter(val) { + stackString = val; + } + }); + return error; + } + } +}); + +// node_modules/bytes/index.js +var require_bytes = __commonJS({ + "node_modules/bytes/index.js"(exports2, module2) { + "use strict"; + module2.exports = bytes; + module2.exports.format = format; + module2.exports.parse = parse4; + var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; + var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; + var map = { + b: 1, + kb: 1 << 10, + mb: 1 << 20, + gb: 1 << 30, + tb: Math.pow(1024, 4), + pb: Math.pow(1024, 5) + }; + var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i; + function bytes(value, options) { + if (typeof value === "string") { + return parse4(value); + } + if (typeof value === "number") { + return format(value, options); + } + return null; + } + function format(value, options) { + if (!Number.isFinite(value)) { + return null; + } + var mag = Math.abs(value); + var thousandsSeparator = options && options.thousandsSeparator || ""; + var unitSeparator = options && options.unitSeparator || ""; + var decimalPlaces = options && options.decimalPlaces !== void 0 ? options.decimalPlaces : 2; + var fixedDecimals = Boolean(options && options.fixedDecimals); + var unit = options && options.unit || ""; + if (!unit || !map[unit.toLowerCase()]) { + if (mag >= map.pb) { + unit = "PB"; + } else if (mag >= map.tb) { + unit = "TB"; + } else if (mag >= map.gb) { + unit = "GB"; + } else if (mag >= map.mb) { + unit = "MB"; + } else if (mag >= map.kb) { + unit = "KB"; + } else { + unit = "B"; + } + } + var val = value / map[unit.toLowerCase()]; + var str = val.toFixed(decimalPlaces); + if (!fixedDecimals) { + str = str.replace(formatDecimalsRegExp, "$1"); + } + if (thousandsSeparator) { + str = str.split(".").map(function(s, i) { + return i === 0 ? s.replace(formatThousandsRegExp, thousandsSeparator) : s; + }).join("."); + } + return str + unitSeparator + unit; + } + function parse4(val) { + if (typeof val === "number" && !isNaN(val)) { + return val; + } + if (typeof val !== "string") { + return null; + } + var results = parseRegExp.exec(val); + var floatValue; + var unit = "b"; + if (!results) { + floatValue = parseInt(val, 10); + unit = "b"; + } else { + floatValue = parseFloat(results[1]); + unit = results[4].toLowerCase(); + } + if (isNaN(floatValue)) { + return null; + } + return Math.floor(map[unit] * floatValue); + } + } +}); + +// node_modules/content-type/index.js +var require_content_type = __commonJS({ + "node_modules/content-type/index.js"(exports2) { + "use strict"; + var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g; + var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/; + var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; + var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g; + var QUOTE_REGEXP = /([\\"])/g; + var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; + exports2.format = format; + exports2.parse = parse4; + function format(obj) { + if (!obj || typeof obj !== "object") { + throw new TypeError("argument obj is required"); + } + var parameters = obj.parameters; + var type = obj.type; + if (!type || !TYPE_REGEXP.test(type)) { + throw new TypeError("invalid type"); + } + var string = type; + if (parameters && typeof parameters === "object") { + var param; + var params = Object.keys(parameters).sort(); + for (var i = 0; i < params.length; i++) { + param = params[i]; + if (!TOKEN_REGEXP.test(param)) { + throw new TypeError("invalid parameter name"); + } + string += "; " + param + "=" + qstring(parameters[param]); + } + } + return string; + } + function parse4(string) { + if (!string) { + throw new TypeError("argument string is required"); + } + var header = typeof string === "object" ? getcontenttype(string) : string; + if (typeof header !== "string") { + throw new TypeError("argument string is required to be a string"); + } + var index = header.indexOf(";"); + var type = index !== -1 ? header.slice(0, index).trim() : header.trim(); + if (!TYPE_REGEXP.test(type)) { + throw new TypeError("invalid media type"); + } + var obj = new ContentType(type.toLowerCase()); + if (index !== -1) { + var key; + var match; + var value; + PARAM_REGEXP.lastIndex = index; + while (match = PARAM_REGEXP.exec(header)) { + if (match.index !== index) { + throw new TypeError("invalid parameter format"); + } + index += match[0].length; + key = match[1].toLowerCase(); + value = match[2]; + if (value.charCodeAt(0) === 34) { + value = value.slice(1, -1); + if (value.indexOf("\\") !== -1) { + value = value.replace(QESC_REGEXP, "$1"); + } + } + obj.parameters[key] = value; + } + if (index !== header.length) { + throw new TypeError("invalid parameter format"); + } + } + return obj; + } + function getcontenttype(obj) { + var header; + if (typeof obj.getHeader === "function") { + header = obj.getHeader("content-type"); + } else if (typeof obj.headers === "object") { + header = obj.headers && obj.headers["content-type"]; + } + if (typeof header !== "string") { + throw new TypeError("content-type header is missing from object"); + } + return header; + } + function qstring(val) { + var str = String(val); + if (TOKEN_REGEXP.test(str)) { + return str; + } + if (str.length > 0 && !TEXT_REGEXP.test(str)) { + throw new TypeError("invalid parameter value"); + } + return '"' + str.replace(QUOTE_REGEXP, "\\$1") + '"'; + } + function ContentType(type) { + this.parameters = /* @__PURE__ */ Object.create(null); + this.type = type; + } + } +}); + +// node_modules/setprototypeof/index.js +var require_setprototypeof = __commonJS({ + "node_modules/setprototypeof/index.js"(exports2, module2) { + "use strict"; + module2.exports = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties); + function setProtoOf(obj, proto) { + obj.__proto__ = proto; + return obj; + } + function mixinProperties(obj, proto) { + for (var prop in proto) { + if (!Object.prototype.hasOwnProperty.call(obj, prop)) { + obj[prop] = proto[prop]; + } + } + return obj; + } + } +}); + +// node_modules/statuses/codes.json +var require_codes = __commonJS({ + "node_modules/statuses/codes.json"(exports2, module2) { + module2.exports = { + "100": "Continue", + "101": "Switching Protocols", + "102": "Processing", + "103": "Early Hints", + "200": "OK", + "201": "Created", + "202": "Accepted", + "203": "Non-Authoritative Information", + "204": "No Content", + "205": "Reset Content", + "206": "Partial Content", + "207": "Multi-Status", + "208": "Already Reported", + "226": "IM Used", + "300": "Multiple Choices", + "301": "Moved Permanently", + "302": "Found", + "303": "See Other", + "304": "Not Modified", + "305": "Use Proxy", + "307": "Temporary Redirect", + "308": "Permanent Redirect", + "400": "Bad Request", + "401": "Unauthorized", + "402": "Payment Required", + "403": "Forbidden", + "404": "Not Found", + "405": "Method Not Allowed", + "406": "Not Acceptable", + "407": "Proxy Authentication Required", + "408": "Request Timeout", + "409": "Conflict", + "410": "Gone", + "411": "Length Required", + "412": "Precondition Failed", + "413": "Payload Too Large", + "414": "URI Too Long", + "415": "Unsupported Media Type", + "416": "Range Not Satisfiable", + "417": "Expectation Failed", + "418": "I'm a Teapot", + "421": "Misdirected Request", + "422": "Unprocessable Entity", + "423": "Locked", + "424": "Failed Dependency", + "425": "Too Early", + "426": "Upgrade Required", + "428": "Precondition Required", + "429": "Too Many Requests", + "431": "Request Header Fields Too Large", + "451": "Unavailable For Legal Reasons", + "500": "Internal Server Error", + "501": "Not Implemented", + "502": "Bad Gateway", + "503": "Service Unavailable", + "504": "Gateway Timeout", + "505": "HTTP Version Not Supported", + "506": "Variant Also Negotiates", + "507": "Insufficient Storage", + "508": "Loop Detected", + "509": "Bandwidth Limit Exceeded", + "510": "Not Extended", + "511": "Network Authentication Required" + }; + } +}); + +// node_modules/statuses/index.js +var require_statuses = __commonJS({ + "node_modules/statuses/index.js"(exports2, module2) { + "use strict"; + var codes = require_codes(); + module2.exports = status; + status.message = codes; + status.code = createMessageToStatusCodeMap(codes); + status.codes = createStatusCodeList(codes); + status.redirect = { + 300: true, + 301: true, + 302: true, + 303: true, + 305: true, + 307: true, + 308: true + }; + status.empty = { + 204: true, + 205: true, + 304: true + }; + status.retry = { + 502: true, + 503: true, + 504: true + }; + function createMessageToStatusCodeMap(codes2) { + var map = {}; + Object.keys(codes2).forEach(function forEachCode(code) { + var message = codes2[code]; + var status2 = Number(code); + map[message.toLowerCase()] = status2; + }); + return map; + } + function createStatusCodeList(codes2) { + return Object.keys(codes2).map(function mapCode(code) { + return Number(code); + }); + } + function getStatusCode(message) { + var msg = message.toLowerCase(); + if (!Object.prototype.hasOwnProperty.call(status.code, msg)) { + throw new Error('invalid status message: "' + message + '"'); + } + return status.code[msg]; + } + function getStatusMessage(code) { + if (!Object.prototype.hasOwnProperty.call(status.message, code)) { + throw new Error("invalid status code: " + code); + } + return status.message[code]; + } + function status(code) { + if (typeof code === "number") { + return getStatusMessage(code); + } + if (typeof code !== "string") { + throw new TypeError("code must be a number or string"); + } + var n = parseInt(code, 10); + if (!isNaN(n)) { + return getStatusMessage(n); + } + return getStatusCode(code); + } + } +}); + +// node_modules/inherits/inherits_browser.js +var require_inherits_browser = __commonJS({ + "node_modules/inherits/inherits_browser.js"(exports2, module2) { + if (typeof Object.create === "function") { + module2.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + } + }; + } else { + module2.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + var TempCtor = function() { + }; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + } + }; + } + } +}); + +// node_modules/inherits/inherits.js +var require_inherits = __commonJS({ + "node_modules/inherits/inherits.js"(exports2, module2) { + try { + util = require("util"); + if (typeof util.inherits !== "function") throw ""; + module2.exports = util.inherits; + } catch (e) { + module2.exports = require_inherits_browser(); + } + var util; + } +}); + +// node_modules/toidentifier/index.js +var require_toidentifier = __commonJS({ + "node_modules/toidentifier/index.js"(exports2, module2) { + "use strict"; + module2.exports = toIdentifier; + function toIdentifier(str) { + return str.split(" ").map(function(token) { + return token.slice(0, 1).toUpperCase() + token.slice(1); + }).join("").replace(/[^ _0-9a-z]/gi, ""); + } + } +}); + +// node_modules/http-errors/index.js +var require_http_errors = __commonJS({ + "node_modules/http-errors/index.js"(exports2, module2) { + "use strict"; + var deprecate = require_depd()("http-errors"); + var setPrototypeOf = require_setprototypeof(); + var statuses = require_statuses(); + var inherits = require_inherits(); + var toIdentifier = require_toidentifier(); + module2.exports = createError; + module2.exports.HttpError = createHttpErrorConstructor(); + module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError); + populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError); + function codeClass(status) { + return Number(String(status).charAt(0) + "00"); + } + function createError() { + var err; + var msg; + var status = 500; + var props = {}; + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + var type = typeof arg; + if (type === "object" && arg instanceof Error) { + err = arg; + status = err.status || err.statusCode || status; + } else if (type === "number" && i === 0) { + status = arg; + } else if (type === "string") { + msg = arg; + } else if (type === "object") { + props = arg; + } else { + throw new TypeError("argument #" + (i + 1) + " unsupported type " + type); + } + } + if (typeof status === "number" && (status < 400 || status >= 600)) { + deprecate("non-error status code; use only 4xx or 5xx status codes"); + } + if (typeof status !== "number" || !statuses.message[status] && (status < 400 || status >= 600)) { + status = 500; + } + var HttpError = createError[status] || createError[codeClass(status)]; + if (!err) { + err = HttpError ? new HttpError(msg) : new Error(msg || statuses.message[status]); + Error.captureStackTrace(err, createError); + } + if (!HttpError || !(err instanceof HttpError) || err.status !== status) { + err.expose = status < 500; + err.status = err.statusCode = status; + } + for (var key in props) { + if (key !== "status" && key !== "statusCode") { + err[key] = props[key]; + } + } + return err; + } + function createHttpErrorConstructor() { + function HttpError() { + throw new TypeError("cannot construct abstract class"); + } + inherits(HttpError, Error); + return HttpError; + } + function createClientErrorConstructor(HttpError, name, code) { + var className = toClassName(name); + function ClientError(message) { + var msg = message != null ? message : statuses.message[code]; + var err = new Error(msg); + Error.captureStackTrace(err, ClientError); + setPrototypeOf(err, ClientError.prototype); + Object.defineProperty(err, "message", { + enumerable: true, + configurable: true, + value: msg, + writable: true + }); + Object.defineProperty(err, "name", { + enumerable: false, + configurable: true, + value: className, + writable: true + }); + return err; + } + inherits(ClientError, HttpError); + nameFunc(ClientError, className); + ClientError.prototype.status = code; + ClientError.prototype.statusCode = code; + ClientError.prototype.expose = true; + return ClientError; + } + function createIsHttpErrorFunction(HttpError) { + return function isHttpError(val) { + if (!val || typeof val !== "object") { + return false; + } + if (val instanceof HttpError) { + return true; + } + return val instanceof Error && typeof val.expose === "boolean" && typeof val.statusCode === "number" && val.status === val.statusCode; + }; + } + function createServerErrorConstructor(HttpError, name, code) { + var className = toClassName(name); + function ServerError(message) { + var msg = message != null ? message : statuses.message[code]; + var err = new Error(msg); + Error.captureStackTrace(err, ServerError); + setPrototypeOf(err, ServerError.prototype); + Object.defineProperty(err, "message", { + enumerable: true, + configurable: true, + value: msg, + writable: true + }); + Object.defineProperty(err, "name", { + enumerable: false, + configurable: true, + value: className, + writable: true + }); + return err; + } + inherits(ServerError, HttpError); + nameFunc(ServerError, className); + ServerError.prototype.status = code; + ServerError.prototype.statusCode = code; + ServerError.prototype.expose = false; + return ServerError; + } + function nameFunc(func, name) { + var desc = Object.getOwnPropertyDescriptor(func, "name"); + if (desc && desc.configurable) { + desc.value = name; + Object.defineProperty(func, "name", desc); + } + } + function populateConstructorExports(exports3, codes, HttpError) { + codes.forEach(function forEachCode(code) { + var CodeError; + var name = toIdentifier(statuses.message[code]); + switch (codeClass(code)) { + case 400: + CodeError = createClientErrorConstructor(HttpError, name, code); + break; + case 500: + CodeError = createServerErrorConstructor(HttpError, name, code); + break; + } + if (CodeError) { + exports3[code] = CodeError; + exports3[name] = CodeError; + } + }); + } + function toClassName(name) { + return name.slice(-5) === "Error" ? name : name + "Error"; + } + } +}); + +// node_modules/body-parser/node_modules/ms/index.js +var require_ms = __commonJS({ + "node_modules/body-parser/node_modules/ms/index.js"(exports2, module2) { + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var y = d * 365.25; + module2.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse4(val); + } else if (type === "number" && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); + }; + function parse4(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + "d"; + } + if (ms >= h) { + return Math.round(ms / h) + "h"; + } + if (ms >= m) { + return Math.round(ms / m) + "m"; + } + if (ms >= s) { + return Math.round(ms / s) + "s"; + } + return ms + "ms"; + } + function fmtLong(ms) { + return plural(ms, d, "day") || plural(ms, h, "hour") || plural(ms, m, "minute") || plural(ms, s, "second") || ms + " ms"; + } + function plural(ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + " " + name; + } + return Math.ceil(ms / n) + " " + name + "s"; + } + } +}); + +// node_modules/body-parser/node_modules/debug/src/debug.js +var require_debug = __commonJS({ + "node_modules/body-parser/node_modules/debug/src/debug.js"(exports2, module2) { + exports2 = module2.exports = createDebug.debug = createDebug["default"] = createDebug; + exports2.coerce = coerce; + exports2.disable = disable; + exports2.enable = enable; + exports2.enabled = enabled; + exports2.humanize = require_ms(); + exports2.names = []; + exports2.skips = []; + exports2.formatters = {}; + var prevTime; + function selectColor(namespace) { + var hash = 0, i; + for (i in namespace) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return exports2.colors[Math.abs(hash) % exports2.colors.length]; + } + function createDebug(namespace) { + function debug() { + if (!debug.enabled) return; + var self2 = debug; + var curr = +/* @__PURE__ */ new Date(); + var ms = curr - (prevTime || curr); + self2.diff = ms; + self2.prev = prevTime; + self2.curr = curr; + prevTime = curr; + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + args[0] = exports2.coerce(args[0]); + if ("string" !== typeof args[0]) { + args.unshift("%O"); + } + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + if (match === "%%") return match; + index++; + var formatter = exports2.formatters[format]; + if ("function" === typeof formatter) { + var val = args[index]; + match = formatter.call(self2, val); + args.splice(index, 1); + index--; + } + return match; + }); + exports2.formatArgs.call(self2, args); + var logFn = debug.log || exports2.log || console.log.bind(console); + logFn.apply(self2, args); + } + debug.namespace = namespace; + debug.enabled = exports2.enabled(namespace); + debug.useColors = exports2.useColors(); + debug.color = selectColor(namespace); + if ("function" === typeof exports2.init) { + exports2.init(debug); + } + return debug; + } + function enable(namespaces) { + exports2.save(namespaces); + exports2.names = []; + exports2.skips = []; + var split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/); + var len = split.length; + for (var i = 0; i < len; i++) { + if (!split[i]) continue; + namespaces = split[i].replace(/\*/g, ".*?"); + if (namespaces[0] === "-") { + exports2.skips.push(new RegExp("^" + namespaces.substr(1) + "$")); + } else { + exports2.names.push(new RegExp("^" + namespaces + "$")); + } + } + } + function disable() { + exports2.enable(""); + } + function enabled(name) { + var i, len; + for (i = 0, len = exports2.skips.length; i < len; i++) { + if (exports2.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports2.names.length; i < len; i++) { + if (exports2.names[i].test(name)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; + } + } +}); + +// node_modules/body-parser/node_modules/debug/src/browser.js +var require_browser = __commonJS({ + "node_modules/body-parser/node_modules/debug/src/browser.js"(exports2, module2) { + exports2 = module2.exports = require_debug(); + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.storage = "undefined" != typeof chrome && "undefined" != typeof chrome.storage ? chrome.storage.local : localstorage(); + exports2.colors = [ + "lightseagreen", + "forestgreen", + "goldenrod", + "dodgerblue", + "darkorchid", + "crimson" + ]; + function useColors() { + if (typeof window !== "undefined" && window.process && window.process.type === "renderer") { + return true; + } + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + exports2.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return "[UnexpectedJSONParseError]: " + err.message; + } + }; + function formatArgs(args) { + var useColors2 = this.useColors; + args[0] = (useColors2 ? "%c" : "") + this.namespace + (useColors2 ? " %c" : " ") + args[0] + (useColors2 ? "%c " : " ") + "+" + exports2.humanize(this.diff); + if (!useColors2) return; + var c = "color: " + this.color; + args.splice(1, 0, c, "color: inherit"); + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ("%%" === match) return; + index++; + if ("%c" === match) { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + function log() { + return "object" === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); + } + function save(namespaces) { + try { + if (null == namespaces) { + exports2.storage.removeItem("debug"); + } else { + exports2.storage.debug = namespaces; + } + } catch (e) { + } + } + function load() { + var r; + try { + r = exports2.storage.debug; + } catch (e) { + } + if (!r && typeof process !== "undefined" && "env" in process) { + r = process.env.DEBUG; + } + return r; + } + exports2.enable(load()); + function localstorage() { + try { + return window.localStorage; + } catch (e) { + } + } + } +}); + +// node_modules/body-parser/node_modules/debug/src/node.js +var require_node = __commonJS({ + "node_modules/body-parser/node_modules/debug/src/node.js"(exports2, module2) { + var tty = require("tty"); + var util = require("util"); + exports2 = module2.exports = require_debug(); + exports2.init = init; + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.colors = [6, 2, 3, 4, 5, 1]; + exports2.inspectOpts = Object.keys(process.env).filter(function(key) { + return /^debug_/i.test(key); + }).reduce(function(obj, key) { + var prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, function(_, k) { + return k.toUpperCase(); + }); + var val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) val = true; + else if (/^(no|off|false|disabled)$/i.test(val)) val = false; + else if (val === "null") val = null; + else val = Number(val); + obj[prop] = val; + return obj; + }, {}); + var fd = parseInt(process.env.DEBUG_FD, 10) || 2; + if (1 !== fd && 2 !== fd) { + util.deprecate(function() { + }, "except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)")(); + } + var stream = 1 === fd ? process.stdout : 2 === fd ? process.stderr : createWritableStdioStream(fd); + function useColors() { + return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty.isatty(fd); + } + exports2.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts).split("\n").map(function(str) { + return str.trim(); + }).join(" "); + }; + exports2.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); + }; + function formatArgs(args) { + var name = this.namespace; + var useColors2 = this.useColors; + if (useColors2) { + var c = this.color; + var prefix = " \x1B[3" + c + ";1m" + name + " \x1B[0m"; + args[0] = prefix + args[0].split("\n").join("\n" + prefix); + args.push("\x1B[3" + c + "m+" + exports2.humanize(this.diff) + "\x1B[0m"); + } else { + args[0] = (/* @__PURE__ */ new Date()).toUTCString() + " " + name + " " + args[0]; + } + } + function log() { + return stream.write(util.format.apply(util, arguments) + "\n"); + } + function save(namespaces) { + if (null == namespaces) { + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; + } + } + function load() { + return process.env.DEBUG; + } + function createWritableStdioStream(fd2) { + var stream2; + var tty_wrap = process.binding("tty_wrap"); + switch (tty_wrap.guessHandleType(fd2)) { + case "TTY": + stream2 = new tty.WriteStream(fd2); + stream2._type = "tty"; + if (stream2._handle && stream2._handle.unref) { + stream2._handle.unref(); + } + break; + case "FILE": + var fs6 = require("fs"); + stream2 = new fs6.SyncWriteStream(fd2, { autoClose: false }); + stream2._type = "fs"; + break; + case "PIPE": + case "TCP": + var net = require("net"); + stream2 = new net.Socket({ + fd: fd2, + readable: false, + writable: true + }); + stream2.readable = false; + stream2.read = null; + stream2._type = "pipe"; + if (stream2._handle && stream2._handle.unref) { + stream2._handle.unref(); + } + break; + default: + throw new Error("Implement me. Unknown stream file type!"); + } + stream2.fd = fd2; + stream2._isStdio = true; + return stream2; + } + function init(debug) { + debug.inspectOpts = {}; + var keys = Object.keys(exports2.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports2.inspectOpts[keys[i]]; + } + } + exports2.enable(load()); + } +}); + +// node_modules/body-parser/node_modules/debug/src/index.js +var require_src = __commonJS({ + "node_modules/body-parser/node_modules/debug/src/index.js"(exports2, module2) { + if (typeof process !== "undefined" && process.type === "renderer") { + module2.exports = require_browser(); + } else { + module2.exports = require_node(); + } + } +}); + +// node_modules/destroy/index.js +var require_destroy = __commonJS({ + "node_modules/destroy/index.js"(exports2, module2) { + "use strict"; + var EventEmitter = require("events").EventEmitter; + var ReadStream = require("fs").ReadStream; + var Stream = require("stream"); + var Zlib = require("zlib"); + module2.exports = destroy; + function destroy(stream, suppress) { + if (isFsReadStream(stream)) { + destroyReadStream(stream); + } else if (isZlibStream(stream)) { + destroyZlibStream(stream); + } else if (hasDestroy(stream)) { + stream.destroy(); + } + if (isEventEmitter(stream) && suppress) { + stream.removeAllListeners("error"); + stream.addListener("error", noop); + } + return stream; + } + function destroyReadStream(stream) { + stream.destroy(); + if (typeof stream.close === "function") { + stream.on("open", onOpenClose); + } + } + function closeZlibStream(stream) { + if (stream._hadError === true) { + var prop = stream._binding === null ? "_binding" : "_handle"; + stream[prop] = { + close: function() { + this[prop] = null; + } + }; + } + stream.close(); + } + function destroyZlibStream(stream) { + if (typeof stream.destroy === "function") { + if (stream._binding) { + stream.destroy(); + if (stream._processing) { + stream._needDrain = true; + stream.once("drain", onDrainClearBinding); + } else { + stream._binding.clear(); + } + } else if (stream._destroy && stream._destroy !== Stream.Transform.prototype._destroy) { + stream.destroy(); + } else if (stream._destroy && typeof stream.close === "function") { + stream.destroyed = true; + stream.close(); + } else { + stream.destroy(); + } + } else if (typeof stream.close === "function") { + closeZlibStream(stream); + } + } + function hasDestroy(stream) { + return stream instanceof Stream && typeof stream.destroy === "function"; + } + function isEventEmitter(val) { + return val instanceof EventEmitter; + } + function isFsReadStream(stream) { + return stream instanceof ReadStream; + } + function isZlibStream(stream) { + return stream instanceof Zlib.Gzip || stream instanceof Zlib.Gunzip || stream instanceof Zlib.Deflate || stream instanceof Zlib.DeflateRaw || stream instanceof Zlib.Inflate || stream instanceof Zlib.InflateRaw || stream instanceof Zlib.Unzip; + } + function noop() { + } + function onDrainClearBinding() { + this._binding.clear(); + } + function onOpenClose() { + if (typeof this.fd === "number") { + this.close(); + } + } + } +}); + +// node_modules/safer-buffer/safer.js +var require_safer = __commonJS({ + "node_modules/safer-buffer/safer.js"(exports2, module2) { + "use strict"; + var buffer = require("buffer"); + var Buffer3 = buffer.Buffer; + var safer = {}; + var key; + for (key in buffer) { + if (!buffer.hasOwnProperty(key)) continue; + if (key === "SlowBuffer" || key === "Buffer") continue; + safer[key] = buffer[key]; + } + var Safer = safer.Buffer = {}; + for (key in Buffer3) { + if (!Buffer3.hasOwnProperty(key)) continue; + if (key === "allocUnsafe" || key === "allocUnsafeSlow") continue; + Safer[key] = Buffer3[key]; + } + safer.Buffer.prototype = Buffer3.prototype; + if (!Safer.from || Safer.from === Uint8Array.from) { + Safer.from = function(value, encodingOrOffset, length) { + if (typeof value === "number") { + throw new TypeError('The "value" argument must not be of type number. Received type ' + typeof value); + } + if (value && typeof value.length === "undefined") { + throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof value); + } + return Buffer3(value, encodingOrOffset, length); + }; + } + if (!Safer.alloc) { + Safer.alloc = function(size, fill, encoding) { + if (typeof size !== "number") { + throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size); + } + if (size < 0 || size >= 2 * (1 << 30)) { + throw new RangeError('The value "' + size + '" is invalid for option "size"'); + } + var buf = Buffer3(size); + if (!fill || fill.length === 0) { + buf.fill(0); + } else if (typeof encoding === "string") { + buf.fill(fill, encoding); + } else { + buf.fill(fill); + } + return buf; + }; + } + if (!safer.kStringMaxLength) { + try { + safer.kStringMaxLength = process.binding("buffer").kStringMaxLength; + } catch (e) { + } + } + if (!safer.constants) { + safer.constants = { + MAX_LENGTH: safer.kMaxLength + }; + if (safer.kStringMaxLength) { + safer.constants.MAX_STRING_LENGTH = safer.kStringMaxLength; + } + } + module2.exports = safer; + } +}); + +// node_modules/iconv-lite/lib/bom-handling.js +var require_bom_handling = __commonJS({ + "node_modules/iconv-lite/lib/bom-handling.js"(exports2) { + "use strict"; + var BOMChar = "\uFEFF"; + exports2.PrependBOM = PrependBOMWrapper; + function PrependBOMWrapper(encoder, options) { + this.encoder = encoder; + this.addBOM = true; + } + PrependBOMWrapper.prototype.write = function(str) { + if (this.addBOM) { + str = BOMChar + str; + this.addBOM = false; + } + return this.encoder.write(str); + }; + PrependBOMWrapper.prototype.end = function() { + return this.encoder.end(); + }; + exports2.StripBOM = StripBOMWrapper; + function StripBOMWrapper(decoder, options) { + this.decoder = decoder; + this.pass = false; + this.options = options || {}; + } + StripBOMWrapper.prototype.write = function(buf) { + var res = this.decoder.write(buf); + if (this.pass || !res) + return res; + if (res[0] === BOMChar) { + res = res.slice(1); + if (typeof this.options.stripBOM === "function") + this.options.stripBOM(); + } + this.pass = true; + return res; + }; + StripBOMWrapper.prototype.end = function() { + return this.decoder.end(); + }; + } +}); + +// node_modules/iconv-lite/encodings/internal.js +var require_internal = __commonJS({ + "node_modules/iconv-lite/encodings/internal.js"(exports2, module2) { + "use strict"; + var Buffer3 = require_safer().Buffer; + module2.exports = { + // Encodings + utf8: { type: "_internal", bomAware: true }, + cesu8: { type: "_internal", bomAware: true }, + unicode11utf8: "utf8", + ucs2: { type: "_internal", bomAware: true }, + utf16le: "ucs2", + binary: { type: "_internal" }, + base64: { type: "_internal" }, + hex: { type: "_internal" }, + // Codec. + _internal: InternalCodec + }; + function InternalCodec(codecOptions, iconv) { + this.enc = codecOptions.encodingName; + this.bomAware = codecOptions.bomAware; + if (this.enc === "base64") + this.encoder = InternalEncoderBase64; + else if (this.enc === "cesu8") { + this.enc = "utf8"; + this.encoder = InternalEncoderCesu8; + if (Buffer3.from("eda0bdedb2a9", "hex").toString() !== "\u{1F4A9}") { + this.decoder = InternalDecoderCesu8; + this.defaultCharUnicode = iconv.defaultCharUnicode; + } + } + } + InternalCodec.prototype.encoder = InternalEncoder; + InternalCodec.prototype.decoder = InternalDecoder; + var StringDecoder = require("string_decoder").StringDecoder; + if (!StringDecoder.prototype.end) + StringDecoder.prototype.end = function() { + }; + function InternalDecoder(options, codec) { + StringDecoder.call(this, codec.enc); + } + InternalDecoder.prototype = StringDecoder.prototype; + function InternalEncoder(options, codec) { + this.enc = codec.enc; + } + InternalEncoder.prototype.write = function(str) { + return Buffer3.from(str, this.enc); + }; + InternalEncoder.prototype.end = function() { + }; + function InternalEncoderBase64(options, codec) { + this.prevStr = ""; + } + InternalEncoderBase64.prototype.write = function(str) { + str = this.prevStr + str; + var completeQuads = str.length - str.length % 4; + this.prevStr = str.slice(completeQuads); + str = str.slice(0, completeQuads); + return Buffer3.from(str, "base64"); + }; + InternalEncoderBase64.prototype.end = function() { + return Buffer3.from(this.prevStr, "base64"); + }; + function InternalEncoderCesu8(options, codec) { + } + InternalEncoderCesu8.prototype.write = function(str) { + var buf = Buffer3.alloc(str.length * 3), bufIdx = 0; + for (var i = 0; i < str.length; i++) { + var charCode = str.charCodeAt(i); + if (charCode < 128) + buf[bufIdx++] = charCode; + else if (charCode < 2048) { + buf[bufIdx++] = 192 + (charCode >>> 6); + buf[bufIdx++] = 128 + (charCode & 63); + } else { + buf[bufIdx++] = 224 + (charCode >>> 12); + buf[bufIdx++] = 128 + (charCode >>> 6 & 63); + buf[bufIdx++] = 128 + (charCode & 63); + } + } + return buf.slice(0, bufIdx); + }; + InternalEncoderCesu8.prototype.end = function() { + }; + function InternalDecoderCesu8(options, codec) { + this.acc = 0; + this.contBytes = 0; + this.accBytes = 0; + this.defaultCharUnicode = codec.defaultCharUnicode; + } + InternalDecoderCesu8.prototype.write = function(buf) { + var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, res = ""; + for (var i = 0; i < buf.length; i++) { + var curByte = buf[i]; + if ((curByte & 192) !== 128) { + if (contBytes > 0) { + res += this.defaultCharUnicode; + contBytes = 0; + } + if (curByte < 128) { + res += String.fromCharCode(curByte); + } else if (curByte < 224) { + acc = curByte & 31; + contBytes = 1; + accBytes = 1; + } else if (curByte < 240) { + acc = curByte & 15; + contBytes = 2; + accBytes = 1; + } else { + res += this.defaultCharUnicode; + } + } else { + if (contBytes > 0) { + acc = acc << 6 | curByte & 63; + contBytes--; + accBytes++; + if (contBytes === 0) { + if (accBytes === 2 && acc < 128 && acc > 0) + res += this.defaultCharUnicode; + else if (accBytes === 3 && acc < 2048) + res += this.defaultCharUnicode; + else + res += String.fromCharCode(acc); + } + } else { + res += this.defaultCharUnicode; + } + } + } + this.acc = acc; + this.contBytes = contBytes; + this.accBytes = accBytes; + return res; + }; + InternalDecoderCesu8.prototype.end = function() { + var res = 0; + if (this.contBytes > 0) + res += this.defaultCharUnicode; + return res; + }; + } +}); + +// node_modules/iconv-lite/encodings/utf16.js +var require_utf16 = __commonJS({ + "node_modules/iconv-lite/encodings/utf16.js"(exports2) { + "use strict"; + var Buffer3 = require_safer().Buffer; + exports2.utf16be = Utf16BECodec; + function Utf16BECodec() { + } + Utf16BECodec.prototype.encoder = Utf16BEEncoder; + Utf16BECodec.prototype.decoder = Utf16BEDecoder; + Utf16BECodec.prototype.bomAware = true; + function Utf16BEEncoder() { + } + Utf16BEEncoder.prototype.write = function(str) { + var buf = Buffer3.from(str, "ucs2"); + for (var i = 0; i < buf.length; i += 2) { + var tmp = buf[i]; + buf[i] = buf[i + 1]; + buf[i + 1] = tmp; + } + return buf; + }; + Utf16BEEncoder.prototype.end = function() { + }; + function Utf16BEDecoder() { + this.overflowByte = -1; + } + Utf16BEDecoder.prototype.write = function(buf) { + if (buf.length == 0) + return ""; + var buf2 = Buffer3.alloc(buf.length + 1), i = 0, j = 0; + if (this.overflowByte !== -1) { + buf2[0] = buf[0]; + buf2[1] = this.overflowByte; + i = 1; + j = 2; + } + for (; i < buf.length - 1; i += 2, j += 2) { + buf2[j] = buf[i + 1]; + buf2[j + 1] = buf[i]; + } + this.overflowByte = i == buf.length - 1 ? buf[buf.length - 1] : -1; + return buf2.slice(0, j).toString("ucs2"); + }; + Utf16BEDecoder.prototype.end = function() { + }; + exports2.utf16 = Utf16Codec; + function Utf16Codec(codecOptions, iconv) { + this.iconv = iconv; + } + Utf16Codec.prototype.encoder = Utf16Encoder; + Utf16Codec.prototype.decoder = Utf16Decoder; + function Utf16Encoder(options, codec) { + options = options || {}; + if (options.addBOM === void 0) + options.addBOM = true; + this.encoder = codec.iconv.getEncoder("utf-16le", options); + } + Utf16Encoder.prototype.write = function(str) { + return this.encoder.write(str); + }; + Utf16Encoder.prototype.end = function() { + return this.encoder.end(); + }; + function Utf16Decoder(options, codec) { + this.decoder = null; + this.initialBytes = []; + this.initialBytesLen = 0; + this.options = options || {}; + this.iconv = codec.iconv; + } + Utf16Decoder.prototype.write = function(buf) { + if (!this.decoder) { + this.initialBytes.push(buf); + this.initialBytesLen += buf.length; + if (this.initialBytesLen < 16) + return ""; + var buf = Buffer3.concat(this.initialBytes), encoding = detectEncoding(buf, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); + this.initialBytes.length = this.initialBytesLen = 0; + } + return this.decoder.write(buf); + }; + Utf16Decoder.prototype.end = function() { + if (!this.decoder) { + var buf = Buffer3.concat(this.initialBytes), encoding = detectEncoding(buf, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); + var res = this.decoder.write(buf), trail = this.decoder.end(); + return trail ? res + trail : res; + } + return this.decoder.end(); + }; + function detectEncoding(buf, defaultEncoding) { + var enc = defaultEncoding || "utf-16le"; + if (buf.length >= 2) { + if (buf[0] == 254 && buf[1] == 255) + enc = "utf-16be"; + else if (buf[0] == 255 && buf[1] == 254) + enc = "utf-16le"; + else { + var asciiCharsLE = 0, asciiCharsBE = 0, _len = Math.min(buf.length - buf.length % 2, 64); + for (var i = 0; i < _len; i += 2) { + if (buf[i] === 0 && buf[i + 1] !== 0) asciiCharsBE++; + if (buf[i] !== 0 && buf[i + 1] === 0) asciiCharsLE++; + } + if (asciiCharsBE > asciiCharsLE) + enc = "utf-16be"; + else if (asciiCharsBE < asciiCharsLE) + enc = "utf-16le"; + } + } + return enc; + } + } +}); + +// node_modules/iconv-lite/encodings/utf7.js +var require_utf7 = __commonJS({ + "node_modules/iconv-lite/encodings/utf7.js"(exports2) { + "use strict"; + var Buffer3 = require_safer().Buffer; + exports2.utf7 = Utf7Codec; + exports2.unicode11utf7 = "utf7"; + function Utf7Codec(codecOptions, iconv) { + this.iconv = iconv; + } + Utf7Codec.prototype.encoder = Utf7Encoder; + Utf7Codec.prototype.decoder = Utf7Decoder; + Utf7Codec.prototype.bomAware = true; + var nonDirectChars = /[^A-Za-z0-9'\(\),-\.\/:\? \n\r\t]+/g; + function Utf7Encoder(options, codec) { + this.iconv = codec.iconv; + } + Utf7Encoder.prototype.write = function(str) { + return Buffer3.from(str.replace(nonDirectChars, function(chunk) { + return "+" + (chunk === "+" ? "" : this.iconv.encode(chunk, "utf16-be").toString("base64").replace(/=+$/, "")) + "-"; + }.bind(this))); + }; + Utf7Encoder.prototype.end = function() { + }; + function Utf7Decoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = ""; + } + var base64Regex = /[A-Za-z0-9\/+]/; + var base64Chars = []; + for (i = 0; i < 256; i++) + base64Chars[i] = base64Regex.test(String.fromCharCode(i)); + var i; + var plusChar = "+".charCodeAt(0); + var minusChar = "-".charCodeAt(0); + var andChar = "&".charCodeAt(0); + Utf7Decoder.prototype.write = function(buf) { + var res = "", lastI = 0, inBase64 = this.inBase64, base64Accum = this.base64Accum; + for (var i2 = 0; i2 < buf.length; i2++) { + if (!inBase64) { + if (buf[i2] == plusChar) { + res += this.iconv.decode(buf.slice(lastI, i2), "ascii"); + lastI = i2 + 1; + inBase64 = true; + } + } else { + if (!base64Chars[buf[i2]]) { + if (i2 == lastI && buf[i2] == minusChar) { + res += "+"; + } else { + var b64str = base64Accum + buf.slice(lastI, i2).toString(); + res += this.iconv.decode(Buffer3.from(b64str, "base64"), "utf16-be"); + } + if (buf[i2] != minusChar) + i2--; + lastI = i2 + 1; + inBase64 = false; + base64Accum = ""; + } + } + } + if (!inBase64) { + res += this.iconv.decode(buf.slice(lastI), "ascii"); + } else { + var b64str = base64Accum + buf.slice(lastI).toString(); + var canBeDecoded = b64str.length - b64str.length % 8; + base64Accum = b64str.slice(canBeDecoded); + b64str = b64str.slice(0, canBeDecoded); + res += this.iconv.decode(Buffer3.from(b64str, "base64"), "utf16-be"); + } + this.inBase64 = inBase64; + this.base64Accum = base64Accum; + return res; + }; + Utf7Decoder.prototype.end = function() { + var res = ""; + if (this.inBase64 && this.base64Accum.length > 0) + res = this.iconv.decode(Buffer3.from(this.base64Accum, "base64"), "utf16-be"); + this.inBase64 = false; + this.base64Accum = ""; + return res; + }; + exports2.utf7imap = Utf7IMAPCodec; + function Utf7IMAPCodec(codecOptions, iconv) { + this.iconv = iconv; + } + Utf7IMAPCodec.prototype.encoder = Utf7IMAPEncoder; + Utf7IMAPCodec.prototype.decoder = Utf7IMAPDecoder; + Utf7IMAPCodec.prototype.bomAware = true; + function Utf7IMAPEncoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = Buffer3.alloc(6); + this.base64AccumIdx = 0; + } + Utf7IMAPEncoder.prototype.write = function(str) { + var inBase64 = this.inBase64, base64Accum = this.base64Accum, base64AccumIdx = this.base64AccumIdx, buf = Buffer3.alloc(str.length * 5 + 10), bufIdx = 0; + for (var i2 = 0; i2 < str.length; i2++) { + var uChar = str.charCodeAt(i2); + if (32 <= uChar && uChar <= 126) { + if (inBase64) { + if (base64AccumIdx > 0) { + bufIdx += buf.write(base64Accum.slice(0, base64AccumIdx).toString("base64").replace(/\//g, ",").replace(/=+$/, ""), bufIdx); + base64AccumIdx = 0; + } + buf[bufIdx++] = minusChar; + inBase64 = false; + } + if (!inBase64) { + buf[bufIdx++] = uChar; + if (uChar === andChar) + buf[bufIdx++] = minusChar; + } + } else { + if (!inBase64) { + buf[bufIdx++] = andChar; + inBase64 = true; + } + if (inBase64) { + base64Accum[base64AccumIdx++] = uChar >> 8; + base64Accum[base64AccumIdx++] = uChar & 255; + if (base64AccumIdx == base64Accum.length) { + bufIdx += buf.write(base64Accum.toString("base64").replace(/\//g, ","), bufIdx); + base64AccumIdx = 0; + } + } + } + } + this.inBase64 = inBase64; + this.base64AccumIdx = base64AccumIdx; + return buf.slice(0, bufIdx); + }; + Utf7IMAPEncoder.prototype.end = function() { + var buf = Buffer3.alloc(10), bufIdx = 0; + if (this.inBase64) { + if (this.base64AccumIdx > 0) { + bufIdx += buf.write(this.base64Accum.slice(0, this.base64AccumIdx).toString("base64").replace(/\//g, ",").replace(/=+$/, ""), bufIdx); + this.base64AccumIdx = 0; + } + buf[bufIdx++] = minusChar; + this.inBase64 = false; + } + return buf.slice(0, bufIdx); + }; + function Utf7IMAPDecoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = ""; + } + var base64IMAPChars = base64Chars.slice(); + base64IMAPChars[",".charCodeAt(0)] = true; + Utf7IMAPDecoder.prototype.write = function(buf) { + var res = "", lastI = 0, inBase64 = this.inBase64, base64Accum = this.base64Accum; + for (var i2 = 0; i2 < buf.length; i2++) { + if (!inBase64) { + if (buf[i2] == andChar) { + res += this.iconv.decode(buf.slice(lastI, i2), "ascii"); + lastI = i2 + 1; + inBase64 = true; + } + } else { + if (!base64IMAPChars[buf[i2]]) { + if (i2 == lastI && buf[i2] == minusChar) { + res += "&"; + } else { + var b64str = base64Accum + buf.slice(lastI, i2).toString().replace(/,/g, "/"); + res += this.iconv.decode(Buffer3.from(b64str, "base64"), "utf16-be"); + } + if (buf[i2] != minusChar) + i2--; + lastI = i2 + 1; + inBase64 = false; + base64Accum = ""; + } + } + } + if (!inBase64) { + res += this.iconv.decode(buf.slice(lastI), "ascii"); + } else { + var b64str = base64Accum + buf.slice(lastI).toString().replace(/,/g, "/"); + var canBeDecoded = b64str.length - b64str.length % 8; + base64Accum = b64str.slice(canBeDecoded); + b64str = b64str.slice(0, canBeDecoded); + res += this.iconv.decode(Buffer3.from(b64str, "base64"), "utf16-be"); + } + this.inBase64 = inBase64; + this.base64Accum = base64Accum; + return res; + }; + Utf7IMAPDecoder.prototype.end = function() { + var res = ""; + if (this.inBase64 && this.base64Accum.length > 0) + res = this.iconv.decode(Buffer3.from(this.base64Accum, "base64"), "utf16-be"); + this.inBase64 = false; + this.base64Accum = ""; + return res; + }; + } +}); + +// node_modules/iconv-lite/encodings/sbcs-codec.js +var require_sbcs_codec = __commonJS({ + "node_modules/iconv-lite/encodings/sbcs-codec.js"(exports2) { + "use strict"; + var Buffer3 = require_safer().Buffer; + exports2._sbcs = SBCSCodec; + function SBCSCodec(codecOptions, iconv) { + if (!codecOptions) + throw new Error("SBCS codec is called without the data."); + if (!codecOptions.chars || codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256) + throw new Error("Encoding '" + codecOptions.type + "' has incorrect 'chars' (must be of len 128 or 256)"); + if (codecOptions.chars.length === 128) { + var asciiString = ""; + for (var i = 0; i < 128; i++) + asciiString += String.fromCharCode(i); + codecOptions.chars = asciiString + codecOptions.chars; + } + this.decodeBuf = Buffer3.from(codecOptions.chars, "ucs2"); + var encodeBuf = Buffer3.alloc(65536, iconv.defaultCharSingleByte.charCodeAt(0)); + for (var i = 0; i < codecOptions.chars.length; i++) + encodeBuf[codecOptions.chars.charCodeAt(i)] = i; + this.encodeBuf = encodeBuf; + } + SBCSCodec.prototype.encoder = SBCSEncoder; + SBCSCodec.prototype.decoder = SBCSDecoder; + function SBCSEncoder(options, codec) { + this.encodeBuf = codec.encodeBuf; + } + SBCSEncoder.prototype.write = function(str) { + var buf = Buffer3.alloc(str.length); + for (var i = 0; i < str.length; i++) + buf[i] = this.encodeBuf[str.charCodeAt(i)]; + return buf; + }; + SBCSEncoder.prototype.end = function() { + }; + function SBCSDecoder(options, codec) { + this.decodeBuf = codec.decodeBuf; + } + SBCSDecoder.prototype.write = function(buf) { + var decodeBuf = this.decodeBuf; + var newBuf = Buffer3.alloc(buf.length * 2); + var idx1 = 0, idx2 = 0; + for (var i = 0; i < buf.length; i++) { + idx1 = buf[i] * 2; + idx2 = i * 2; + newBuf[idx2] = decodeBuf[idx1]; + newBuf[idx2 + 1] = decodeBuf[idx1 + 1]; + } + return newBuf.toString("ucs2"); + }; + SBCSDecoder.prototype.end = function() { + }; + } +}); + +// node_modules/iconv-lite/encodings/sbcs-data.js +var require_sbcs_data = __commonJS({ + "node_modules/iconv-lite/encodings/sbcs-data.js"(exports2, module2) { + "use strict"; + module2.exports = { + // Not supported by iconv, not sure why. + "10029": "maccenteuro", + "maccenteuro": { + "type": "_sbcs", + "chars": "\xC4\u0100\u0101\xC9\u0104\xD6\xDC\xE1\u0105\u010C\xE4\u010D\u0106\u0107\xE9\u0179\u017A\u010E\xED\u010F\u0112\u0113\u0116\xF3\u0117\xF4\xF6\xF5\xFA\u011A\u011B\xFC\u2020\xB0\u0118\xA3\xA7\u2022\xB6\xDF\xAE\xA9\u2122\u0119\xA8\u2260\u0123\u012E\u012F\u012A\u2264\u2265\u012B\u0136\u2202\u2211\u0142\u013B\u013C\u013D\u013E\u0139\u013A\u0145\u0146\u0143\xAC\u221A\u0144\u0147\u2206\xAB\xBB\u2026\xA0\u0148\u0150\xD5\u0151\u014C\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\u014D\u0154\u0155\u0158\u2039\u203A\u0159\u0156\u0157\u0160\u201A\u201E\u0161\u015A\u015B\xC1\u0164\u0165\xCD\u017D\u017E\u016A\xD3\xD4\u016B\u016E\xDA\u016F\u0170\u0171\u0172\u0173\xDD\xFD\u0137\u017B\u0141\u017C\u0122\u02C7" + }, + "808": "cp808", + "ibm808": "cp808", + "cp808": { + "type": "_sbcs", + "chars": "\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\u0401\u0451\u0404\u0454\u0407\u0457\u040E\u045E\xB0\u2219\xB7\u221A\u2116\u20AC\u25A0\xA0" + }, + "mik": { + "type": "_sbcs", + "chars": "\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\u2514\u2534\u252C\u251C\u2500\u253C\u2563\u2551\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2510\u2591\u2592\u2593\u2502\u2524\u2116\xA7\u2557\u255D\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0" + }, + // Aliases of generated encodings. + "ascii8bit": "ascii", + "usascii": "ascii", + "ansix34": "ascii", + "ansix341968": "ascii", + "ansix341986": "ascii", + "csascii": "ascii", + "cp367": "ascii", + "ibm367": "ascii", + "isoir6": "ascii", + "iso646us": "ascii", + "iso646irv": "ascii", + "us": "ascii", + "latin1": "iso88591", + "latin2": "iso88592", + "latin3": "iso88593", + "latin4": "iso88594", + "latin5": "iso88599", + "latin6": "iso885910", + "latin7": "iso885913", + "latin8": "iso885914", + "latin9": "iso885915", + "latin10": "iso885916", + "csisolatin1": "iso88591", + "csisolatin2": "iso88592", + "csisolatin3": "iso88593", + "csisolatin4": "iso88594", + "csisolatincyrillic": "iso88595", + "csisolatinarabic": "iso88596", + "csisolatingreek": "iso88597", + "csisolatinhebrew": "iso88598", + "csisolatin5": "iso88599", + "csisolatin6": "iso885910", + "l1": "iso88591", + "l2": "iso88592", + "l3": "iso88593", + "l4": "iso88594", + "l5": "iso88599", + "l6": "iso885910", + "l7": "iso885913", + "l8": "iso885914", + "l9": "iso885915", + "l10": "iso885916", + "isoir14": "iso646jp", + "isoir57": "iso646cn", + "isoir100": "iso88591", + "isoir101": "iso88592", + "isoir109": "iso88593", + "isoir110": "iso88594", + "isoir144": "iso88595", + "isoir127": "iso88596", + "isoir126": "iso88597", + "isoir138": "iso88598", + "isoir148": "iso88599", + "isoir157": "iso885910", + "isoir166": "tis620", + "isoir179": "iso885913", + "isoir199": "iso885914", + "isoir203": "iso885915", + "isoir226": "iso885916", + "cp819": "iso88591", + "ibm819": "iso88591", + "cyrillic": "iso88595", + "arabic": "iso88596", + "arabic8": "iso88596", + "ecma114": "iso88596", + "asmo708": "iso88596", + "greek": "iso88597", + "greek8": "iso88597", + "ecma118": "iso88597", + "elot928": "iso88597", + "hebrew": "iso88598", + "hebrew8": "iso88598", + "turkish": "iso88599", + "turkish8": "iso88599", + "thai": "iso885911", + "thai8": "iso885911", + "celtic": "iso885914", + "celtic8": "iso885914", + "isoceltic": "iso885914", + "tis6200": "tis620", + "tis62025291": "tis620", + "tis62025330": "tis620", + "10000": "macroman", + "10006": "macgreek", + "10007": "maccyrillic", + "10079": "maciceland", + "10081": "macturkish", + "cspc8codepage437": "cp437", + "cspc775baltic": "cp775", + "cspc850multilingual": "cp850", + "cspcp852": "cp852", + "cspc862latinhebrew": "cp862", + "cpgr": "cp869", + "msee": "cp1250", + "mscyrl": "cp1251", + "msansi": "cp1252", + "msgreek": "cp1253", + "msturk": "cp1254", + "mshebr": "cp1255", + "msarab": "cp1256", + "winbaltrim": "cp1257", + "cp20866": "koi8r", + "20866": "koi8r", + "ibm878": "koi8r", + "cskoi8r": "koi8r", + "cp21866": "koi8u", + "21866": "koi8u", + "ibm1168": "koi8u", + "strk10482002": "rk1048", + "tcvn5712": "tcvn", + "tcvn57121": "tcvn", + "gb198880": "iso646cn", + "cn": "iso646cn", + "csiso14jisc6220ro": "iso646jp", + "jisc62201969ro": "iso646jp", + "jp": "iso646jp", + "cshproman8": "hproman8", + "r8": "hproman8", + "roman8": "hproman8", + "xroman8": "hproman8", + "ibm1051": "hproman8", + "mac": "macintosh", + "csmacintosh": "macintosh" + }; + } +}); + +// node_modules/iconv-lite/encodings/sbcs-data-generated.js +var require_sbcs_data_generated = __commonJS({ + "node_modules/iconv-lite/encodings/sbcs-data-generated.js"(exports2, module2) { + "use strict"; + module2.exports = { + "437": "cp437", + "737": "cp737", + "775": "cp775", + "850": "cp850", + "852": "cp852", + "855": "cp855", + "856": "cp856", + "857": "cp857", + "858": "cp858", + "860": "cp860", + "861": "cp861", + "862": "cp862", + "863": "cp863", + "864": "cp864", + "865": "cp865", + "866": "cp866", + "869": "cp869", + "874": "windows874", + "922": "cp922", + "1046": "cp1046", + "1124": "cp1124", + "1125": "cp1125", + "1129": "cp1129", + "1133": "cp1133", + "1161": "cp1161", + "1162": "cp1162", + "1163": "cp1163", + "1250": "windows1250", + "1251": "windows1251", + "1252": "windows1252", + "1253": "windows1253", + "1254": "windows1254", + "1255": "windows1255", + "1256": "windows1256", + "1257": "windows1257", + "1258": "windows1258", + "28591": "iso88591", + "28592": "iso88592", + "28593": "iso88593", + "28594": "iso88594", + "28595": "iso88595", + "28596": "iso88596", + "28597": "iso88597", + "28598": "iso88598", + "28599": "iso88599", + "28600": "iso885910", + "28601": "iso885911", + "28603": "iso885913", + "28604": "iso885914", + "28605": "iso885915", + "28606": "iso885916", + "windows874": { + "type": "_sbcs", + "chars": "\u20AC\uFFFD\uFFFD\uFFFD\uFFFD\u2026\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\xA0\u0E01\u0E02\u0E03\u0E04\u0E05\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D\u0E2E\u0E2F\u0E30\u0E31\u0E32\u0E33\u0E34\u0E35\u0E36\u0E37\u0E38\u0E39\u0E3A\uFFFD\uFFFD\uFFFD\uFFFD\u0E3F\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45\u0E46\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D\u0E4E\u0E4F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59\u0E5A\u0E5B\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "win874": "windows874", + "cp874": "windows874", + "windows1250": { + "type": "_sbcs", + "chars": "\u20AC\uFFFD\u201A\uFFFD\u201E\u2026\u2020\u2021\uFFFD\u2030\u0160\u2039\u015A\u0164\u017D\u0179\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\uFFFD\u2122\u0161\u203A\u015B\u0165\u017E\u017A\xA0\u02C7\u02D8\u0141\xA4\u0104\xA6\xA7\xA8\xA9\u015E\xAB\xAC\xAD\xAE\u017B\xB0\xB1\u02DB\u0142\xB4\xB5\xB6\xB7\xB8\u0105\u015F\xBB\u013D\u02DD\u013E\u017C\u0154\xC1\xC2\u0102\xC4\u0139\u0106\xC7\u010C\xC9\u0118\xCB\u011A\xCD\xCE\u010E\u0110\u0143\u0147\xD3\xD4\u0150\xD6\xD7\u0158\u016E\xDA\u0170\xDC\xDD\u0162\xDF\u0155\xE1\xE2\u0103\xE4\u013A\u0107\xE7\u010D\xE9\u0119\xEB\u011B\xED\xEE\u010F\u0111\u0144\u0148\xF3\xF4\u0151\xF6\xF7\u0159\u016F\xFA\u0171\xFC\xFD\u0163\u02D9" + }, + "win1250": "windows1250", + "cp1250": "windows1250", + "windows1251": { + "type": "_sbcs", + "chars": "\u0402\u0403\u201A\u0453\u201E\u2026\u2020\u2021\u20AC\u2030\u0409\u2039\u040A\u040C\u040B\u040F\u0452\u2018\u2019\u201C\u201D\u2022\u2013\u2014\uFFFD\u2122\u0459\u203A\u045A\u045C\u045B\u045F\xA0\u040E\u045E\u0408\xA4\u0490\xA6\xA7\u0401\xA9\u0404\xAB\xAC\xAD\xAE\u0407\xB0\xB1\u0406\u0456\u0491\xB5\xB6\xB7\u0451\u2116\u0454\xBB\u0458\u0405\u0455\u0457\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F" + }, + "win1251": "windows1251", + "cp1251": "windows1251", + "windows1252": { + "type": "_sbcs", + "chars": "\u20AC\uFFFD\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u0152\uFFFD\u017D\uFFFD\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\u0161\u203A\u0153\uFFFD\u017E\u0178\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF" + }, + "win1252": "windows1252", + "cp1252": "windows1252", + "windows1253": { + "type": "_sbcs", + "chars": "\u20AC\uFFFD\u201A\u0192\u201E\u2026\u2020\u2021\uFFFD\u2030\uFFFD\u2039\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\uFFFD\u2122\uFFFD\u203A\uFFFD\uFFFD\uFFFD\uFFFD\xA0\u0385\u0386\xA3\xA4\xA5\xA6\xA7\xA8\xA9\uFFFD\xAB\xAC\xAD\xAE\u2015\xB0\xB1\xB2\xB3\u0384\xB5\xB6\xB7\u0388\u0389\u038A\xBB\u038C\xBD\u038E\u038F\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\uFFFD\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03AA\u03AB\u03AC\u03AD\u03AE\u03AF\u03B0\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C2\u03C3\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\u03CA\u03CB\u03CC\u03CD\u03CE\uFFFD" + }, + "win1253": "windows1253", + "cp1253": "windows1253", + "windows1254": { + "type": "_sbcs", + "chars": "\u20AC\uFFFD\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u0152\uFFFD\uFFFD\uFFFD\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\u0161\u203A\u0153\uFFFD\uFFFD\u0178\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\u011E\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\u0130\u015E\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\u011F\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\u0131\u015F\xFF" + }, + "win1254": "windows1254", + "cp1254": "windows1254", + "windows1255": { + "type": "_sbcs", + "chars": "\u20AC\uFFFD\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\uFFFD\u2039\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\uFFFD\u203A\uFFFD\uFFFD\uFFFD\uFFFD\xA0\xA1\xA2\xA3\u20AA\xA5\xA6\xA7\xA8\xA9\xD7\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xF7\xBB\xBC\xBD\xBE\xBF\u05B0\u05B1\u05B2\u05B3\u05B4\u05B5\u05B6\u05B7\u05B8\u05B9\u05BA\u05BB\u05BC\u05BD\u05BE\u05BF\u05C0\u05C1\u05C2\u05C3\u05F0\u05F1\u05F2\u05F3\u05F4\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB\u05DC\u05DD\u05DE\u05DF\u05E0\u05E1\u05E2\u05E3\u05E4\u05E5\u05E6\u05E7\u05E8\u05E9\u05EA\uFFFD\uFFFD\u200E\u200F\uFFFD" + }, + "win1255": "windows1255", + "cp1255": "windows1255", + "windows1256": { + "type": "_sbcs", + "chars": "\u20AC\u067E\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0679\u2039\u0152\u0686\u0698\u0688\u06AF\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u06A9\u2122\u0691\u203A\u0153\u200C\u200D\u06BA\xA0\u060C\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\u06BE\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\u061B\xBB\xBC\xBD\xBE\u061F\u06C1\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062A\u062B\u062C\u062D\u062E\u062F\u0630\u0631\u0632\u0633\u0634\u0635\u0636\xD7\u0637\u0638\u0639\u063A\u0640\u0641\u0642\u0643\xE0\u0644\xE2\u0645\u0646\u0647\u0648\xE7\xE8\xE9\xEA\xEB\u0649\u064A\xEE\xEF\u064B\u064C\u064D\u064E\xF4\u064F\u0650\xF7\u0651\xF9\u0652\xFB\xFC\u200E\u200F\u06D2" + }, + "win1256": "windows1256", + "cp1256": "windows1256", + "windows1257": { + "type": "_sbcs", + "chars": "\u20AC\uFFFD\u201A\uFFFD\u201E\u2026\u2020\u2021\uFFFD\u2030\uFFFD\u2039\uFFFD\xA8\u02C7\xB8\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\uFFFD\u2122\uFFFD\u203A\uFFFD\xAF\u02DB\uFFFD\xA0\uFFFD\xA2\xA3\xA4\uFFFD\xA6\xA7\xD8\xA9\u0156\xAB\xAC\xAD\xAE\xC6\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xF8\xB9\u0157\xBB\xBC\xBD\xBE\xE6\u0104\u012E\u0100\u0106\xC4\xC5\u0118\u0112\u010C\xC9\u0179\u0116\u0122\u0136\u012A\u013B\u0160\u0143\u0145\xD3\u014C\xD5\xD6\xD7\u0172\u0141\u015A\u016A\xDC\u017B\u017D\xDF\u0105\u012F\u0101\u0107\xE4\xE5\u0119\u0113\u010D\xE9\u017A\u0117\u0123\u0137\u012B\u013C\u0161\u0144\u0146\xF3\u014D\xF5\xF6\xF7\u0173\u0142\u015B\u016B\xFC\u017C\u017E\u02D9" + }, + "win1257": "windows1257", + "cp1257": "windows1257", + "windows1258": { + "type": "_sbcs", + "chars": "\u20AC\uFFFD\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\uFFFD\u2039\u0152\uFFFD\uFFFD\uFFFD\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\uFFFD\u203A\u0153\uFFFD\uFFFD\u0178\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\u0102\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\u0300\xCD\xCE\xCF\u0110\xD1\u0309\xD3\xD4\u01A0\xD6\xD7\xD8\xD9\xDA\xDB\xDC\u01AF\u0303\xDF\xE0\xE1\xE2\u0103\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\u0301\xED\xEE\xEF\u0111\xF1\u0323\xF3\xF4\u01A1\xF6\xF7\xF8\xF9\xFA\xFB\xFC\u01B0\u20AB\xFF" + }, + "win1258": "windows1258", + "cp1258": "windows1258", + "iso88591": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF" + }, + "cp28591": "iso88591", + "iso88592": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0104\u02D8\u0141\xA4\u013D\u015A\xA7\xA8\u0160\u015E\u0164\u0179\xAD\u017D\u017B\xB0\u0105\u02DB\u0142\xB4\u013E\u015B\u02C7\xB8\u0161\u015F\u0165\u017A\u02DD\u017E\u017C\u0154\xC1\xC2\u0102\xC4\u0139\u0106\xC7\u010C\xC9\u0118\xCB\u011A\xCD\xCE\u010E\u0110\u0143\u0147\xD3\xD4\u0150\xD6\xD7\u0158\u016E\xDA\u0170\xDC\xDD\u0162\xDF\u0155\xE1\xE2\u0103\xE4\u013A\u0107\xE7\u010D\xE9\u0119\xEB\u011B\xED\xEE\u010F\u0111\u0144\u0148\xF3\xF4\u0151\xF6\xF7\u0159\u016F\xFA\u0171\xFC\xFD\u0163\u02D9" + }, + "cp28592": "iso88592", + "iso88593": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0126\u02D8\xA3\xA4\uFFFD\u0124\xA7\xA8\u0130\u015E\u011E\u0134\xAD\uFFFD\u017B\xB0\u0127\xB2\xB3\xB4\xB5\u0125\xB7\xB8\u0131\u015F\u011F\u0135\xBD\uFFFD\u017C\xC0\xC1\xC2\uFFFD\xC4\u010A\u0108\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\uFFFD\xD1\xD2\xD3\xD4\u0120\xD6\xD7\u011C\xD9\xDA\xDB\xDC\u016C\u015C\xDF\xE0\xE1\xE2\uFFFD\xE4\u010B\u0109\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\uFFFD\xF1\xF2\xF3\xF4\u0121\xF6\xF7\u011D\xF9\xFA\xFB\xFC\u016D\u015D\u02D9" + }, + "cp28593": "iso88593", + "iso88594": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0104\u0138\u0156\xA4\u0128\u013B\xA7\xA8\u0160\u0112\u0122\u0166\xAD\u017D\xAF\xB0\u0105\u02DB\u0157\xB4\u0129\u013C\u02C7\xB8\u0161\u0113\u0123\u0167\u014A\u017E\u014B\u0100\xC1\xC2\xC3\xC4\xC5\xC6\u012E\u010C\xC9\u0118\xCB\u0116\xCD\xCE\u012A\u0110\u0145\u014C\u0136\xD4\xD5\xD6\xD7\xD8\u0172\xDA\xDB\xDC\u0168\u016A\xDF\u0101\xE1\xE2\xE3\xE4\xE5\xE6\u012F\u010D\xE9\u0119\xEB\u0117\xED\xEE\u012B\u0111\u0146\u014D\u0137\xF4\xF5\xF6\xF7\xF8\u0173\xFA\xFB\xFC\u0169\u016B\u02D9" + }, + "cp28594": "iso88594", + "iso88595": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040A\u040B\u040C\xAD\u040E\u040F\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\u2116\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045A\u045B\u045C\xA7\u045E\u045F" + }, + "cp28595": "iso88595", + "iso88596": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\uFFFD\uFFFD\uFFFD\xA4\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u060C\xAD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u061B\uFFFD\uFFFD\uFFFD\u061F\uFFFD\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062A\u062B\u062C\u062D\u062E\u062F\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063A\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0640\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064A\u064B\u064C\u064D\u064E\u064F\u0650\u0651\u0652\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "cp28596": "iso88596", + "iso88597": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u2018\u2019\xA3\u20AC\u20AF\xA6\xA7\xA8\xA9\u037A\xAB\xAC\xAD\uFFFD\u2015\xB0\xB1\xB2\xB3\u0384\u0385\u0386\xB7\u0388\u0389\u038A\xBB\u038C\xBD\u038E\u038F\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\uFFFD\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03AA\u03AB\u03AC\u03AD\u03AE\u03AF\u03B0\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C2\u03C3\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\u03CA\u03CB\u03CC\u03CD\u03CE\uFFFD" + }, + "cp28597": "iso88597", + "iso88598": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\uFFFD\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xD7\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xF7\xBB\xBC\xBD\xBE\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2017\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB\u05DC\u05DD\u05DE\u05DF\u05E0\u05E1\u05E2\u05E3\u05E4\u05E5\u05E6\u05E7\u05E8\u05E9\u05EA\uFFFD\uFFFD\u200E\u200F\uFFFD" + }, + "cp28598": "iso88598", + "iso88599": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\u011E\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\u0130\u015E\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\u011F\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\u0131\u015F\xFF" + }, + "cp28599": "iso88599", + "iso885910": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0104\u0112\u0122\u012A\u0128\u0136\xA7\u013B\u0110\u0160\u0166\u017D\xAD\u016A\u014A\xB0\u0105\u0113\u0123\u012B\u0129\u0137\xB7\u013C\u0111\u0161\u0167\u017E\u2015\u016B\u014B\u0100\xC1\xC2\xC3\xC4\xC5\xC6\u012E\u010C\xC9\u0118\xCB\u0116\xCD\xCE\xCF\xD0\u0145\u014C\xD3\xD4\xD5\xD6\u0168\xD8\u0172\xDA\xDB\xDC\xDD\xDE\xDF\u0101\xE1\xE2\xE3\xE4\xE5\xE6\u012F\u010D\xE9\u0119\xEB\u0117\xED\xEE\xEF\xF0\u0146\u014D\xF3\xF4\xF5\xF6\u0169\xF8\u0173\xFA\xFB\xFC\xFD\xFE\u0138" + }, + "cp28600": "iso885910", + "iso885911": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0E01\u0E02\u0E03\u0E04\u0E05\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D\u0E2E\u0E2F\u0E30\u0E31\u0E32\u0E33\u0E34\u0E35\u0E36\u0E37\u0E38\u0E39\u0E3A\uFFFD\uFFFD\uFFFD\uFFFD\u0E3F\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45\u0E46\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D\u0E4E\u0E4F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59\u0E5A\u0E5B\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "cp28601": "iso885911", + "iso885913": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u201D\xA2\xA3\xA4\u201E\xA6\xA7\xD8\xA9\u0156\xAB\xAC\xAD\xAE\xC6\xB0\xB1\xB2\xB3\u201C\xB5\xB6\xB7\xF8\xB9\u0157\xBB\xBC\xBD\xBE\xE6\u0104\u012E\u0100\u0106\xC4\xC5\u0118\u0112\u010C\xC9\u0179\u0116\u0122\u0136\u012A\u013B\u0160\u0143\u0145\xD3\u014C\xD5\xD6\xD7\u0172\u0141\u015A\u016A\xDC\u017B\u017D\xDF\u0105\u012F\u0101\u0107\xE4\xE5\u0119\u0113\u010D\xE9\u017A\u0117\u0123\u0137\u012B\u013C\u0161\u0144\u0146\xF3\u014D\xF5\xF6\xF7\u0173\u0142\u015B\u016B\xFC\u017C\u017E\u2019" + }, + "cp28603": "iso885913", + "iso885914": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u1E02\u1E03\xA3\u010A\u010B\u1E0A\xA7\u1E80\xA9\u1E82\u1E0B\u1EF2\xAD\xAE\u0178\u1E1E\u1E1F\u0120\u0121\u1E40\u1E41\xB6\u1E56\u1E81\u1E57\u1E83\u1E60\u1EF3\u1E84\u1E85\u1E61\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\u0174\xD1\xD2\xD3\xD4\xD5\xD6\u1E6A\xD8\xD9\xDA\xDB\xDC\xDD\u0176\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\u0175\xF1\xF2\xF3\xF4\xF5\xF6\u1E6B\xF8\xF9\xFA\xFB\xFC\xFD\u0177\xFF" + }, + "cp28604": "iso885914", + "iso885915": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\u20AC\xA5\u0160\xA7\u0161\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\u017D\xB5\xB6\xB7\u017E\xB9\xBA\xBB\u0152\u0153\u0178\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF" + }, + "cp28605": "iso885915", + "iso885916": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0104\u0105\u0141\u20AC\u201E\u0160\xA7\u0161\xA9\u0218\xAB\u0179\xAD\u017A\u017B\xB0\xB1\u010C\u0142\u017D\u201D\xB6\xB7\u017E\u010D\u0219\xBB\u0152\u0153\u0178\u017C\xC0\xC1\xC2\u0102\xC4\u0106\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\u0110\u0143\xD2\xD3\xD4\u0150\xD6\u015A\u0170\xD9\xDA\xDB\xDC\u0118\u021A\xDF\xE0\xE1\xE2\u0103\xE4\u0107\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\u0111\u0144\xF2\xF3\xF4\u0151\xF6\u015B\u0171\xF9\xFA\xFB\xFC\u0119\u021B\xFF" + }, + "cp28606": "iso885916", + "cp437": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xA2\xA3\xA5\u20A7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0" + }, + "ibm437": "cp437", + "csibm437": "cp437", + "cp737": { + "type": "_sbcs", + "chars": "\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C3\u03C2\u03C4\u03C5\u03C6\u03C7\u03C8\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03C9\u03AC\u03AD\u03AE\u03CA\u03AF\u03CC\u03CD\u03CB\u03CE\u0386\u0388\u0389\u038A\u038C\u038E\u038F\xB1\u2265\u2264\u03AA\u03AB\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0" + }, + "ibm737": "cp737", + "csibm737": "cp737", + "cp775": { + "type": "_sbcs", + "chars": "\u0106\xFC\xE9\u0101\xE4\u0123\xE5\u0107\u0142\u0113\u0156\u0157\u012B\u0179\xC4\xC5\xC9\xE6\xC6\u014D\xF6\u0122\xA2\u015A\u015B\xD6\xDC\xF8\xA3\xD8\xD7\xA4\u0100\u012A\xF3\u017B\u017C\u017A\u201D\xA6\xA9\xAE\xAC\xBD\xBC\u0141\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u0104\u010C\u0118\u0116\u2563\u2551\u2557\u255D\u012E\u0160\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u0172\u016A\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u017D\u0105\u010D\u0119\u0117\u012F\u0161\u0173\u016B\u017E\u2518\u250C\u2588\u2584\u258C\u2590\u2580\xD3\xDF\u014C\u0143\xF5\xD5\xB5\u0144\u0136\u0137\u013B\u013C\u0146\u0112\u0145\u2019\xAD\xB1\u201C\xBE\xB6\xA7\xF7\u201E\xB0\u2219\xB7\xB9\xB3\xB2\u25A0\xA0" + }, + "ibm775": "cp775", + "csibm775": "cp775", + "cp850": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xF8\xA3\xD8\xD7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\xAE\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\xC1\xC2\xC0\xA9\u2563\u2551\u2557\u255D\xA2\xA5\u2510\u2514\u2534\u252C\u251C\u2500\u253C\xE3\xC3\u255A\u2554\u2569\u2566\u2560\u2550\u256C\xA4\xF0\xD0\xCA\xCB\xC8\u0131\xCD\xCE\xCF\u2518\u250C\u2588\u2584\xA6\xCC\u2580\xD3\xDF\xD4\xD2\xF5\xD5\xB5\xFE\xDE\xDA\xDB\xD9\xFD\xDD\xAF\xB4\xAD\xB1\u2017\xBE\xB6\xA7\xF7\xB8\xB0\xA8\xB7\xB9\xB3\xB2\u25A0\xA0" + }, + "ibm850": "cp850", + "csibm850": "cp850", + "cp852": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xE4\u016F\u0107\xE7\u0142\xEB\u0150\u0151\xEE\u0179\xC4\u0106\xC9\u0139\u013A\xF4\xF6\u013D\u013E\u015A\u015B\xD6\xDC\u0164\u0165\u0141\xD7\u010D\xE1\xED\xF3\xFA\u0104\u0105\u017D\u017E\u0118\u0119\xAC\u017A\u010C\u015F\xAB\xBB\u2591\u2592\u2593\u2502\u2524\xC1\xC2\u011A\u015E\u2563\u2551\u2557\u255D\u017B\u017C\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u0102\u0103\u255A\u2554\u2569\u2566\u2560\u2550\u256C\xA4\u0111\u0110\u010E\xCB\u010F\u0147\xCD\xCE\u011B\u2518\u250C\u2588\u2584\u0162\u016E\u2580\xD3\xDF\xD4\u0143\u0144\u0148\u0160\u0161\u0154\xDA\u0155\u0170\xFD\xDD\u0163\xB4\xAD\u02DD\u02DB\u02C7\u02D8\xA7\xF7\xB8\xB0\xA8\u02D9\u0171\u0158\u0159\u25A0\xA0" + }, + "ibm852": "cp852", + "csibm852": "cp852", + "cp855": { + "type": "_sbcs", + "chars": "\u0452\u0402\u0453\u0403\u0451\u0401\u0454\u0404\u0455\u0405\u0456\u0406\u0457\u0407\u0458\u0408\u0459\u0409\u045A\u040A\u045B\u040B\u045C\u040C\u045E\u040E\u045F\u040F\u044E\u042E\u044A\u042A\u0430\u0410\u0431\u0411\u0446\u0426\u0434\u0414\u0435\u0415\u0444\u0424\u0433\u0413\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u0445\u0425\u0438\u0418\u2563\u2551\u2557\u255D\u0439\u0419\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u043A\u041A\u255A\u2554\u2569\u2566\u2560\u2550\u256C\xA4\u043B\u041B\u043C\u041C\u043D\u041D\u043E\u041E\u043F\u2518\u250C\u2588\u2584\u041F\u044F\u2580\u042F\u0440\u0420\u0441\u0421\u0442\u0422\u0443\u0423\u0436\u0416\u0432\u0412\u044C\u042C\u2116\xAD\u044B\u042B\u0437\u0417\u0448\u0428\u044D\u042D\u0449\u0429\u0447\u0427\xA7\u25A0\xA0" + }, + "ibm855": "cp855", + "csibm855": "cp855", + "cp856": { + "type": "_sbcs", + "chars": "\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB\u05DC\u05DD\u05DE\u05DF\u05E0\u05E1\u05E2\u05E3\u05E4\u05E5\u05E6\u05E7\u05E8\u05E9\u05EA\uFFFD\xA3\uFFFD\xD7\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\xAE\xAC\xBD\xBC\uFFFD\xAB\xBB\u2591\u2592\u2593\u2502\u2524\uFFFD\uFFFD\uFFFD\xA9\u2563\u2551\u2557\u255D\xA2\xA5\u2510\u2514\u2534\u252C\u251C\u2500\u253C\uFFFD\uFFFD\u255A\u2554\u2569\u2566\u2560\u2550\u256C\xA4\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2518\u250C\u2588\u2584\xA6\uFFFD\u2580\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\xB5\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\xAF\xB4\xAD\xB1\u2017\xBE\xB6\xA7\xF7\xB8\xB0\xA8\xB7\xB9\xB3\xB2\u25A0\xA0" + }, + "ibm856": "cp856", + "csibm856": "cp856", + "cp857": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\u0131\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\u0130\xD6\xDC\xF8\xA3\xD8\u015E\u015F\xE1\xED\xF3\xFA\xF1\xD1\u011E\u011F\xBF\xAE\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\xC1\xC2\xC0\xA9\u2563\u2551\u2557\u255D\xA2\xA5\u2510\u2514\u2534\u252C\u251C\u2500\u253C\xE3\xC3\u255A\u2554\u2569\u2566\u2560\u2550\u256C\xA4\xBA\xAA\xCA\xCB\xC8\uFFFD\xCD\xCE\xCF\u2518\u250C\u2588\u2584\xA6\xCC\u2580\xD3\xDF\xD4\xD2\xF5\xD5\xB5\uFFFD\xD7\xDA\xDB\xD9\xEC\xFF\xAF\xB4\xAD\xB1\uFFFD\xBE\xB6\xA7\xF7\xB8\xB0\xA8\xB7\xB9\xB3\xB2\u25A0\xA0" + }, + "ibm857": "cp857", + "csibm857": "cp857", + "cp858": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xF8\xA3\xD8\xD7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\xAE\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\xC1\xC2\xC0\xA9\u2563\u2551\u2557\u255D\xA2\xA5\u2510\u2514\u2534\u252C\u251C\u2500\u253C\xE3\xC3\u255A\u2554\u2569\u2566\u2560\u2550\u256C\xA4\xF0\xD0\xCA\xCB\xC8\u20AC\xCD\xCE\xCF\u2518\u250C\u2588\u2584\xA6\xCC\u2580\xD3\xDF\xD4\xD2\xF5\xD5\xB5\xFE\xDE\xDA\xDB\xD9\xFD\xDD\xAF\xB4\xAD\xB1\u2017\xBE\xB6\xA7\xF7\xB8\xB0\xA8\xB7\xB9\xB3\xB2\u25A0\xA0" + }, + "ibm858": "cp858", + "csibm858": "cp858", + "cp860": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xE3\xE0\xC1\xE7\xEA\xCA\xE8\xCD\xD4\xEC\xC3\xC2\xC9\xC0\xC8\xF4\xF5\xF2\xDA\xF9\xCC\xD5\xDC\xA2\xA3\xD9\u20A7\xD3\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\xD2\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0" + }, + "ibm860": "cp860", + "csibm860": "cp860", + "cp861": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xD0\xF0\xDE\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xFE\xFB\xDD\xFD\xD6\xDC\xF8\xA3\xD8\u20A7\u0192\xE1\xED\xF3\xFA\xC1\xCD\xD3\xDA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0" + }, + "ibm861": "cp861", + "csibm861": "cp861", + "cp862": { + "type": "_sbcs", + "chars": "\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB\u05DC\u05DD\u05DE\u05DF\u05E0\u05E1\u05E2\u05E3\u05E4\u05E5\u05E6\u05E7\u05E8\u05E9\u05EA\xA2\xA3\xA5\u20A7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0" + }, + "ibm862": "cp862", + "csibm862": "cp862", + "cp863": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xC2\xE0\xB6\xE7\xEA\xEB\xE8\xEF\xEE\u2017\xC0\xA7\xC9\xC8\xCA\xF4\xCB\xCF\xFB\xF9\xA4\xD4\xDC\xA2\xA3\xD9\xDB\u0192\xA6\xB4\xF3\xFA\xA8\xB8\xB3\xAF\xCE\u2310\xAC\xBD\xBC\xBE\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0" + }, + "ibm863": "cp863", + "csibm863": "cp863", + "cp864": { + "type": "_sbcs", + "chars": "\0\x07\b \n\v\f\r\x1B !\"#$\u066A&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F\xB0\xB7\u2219\u221A\u2592\u2500\u2502\u253C\u2524\u252C\u251C\u2534\u2510\u250C\u2514\u2518\u03B2\u221E\u03C6\xB1\xBD\xBC\u2248\xAB\xBB\uFEF7\uFEF8\uFFFD\uFFFD\uFEFB\uFEFC\uFFFD\xA0\xAD\uFE82\xA3\xA4\uFE84\uFFFD\uFFFD\uFE8E\uFE8F\uFE95\uFE99\u060C\uFE9D\uFEA1\uFEA5\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\uFED1\u061B\uFEB1\uFEB5\uFEB9\u061F\xA2\uFE80\uFE81\uFE83\uFE85\uFECA\uFE8B\uFE8D\uFE91\uFE93\uFE97\uFE9B\uFE9F\uFEA3\uFEA7\uFEA9\uFEAB\uFEAD\uFEAF\uFEB3\uFEB7\uFEBB\uFEBF\uFEC1\uFEC5\uFECB\uFECF\xA6\xAC\xF7\xD7\uFEC9\u0640\uFED3\uFED7\uFEDB\uFEDF\uFEE3\uFEE7\uFEEB\uFEED\uFEEF\uFEF3\uFEBD\uFECC\uFECE\uFECD\uFEE1\uFE7D\u0651\uFEE5\uFEE9\uFEEC\uFEF0\uFEF2\uFED0\uFED5\uFEF5\uFEF6\uFEDD\uFED9\uFEF1\u25A0\uFFFD" + }, + "ibm864": "cp864", + "csibm864": "cp864", + "cp865": { + "type": "_sbcs", + "chars": "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xF8\xA3\xD8\u20A7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xA4\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0" + }, + "ibm865": "cp865", + "csibm865": "cp865", + "cp866": { + "type": "_sbcs", + "chars": "\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\u0401\u0451\u0404\u0454\u0407\u0457\u040E\u045E\xB0\u2219\xB7\u221A\u2116\xA4\u25A0\xA0" + }, + "ibm866": "cp866", + "csibm866": "cp866", + "cp869": { + "type": "_sbcs", + "chars": "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0386\uFFFD\xB7\xAC\xA6\u2018\u2019\u0388\u2015\u0389\u038A\u03AA\u038C\uFFFD\uFFFD\u038E\u03AB\xA9\u038F\xB2\xB3\u03AC\xA3\u03AD\u03AE\u03AF\u03CA\u0390\u03CC\u03CD\u0391\u0392\u0393\u0394\u0395\u0396\u0397\xBD\u0398\u0399\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u039A\u039B\u039C\u039D\u2563\u2551\u2557\u255D\u039E\u039F\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u03A0\u03A1\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03B1\u03B2\u03B3\u2518\u250C\u2588\u2584\u03B4\u03B5\u2580\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C3\u03C2\u03C4\u0384\xAD\xB1\u03C5\u03C6\u03C7\xA7\u03C8\u0385\xB0\xA8\u03C9\u03CB\u03B0\u03CE\u25A0\xA0" + }, + "ibm869": "cp869", + "csibm869": "cp869", + "cp922": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\u203E\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\u0160\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\u017D\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\u0161\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\u017E\xFF" + }, + "ibm922": "cp922", + "csibm922": "cp922", + "cp1046": { + "type": "_sbcs", + "chars": "\uFE88\xD7\xF7\uF8F6\uF8F5\uF8F4\uF8F7\uFE71\x88\u25A0\u2502\u2500\u2510\u250C\u2514\u2518\uFE79\uFE7B\uFE7D\uFE7F\uFE77\uFE8A\uFEF0\uFEF3\uFEF2\uFECE\uFECF\uFED0\uFEF6\uFEF8\uFEFA\uFEFC\xA0\uF8FA\uF8F9\uF8F8\xA4\uF8FB\uFE8B\uFE91\uFE97\uFE9B\uFE9F\uFEA3\u060C\xAD\uFEA7\uFEB3\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\uFEB7\u061B\uFEBB\uFEBF\uFECA\u061F\uFECB\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062A\u062B\u062C\u062D\u062E\u062F\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\uFEC7\u0639\u063A\uFECC\uFE82\uFE84\uFE8E\uFED3\u0640\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064A\u064B\u064C\u064D\u064E\u064F\u0650\u0651\u0652\uFED7\uFEDB\uFEDF\uF8FC\uFEF5\uFEF7\uFEF9\uFEFB\uFEE3\uFEE7\uFEEC\uFEE9\uFFFD" + }, + "ibm1046": "cp1046", + "csibm1046": "cp1046", + "cp1124": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0401\u0402\u0490\u0404\u0405\u0406\u0407\u0408\u0409\u040A\u040B\u040C\xAD\u040E\u040F\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\u2116\u0451\u0452\u0491\u0454\u0455\u0456\u0457\u0458\u0459\u045A\u045B\u045C\xA7\u045E\u045F" + }, + "ibm1124": "cp1124", + "csibm1124": "cp1124", + "cp1125": { + "type": "_sbcs", + "chars": "\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\u0401\u0451\u0490\u0491\u0404\u0454\u0406\u0456\u0407\u0457\xB7\u221A\u2116\xA4\u25A0\xA0" + }, + "ibm1125": "cp1125", + "csibm1125": "cp1125", + "cp1129": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\u0153\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\u0178\xB5\xB6\xB7\u0152\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\u0102\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\u0300\xCD\xCE\xCF\u0110\xD1\u0309\xD3\xD4\u01A0\xD6\xD7\xD8\xD9\xDA\xDB\xDC\u01AF\u0303\xDF\xE0\xE1\xE2\u0103\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\u0301\xED\xEE\xEF\u0111\xF1\u0323\xF3\xF4\u01A1\xF6\xF7\xF8\xF9\xFA\xFB\xFC\u01B0\u20AB\xFF" + }, + "ibm1129": "cp1129", + "csibm1129": "cp1129", + "cp1133": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0E81\u0E82\u0E84\u0E87\u0E88\u0EAA\u0E8A\u0E8D\u0E94\u0E95\u0E96\u0E97\u0E99\u0E9A\u0E9B\u0E9C\u0E9D\u0E9E\u0E9F\u0EA1\u0EA2\u0EA3\u0EA5\u0EA7\u0EAB\u0EAD\u0EAE\uFFFD\uFFFD\uFFFD\u0EAF\u0EB0\u0EB2\u0EB3\u0EB4\u0EB5\u0EB6\u0EB7\u0EB8\u0EB9\u0EBC\u0EB1\u0EBB\u0EBD\uFFFD\uFFFD\uFFFD\u0EC0\u0EC1\u0EC2\u0EC3\u0EC4\u0EC8\u0EC9\u0ECA\u0ECB\u0ECC\u0ECD\u0EC6\uFFFD\u0EDC\u0EDD\u20AD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0ED0\u0ED1\u0ED2\u0ED3\u0ED4\u0ED5\u0ED6\u0ED7\u0ED8\u0ED9\uFFFD\uFFFD\xA2\xAC\xA6\uFFFD" + }, + "ibm1133": "cp1133", + "csibm1133": "cp1133", + "cp1161": { + "type": "_sbcs", + "chars": "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0E48\u0E01\u0E02\u0E03\u0E04\u0E05\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D\u0E2E\u0E2F\u0E30\u0E31\u0E32\u0E33\u0E34\u0E35\u0E36\u0E37\u0E38\u0E39\u0E3A\u0E49\u0E4A\u0E4B\u20AC\u0E3F\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45\u0E46\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D\u0E4E\u0E4F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59\u0E5A\u0E5B\xA2\xAC\xA6\xA0" + }, + "ibm1161": "cp1161", + "csibm1161": "cp1161", + "cp1162": { + "type": "_sbcs", + "chars": "\u20AC\x81\x82\x83\x84\u2026\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\u2018\u2019\u201C\u201D\u2022\u2013\u2014\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\u0E01\u0E02\u0E03\u0E04\u0E05\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D\u0E2E\u0E2F\u0E30\u0E31\u0E32\u0E33\u0E34\u0E35\u0E36\u0E37\u0E38\u0E39\u0E3A\uFFFD\uFFFD\uFFFD\uFFFD\u0E3F\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45\u0E46\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D\u0E4E\u0E4F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59\u0E5A\u0E5B\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "ibm1162": "cp1162", + "csibm1162": "cp1162", + "cp1163": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\u20AC\xA5\xA6\xA7\u0153\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\u0178\xB5\xB6\xB7\u0152\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\u0102\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\u0300\xCD\xCE\xCF\u0110\xD1\u0309\xD3\xD4\u01A0\xD6\xD7\xD8\xD9\xDA\xDB\xDC\u01AF\u0303\xDF\xE0\xE1\xE2\u0103\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\u0301\xED\xEE\xEF\u0111\xF1\u0323\xF3\xF4\u01A1\xF6\xF7\xF8\xF9\xFA\xFB\xFC\u01B0\u20AB\xFF" + }, + "ibm1163": "cp1163", + "csibm1163": "cp1163", + "maccroatian": { + "type": "_sbcs", + "chars": "\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC\u2020\xB0\xA2\xA3\xA7\u2022\xB6\xDF\xAE\u0160\u2122\xB4\xA8\u2260\u017D\xD8\u221E\xB1\u2264\u2265\u2206\xB5\u2202\u2211\u220F\u0161\u222B\xAA\xBA\u2126\u017E\xF8\xBF\xA1\xAC\u221A\u0192\u2248\u0106\xAB\u010C\u2026\xA0\xC0\xC3\xD5\u0152\u0153\u0110\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\uFFFD\xA9\u2044\xA4\u2039\u203A\xC6\xBB\u2013\xB7\u201A\u201E\u2030\xC2\u0107\xC1\u010D\xC8\xCD\xCE\xCF\xCC\xD3\xD4\u0111\xD2\xDA\xDB\xD9\u0131\u02C6\u02DC\xAF\u03C0\xCB\u02DA\xB8\xCA\xE6\u02C7" + }, + "maccyrillic": { + "type": "_sbcs", + "chars": "\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u2020\xB0\xA2\xA3\xA7\u2022\xB6\u0406\xAE\xA9\u2122\u0402\u0452\u2260\u0403\u0453\u221E\xB1\u2264\u2265\u0456\xB5\u2202\u0408\u0404\u0454\u0407\u0457\u0409\u0459\u040A\u045A\u0458\u0405\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\u040B\u045B\u040C\u045C\u0455\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u201E\u040E\u045E\u040F\u045F\u2116\u0401\u0451\u044F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\xA4" + }, + "macgreek": { + "type": "_sbcs", + "chars": "\xC4\xB9\xB2\xC9\xB3\xD6\xDC\u0385\xE0\xE2\xE4\u0384\xA8\xE7\xE9\xE8\xEA\xEB\xA3\u2122\xEE\xEF\u2022\xBD\u2030\xF4\xF6\xA6\xAD\xF9\xFB\xFC\u2020\u0393\u0394\u0398\u039B\u039E\u03A0\xDF\xAE\xA9\u03A3\u03AA\xA7\u2260\xB0\u0387\u0391\xB1\u2264\u2265\xA5\u0392\u0395\u0396\u0397\u0399\u039A\u039C\u03A6\u03AB\u03A8\u03A9\u03AC\u039D\xAC\u039F\u03A1\u2248\u03A4\xAB\xBB\u2026\xA0\u03A5\u03A7\u0386\u0388\u0153\u2013\u2015\u201C\u201D\u2018\u2019\xF7\u0389\u038A\u038C\u038E\u03AD\u03AE\u03AF\u03CC\u038F\u03CD\u03B1\u03B2\u03C8\u03B4\u03B5\u03C6\u03B3\u03B7\u03B9\u03BE\u03BA\u03BB\u03BC\u03BD\u03BF\u03C0\u03CE\u03C1\u03C3\u03C4\u03B8\u03C9\u03C2\u03C7\u03C5\u03B6\u03CA\u03CB\u0390\u03B0\uFFFD" + }, + "maciceland": { + "type": "_sbcs", + "chars": "\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC\xDD\xB0\xA2\xA3\xA7\u2022\xB6\xDF\xAE\xA9\u2122\xB4\xA8\u2260\xC6\xD8\u221E\xB1\u2264\u2265\xA5\xB5\u2202\u2211\u220F\u03C0\u222B\xAA\xBA\u2126\xE6\xF8\xBF\xA1\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\xC0\xC3\xD5\u0152\u0153\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\xFF\u0178\u2044\xA4\xD0\xF0\xDE\xFE\xFD\xB7\u201A\u201E\u2030\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4\uFFFD\xD2\xDA\xDB\xD9\u0131\u02C6\u02DC\xAF\u02D8\u02D9\u02DA\xB8\u02DD\u02DB\u02C7" + }, + "macroman": { + "type": "_sbcs", + "chars": "\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC\u2020\xB0\xA2\xA3\xA7\u2022\xB6\xDF\xAE\xA9\u2122\xB4\xA8\u2260\xC6\xD8\u221E\xB1\u2264\u2265\xA5\xB5\u2202\u2211\u220F\u03C0\u222B\xAA\xBA\u2126\xE6\xF8\xBF\xA1\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\xC0\xC3\xD5\u0152\u0153\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\xFF\u0178\u2044\xA4\u2039\u203A\uFB01\uFB02\u2021\xB7\u201A\u201E\u2030\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4\uFFFD\xD2\xDA\xDB\xD9\u0131\u02C6\u02DC\xAF\u02D8\u02D9\u02DA\xB8\u02DD\u02DB\u02C7" + }, + "macromania": { + "type": "_sbcs", + "chars": "\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC\u2020\xB0\xA2\xA3\xA7\u2022\xB6\xDF\xAE\xA9\u2122\xB4\xA8\u2260\u0102\u015E\u221E\xB1\u2264\u2265\xA5\xB5\u2202\u2211\u220F\u03C0\u222B\xAA\xBA\u2126\u0103\u015F\xBF\xA1\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\xC0\xC3\xD5\u0152\u0153\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\xFF\u0178\u2044\xA4\u2039\u203A\u0162\u0163\u2021\xB7\u201A\u201E\u2030\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4\uFFFD\xD2\xDA\xDB\xD9\u0131\u02C6\u02DC\xAF\u02D8\u02D9\u02DA\xB8\u02DD\u02DB\u02C7" + }, + "macthai": { + "type": "_sbcs", + "chars": "\xAB\xBB\u2026\uF88C\uF88F\uF892\uF895\uF898\uF88B\uF88E\uF891\uF894\uF897\u201C\u201D\uF899\uFFFD\u2022\uF884\uF889\uF885\uF886\uF887\uF888\uF88A\uF88D\uF890\uF893\uF896\u2018\u2019\uFFFD\xA0\u0E01\u0E02\u0E03\u0E04\u0E05\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D\u0E2E\u0E2F\u0E30\u0E31\u0E32\u0E33\u0E34\u0E35\u0E36\u0E37\u0E38\u0E39\u0E3A\uFEFF\u200B\u2013\u2014\u0E3F\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45\u0E46\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D\u2122\u0E4F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59\xAE\xA9\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "macturkish": { + "type": "_sbcs", + "chars": "\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC\u2020\xB0\xA2\xA3\xA7\u2022\xB6\xDF\xAE\xA9\u2122\xB4\xA8\u2260\xC6\xD8\u221E\xB1\u2264\u2265\xA5\xB5\u2202\u2211\u220F\u03C0\u222B\xAA\xBA\u2126\xE6\xF8\xBF\xA1\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\xC0\xC3\xD5\u0152\u0153\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\xFF\u0178\u011E\u011F\u0130\u0131\u015E\u015F\u2021\xB7\u201A\u201E\u2030\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4\uFFFD\xD2\xDA\xDB\xD9\uFFFD\u02C6\u02DC\xAF\u02D8\u02D9\u02DA\xB8\u02DD\u02DB\u02C7" + }, + "macukraine": { + "type": "_sbcs", + "chars": "\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u2020\xB0\u0490\xA3\xA7\u2022\xB6\u0406\xAE\xA9\u2122\u0402\u0452\u2260\u0403\u0453\u221E\xB1\u2264\u2265\u0456\xB5\u0491\u0408\u0404\u0454\u0407\u0457\u0409\u0459\u040A\u045A\u0458\u0405\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\u040B\u045B\u040C\u045C\u0455\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u201E\u040E\u045E\u040F\u045F\u2116\u0401\u0451\u044F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\xA4" + }, + "koi8r": { + "type": "_sbcs", + "chars": "\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2580\u2584\u2588\u258C\u2590\u2591\u2592\u2593\u2320\u25A0\u2219\u221A\u2248\u2264\u2265\xA0\u2321\xB0\xB2\xB7\xF7\u2550\u2551\u2552\u0451\u2553\u2554\u2555\u2556\u2557\u2558\u2559\u255A\u255B\u255C\u255D\u255E\u255F\u2560\u2561\u0401\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569\u256A\u256B\u256C\xA9\u044E\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u044F\u0440\u0441\u0442\u0443\u0436\u0432\u044C\u044B\u0437\u0448\u044D\u0449\u0447\u044A\u042E\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u042F\u0420\u0421\u0422\u0423\u0416\u0412\u042C\u042B\u0417\u0428\u042D\u0429\u0427\u042A" + }, + "koi8u": { + "type": "_sbcs", + "chars": "\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2580\u2584\u2588\u258C\u2590\u2591\u2592\u2593\u2320\u25A0\u2219\u221A\u2248\u2264\u2265\xA0\u2321\xB0\xB2\xB7\xF7\u2550\u2551\u2552\u0451\u0454\u2554\u0456\u0457\u2557\u2558\u2559\u255A\u255B\u0491\u255D\u255E\u255F\u2560\u2561\u0401\u0404\u2563\u0406\u0407\u2566\u2567\u2568\u2569\u256A\u0490\u256C\xA9\u044E\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u044F\u0440\u0441\u0442\u0443\u0436\u0432\u044C\u044B\u0437\u0448\u044D\u0449\u0447\u044A\u042E\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u042F\u0420\u0421\u0422\u0423\u0416\u0412\u042C\u042B\u0417\u0428\u042D\u0429\u0427\u042A" + }, + "koi8ru": { + "type": "_sbcs", + "chars": "\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2580\u2584\u2588\u258C\u2590\u2591\u2592\u2593\u2320\u25A0\u2219\u221A\u2248\u2264\u2265\xA0\u2321\xB0\xB2\xB7\xF7\u2550\u2551\u2552\u0451\u0454\u2554\u0456\u0457\u2557\u2558\u2559\u255A\u255B\u0491\u045E\u255E\u255F\u2560\u2561\u0401\u0404\u2563\u0406\u0407\u2566\u2567\u2568\u2569\u256A\u0490\u040E\xA9\u044E\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u044F\u0440\u0441\u0442\u0443\u0436\u0432\u044C\u044B\u0437\u0448\u044D\u0449\u0447\u044A\u042E\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u042F\u0420\u0421\u0422\u0423\u0416\u0412\u042C\u042B\u0417\u0428\u042D\u0429\u0427\u042A" + }, + "koi8t": { + "type": "_sbcs", + "chars": "\u049B\u0493\u201A\u0492\u201E\u2026\u2020\u2021\uFFFD\u2030\u04B3\u2039\u04B2\u04B7\u04B6\uFFFD\u049A\u2018\u2019\u201C\u201D\u2022\u2013\u2014\uFFFD\u2122\uFFFD\u203A\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u04EF\u04EE\u0451\xA4\u04E3\xA6\xA7\uFFFD\uFFFD\uFFFD\xAB\xAC\xAD\xAE\uFFFD\xB0\xB1\xB2\u0401\uFFFD\u04E2\xB6\xB7\uFFFD\u2116\uFFFD\xBB\uFFFD\uFFFD\uFFFD\xA9\u044E\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u044F\u0440\u0441\u0442\u0443\u0436\u0432\u044C\u044B\u0437\u0448\u044D\u0449\u0447\u044A\u042E\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u042F\u0420\u0421\u0422\u0423\u0416\u0412\u042C\u042B\u0417\u0428\u042D\u0429\u0427\u042A" + }, + "armscii8": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\uFFFD\u0587\u0589)(\xBB\xAB\u2014.\u055D,-\u058A\u2026\u055C\u055B\u055E\u0531\u0561\u0532\u0562\u0533\u0563\u0534\u0564\u0535\u0565\u0536\u0566\u0537\u0567\u0538\u0568\u0539\u0569\u053A\u056A\u053B\u056B\u053C\u056C\u053D\u056D\u053E\u056E\u053F\u056F\u0540\u0570\u0541\u0571\u0542\u0572\u0543\u0573\u0544\u0574\u0545\u0575\u0546\u0576\u0547\u0577\u0548\u0578\u0549\u0579\u054A\u057A\u054B\u057B\u054C\u057C\u054D\u057D\u054E\u057E\u054F\u057F\u0550\u0580\u0551\u0581\u0552\u0582\u0553\u0583\u0554\u0584\u0555\u0585\u0556\u0586\u055A\uFFFD" + }, + "rk1048": { + "type": "_sbcs", + "chars": "\u0402\u0403\u201A\u0453\u201E\u2026\u2020\u2021\u20AC\u2030\u0409\u2039\u040A\u049A\u04BA\u040F\u0452\u2018\u2019\u201C\u201D\u2022\u2013\u2014\uFFFD\u2122\u0459\u203A\u045A\u049B\u04BB\u045F\xA0\u04B0\u04B1\u04D8\xA4\u04E8\xA6\xA7\u0401\xA9\u0492\xAB\xAC\xAD\xAE\u04AE\xB0\xB1\u0406\u0456\u04E9\xB5\xB6\xB7\u0451\u2116\u0493\xBB\u04D9\u04A2\u04A3\u04AF\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F" + }, + "tcvn": { + "type": "_sbcs", + "chars": "\0\xDA\u1EE4\u1EEA\u1EEC\u1EEE\x07\b \n\v\f\r\u1EE8\u1EF0\u1EF2\u1EF6\u1EF8\xDD\u1EF4\x1B !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F\xC0\u1EA2\xC3\xC1\u1EA0\u1EB6\u1EAC\xC8\u1EBA\u1EBC\xC9\u1EB8\u1EC6\xCC\u1EC8\u0128\xCD\u1ECA\xD2\u1ECE\xD5\xD3\u1ECC\u1ED8\u1EDC\u1EDE\u1EE0\u1EDA\u1EE2\xD9\u1EE6\u0168\xA0\u0102\xC2\xCA\xD4\u01A0\u01AF\u0110\u0103\xE2\xEA\xF4\u01A1\u01B0\u0111\u1EB0\u0300\u0309\u0303\u0301\u0323\xE0\u1EA3\xE3\xE1\u1EA1\u1EB2\u1EB1\u1EB3\u1EB5\u1EAF\u1EB4\u1EAE\u1EA6\u1EA8\u1EAA\u1EA4\u1EC0\u1EB7\u1EA7\u1EA9\u1EAB\u1EA5\u1EAD\xE8\u1EC2\u1EBB\u1EBD\xE9\u1EB9\u1EC1\u1EC3\u1EC5\u1EBF\u1EC7\xEC\u1EC9\u1EC4\u1EBE\u1ED2\u0129\xED\u1ECB\xF2\u1ED4\u1ECF\xF5\xF3\u1ECD\u1ED3\u1ED5\u1ED7\u1ED1\u1ED9\u1EDD\u1EDF\u1EE1\u1EDB\u1EE3\xF9\u1ED6\u1EE7\u0169\xFA\u1EE5\u1EEB\u1EED\u1EEF\u1EE9\u1EF1\u1EF3\u1EF7\u1EF9\xFD\u1EF5\u1ED0" + }, + "georgianacademy": { + "type": "_sbcs", + "chars": "\x80\x81\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u0152\x8D\x8E\x8F\x90\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\u0161\u203A\u0153\x9D\x9E\u0178\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5\u10D6\u10D7\u10D8\u10D9\u10DA\u10DB\u10DC\u10DD\u10DE\u10DF\u10E0\u10E1\u10E2\u10E3\u10E4\u10E5\u10E6\u10E7\u10E8\u10E9\u10EA\u10EB\u10EC\u10ED\u10EE\u10EF\u10F0\u10F1\u10F2\u10F3\u10F4\u10F5\u10F6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF" + }, + "georgianps": { + "type": "_sbcs", + "chars": "\x80\x81\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u0152\x8D\x8E\x8F\x90\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\u0161\u203A\u0153\x9D\x9E\u0178\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5\u10D6\u10F1\u10D7\u10D8\u10D9\u10DA\u10DB\u10DC\u10F2\u10DD\u10DE\u10DF\u10E0\u10E1\u10E2\u10F3\u10E3\u10E4\u10E5\u10E6\u10E7\u10E8\u10E9\u10EA\u10EB\u10EC\u10ED\u10EE\u10F4\u10EF\u10F0\u10F5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF" + }, + "pt154": { + "type": "_sbcs", + "chars": "\u0496\u0492\u04EE\u0493\u201E\u2026\u04B6\u04AE\u04B2\u04AF\u04A0\u04E2\u04A2\u049A\u04BA\u04B8\u0497\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u04B3\u04B7\u04A1\u04E3\u04A3\u049B\u04BB\u04B9\xA0\u040E\u045E\u0408\u04E8\u0498\u04B0\xA7\u0401\xA9\u04D8\xAB\xAC\u04EF\xAE\u049C\xB0\u04B1\u0406\u0456\u0499\u04E9\xB6\xB7\u0451\u2116\u04D9\xBB\u0458\u04AA\u04AB\u049D\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F" + }, + "viscii": { + "type": "_sbcs", + "chars": "\0\u1EB2\u1EB4\u1EAA\x07\b \n\v\f\r\u1EF6\u1EF8\x1B\u1EF4 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F\u1EA0\u1EAE\u1EB0\u1EB6\u1EA4\u1EA6\u1EA8\u1EAC\u1EBC\u1EB8\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EE2\u1EDA\u1EDC\u1EDE\u1ECA\u1ECE\u1ECC\u1EC8\u1EE6\u0168\u1EE4\u1EF2\xD5\u1EAF\u1EB1\u1EB7\u1EA5\u1EA7\u1EA9\u1EAD\u1EBD\u1EB9\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1ED1\u1ED3\u1ED5\u1ED7\u1EE0\u01A0\u1ED9\u1EDD\u1EDF\u1ECB\u1EF0\u1EE8\u1EEA\u1EEC\u01A1\u1EDB\u01AF\xC0\xC1\xC2\xC3\u1EA2\u0102\u1EB3\u1EB5\xC8\xC9\xCA\u1EBA\xCC\xCD\u0128\u1EF3\u0110\u1EE9\xD2\xD3\xD4\u1EA1\u1EF7\u1EEB\u1EED\xD9\xDA\u1EF9\u1EF5\xDD\u1EE1\u01B0\xE0\xE1\xE2\xE3\u1EA3\u0103\u1EEF\u1EAB\xE8\xE9\xEA\u1EBB\xEC\xED\u0129\u1EC9\u0111\u1EF1\xF2\xF3\xF4\xF5\u1ECF\u1ECD\u1EE5\xF9\xFA\u0169\u1EE7\xFD\u1EE3\u1EEE" + }, + "iso646cn": { + "type": "_sbcs", + "chars": "\0\x07\b \n\v\f\r\x1B !\"#\xA5%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}\u203E\x7F\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "iso646jp": { + "type": "_sbcs", + "chars": "\0\x07\b \n\v\f\r\x1B !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\xA5]^_`abcdefghijklmnopqrstuvwxyz{|}\u203E\x7F\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "hproman8": { + "type": "_sbcs", + "chars": "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xC0\xC2\xC8\xCA\xCB\xCE\xCF\xB4\u02CB\u02C6\xA8\u02DC\xD9\xDB\u20A4\xAF\xDD\xFD\xB0\xC7\xE7\xD1\xF1\xA1\xBF\xA4\xA3\xA5\xA7\u0192\xA2\xE2\xEA\xF4\xFB\xE1\xE9\xF3\xFA\xE0\xE8\xF2\xF9\xE4\xEB\xF6\xFC\xC5\xEE\xD8\xC6\xE5\xED\xF8\xE6\xC4\xEC\xD6\xDC\xC9\xEF\xDF\xD4\xC1\xC3\xE3\xD0\xF0\xCD\xCC\xD3\xD2\xD5\xF5\u0160\u0161\xDA\u0178\xFF\xDE\xFE\xB7\xB5\xB6\xBE\u2014\xBC\xBD\xAA\xBA\xAB\u25A0\xBB\xB1\uFFFD" + }, + "macintosh": { + "type": "_sbcs", + "chars": "\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC\u2020\xB0\xA2\xA3\xA7\u2022\xB6\xDF\xAE\xA9\u2122\xB4\xA8\u2260\xC6\xD8\u221E\xB1\u2264\u2265\xA5\xB5\u2202\u2211\u220F\u03C0\u222B\xAA\xBA\u2126\xE6\xF8\xBF\xA1\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\xC0\xC3\xD5\u0152\u0153\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\xFF\u0178\u2044\xA4\u2039\u203A\uFB01\uFB02\u2021\xB7\u201A\u201E\u2030\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4\uFFFD\xD2\xDA\xDB\xD9\u0131\u02C6\u02DC\xAF\u02D8\u02D9\u02DA\xB8\u02DD\u02DB\u02C7" + }, + "ascii": { + "type": "_sbcs", + "chars": "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "tis620": { + "type": "_sbcs", + "chars": "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0E01\u0E02\u0E03\u0E04\u0E05\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D\u0E2E\u0E2F\u0E30\u0E31\u0E32\u0E33\u0E34\u0E35\u0E36\u0E37\u0E38\u0E39\u0E3A\uFFFD\uFFFD\uFFFD\uFFFD\u0E3F\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45\u0E46\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D\u0E4E\u0E4F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59\u0E5A\u0E5B\uFFFD\uFFFD\uFFFD\uFFFD" + } + }; + } +}); + +// node_modules/iconv-lite/encodings/dbcs-codec.js +var require_dbcs_codec = __commonJS({ + "node_modules/iconv-lite/encodings/dbcs-codec.js"(exports2) { + "use strict"; + var Buffer3 = require_safer().Buffer; + exports2._dbcs = DBCSCodec; + var UNASSIGNED = -1; + var GB18030_CODE = -2; + var SEQ_START = -10; + var NODE_START = -1e3; + var UNASSIGNED_NODE = new Array(256); + var DEF_CHAR = -1; + for (i = 0; i < 256; i++) + UNASSIGNED_NODE[i] = UNASSIGNED; + var i; + function DBCSCodec(codecOptions, iconv) { + this.encodingName = codecOptions.encodingName; + if (!codecOptions) + throw new Error("DBCS codec is called without the data."); + if (!codecOptions.table) + throw new Error("Encoding '" + this.encodingName + "' has no data."); + var mappingTable = codecOptions.table(); + this.decodeTables = []; + this.decodeTables[0] = UNASSIGNED_NODE.slice(0); + this.decodeTableSeq = []; + for (var i2 = 0; i2 < mappingTable.length; i2++) + this._addDecodeChunk(mappingTable[i2]); + this.defaultCharUnicode = iconv.defaultCharUnicode; + this.encodeTable = []; + this.encodeTableSeq = []; + var skipEncodeChars = {}; + if (codecOptions.encodeSkipVals) + for (var i2 = 0; i2 < codecOptions.encodeSkipVals.length; i2++) { + var val = codecOptions.encodeSkipVals[i2]; + if (typeof val === "number") + skipEncodeChars[val] = true; + else + for (var j = val.from; j <= val.to; j++) + skipEncodeChars[j] = true; + } + this._fillEncodeTable(0, 0, skipEncodeChars); + if (codecOptions.encodeAdd) { + for (var uChar in codecOptions.encodeAdd) + if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar)) + this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]); + } + this.defCharSB = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)]; + if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]["?"]; + if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0); + if (typeof codecOptions.gb18030 === "function") { + this.gb18030 = codecOptions.gb18030(); + var thirdByteNodeIdx = this.decodeTables.length; + var thirdByteNode = this.decodeTables[thirdByteNodeIdx] = UNASSIGNED_NODE.slice(0); + var fourthByteNodeIdx = this.decodeTables.length; + var fourthByteNode = this.decodeTables[fourthByteNodeIdx] = UNASSIGNED_NODE.slice(0); + for (var i2 = 129; i2 <= 254; i2++) { + var secondByteNodeIdx = NODE_START - this.decodeTables[0][i2]; + var secondByteNode = this.decodeTables[secondByteNodeIdx]; + for (var j = 48; j <= 57; j++) + secondByteNode[j] = NODE_START - thirdByteNodeIdx; + } + for (var i2 = 129; i2 <= 254; i2++) + thirdByteNode[i2] = NODE_START - fourthByteNodeIdx; + for (var i2 = 48; i2 <= 57; i2++) + fourthByteNode[i2] = GB18030_CODE; + } + } + DBCSCodec.prototype.encoder = DBCSEncoder; + DBCSCodec.prototype.decoder = DBCSDecoder; + DBCSCodec.prototype._getDecodeTrieNode = function(addr) { + var bytes = []; + for (; addr > 0; addr >>= 8) + bytes.push(addr & 255); + if (bytes.length == 0) + bytes.push(0); + var node = this.decodeTables[0]; + for (var i2 = bytes.length - 1; i2 > 0; i2--) { + var val = node[bytes[i2]]; + if (val == UNASSIGNED) { + node[bytes[i2]] = NODE_START - this.decodeTables.length; + this.decodeTables.push(node = UNASSIGNED_NODE.slice(0)); + } else if (val <= NODE_START) { + node = this.decodeTables[NODE_START - val]; + } else + throw new Error("Overwrite byte in " + this.encodingName + ", addr: " + addr.toString(16)); + } + return node; + }; + DBCSCodec.prototype._addDecodeChunk = function(chunk) { + var curAddr = parseInt(chunk[0], 16); + var writeTable = this._getDecodeTrieNode(curAddr); + curAddr = curAddr & 255; + for (var k = 1; k < chunk.length; k++) { + var part = chunk[k]; + if (typeof part === "string") { + for (var l = 0; l < part.length; ) { + var code = part.charCodeAt(l++); + if (55296 <= code && code < 56320) { + var codeTrail = part.charCodeAt(l++); + if (56320 <= codeTrail && codeTrail < 57344) + writeTable[curAddr++] = 65536 + (code - 55296) * 1024 + (codeTrail - 56320); + else + throw new Error("Incorrect surrogate pair in " + this.encodingName + " at chunk " + chunk[0]); + } else if (4080 < code && code <= 4095) { + var len = 4095 - code + 2; + var seq = []; + for (var m = 0; m < len; m++) + seq.push(part.charCodeAt(l++)); + writeTable[curAddr++] = SEQ_START - this.decodeTableSeq.length; + this.decodeTableSeq.push(seq); + } else + writeTable[curAddr++] = code; + } + } else if (typeof part === "number") { + var charCode = writeTable[curAddr - 1] + 1; + for (var l = 0; l < part; l++) + writeTable[curAddr++] = charCode++; + } else + throw new Error("Incorrect type '" + typeof part + "' given in " + this.encodingName + " at chunk " + chunk[0]); + } + if (curAddr > 255) + throw new Error("Incorrect chunk in " + this.encodingName + " at addr " + chunk[0] + ": too long" + curAddr); + }; + DBCSCodec.prototype._getEncodeBucket = function(uCode) { + var high = uCode >> 8; + if (this.encodeTable[high] === void 0) + this.encodeTable[high] = UNASSIGNED_NODE.slice(0); + return this.encodeTable[high]; + }; + DBCSCodec.prototype._setEncodeChar = function(uCode, dbcsCode) { + var bucket = this._getEncodeBucket(uCode); + var low = uCode & 255; + if (bucket[low] <= SEQ_START) + this.encodeTableSeq[SEQ_START - bucket[low]][DEF_CHAR] = dbcsCode; + else if (bucket[low] == UNASSIGNED) + bucket[low] = dbcsCode; + }; + DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) { + var uCode = seq[0]; + var bucket = this._getEncodeBucket(uCode); + var low = uCode & 255; + var node; + if (bucket[low] <= SEQ_START) { + node = this.encodeTableSeq[SEQ_START - bucket[low]]; + } else { + node = {}; + if (bucket[low] !== UNASSIGNED) node[DEF_CHAR] = bucket[low]; + bucket[low] = SEQ_START - this.encodeTableSeq.length; + this.encodeTableSeq.push(node); + } + for (var j = 1; j < seq.length - 1; j++) { + var oldVal = node[uCode]; + if (typeof oldVal === "object") + node = oldVal; + else { + node = node[uCode] = {}; + if (oldVal !== void 0) + node[DEF_CHAR] = oldVal; + } + } + uCode = seq[seq.length - 1]; + node[uCode] = dbcsCode; + }; + DBCSCodec.prototype._fillEncodeTable = function(nodeIdx, prefix, skipEncodeChars) { + var node = this.decodeTables[nodeIdx]; + for (var i2 = 0; i2 < 256; i2++) { + var uCode = node[i2]; + var mbCode = prefix + i2; + if (skipEncodeChars[mbCode]) + continue; + if (uCode >= 0) + this._setEncodeChar(uCode, mbCode); + else if (uCode <= NODE_START) + this._fillEncodeTable(NODE_START - uCode, mbCode << 8, skipEncodeChars); + else if (uCode <= SEQ_START) + this._setEncodeSequence(this.decodeTableSeq[SEQ_START - uCode], mbCode); + } + }; + function DBCSEncoder(options, codec) { + this.leadSurrogate = -1; + this.seqObj = void 0; + this.encodeTable = codec.encodeTable; + this.encodeTableSeq = codec.encodeTableSeq; + this.defaultCharSingleByte = codec.defCharSB; + this.gb18030 = codec.gb18030; + } + DBCSEncoder.prototype.write = function(str) { + var newBuf = Buffer3.alloc(str.length * (this.gb18030 ? 4 : 3)), leadSurrogate = this.leadSurrogate, seqObj = this.seqObj, nextChar = -1, i2 = 0, j = 0; + while (true) { + if (nextChar === -1) { + if (i2 == str.length) break; + var uCode = str.charCodeAt(i2++); + } else { + var uCode = nextChar; + nextChar = -1; + } + if (55296 <= uCode && uCode < 57344) { + if (uCode < 56320) { + if (leadSurrogate === -1) { + leadSurrogate = uCode; + continue; + } else { + leadSurrogate = uCode; + uCode = UNASSIGNED; + } + } else { + if (leadSurrogate !== -1) { + uCode = 65536 + (leadSurrogate - 55296) * 1024 + (uCode - 56320); + leadSurrogate = -1; + } else { + uCode = UNASSIGNED; + } + } + } else if (leadSurrogate !== -1) { + nextChar = uCode; + uCode = UNASSIGNED; + leadSurrogate = -1; + } + var dbcsCode = UNASSIGNED; + if (seqObj !== void 0 && uCode != UNASSIGNED) { + var resCode = seqObj[uCode]; + if (typeof resCode === "object") { + seqObj = resCode; + continue; + } else if (typeof resCode == "number") { + dbcsCode = resCode; + } else if (resCode == void 0) { + resCode = seqObj[DEF_CHAR]; + if (resCode !== void 0) { + dbcsCode = resCode; + nextChar = uCode; + } else { + } + } + seqObj = void 0; + } else if (uCode >= 0) { + var subtable = this.encodeTable[uCode >> 8]; + if (subtable !== void 0) + dbcsCode = subtable[uCode & 255]; + if (dbcsCode <= SEQ_START) { + seqObj = this.encodeTableSeq[SEQ_START - dbcsCode]; + continue; + } + if (dbcsCode == UNASSIGNED && this.gb18030) { + var idx = findIdx(this.gb18030.uChars, uCode); + if (idx != -1) { + var dbcsCode = this.gb18030.gbChars[idx] + (uCode - this.gb18030.uChars[idx]); + newBuf[j++] = 129 + Math.floor(dbcsCode / 12600); + dbcsCode = dbcsCode % 12600; + newBuf[j++] = 48 + Math.floor(dbcsCode / 1260); + dbcsCode = dbcsCode % 1260; + newBuf[j++] = 129 + Math.floor(dbcsCode / 10); + dbcsCode = dbcsCode % 10; + newBuf[j++] = 48 + dbcsCode; + continue; + } + } + } + if (dbcsCode === UNASSIGNED) + dbcsCode = this.defaultCharSingleByte; + if (dbcsCode < 256) { + newBuf[j++] = dbcsCode; + } else if (dbcsCode < 65536) { + newBuf[j++] = dbcsCode >> 8; + newBuf[j++] = dbcsCode & 255; + } else { + newBuf[j++] = dbcsCode >> 16; + newBuf[j++] = dbcsCode >> 8 & 255; + newBuf[j++] = dbcsCode & 255; + } + } + this.seqObj = seqObj; + this.leadSurrogate = leadSurrogate; + return newBuf.slice(0, j); + }; + DBCSEncoder.prototype.end = function() { + if (this.leadSurrogate === -1 && this.seqObj === void 0) + return; + var newBuf = Buffer3.alloc(10), j = 0; + if (this.seqObj) { + var dbcsCode = this.seqObj[DEF_CHAR]; + if (dbcsCode !== void 0) { + if (dbcsCode < 256) { + newBuf[j++] = dbcsCode; + } else { + newBuf[j++] = dbcsCode >> 8; + newBuf[j++] = dbcsCode & 255; + } + } else { + } + this.seqObj = void 0; + } + if (this.leadSurrogate !== -1) { + newBuf[j++] = this.defaultCharSingleByte; + this.leadSurrogate = -1; + } + return newBuf.slice(0, j); + }; + DBCSEncoder.prototype.findIdx = findIdx; + function DBCSDecoder(options, codec) { + this.nodeIdx = 0; + this.prevBuf = Buffer3.alloc(0); + this.decodeTables = codec.decodeTables; + this.decodeTableSeq = codec.decodeTableSeq; + this.defaultCharUnicode = codec.defaultCharUnicode; + this.gb18030 = codec.gb18030; + } + DBCSDecoder.prototype.write = function(buf) { + var newBuf = Buffer3.alloc(buf.length * 2), nodeIdx = this.nodeIdx, prevBuf = this.prevBuf, prevBufOffset = this.prevBuf.length, seqStart = -this.prevBuf.length, uCode; + if (prevBufOffset > 0) + prevBuf = Buffer3.concat([prevBuf, buf.slice(0, 10)]); + for (var i2 = 0, j = 0; i2 < buf.length; i2++) { + var curByte = i2 >= 0 ? buf[i2] : prevBuf[i2 + prevBufOffset]; + var uCode = this.decodeTables[nodeIdx][curByte]; + if (uCode >= 0) { + } else if (uCode === UNASSIGNED) { + i2 = seqStart; + uCode = this.defaultCharUnicode.charCodeAt(0); + } else if (uCode === GB18030_CODE) { + var curSeq = seqStart >= 0 ? buf.slice(seqStart, i2 + 1) : prevBuf.slice(seqStart + prevBufOffset, i2 + 1 + prevBufOffset); + var ptr = (curSeq[0] - 129) * 12600 + (curSeq[1] - 48) * 1260 + (curSeq[2] - 129) * 10 + (curSeq[3] - 48); + var idx = findIdx(this.gb18030.gbChars, ptr); + uCode = this.gb18030.uChars[idx] + ptr - this.gb18030.gbChars[idx]; + } else if (uCode <= NODE_START) { + nodeIdx = NODE_START - uCode; + continue; + } else if (uCode <= SEQ_START) { + var seq = this.decodeTableSeq[SEQ_START - uCode]; + for (var k = 0; k < seq.length - 1; k++) { + uCode = seq[k]; + newBuf[j++] = uCode & 255; + newBuf[j++] = uCode >> 8; + } + uCode = seq[seq.length - 1]; + } else + throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte); + if (uCode > 65535) { + uCode -= 65536; + var uCodeLead = 55296 + Math.floor(uCode / 1024); + newBuf[j++] = uCodeLead & 255; + newBuf[j++] = uCodeLead >> 8; + uCode = 56320 + uCode % 1024; + } + newBuf[j++] = uCode & 255; + newBuf[j++] = uCode >> 8; + nodeIdx = 0; + seqStart = i2 + 1; + } + this.nodeIdx = nodeIdx; + this.prevBuf = seqStart >= 0 ? buf.slice(seqStart) : prevBuf.slice(seqStart + prevBufOffset); + return newBuf.slice(0, j).toString("ucs2"); + }; + DBCSDecoder.prototype.end = function() { + var ret = ""; + while (this.prevBuf.length > 0) { + ret += this.defaultCharUnicode; + var buf = this.prevBuf.slice(1); + this.prevBuf = Buffer3.alloc(0); + this.nodeIdx = 0; + if (buf.length > 0) + ret += this.write(buf); + } + this.nodeIdx = 0; + return ret; + }; + function findIdx(table, val) { + if (table[0] > val) + return -1; + var l = 0, r = table.length; + while (l < r - 1) { + var mid = l + Math.floor((r - l + 1) / 2); + if (table[mid] <= val) + l = mid; + else + r = mid; + } + return l; + } + } +}); + +// node_modules/iconv-lite/encodings/tables/shiftjis.json +var require_shiftjis = __commonJS({ + "node_modules/iconv-lite/encodings/tables/shiftjis.json"(exports2, module2) { + module2.exports = [ + ["0", "\0", 128], + ["a1", "\uFF61", 62], + ["8140", "\u3000\u3001\u3002\uFF0C\uFF0E\u30FB\uFF1A\uFF1B\uFF1F\uFF01\u309B\u309C\xB4\uFF40\xA8\uFF3E\uFFE3\uFF3F\u30FD\u30FE\u309D\u309E\u3003\u4EDD\u3005\u3006\u3007\u30FC\u2015\u2010\uFF0F\uFF3C\uFF5E\u2225\uFF5C\u2026\u2025\u2018\u2019\u201C\u201D\uFF08\uFF09\u3014\u3015\uFF3B\uFF3D\uFF5B\uFF5D\u3008", 9, "\uFF0B\uFF0D\xB1\xD7"], + ["8180", "\xF7\uFF1D\u2260\uFF1C\uFF1E\u2266\u2267\u221E\u2234\u2642\u2640\xB0\u2032\u2033\u2103\uFFE5\uFF04\uFFE0\uFFE1\uFF05\uFF03\uFF06\uFF0A\uFF20\xA7\u2606\u2605\u25CB\u25CF\u25CE\u25C7\u25C6\u25A1\u25A0\u25B3\u25B2\u25BD\u25BC\u203B\u3012\u2192\u2190\u2191\u2193\u3013"], + ["81b8", "\u2208\u220B\u2286\u2287\u2282\u2283\u222A\u2229"], + ["81c8", "\u2227\u2228\uFFE2\u21D2\u21D4\u2200\u2203"], + ["81da", "\u2220\u22A5\u2312\u2202\u2207\u2261\u2252\u226A\u226B\u221A\u223D\u221D\u2235\u222B\u222C"], + ["81f0", "\u212B\u2030\u266F\u266D\u266A\u2020\u2021\xB6"], + ["81fc", "\u25EF"], + ["824f", "\uFF10", 9], + ["8260", "\uFF21", 25], + ["8281", "\uFF41", 25], + ["829f", "\u3041", 82], + ["8340", "\u30A1", 62], + ["8380", "\u30E0", 22], + ["839f", "\u0391", 16, "\u03A3", 6], + ["83bf", "\u03B1", 16, "\u03C3", 6], + ["8440", "\u0410", 5, "\u0401\u0416", 25], + ["8470", "\u0430", 5, "\u0451\u0436", 7], + ["8480", "\u043E", 17], + ["849f", "\u2500\u2502\u250C\u2510\u2518\u2514\u251C\u252C\u2524\u2534\u253C\u2501\u2503\u250F\u2513\u251B\u2517\u2523\u2533\u252B\u253B\u254B\u2520\u252F\u2528\u2537\u253F\u251D\u2530\u2525\u2538\u2542"], + ["8740", "\u2460", 19, "\u2160", 9], + ["875f", "\u3349\u3314\u3322\u334D\u3318\u3327\u3303\u3336\u3351\u3357\u330D\u3326\u3323\u332B\u334A\u333B\u339C\u339D\u339E\u338E\u338F\u33C4\u33A1"], + ["877e", "\u337B"], + ["8780", "\u301D\u301F\u2116\u33CD\u2121\u32A4", 4, "\u3231\u3232\u3239\u337E\u337D\u337C\u2252\u2261\u222B\u222E\u2211\u221A\u22A5\u2220\u221F\u22BF\u2235\u2229\u222A"], + ["889f", "\u4E9C\u5516\u5A03\u963F\u54C0\u611B\u6328\u59F6\u9022\u8475\u831C\u7A50\u60AA\u63E1\u6E25\u65ED\u8466\u82A6\u9BF5\u6893\u5727\u65A1\u6271\u5B9B\u59D0\u867B\u98F4\u7D62\u7DBE\u9B8E\u6216\u7C9F\u88B7\u5B89\u5EB5\u6309\u6697\u6848\u95C7\u978D\u674F\u4EE5\u4F0A\u4F4D\u4F9D\u5049\u56F2\u5937\u59D4\u5A01\u5C09\u60DF\u610F\u6170\u6613\u6905\u70BA\u754F\u7570\u79FB\u7DAD\u7DEF\u80C3\u840E\u8863\u8B02\u9055\u907A\u533B\u4E95\u4EA5\u57DF\u80B2\u90C1\u78EF\u4E00\u58F1\u6EA2\u9038\u7A32\u8328\u828B\u9C2F\u5141\u5370\u54BD\u54E1\u56E0\u59FB\u5F15\u98F2\u6DEB\u80E4\u852D"], + ["8940", "\u9662\u9670\u96A0\u97FB\u540B\u53F3\u5B87\u70CF\u7FBD\u8FC2\u96E8\u536F\u9D5C\u7ABA\u4E11\u7893\u81FC\u6E26\u5618\u5504\u6B1D\u851A\u9C3B\u59E5\u53A9\u6D66\u74DC\u958F\u5642\u4E91\u904B\u96F2\u834F\u990C\u53E1\u55B6\u5B30\u5F71\u6620\u66F3\u6804\u6C38\u6CF3\u6D29\u745B\u76C8\u7A4E\u9834\u82F1\u885B\u8A60\u92ED\u6DB2\u75AB\u76CA\u99C5\u60A6\u8B01\u8D8A\u95B2\u698E\u53AD\u5186"], + ["8980", "\u5712\u5830\u5944\u5BB4\u5EF6\u6028\u63A9\u63F4\u6CBF\u6F14\u708E\u7114\u7159\u71D5\u733F\u7E01\u8276\u82D1\u8597\u9060\u925B\u9D1B\u5869\u65BC\u6C5A\u7525\u51F9\u592E\u5965\u5F80\u5FDC\u62BC\u65FA\u6A2A\u6B27\u6BB4\u738B\u7FC1\u8956\u9D2C\u9D0E\u9EC4\u5CA1\u6C96\u837B\u5104\u5C4B\u61B6\u81C6\u6876\u7261\u4E59\u4FFA\u5378\u6069\u6E29\u7A4F\u97F3\u4E0B\u5316\u4EEE\u4F55\u4F3D\u4FA1\u4F73\u52A0\u53EF\u5609\u590F\u5AC1\u5BB6\u5BE1\u79D1\u6687\u679C\u67B6\u6B4C\u6CB3\u706B\u73C2\u798D\u79BE\u7A3C\u7B87\u82B1\u82DB\u8304\u8377\u83EF\u83D3\u8766\u8AB2\u5629\u8CA8\u8FE6\u904E\u971E\u868A\u4FC4\u5CE8\u6211\u7259\u753B\u81E5\u82BD\u86FE\u8CC0\u96C5\u9913\u99D5\u4ECB\u4F1A\u89E3\u56DE\u584A\u58CA\u5EFB\u5FEB\u602A\u6094\u6062\u61D0\u6212\u62D0\u6539"], + ["8a40", "\u9B41\u6666\u68B0\u6D77\u7070\u754C\u7686\u7D75\u82A5\u87F9\u958B\u968E\u8C9D\u51F1\u52BE\u5916\u54B3\u5BB3\u5D16\u6168\u6982\u6DAF\u788D\u84CB\u8857\u8A72\u93A7\u9AB8\u6D6C\u99A8\u86D9\u57A3\u67FF\u86CE\u920E\u5283\u5687\u5404\u5ED3\u62E1\u64B9\u683C\u6838\u6BBB\u7372\u78BA\u7A6B\u899A\u89D2\u8D6B\u8F03\u90ED\u95A3\u9694\u9769\u5B66\u5CB3\u697D\u984D\u984E\u639B\u7B20\u6A2B"], + ["8a80", "\u6A7F\u68B6\u9C0D\u6F5F\u5272\u559D\u6070\u62EC\u6D3B\u6E07\u6ED1\u845B\u8910\u8F44\u4E14\u9C39\u53F6\u691B\u6A3A\u9784\u682A\u515C\u7AC3\u84B2\u91DC\u938C\u565B\u9D28\u6822\u8305\u8431\u7CA5\u5208\u82C5\u74E6\u4E7E\u4F83\u51A0\u5BD2\u520A\u52D8\u52E7\u5DFB\u559A\u582A\u59E6\u5B8C\u5B98\u5BDB\u5E72\u5E79\u60A3\u611F\u6163\u61BE\u63DB\u6562\u67D1\u6853\u68FA\u6B3E\u6B53\u6C57\u6F22\u6F97\u6F45\u74B0\u7518\u76E3\u770B\u7AFF\u7BA1\u7C21\u7DE9\u7F36\u7FF0\u809D\u8266\u839E\u89B3\u8ACC\u8CAB\u9084\u9451\u9593\u9591\u95A2\u9665\u97D3\u9928\u8218\u4E38\u542B\u5CB8\u5DCC\u73A9\u764C\u773C\u5CA9\u7FEB\u8D0B\u96C1\u9811\u9854\u9858\u4F01\u4F0E\u5371\u559C\u5668\u57FA\u5947\u5B09\u5BC4\u5C90\u5E0C\u5E7E\u5FCC\u63EE\u673A\u65D7\u65E2\u671F\u68CB\u68C4"], + ["8b40", "\u6A5F\u5E30\u6BC5\u6C17\u6C7D\u757F\u7948\u5B63\u7A00\u7D00\u5FBD\u898F\u8A18\u8CB4\u8D77\u8ECC\u8F1D\u98E2\u9A0E\u9B3C\u4E80\u507D\u5100\u5993\u5B9C\u622F\u6280\u64EC\u6B3A\u72A0\u7591\u7947\u7FA9\u87FB\u8ABC\u8B70\u63AC\u83CA\u97A0\u5409\u5403\u55AB\u6854\u6A58\u8A70\u7827\u6775\u9ECD\u5374\u5BA2\u811A\u8650\u9006\u4E18\u4E45\u4EC7\u4F11\u53CA\u5438\u5BAE\u5F13\u6025\u6551"], + ["8b80", "\u673D\u6C42\u6C72\u6CE3\u7078\u7403\u7A76\u7AAE\u7B08\u7D1A\u7CFE\u7D66\u65E7\u725B\u53BB\u5C45\u5DE8\u62D2\u62E0\u6319\u6E20\u865A\u8A31\u8DDD\u92F8\u6F01\u79A6\u9B5A\u4EA8\u4EAB\u4EAC\u4F9B\u4FA0\u50D1\u5147\u7AF6\u5171\u51F6\u5354\u5321\u537F\u53EB\u55AC\u5883\u5CE1\u5F37\u5F4A\u602F\u6050\u606D\u631F\u6559\u6A4B\u6CC1\u72C2\u72ED\u77EF\u80F8\u8105\u8208\u854E\u90F7\u93E1\u97FF\u9957\u9A5A\u4EF0\u51DD\u5C2D\u6681\u696D\u5C40\u66F2\u6975\u7389\u6850\u7C81\u50C5\u52E4\u5747\u5DFE\u9326\u65A4\u6B23\u6B3D\u7434\u7981\u79BD\u7B4B\u7DCA\u82B9\u83CC\u887F\u895F\u8B39\u8FD1\u91D1\u541F\u9280\u4E5D\u5036\u53E5\u533A\u72D7\u7396\u77E9\u82E6\u8EAF\u99C6\u99C8\u99D2\u5177\u611A\u865E\u55B0\u7A7A\u5076\u5BD3\u9047\u9685\u4E32\u6ADB\u91E7\u5C51\u5C48"], + ["8c40", "\u6398\u7A9F\u6C93\u9774\u8F61\u7AAA\u718A\u9688\u7C82\u6817\u7E70\u6851\u936C\u52F2\u541B\u85AB\u8A13\u7FA4\u8ECD\u90E1\u5366\u8888\u7941\u4FC2\u50BE\u5211\u5144\u5553\u572D\u73EA\u578B\u5951\u5F62\u5F84\u6075\u6176\u6167\u61A9\u63B2\u643A\u656C\u666F\u6842\u6E13\u7566\u7A3D\u7CFB\u7D4C\u7D99\u7E4B\u7F6B\u830E\u834A\u86CD\u8A08\u8A63\u8B66\u8EFD\u981A\u9D8F\u82B8\u8FCE\u9BE8"], + ["8c80", "\u5287\u621F\u6483\u6FC0\u9699\u6841\u5091\u6B20\u6C7A\u6F54\u7A74\u7D50\u8840\u8A23\u6708\u4EF6\u5039\u5026\u5065\u517C\u5238\u5263\u55A7\u570F\u5805\u5ACC\u5EFA\u61B2\u61F8\u62F3\u6372\u691C\u6A29\u727D\u72AC\u732E\u7814\u786F\u7D79\u770C\u80A9\u898B\u8B19\u8CE2\u8ED2\u9063\u9375\u967A\u9855\u9A13\u9E78\u5143\u539F\u53B3\u5E7B\u5F26\u6E1B\u6E90\u7384\u73FE\u7D43\u8237\u8A00\u8AFA\u9650\u4E4E\u500B\u53E4\u547C\u56FA\u59D1\u5B64\u5DF1\u5EAB\u5F27\u6238\u6545\u67AF\u6E56\u72D0\u7CCA\u88B4\u80A1\u80E1\u83F0\u864E\u8A87\u8DE8\u9237\u96C7\u9867\u9F13\u4E94\u4E92\u4F0D\u5348\u5449\u543E\u5A2F\u5F8C\u5FA1\u609F\u68A7\u6A8E\u745A\u7881\u8A9E\u8AA4\u8B77\u9190\u4E5E\u9BC9\u4EA4\u4F7C\u4FAF\u5019\u5016\u5149\u516C\u529F\u52B9\u52FE\u539A\u53E3\u5411"], + ["8d40", "\u540E\u5589\u5751\u57A2\u597D\u5B54\u5B5D\u5B8F\u5DE5\u5DE7\u5DF7\u5E78\u5E83\u5E9A\u5EB7\u5F18\u6052\u614C\u6297\u62D8\u63A7\u653B\u6602\u6643\u66F4\u676D\u6821\u6897\u69CB\u6C5F\u6D2A\u6D69\u6E2F\u6E9D\u7532\u7687\u786C\u7A3F\u7CE0\u7D05\u7D18\u7D5E\u7DB1\u8015\u8003\u80AF\u80B1\u8154\u818F\u822A\u8352\u884C\u8861\u8B1B\u8CA2\u8CFC\u90CA\u9175\u9271\u783F\u92FC\u95A4\u964D"], + ["8d80", "\u9805\u9999\u9AD8\u9D3B\u525B\u52AB\u53F7\u5408\u58D5\u62F7\u6FE0\u8C6A\u8F5F\u9EB9\u514B\u523B\u544A\u56FD\u7A40\u9177\u9D60\u9ED2\u7344\u6F09\u8170\u7511\u5FFD\u60DA\u9AA8\u72DB\u8FBC\u6B64\u9803\u4ECA\u56F0\u5764\u58BE\u5A5A\u6068\u61C7\u660F\u6606\u6839\u68B1\u6DF7\u75D5\u7D3A\u826E\u9B42\u4E9B\u4F50\u53C9\u5506\u5D6F\u5DE6\u5DEE\u67FB\u6C99\u7473\u7802\u8A50\u9396\u88DF\u5750\u5EA7\u632B\u50B5\u50AC\u518D\u6700\u54C9\u585E\u59BB\u5BB0\u5F69\u624D\u63A1\u683D\u6B73\u6E08\u707D\u91C7\u7280\u7815\u7826\u796D\u658E\u7D30\u83DC\u88C1\u8F09\u969B\u5264\u5728\u6750\u7F6A\u8CA1\u51B4\u5742\u962A\u583A\u698A\u80B4\u54B2\u5D0E\u57FC\u7895\u9DFA\u4F5C\u524A\u548B\u643E\u6628\u6714\u67F5\u7A84\u7B56\u7D22\u932F\u685C\u9BAD\u7B39\u5319\u518A\u5237"], + ["8e40", "\u5BDF\u62F6\u64AE\u64E6\u672D\u6BBA\u85A9\u96D1\u7690\u9BD6\u634C\u9306\u9BAB\u76BF\u6652\u4E09\u5098\u53C2\u5C71\u60E8\u6492\u6563\u685F\u71E6\u73CA\u7523\u7B97\u7E82\u8695\u8B83\u8CDB\u9178\u9910\u65AC\u66AB\u6B8B\u4ED5\u4ED4\u4F3A\u4F7F\u523A\u53F8\u53F2\u55E3\u56DB\u58EB\u59CB\u59C9\u59FF\u5B50\u5C4D\u5E02\u5E2B\u5FD7\u601D\u6307\u652F\u5B5C\u65AF\u65BD\u65E8\u679D\u6B62"], + ["8e80", "\u6B7B\u6C0F\u7345\u7949\u79C1\u7CF8\u7D19\u7D2B\u80A2\u8102\u81F3\u8996\u8A5E\u8A69\u8A66\u8A8C\u8AEE\u8CC7\u8CDC\u96CC\u98FC\u6B6F\u4E8B\u4F3C\u4F8D\u5150\u5B57\u5BFA\u6148\u6301\u6642\u6B21\u6ECB\u6CBB\u723E\u74BD\u75D4\u78C1\u793A\u800C\u8033\u81EA\u8494\u8F9E\u6C50\u9E7F\u5F0F\u8B58\u9D2B\u7AFA\u8EF8\u5B8D\u96EB\u4E03\u53F1\u57F7\u5931\u5AC9\u5BA4\u6089\u6E7F\u6F06\u75BE\u8CEA\u5B9F\u8500\u7BE0\u5072\u67F4\u829D\u5C61\u854A\u7E1E\u820E\u5199\u5C04\u6368\u8D66\u659C\u716E\u793E\u7D17\u8005\u8B1D\u8ECA\u906E\u86C7\u90AA\u501F\u52FA\u5C3A\u6753\u707C\u7235\u914C\u91C8\u932B\u82E5\u5BC2\u5F31\u60F9\u4E3B\u53D6\u5B88\u624B\u6731\u6B8A\u72E9\u73E0\u7A2E\u816B\u8DA3\u9152\u9996\u5112\u53D7\u546A\u5BFF\u6388\u6A39\u7DAC\u9700\u56DA\u53CE\u5468"], + ["8f40", "\u5B97\u5C31\u5DDE\u4FEE\u6101\u62FE\u6D32\u79C0\u79CB\u7D42\u7E4D\u7FD2\u81ED\u821F\u8490\u8846\u8972\u8B90\u8E74\u8F2F\u9031\u914B\u916C\u96C6\u919C\u4EC0\u4F4F\u5145\u5341\u5F93\u620E\u67D4\u6C41\u6E0B\u7363\u7E26\u91CD\u9283\u53D4\u5919\u5BBF\u6DD1\u795D\u7E2E\u7C9B\u587E\u719F\u51FA\u8853\u8FF0\u4FCA\u5CFB\u6625\u77AC\u7AE3\u821C\u99FF\u51C6\u5FAA\u65EC\u696F\u6B89\u6DF3"], + ["8f80", "\u6E96\u6F64\u76FE\u7D14\u5DE1\u9075\u9187\u9806\u51E6\u521D\u6240\u6691\u66D9\u6E1A\u5EB6\u7DD2\u7F72\u66F8\u85AF\u85F7\u8AF8\u52A9\u53D9\u5973\u5E8F\u5F90\u6055\u92E4\u9664\u50B7\u511F\u52DD\u5320\u5347\u53EC\u54E8\u5546\u5531\u5617\u5968\u59BE\u5A3C\u5BB5\u5C06\u5C0F\u5C11\u5C1A\u5E84\u5E8A\u5EE0\u5F70\u627F\u6284\u62DB\u638C\u6377\u6607\u660C\u662D\u6676\u677E\u68A2\u6A1F\u6A35\u6CBC\u6D88\u6E09\u6E58\u713C\u7126\u7167\u75C7\u7701\u785D\u7901\u7965\u79F0\u7AE0\u7B11\u7CA7\u7D39\u8096\u83D6\u848B\u8549\u885D\u88F3\u8A1F\u8A3C\u8A54\u8A73\u8C61\u8CDE\u91A4\u9266\u937E\u9418\u969C\u9798\u4E0A\u4E08\u4E1E\u4E57\u5197\u5270\u57CE\u5834\u58CC\u5B22\u5E38\u60C5\u64FE\u6761\u6756\u6D44\u72B6\u7573\u7A63\u84B8\u8B72\u91B8\u9320\u5631\u57F4\u98FE"], + ["9040", "\u62ED\u690D\u6B96\u71ED\u7E54\u8077\u8272\u89E6\u98DF\u8755\u8FB1\u5C3B\u4F38\u4FE1\u4FB5\u5507\u5A20\u5BDD\u5BE9\u5FC3\u614E\u632F\u65B0\u664B\u68EE\u699B\u6D78\u6DF1\u7533\u75B9\u771F\u795E\u79E6\u7D33\u81E3\u82AF\u85AA\u89AA\u8A3A\u8EAB\u8F9B\u9032\u91DD\u9707\u4EBA\u4EC1\u5203\u5875\u58EC\u5C0B\u751A\u5C3D\u814E\u8A0A\u8FC5\u9663\u976D\u7B25\u8ACF\u9808\u9162\u56F3\u53A8"], + ["9080", "\u9017\u5439\u5782\u5E25\u63A8\u6C34\u708A\u7761\u7C8B\u7FE0\u8870\u9042\u9154\u9310\u9318\u968F\u745E\u9AC4\u5D07\u5D69\u6570\u67A2\u8DA8\u96DB\u636E\u6749\u6919\u83C5\u9817\u96C0\u88FE\u6F84\u647A\u5BF8\u4E16\u702C\u755D\u662F\u51C4\u5236\u52E2\u59D3\u5F81\u6027\u6210\u653F\u6574\u661F\u6674\u68F2\u6816\u6B63\u6E05\u7272\u751F\u76DB\u7CBE\u8056\u58F0\u88FD\u897F\u8AA0\u8A93\u8ACB\u901D\u9192\u9752\u9759\u6589\u7A0E\u8106\u96BB\u5E2D\u60DC\u621A\u65A5\u6614\u6790\u77F3\u7A4D\u7C4D\u7E3E\u810A\u8CAC\u8D64\u8DE1\u8E5F\u78A9\u5207\u62D9\u63A5\u6442\u6298\u8A2D\u7A83\u7BC0\u8AAC\u96EA\u7D76\u820C\u8749\u4ED9\u5148\u5343\u5360\u5BA3\u5C02\u5C16\u5DDD\u6226\u6247\u64B0\u6813\u6834\u6CC9\u6D45\u6D17\u67D3\u6F5C\u714E\u717D\u65CB\u7A7F\u7BAD\u7DDA"], + ["9140", "\u7E4A\u7FA8\u817A\u821B\u8239\u85A6\u8A6E\u8CCE\u8DF5\u9078\u9077\u92AD\u9291\u9583\u9BAE\u524D\u5584\u6F38\u7136\u5168\u7985\u7E55\u81B3\u7CCE\u564C\u5851\u5CA8\u63AA\u66FE\u66FD\u695A\u72D9\u758F\u758E\u790E\u7956\u79DF\u7C97\u7D20\u7D44\u8607\u8A34\u963B\u9061\u9F20\u50E7\u5275\u53CC\u53E2\u5009\u55AA\u58EE\u594F\u723D\u5B8B\u5C64\u531D\u60E3\u60F3\u635C\u6383\u633F\u63BB"], + ["9180", "\u64CD\u65E9\u66F9\u5DE3\u69CD\u69FD\u6F15\u71E5\u4E89\u75E9\u76F8\u7A93\u7CDF\u7DCF\u7D9C\u8061\u8349\u8358\u846C\u84BC\u85FB\u88C5\u8D70\u9001\u906D\u9397\u971C\u9A12\u50CF\u5897\u618E\u81D3\u8535\u8D08\u9020\u4FC3\u5074\u5247\u5373\u606F\u6349\u675F\u6E2C\u8DB3\u901F\u4FD7\u5C5E\u8CCA\u65CF\u7D9A\u5352\u8896\u5176\u63C3\u5B58\u5B6B\u5C0A\u640D\u6751\u905C\u4ED6\u591A\u592A\u6C70\u8A51\u553E\u5815\u59A5\u60F0\u6253\u67C1\u8235\u6955\u9640\u99C4\u9A28\u4F53\u5806\u5BFE\u8010\u5CB1\u5E2F\u5F85\u6020\u614B\u6234\u66FF\u6CF0\u6EDE\u80CE\u817F\u82D4\u888B\u8CB8\u9000\u902E\u968A\u9EDB\u9BDB\u4EE3\u53F0\u5927\u7B2C\u918D\u984C\u9DF9\u6EDD\u7027\u5353\u5544\u5B85\u6258\u629E\u62D3\u6CA2\u6FEF\u7422\u8A17\u9438\u6FC1\u8AFE\u8338\u51E7\u86F8\u53EA"], + ["9240", "\u53E9\u4F46\u9054\u8FB0\u596A\u8131\u5DFD\u7AEA\u8FBF\u68DA\u8C37\u72F8\u9C48\u6A3D\u8AB0\u4E39\u5358\u5606\u5766\u62C5\u63A2\u65E6\u6B4E\u6DE1\u6E5B\u70AD\u77ED\u7AEF\u7BAA\u7DBB\u803D\u80C6\u86CB\u8A95\u935B\u56E3\u58C7\u5F3E\u65AD\u6696\u6A80\u6BB5\u7537\u8AC7\u5024\u77E5\u5730\u5F1B\u6065\u667A\u6C60\u75F4\u7A1A\u7F6E\u81F4\u8718\u9045\u99B3\u7BC9\u755C\u7AF9\u7B51\u84C4"], + ["9280", "\u9010\u79E9\u7A92\u8336\u5AE1\u7740\u4E2D\u4EF2\u5B99\u5FE0\u62BD\u663C\u67F1\u6CE8\u866B\u8877\u8A3B\u914E\u92F3\u99D0\u6A17\u7026\u732A\u82E7\u8457\u8CAF\u4E01\u5146\u51CB\u558B\u5BF5\u5E16\u5E33\u5E81\u5F14\u5F35\u5F6B\u5FB4\u61F2\u6311\u66A2\u671D\u6F6E\u7252\u753A\u773A\u8074\u8139\u8178\u8776\u8ABF\u8ADC\u8D85\u8DF3\u929A\u9577\u9802\u9CE5\u52C5\u6357\u76F4\u6715\u6C88\u73CD\u8CC3\u93AE\u9673\u6D25\u589C\u690E\u69CC\u8FFD\u939A\u75DB\u901A\u585A\u6802\u63B4\u69FB\u4F43\u6F2C\u67D8\u8FBB\u8526\u7DB4\u9354\u693F\u6F70\u576A\u58F7\u5B2C\u7D2C\u722A\u540A\u91E3\u9DB4\u4EAD\u4F4E\u505C\u5075\u5243\u8C9E\u5448\u5824\u5B9A\u5E1D\u5E95\u5EAD\u5EF7\u5F1F\u608C\u62B5\u633A\u63D0\u68AF\u6C40\u7887\u798E\u7A0B\u7DE0\u8247\u8A02\u8AE6\u8E44\u9013"], + ["9340", "\u90B8\u912D\u91D8\u9F0E\u6CE5\u6458\u64E2\u6575\u6EF4\u7684\u7B1B\u9069\u93D1\u6EBA\u54F2\u5FB9\u64A4\u8F4D\u8FED\u9244\u5178\u586B\u5929\u5C55\u5E97\u6DFB\u7E8F\u751C\u8CBC\u8EE2\u985B\u70B9\u4F1D\u6BBF\u6FB1\u7530\u96FB\u514E\u5410\u5835\u5857\u59AC\u5C60\u5F92\u6597\u675C\u6E21\u767B\u83DF\u8CED\u9014\u90FD\u934D\u7825\u783A\u52AA\u5EA6\u571F\u5974\u6012\u5012\u515A\u51AC"], + ["9380", "\u51CD\u5200\u5510\u5854\u5858\u5957\u5B95\u5CF6\u5D8B\u60BC\u6295\u642D\u6771\u6843\u68BC\u68DF\u76D7\u6DD8\u6E6F\u6D9B\u706F\u71C8\u5F53\u75D8\u7977\u7B49\u7B54\u7B52\u7CD6\u7D71\u5230\u8463\u8569\u85E4\u8A0E\u8B04\u8C46\u8E0F\u9003\u900F\u9419\u9676\u982D\u9A30\u95D8\u50CD\u52D5\u540C\u5802\u5C0E\u61A7\u649E\u6D1E\u77B3\u7AE5\u80F4\u8404\u9053\u9285\u5CE0\u9D07\u533F\u5F97\u5FB3\u6D9C\u7279\u7763\u79BF\u7BE4\u6BD2\u72EC\u8AAD\u6803\u6A61\u51F8\u7A81\u6934\u5C4A\u9CF6\u82EB\u5BC5\u9149\u701E\u5678\u5C6F\u60C7\u6566\u6C8C\u8C5A\u9041\u9813\u5451\u66C7\u920D\u5948\u90A3\u5185\u4E4D\u51EA\u8599\u8B0E\u7058\u637A\u934B\u6962\u99B4\u7E04\u7577\u5357\u6960\u8EDF\u96E3\u6C5D\u4E8C\u5C3C\u5F10\u8FE9\u5302\u8CD1\u8089\u8679\u5EFF\u65E5\u4E73\u5165"], + ["9440", "\u5982\u5C3F\u97EE\u4EFB\u598A\u5FCD\u8A8D\u6FE1\u79B0\u7962\u5BE7\u8471\u732B\u71B1\u5E74\u5FF5\u637B\u649A\u71C3\u7C98\u4E43\u5EFC\u4E4B\u57DC\u56A2\u60A9\u6FC3\u7D0D\u80FD\u8133\u81BF\u8FB2\u8997\u86A4\u5DF4\u628A\u64AD\u8987\u6777\u6CE2\u6D3E\u7436\u7834\u5A46\u7F75\u82AD\u99AC\u4FF3\u5EC3\u62DD\u6392\u6557\u676F\u76C3\u724C\u80CC\u80BA\u8F29\u914D\u500D\u57F9\u5A92\u6885"], + ["9480", "\u6973\u7164\u72FD\u8CB7\u58F2\u8CE0\u966A\u9019\u877F\u79E4\u77E7\u8429\u4F2F\u5265\u535A\u62CD\u67CF\u6CCA\u767D\u7B94\u7C95\u8236\u8584\u8FEB\u66DD\u6F20\u7206\u7E1B\u83AB\u99C1\u9EA6\u51FD\u7BB1\u7872\u7BB8\u8087\u7B48\u6AE8\u5E61\u808C\u7551\u7560\u516B\u9262\u6E8C\u767A\u9197\u9AEA\u4F10\u7F70\u629C\u7B4F\u95A5\u9CE9\u567A\u5859\u86E4\u96BC\u4F34\u5224\u534A\u53CD\u53DB\u5E06\u642C\u6591\u677F\u6C3E\u6C4E\u7248\u72AF\u73ED\u7554\u7E41\u822C\u85E9\u8CA9\u7BC4\u91C6\u7169\u9812\u98EF\u633D\u6669\u756A\u76E4\u78D0\u8543\u86EE\u532A\u5351\u5426\u5983\u5E87\u5F7C\u60B2\u6249\u6279\u62AB\u6590\u6BD4\u6CCC\u75B2\u76AE\u7891\u79D8\u7DCB\u7F77\u80A5\u88AB\u8AB9\u8CBB\u907F\u975E\u98DB\u6A0B\u7C38\u5099\u5C3E\u5FAE\u6787\u6BD8\u7435\u7709\u7F8E"], + ["9540", "\u9F3B\u67CA\u7A17\u5339\u758B\u9AED\u5F66\u819D\u83F1\u8098\u5F3C\u5FC5\u7562\u7B46\u903C\u6867\u59EB\u5A9B\u7D10\u767E\u8B2C\u4FF5\u5F6A\u6A19\u6C37\u6F02\u74E2\u7968\u8868\u8A55\u8C79\u5EDF\u63CF\u75C5\u79D2\u82D7\u9328\u92F2\u849C\u86ED\u9C2D\u54C1\u5F6C\u658C\u6D5C\u7015\u8CA7\u8CD3\u983B\u654F\u74F6\u4E0D\u4ED8\u57E0\u592B\u5A66\u5BCC\u51A8\u5E03\u5E9C\u6016\u6276\u6577"], + ["9580", "\u65A7\u666E\u6D6E\u7236\u7B26\u8150\u819A\u8299\u8B5C\u8CA0\u8CE6\u8D74\u961C\u9644\u4FAE\u64AB\u6B66\u821E\u8461\u856A\u90E8\u5C01\u6953\u98A8\u847A\u8557\u4F0F\u526F\u5FA9\u5E45\u670D\u798F\u8179\u8907\u8986\u6DF5\u5F17\u6255\u6CB8\u4ECF\u7269\u9B92\u5206\u543B\u5674\u58B3\u61A4\u626E\u711A\u596E\u7C89\u7CDE\u7D1B\u96F0\u6587\u805E\u4E19\u4F75\u5175\u5840\u5E63\u5E73\u5F0A\u67C4\u4E26\u853D\u9589\u965B\u7C73\u9801\u50FB\u58C1\u7656\u78A7\u5225\u77A5\u8511\u7B86\u504F\u5909\u7247\u7BC7\u7DE8\u8FBA\u8FD4\u904D\u4FBF\u52C9\u5A29\u5F01\u97AD\u4FDD\u8217\u92EA\u5703\u6355\u6B69\u752B\u88DC\u8F14\u7A42\u52DF\u5893\u6155\u620A\u66AE\u6BCD\u7C3F\u83E9\u5023\u4FF8\u5305\u5446\u5831\u5949\u5B9D\u5CF0\u5CEF\u5D29\u5E96\u62B1\u6367\u653E\u65B9\u670B"], + ["9640", "\u6CD5\u6CE1\u70F9\u7832\u7E2B\u80DE\u82B3\u840C\u84EC\u8702\u8912\u8A2A\u8C4A\u90A6\u92D2\u98FD\u9CF3\u9D6C\u4E4F\u4EA1\u508D\u5256\u574A\u59A8\u5E3D\u5FD8\u5FD9\u623F\u66B4\u671B\u67D0\u68D2\u5192\u7D21\u80AA\u81A8\u8B00\u8C8C\u8CBF\u927E\u9632\u5420\u982C\u5317\u50D5\u535C\u58A8\u64B2\u6734\u7267\u7766\u7A46\u91E6\u52C3\u6CA1\u6B86\u5800\u5E4C\u5954\u672C\u7FFB\u51E1\u76C6"], + ["9680", "\u6469\u78E8\u9B54\u9EBB\u57CB\u59B9\u6627\u679A\u6BCE\u54E9\u69D9\u5E55\u819C\u6795\u9BAA\u67FE\u9C52\u685D\u4EA6\u4FE3\u53C8\u62B9\u672B\u6CAB\u8FC4\u4FAD\u7E6D\u9EBF\u4E07\u6162\u6E80\u6F2B\u8513\u5473\u672A\u9B45\u5DF3\u7B95\u5CAC\u5BC6\u871C\u6E4A\u84D1\u7A14\u8108\u5999\u7C8D\u6C11\u7720\u52D9\u5922\u7121\u725F\u77DB\u9727\u9D61\u690B\u5A7F\u5A18\u51A5\u540D\u547D\u660E\u76DF\u8FF7\u9298\u9CF4\u59EA\u725D\u6EC5\u514D\u68C9\u7DBF\u7DEC\u9762\u9EBA\u6478\u6A21\u8302\u5984\u5B5F\u6BDB\u731B\u76F2\u7DB2\u8017\u8499\u5132\u6728\u9ED9\u76EE\u6762\u52FF\u9905\u5C24\u623B\u7C7E\u8CB0\u554F\u60B6\u7D0B\u9580\u5301\u4E5F\u51B6\u591C\u723A\u8036\u91CE\u5F25\u77E2\u5384\u5F79\u7D04\u85AC\u8A33\u8E8D\u9756\u67F3\u85AE\u9453\u6109\u6108\u6CB9\u7652"], + ["9740", "\u8AED\u8F38\u552F\u4F51\u512A\u52C7\u53CB\u5BA5\u5E7D\u60A0\u6182\u63D6\u6709\u67DA\u6E67\u6D8C\u7336\u7337\u7531\u7950\u88D5\u8A98\u904A\u9091\u90F5\u96C4\u878D\u5915\u4E88\u4F59\u4E0E\u8A89\u8F3F\u9810\u50AD\u5E7C\u5996\u5BB9\u5EB8\u63DA\u63FA\u64C1\u66DC\u694A\u69D8\u6D0B\u6EB6\u7194\u7528\u7AAF\u7F8A\u8000\u8449\u84C9\u8981\u8B21\u8E0A\u9065\u967D\u990A\u617E\u6291\u6B32"], + ["9780", "\u6C83\u6D74\u7FCC\u7FFC\u6DC0\u7F85\u87BA\u88F8\u6765\u83B1\u983C\u96F7\u6D1B\u7D61\u843D\u916A\u4E71\u5375\u5D50\u6B04\u6FEB\u85CD\u862D\u89A7\u5229\u540F\u5C65\u674E\u68A8\u7406\u7483\u75E2\u88CF\u88E1\u91CC\u96E2\u9678\u5F8B\u7387\u7ACB\u844E\u63A0\u7565\u5289\u6D41\u6E9C\u7409\u7559\u786B\u7C92\u9686\u7ADC\u9F8D\u4FB6\u616E\u65C5\u865C\u4E86\u4EAE\u50DA\u4E21\u51CC\u5BEE\u6599\u6881\u6DBC\u731F\u7642\u77AD\u7A1C\u7CE7\u826F\u8AD2\u907C\u91CF\u9675\u9818\u529B\u7DD1\u502B\u5398\u6797\u6DCB\u71D0\u7433\u81E8\u8F2A\u96A3\u9C57\u9E9F\u7460\u5841\u6D99\u7D2F\u985E\u4EE4\u4F36\u4F8B\u51B7\u52B1\u5DBA\u601C\u73B2\u793C\u82D3\u9234\u96B7\u96F6\u970A\u9E97\u9F62\u66A6\u6B74\u5217\u52A3\u70C8\u88C2\u5EC9\u604B\u6190\u6F23\u7149\u7C3E\u7DF4\u806F"], + ["9840", "\u84EE\u9023\u932C\u5442\u9B6F\u6AD3\u7089\u8CC2\u8DEF\u9732\u52B4\u5A41\u5ECA\u5F04\u6717\u697C\u6994\u6D6A\u6F0F\u7262\u72FC\u7BED\u8001\u807E\u874B\u90CE\u516D\u9E93\u7984\u808B\u9332\u8AD6\u502D\u548C\u8A71\u6B6A\u8CC4\u8107\u60D1\u67A0\u9DF2\u4E99\u4E98\u9C10\u8A6B\u85C1\u8568\u6900\u6E7E\u7897\u8155"], + ["989f", "\u5F0C\u4E10\u4E15\u4E2A\u4E31\u4E36\u4E3C\u4E3F\u4E42\u4E56\u4E58\u4E82\u4E85\u8C6B\u4E8A\u8212\u5F0D\u4E8E\u4E9E\u4E9F\u4EA0\u4EA2\u4EB0\u4EB3\u4EB6\u4ECE\u4ECD\u4EC4\u4EC6\u4EC2\u4ED7\u4EDE\u4EED\u4EDF\u4EF7\u4F09\u4F5A\u4F30\u4F5B\u4F5D\u4F57\u4F47\u4F76\u4F88\u4F8F\u4F98\u4F7B\u4F69\u4F70\u4F91\u4F6F\u4F86\u4F96\u5118\u4FD4\u4FDF\u4FCE\u4FD8\u4FDB\u4FD1\u4FDA\u4FD0\u4FE4\u4FE5\u501A\u5028\u5014\u502A\u5025\u5005\u4F1C\u4FF6\u5021\u5029\u502C\u4FFE\u4FEF\u5011\u5006\u5043\u5047\u6703\u5055\u5050\u5048\u505A\u5056\u506C\u5078\u5080\u509A\u5085\u50B4\u50B2"], + ["9940", "\u50C9\u50CA\u50B3\u50C2\u50D6\u50DE\u50E5\u50ED\u50E3\u50EE\u50F9\u50F5\u5109\u5101\u5102\u5116\u5115\u5114\u511A\u5121\u513A\u5137\u513C\u513B\u513F\u5140\u5152\u514C\u5154\u5162\u7AF8\u5169\u516A\u516E\u5180\u5182\u56D8\u518C\u5189\u518F\u5191\u5193\u5195\u5196\u51A4\u51A6\u51A2\u51A9\u51AA\u51AB\u51B3\u51B1\u51B2\u51B0\u51B5\u51BD\u51C5\u51C9\u51DB\u51E0\u8655\u51E9\u51ED"], + ["9980", "\u51F0\u51F5\u51FE\u5204\u520B\u5214\u520E\u5227\u522A\u522E\u5233\u5239\u524F\u5244\u524B\u524C\u525E\u5254\u526A\u5274\u5269\u5273\u527F\u527D\u528D\u5294\u5292\u5271\u5288\u5291\u8FA8\u8FA7\u52AC\u52AD\u52BC\u52B5\u52C1\u52CD\u52D7\u52DE\u52E3\u52E6\u98ED\u52E0\u52F3\u52F5\u52F8\u52F9\u5306\u5308\u7538\u530D\u5310\u530F\u5315\u531A\u5323\u532F\u5331\u5333\u5338\u5340\u5346\u5345\u4E17\u5349\u534D\u51D6\u535E\u5369\u536E\u5918\u537B\u5377\u5382\u5396\u53A0\u53A6\u53A5\u53AE\u53B0\u53B6\u53C3\u7C12\u96D9\u53DF\u66FC\u71EE\u53EE\u53E8\u53ED\u53FA\u5401\u543D\u5440\u542C\u542D\u543C\u542E\u5436\u5429\u541D\u544E\u548F\u5475\u548E\u545F\u5471\u5477\u5470\u5492\u547B\u5480\u5476\u5484\u5490\u5486\u54C7\u54A2\u54B8\u54A5\u54AC\u54C4\u54C8\u54A8"], + ["9a40", "\u54AB\u54C2\u54A4\u54BE\u54BC\u54D8\u54E5\u54E6\u550F\u5514\u54FD\u54EE\u54ED\u54FA\u54E2\u5539\u5540\u5563\u554C\u552E\u555C\u5545\u5556\u5557\u5538\u5533\u555D\u5599\u5580\u54AF\u558A\u559F\u557B\u557E\u5598\u559E\u55AE\u557C\u5583\u55A9\u5587\u55A8\u55DA\u55C5\u55DF\u55C4\u55DC\u55E4\u55D4\u5614\u55F7\u5616\u55FE\u55FD\u561B\u55F9\u564E\u5650\u71DF\u5634\u5636\u5632\u5638"], + ["9a80", "\u566B\u5664\u562F\u566C\u566A\u5686\u5680\u568A\u56A0\u5694\u568F\u56A5\u56AE\u56B6\u56B4\u56C2\u56BC\u56C1\u56C3\u56C0\u56C8\u56CE\u56D1\u56D3\u56D7\u56EE\u56F9\u5700\u56FF\u5704\u5709\u5708\u570B\u570D\u5713\u5718\u5716\u55C7\u571C\u5726\u5737\u5738\u574E\u573B\u5740\u574F\u5769\u57C0\u5788\u5761\u577F\u5789\u5793\u57A0\u57B3\u57A4\u57AA\u57B0\u57C3\u57C6\u57D4\u57D2\u57D3\u580A\u57D6\u57E3\u580B\u5819\u581D\u5872\u5821\u5862\u584B\u5870\u6BC0\u5852\u583D\u5879\u5885\u58B9\u589F\u58AB\u58BA\u58DE\u58BB\u58B8\u58AE\u58C5\u58D3\u58D1\u58D7\u58D9\u58D8\u58E5\u58DC\u58E4\u58DF\u58EF\u58FA\u58F9\u58FB\u58FC\u58FD\u5902\u590A\u5910\u591B\u68A6\u5925\u592C\u592D\u5932\u5938\u593E\u7AD2\u5955\u5950\u594E\u595A\u5958\u5962\u5960\u5967\u596C\u5969"], + ["9b40", "\u5978\u5981\u599D\u4F5E\u4FAB\u59A3\u59B2\u59C6\u59E8\u59DC\u598D\u59D9\u59DA\u5A25\u5A1F\u5A11\u5A1C\u5A09\u5A1A\u5A40\u5A6C\u5A49\u5A35\u5A36\u5A62\u5A6A\u5A9A\u5ABC\u5ABE\u5ACB\u5AC2\u5ABD\u5AE3\u5AD7\u5AE6\u5AE9\u5AD6\u5AFA\u5AFB\u5B0C\u5B0B\u5B16\u5B32\u5AD0\u5B2A\u5B36\u5B3E\u5B43\u5B45\u5B40\u5B51\u5B55\u5B5A\u5B5B\u5B65\u5B69\u5B70\u5B73\u5B75\u5B78\u6588\u5B7A\u5B80"], + ["9b80", "\u5B83\u5BA6\u5BB8\u5BC3\u5BC7\u5BC9\u5BD4\u5BD0\u5BE4\u5BE6\u5BE2\u5BDE\u5BE5\u5BEB\u5BF0\u5BF6\u5BF3\u5C05\u5C07\u5C08\u5C0D\u5C13\u5C20\u5C22\u5C28\u5C38\u5C39\u5C41\u5C46\u5C4E\u5C53\u5C50\u5C4F\u5B71\u5C6C\u5C6E\u4E62\u5C76\u5C79\u5C8C\u5C91\u5C94\u599B\u5CAB\u5CBB\u5CB6\u5CBC\u5CB7\u5CC5\u5CBE\u5CC7\u5CD9\u5CE9\u5CFD\u5CFA\u5CED\u5D8C\u5CEA\u5D0B\u5D15\u5D17\u5D5C\u5D1F\u5D1B\u5D11\u5D14\u5D22\u5D1A\u5D19\u5D18\u5D4C\u5D52\u5D4E\u5D4B\u5D6C\u5D73\u5D76\u5D87\u5D84\u5D82\u5DA2\u5D9D\u5DAC\u5DAE\u5DBD\u5D90\u5DB7\u5DBC\u5DC9\u5DCD\u5DD3\u5DD2\u5DD6\u5DDB\u5DEB\u5DF2\u5DF5\u5E0B\u5E1A\u5E19\u5E11\u5E1B\u5E36\u5E37\u5E44\u5E43\u5E40\u5E4E\u5E57\u5E54\u5E5F\u5E62\u5E64\u5E47\u5E75\u5E76\u5E7A\u9EBC\u5E7F\u5EA0\u5EC1\u5EC2\u5EC8\u5ED0\u5ECF"], + ["9c40", "\u5ED6\u5EE3\u5EDD\u5EDA\u5EDB\u5EE2\u5EE1\u5EE8\u5EE9\u5EEC\u5EF1\u5EF3\u5EF0\u5EF4\u5EF8\u5EFE\u5F03\u5F09\u5F5D\u5F5C\u5F0B\u5F11\u5F16\u5F29\u5F2D\u5F38\u5F41\u5F48\u5F4C\u5F4E\u5F2F\u5F51\u5F56\u5F57\u5F59\u5F61\u5F6D\u5F73\u5F77\u5F83\u5F82\u5F7F\u5F8A\u5F88\u5F91\u5F87\u5F9E\u5F99\u5F98\u5FA0\u5FA8\u5FAD\u5FBC\u5FD6\u5FFB\u5FE4\u5FF8\u5FF1\u5FDD\u60B3\u5FFF\u6021\u6060"], + ["9c80", "\u6019\u6010\u6029\u600E\u6031\u601B\u6015\u602B\u6026\u600F\u603A\u605A\u6041\u606A\u6077\u605F\u604A\u6046\u604D\u6063\u6043\u6064\u6042\u606C\u606B\u6059\u6081\u608D\u60E7\u6083\u609A\u6084\u609B\u6096\u6097\u6092\u60A7\u608B\u60E1\u60B8\u60E0\u60D3\u60B4\u5FF0\u60BD\u60C6\u60B5\u60D8\u614D\u6115\u6106\u60F6\u60F7\u6100\u60F4\u60FA\u6103\u6121\u60FB\u60F1\u610D\u610E\u6147\u613E\u6128\u6127\u614A\u613F\u613C\u612C\u6134\u613D\u6142\u6144\u6173\u6177\u6158\u6159\u615A\u616B\u6174\u616F\u6165\u6171\u615F\u615D\u6153\u6175\u6199\u6196\u6187\u61AC\u6194\u619A\u618A\u6191\u61AB\u61AE\u61CC\u61CA\u61C9\u61F7\u61C8\u61C3\u61C6\u61BA\u61CB\u7F79\u61CD\u61E6\u61E3\u61F6\u61FA\u61F4\u61FF\u61FD\u61FC\u61FE\u6200\u6208\u6209\u620D\u620C\u6214\u621B"], + ["9d40", "\u621E\u6221\u622A\u622E\u6230\u6232\u6233\u6241\u624E\u625E\u6263\u625B\u6260\u6268\u627C\u6282\u6289\u627E\u6292\u6293\u6296\u62D4\u6283\u6294\u62D7\u62D1\u62BB\u62CF\u62FF\u62C6\u64D4\u62C8\u62DC\u62CC\u62CA\u62C2\u62C7\u629B\u62C9\u630C\u62EE\u62F1\u6327\u6302\u6308\u62EF\u62F5\u6350\u633E\u634D\u641C\u634F\u6396\u638E\u6380\u63AB\u6376\u63A3\u638F\u6389\u639F\u63B5\u636B"], + ["9d80", "\u6369\u63BE\u63E9\u63C0\u63C6\u63E3\u63C9\u63D2\u63F6\u63C4\u6416\u6434\u6406\u6413\u6426\u6436\u651D\u6417\u6428\u640F\u6467\u646F\u6476\u644E\u652A\u6495\u6493\u64A5\u64A9\u6488\u64BC\u64DA\u64D2\u64C5\u64C7\u64BB\u64D8\u64C2\u64F1\u64E7\u8209\u64E0\u64E1\u62AC\u64E3\u64EF\u652C\u64F6\u64F4\u64F2\u64FA\u6500\u64FD\u6518\u651C\u6505\u6524\u6523\u652B\u6534\u6535\u6537\u6536\u6538\u754B\u6548\u6556\u6555\u654D\u6558\u655E\u655D\u6572\u6578\u6582\u6583\u8B8A\u659B\u659F\u65AB\u65B7\u65C3\u65C6\u65C1\u65C4\u65CC\u65D2\u65DB\u65D9\u65E0\u65E1\u65F1\u6772\u660A\u6603\u65FB\u6773\u6635\u6636\u6634\u661C\u664F\u6644\u6649\u6641\u665E\u665D\u6664\u6667\u6668\u665F\u6662\u6670\u6683\u6688\u668E\u6689\u6684\u6698\u669D\u66C1\u66B9\u66C9\u66BE\u66BC"], + ["9e40", "\u66C4\u66B8\u66D6\u66DA\u66E0\u663F\u66E6\u66E9\u66F0\u66F5\u66F7\u670F\u6716\u671E\u6726\u6727\u9738\u672E\u673F\u6736\u6741\u6738\u6737\u6746\u675E\u6760\u6759\u6763\u6764\u6789\u6770\u67A9\u677C\u676A\u678C\u678B\u67A6\u67A1\u6785\u67B7\u67EF\u67B4\u67EC\u67B3\u67E9\u67B8\u67E4\u67DE\u67DD\u67E2\u67EE\u67B9\u67CE\u67C6\u67E7\u6A9C\u681E\u6846\u6829\u6840\u684D\u6832\u684E"], + ["9e80", "\u68B3\u682B\u6859\u6863\u6877\u687F\u689F\u688F\u68AD\u6894\u689D\u689B\u6883\u6AAE\u68B9\u6874\u68B5\u68A0\u68BA\u690F\u688D\u687E\u6901\u68CA\u6908\u68D8\u6922\u6926\u68E1\u690C\u68CD\u68D4\u68E7\u68D5\u6936\u6912\u6904\u68D7\u68E3\u6925\u68F9\u68E0\u68EF\u6928\u692A\u691A\u6923\u6921\u68C6\u6979\u6977\u695C\u6978\u696B\u6954\u697E\u696E\u6939\u6974\u693D\u6959\u6930\u6961\u695E\u695D\u6981\u696A\u69B2\u69AE\u69D0\u69BF\u69C1\u69D3\u69BE\u69CE\u5BE8\u69CA\u69DD\u69BB\u69C3\u69A7\u6A2E\u6991\u69A0\u699C\u6995\u69B4\u69DE\u69E8\u6A02\u6A1B\u69FF\u6B0A\u69F9\u69F2\u69E7\u6A05\u69B1\u6A1E\u69ED\u6A14\u69EB\u6A0A\u6A12\u6AC1\u6A23\u6A13\u6A44\u6A0C\u6A72\u6A36\u6A78\u6A47\u6A62\u6A59\u6A66\u6A48\u6A38\u6A22\u6A90\u6A8D\u6AA0\u6A84\u6AA2\u6AA3"], + ["9f40", "\u6A97\u8617\u6ABB\u6AC3\u6AC2\u6AB8\u6AB3\u6AAC\u6ADE\u6AD1\u6ADF\u6AAA\u6ADA\u6AEA\u6AFB\u6B05\u8616\u6AFA\u6B12\u6B16\u9B31\u6B1F\u6B38\u6B37\u76DC\u6B39\u98EE\u6B47\u6B43\u6B49\u6B50\u6B59\u6B54\u6B5B\u6B5F\u6B61\u6B78\u6B79\u6B7F\u6B80\u6B84\u6B83\u6B8D\u6B98\u6B95\u6B9E\u6BA4\u6BAA\u6BAB\u6BAF\u6BB2\u6BB1\u6BB3\u6BB7\u6BBC\u6BC6\u6BCB\u6BD3\u6BDF\u6BEC\u6BEB\u6BF3\u6BEF"], + ["9f80", "\u9EBE\u6C08\u6C13\u6C14\u6C1B\u6C24\u6C23\u6C5E\u6C55\u6C62\u6C6A\u6C82\u6C8D\u6C9A\u6C81\u6C9B\u6C7E\u6C68\u6C73\u6C92\u6C90\u6CC4\u6CF1\u6CD3\u6CBD\u6CD7\u6CC5\u6CDD\u6CAE\u6CB1\u6CBE\u6CBA\u6CDB\u6CEF\u6CD9\u6CEA\u6D1F\u884D\u6D36\u6D2B\u6D3D\u6D38\u6D19\u6D35\u6D33\u6D12\u6D0C\u6D63\u6D93\u6D64\u6D5A\u6D79\u6D59\u6D8E\u6D95\u6FE4\u6D85\u6DF9\u6E15\u6E0A\u6DB5\u6DC7\u6DE6\u6DB8\u6DC6\u6DEC\u6DDE\u6DCC\u6DE8\u6DD2\u6DC5\u6DFA\u6DD9\u6DE4\u6DD5\u6DEA\u6DEE\u6E2D\u6E6E\u6E2E\u6E19\u6E72\u6E5F\u6E3E\u6E23\u6E6B\u6E2B\u6E76\u6E4D\u6E1F\u6E43\u6E3A\u6E4E\u6E24\u6EFF\u6E1D\u6E38\u6E82\u6EAA\u6E98\u6EC9\u6EB7\u6ED3\u6EBD\u6EAF\u6EC4\u6EB2\u6ED4\u6ED5\u6E8F\u6EA5\u6EC2\u6E9F\u6F41\u6F11\u704C\u6EEC\u6EF8\u6EFE\u6F3F\u6EF2\u6F31\u6EEF\u6F32\u6ECC"], + ["e040", "\u6F3E\u6F13\u6EF7\u6F86\u6F7A\u6F78\u6F81\u6F80\u6F6F\u6F5B\u6FF3\u6F6D\u6F82\u6F7C\u6F58\u6F8E\u6F91\u6FC2\u6F66\u6FB3\u6FA3\u6FA1\u6FA4\u6FB9\u6FC6\u6FAA\u6FDF\u6FD5\u6FEC\u6FD4\u6FD8\u6FF1\u6FEE\u6FDB\u7009\u700B\u6FFA\u7011\u7001\u700F\u6FFE\u701B\u701A\u6F74\u701D\u7018\u701F\u7030\u703E\u7032\u7051\u7063\u7099\u7092\u70AF\u70F1\u70AC\u70B8\u70B3\u70AE\u70DF\u70CB\u70DD"], + ["e080", "\u70D9\u7109\u70FD\u711C\u7119\u7165\u7155\u7188\u7166\u7162\u714C\u7156\u716C\u718F\u71FB\u7184\u7195\u71A8\u71AC\u71D7\u71B9\u71BE\u71D2\u71C9\u71D4\u71CE\u71E0\u71EC\u71E7\u71F5\u71FC\u71F9\u71FF\u720D\u7210\u721B\u7228\u722D\u722C\u7230\u7232\u723B\u723C\u723F\u7240\u7246\u724B\u7258\u7274\u727E\u7282\u7281\u7287\u7292\u7296\u72A2\u72A7\u72B9\u72B2\u72C3\u72C6\u72C4\u72CE\u72D2\u72E2\u72E0\u72E1\u72F9\u72F7\u500F\u7317\u730A\u731C\u7316\u731D\u7334\u732F\u7329\u7325\u733E\u734E\u734F\u9ED8\u7357\u736A\u7368\u7370\u7378\u7375\u737B\u737A\u73C8\u73B3\u73CE\u73BB\u73C0\u73E5\u73EE\u73DE\u74A2\u7405\u746F\u7425\u73F8\u7432\u743A\u7455\u743F\u745F\u7459\u7441\u745C\u7469\u7470\u7463\u746A\u7476\u747E\u748B\u749E\u74A7\u74CA\u74CF\u74D4\u73F1"], + ["e140", "\u74E0\u74E3\u74E7\u74E9\u74EE\u74F2\u74F0\u74F1\u74F8\u74F7\u7504\u7503\u7505\u750C\u750E\u750D\u7515\u7513\u751E\u7526\u752C\u753C\u7544\u754D\u754A\u7549\u755B\u7546\u755A\u7569\u7564\u7567\u756B\u756D\u7578\u7576\u7586\u7587\u7574\u758A\u7589\u7582\u7594\u759A\u759D\u75A5\u75A3\u75C2\u75B3\u75C3\u75B5\u75BD\u75B8\u75BC\u75B1\u75CD\u75CA\u75D2\u75D9\u75E3\u75DE\u75FE\u75FF"], + ["e180", "\u75FC\u7601\u75F0\u75FA\u75F2\u75F3\u760B\u760D\u7609\u761F\u7627\u7620\u7621\u7622\u7624\u7634\u7630\u763B\u7647\u7648\u7646\u765C\u7658\u7661\u7662\u7668\u7669\u766A\u7667\u766C\u7670\u7672\u7676\u7678\u767C\u7680\u7683\u7688\u768B\u768E\u7696\u7693\u7699\u769A\u76B0\u76B4\u76B8\u76B9\u76BA\u76C2\u76CD\u76D6\u76D2\u76DE\u76E1\u76E5\u76E7\u76EA\u862F\u76FB\u7708\u7707\u7704\u7729\u7724\u771E\u7725\u7726\u771B\u7737\u7738\u7747\u775A\u7768\u776B\u775B\u7765\u777F\u777E\u7779\u778E\u778B\u7791\u77A0\u779E\u77B0\u77B6\u77B9\u77BF\u77BC\u77BD\u77BB\u77C7\u77CD\u77D7\u77DA\u77DC\u77E3\u77EE\u77FC\u780C\u7812\u7926\u7820\u792A\u7845\u788E\u7874\u7886\u787C\u789A\u788C\u78A3\u78B5\u78AA\u78AF\u78D1\u78C6\u78CB\u78D4\u78BE\u78BC\u78C5\u78CA\u78EC"], + ["e240", "\u78E7\u78DA\u78FD\u78F4\u7907\u7912\u7911\u7919\u792C\u792B\u7940\u7960\u7957\u795F\u795A\u7955\u7953\u797A\u797F\u798A\u799D\u79A7\u9F4B\u79AA\u79AE\u79B3\u79B9\u79BA\u79C9\u79D5\u79E7\u79EC\u79E1\u79E3\u7A08\u7A0D\u7A18\u7A19\u7A20\u7A1F\u7980\u7A31\u7A3B\u7A3E\u7A37\u7A43\u7A57\u7A49\u7A61\u7A62\u7A69\u9F9D\u7A70\u7A79\u7A7D\u7A88\u7A97\u7A95\u7A98\u7A96\u7AA9\u7AC8\u7AB0"], + ["e280", "\u7AB6\u7AC5\u7AC4\u7ABF\u9083\u7AC7\u7ACA\u7ACD\u7ACF\u7AD5\u7AD3\u7AD9\u7ADA\u7ADD\u7AE1\u7AE2\u7AE6\u7AED\u7AF0\u7B02\u7B0F\u7B0A\u7B06\u7B33\u7B18\u7B19\u7B1E\u7B35\u7B28\u7B36\u7B50\u7B7A\u7B04\u7B4D\u7B0B\u7B4C\u7B45\u7B75\u7B65\u7B74\u7B67\u7B70\u7B71\u7B6C\u7B6E\u7B9D\u7B98\u7B9F\u7B8D\u7B9C\u7B9A\u7B8B\u7B92\u7B8F\u7B5D\u7B99\u7BCB\u7BC1\u7BCC\u7BCF\u7BB4\u7BC6\u7BDD\u7BE9\u7C11\u7C14\u7BE6\u7BE5\u7C60\u7C00\u7C07\u7C13\u7BF3\u7BF7\u7C17\u7C0D\u7BF6\u7C23\u7C27\u7C2A\u7C1F\u7C37\u7C2B\u7C3D\u7C4C\u7C43\u7C54\u7C4F\u7C40\u7C50\u7C58\u7C5F\u7C64\u7C56\u7C65\u7C6C\u7C75\u7C83\u7C90\u7CA4\u7CAD\u7CA2\u7CAB\u7CA1\u7CA8\u7CB3\u7CB2\u7CB1\u7CAE\u7CB9\u7CBD\u7CC0\u7CC5\u7CC2\u7CD8\u7CD2\u7CDC\u7CE2\u9B3B\u7CEF\u7CF2\u7CF4\u7CF6\u7CFA\u7D06"], + ["e340", "\u7D02\u7D1C\u7D15\u7D0A\u7D45\u7D4B\u7D2E\u7D32\u7D3F\u7D35\u7D46\u7D73\u7D56\u7D4E\u7D72\u7D68\u7D6E\u7D4F\u7D63\u7D93\u7D89\u7D5B\u7D8F\u7D7D\u7D9B\u7DBA\u7DAE\u7DA3\u7DB5\u7DC7\u7DBD\u7DAB\u7E3D\u7DA2\u7DAF\u7DDC\u7DB8\u7D9F\u7DB0\u7DD8\u7DDD\u7DE4\u7DDE\u7DFB\u7DF2\u7DE1\u7E05\u7E0A\u7E23\u7E21\u7E12\u7E31\u7E1F\u7E09\u7E0B\u7E22\u7E46\u7E66\u7E3B\u7E35\u7E39\u7E43\u7E37"], + ["e380", "\u7E32\u7E3A\u7E67\u7E5D\u7E56\u7E5E\u7E59\u7E5A\u7E79\u7E6A\u7E69\u7E7C\u7E7B\u7E83\u7DD5\u7E7D\u8FAE\u7E7F\u7E88\u7E89\u7E8C\u7E92\u7E90\u7E93\u7E94\u7E96\u7E8E\u7E9B\u7E9C\u7F38\u7F3A\u7F45\u7F4C\u7F4D\u7F4E\u7F50\u7F51\u7F55\u7F54\u7F58\u7F5F\u7F60\u7F68\u7F69\u7F67\u7F78\u7F82\u7F86\u7F83\u7F88\u7F87\u7F8C\u7F94\u7F9E\u7F9D\u7F9A\u7FA3\u7FAF\u7FB2\u7FB9\u7FAE\u7FB6\u7FB8\u8B71\u7FC5\u7FC6\u7FCA\u7FD5\u7FD4\u7FE1\u7FE6\u7FE9\u7FF3\u7FF9\u98DC\u8006\u8004\u800B\u8012\u8018\u8019\u801C\u8021\u8028\u803F\u803B\u804A\u8046\u8052\u8058\u805A\u805F\u8062\u8068\u8073\u8072\u8070\u8076\u8079\u807D\u807F\u8084\u8086\u8085\u809B\u8093\u809A\u80AD\u5190\u80AC\u80DB\u80E5\u80D9\u80DD\u80C4\u80DA\u80D6\u8109\u80EF\u80F1\u811B\u8129\u8123\u812F\u814B"], + ["e440", "\u968B\u8146\u813E\u8153\u8151\u80FC\u8171\u816E\u8165\u8166\u8174\u8183\u8188\u818A\u8180\u8182\u81A0\u8195\u81A4\u81A3\u815F\u8193\u81A9\u81B0\u81B5\u81BE\u81B8\u81BD\u81C0\u81C2\u81BA\u81C9\u81CD\u81D1\u81D9\u81D8\u81C8\u81DA\u81DF\u81E0\u81E7\u81FA\u81FB\u81FE\u8201\u8202\u8205\u8207\u820A\u820D\u8210\u8216\u8229\u822B\u8238\u8233\u8240\u8259\u8258\u825D\u825A\u825F\u8264"], + ["e480", "\u8262\u8268\u826A\u826B\u822E\u8271\u8277\u8278\u827E\u828D\u8292\u82AB\u829F\u82BB\u82AC\u82E1\u82E3\u82DF\u82D2\u82F4\u82F3\u82FA\u8393\u8303\u82FB\u82F9\u82DE\u8306\u82DC\u8309\u82D9\u8335\u8334\u8316\u8332\u8331\u8340\u8339\u8350\u8345\u832F\u832B\u8317\u8318\u8385\u839A\u83AA\u839F\u83A2\u8396\u8323\u838E\u8387\u838A\u837C\u83B5\u8373\u8375\u83A0\u8389\u83A8\u83F4\u8413\u83EB\u83CE\u83FD\u8403\u83D8\u840B\u83C1\u83F7\u8407\u83E0\u83F2\u840D\u8422\u8420\u83BD\u8438\u8506\u83FB\u846D\u842A\u843C\u855A\u8484\u8477\u846B\u84AD\u846E\u8482\u8469\u8446\u842C\u846F\u8479\u8435\u84CA\u8462\u84B9\u84BF\u849F\u84D9\u84CD\u84BB\u84DA\u84D0\u84C1\u84C6\u84D6\u84A1\u8521\u84FF\u84F4\u8517\u8518\u852C\u851F\u8515\u8514\u84FC\u8540\u8563\u8558\u8548"], + ["e540", "\u8541\u8602\u854B\u8555\u8580\u85A4\u8588\u8591\u858A\u85A8\u856D\u8594\u859B\u85EA\u8587\u859C\u8577\u857E\u8590\u85C9\u85BA\u85CF\u85B9\u85D0\u85D5\u85DD\u85E5\u85DC\u85F9\u860A\u8613\u860B\u85FE\u85FA\u8606\u8622\u861A\u8630\u863F\u864D\u4E55\u8654\u865F\u8667\u8671\u8693\u86A3\u86A9\u86AA\u868B\u868C\u86B6\u86AF\u86C4\u86C6\u86B0\u86C9\u8823\u86AB\u86D4\u86DE\u86E9\u86EC"], + ["e580", "\u86DF\u86DB\u86EF\u8712\u8706\u8708\u8700\u8703\u86FB\u8711\u8709\u870D\u86F9\u870A\u8734\u873F\u8737\u873B\u8725\u8729\u871A\u8760\u875F\u8778\u874C\u874E\u8774\u8757\u8768\u876E\u8759\u8753\u8763\u876A\u8805\u87A2\u879F\u8782\u87AF\u87CB\u87BD\u87C0\u87D0\u96D6\u87AB\u87C4\u87B3\u87C7\u87C6\u87BB\u87EF\u87F2\u87E0\u880F\u880D\u87FE\u87F6\u87F7\u880E\u87D2\u8811\u8816\u8815\u8822\u8821\u8831\u8836\u8839\u8827\u883B\u8844\u8842\u8852\u8859\u885E\u8862\u886B\u8881\u887E\u889E\u8875\u887D\u88B5\u8872\u8882\u8897\u8892\u88AE\u8899\u88A2\u888D\u88A4\u88B0\u88BF\u88B1\u88C3\u88C4\u88D4\u88D8\u88D9\u88DD\u88F9\u8902\u88FC\u88F4\u88E8\u88F2\u8904\u890C\u890A\u8913\u8943\u891E\u8925\u892A\u892B\u8941\u8944\u893B\u8936\u8938\u894C\u891D\u8960\u895E"], + ["e640", "\u8966\u8964\u896D\u896A\u896F\u8974\u8977\u897E\u8983\u8988\u898A\u8993\u8998\u89A1\u89A9\u89A6\u89AC\u89AF\u89B2\u89BA\u89BD\u89BF\u89C0\u89DA\u89DC\u89DD\u89E7\u89F4\u89F8\u8A03\u8A16\u8A10\u8A0C\u8A1B\u8A1D\u8A25\u8A36\u8A41\u8A5B\u8A52\u8A46\u8A48\u8A7C\u8A6D\u8A6C\u8A62\u8A85\u8A82\u8A84\u8AA8\u8AA1\u8A91\u8AA5\u8AA6\u8A9A\u8AA3\u8AC4\u8ACD\u8AC2\u8ADA\u8AEB\u8AF3\u8AE7"], + ["e680", "\u8AE4\u8AF1\u8B14\u8AE0\u8AE2\u8AF7\u8ADE\u8ADB\u8B0C\u8B07\u8B1A\u8AE1\u8B16\u8B10\u8B17\u8B20\u8B33\u97AB\u8B26\u8B2B\u8B3E\u8B28\u8B41\u8B4C\u8B4F\u8B4E\u8B49\u8B56\u8B5B\u8B5A\u8B6B\u8B5F\u8B6C\u8B6F\u8B74\u8B7D\u8B80\u8B8C\u8B8E\u8B92\u8B93\u8B96\u8B99\u8B9A\u8C3A\u8C41\u8C3F\u8C48\u8C4C\u8C4E\u8C50\u8C55\u8C62\u8C6C\u8C78\u8C7A\u8C82\u8C89\u8C85\u8C8A\u8C8D\u8C8E\u8C94\u8C7C\u8C98\u621D\u8CAD\u8CAA\u8CBD\u8CB2\u8CB3\u8CAE\u8CB6\u8CC8\u8CC1\u8CE4\u8CE3\u8CDA\u8CFD\u8CFA\u8CFB\u8D04\u8D05\u8D0A\u8D07\u8D0F\u8D0D\u8D10\u9F4E\u8D13\u8CCD\u8D14\u8D16\u8D67\u8D6D\u8D71\u8D73\u8D81\u8D99\u8DC2\u8DBE\u8DBA\u8DCF\u8DDA\u8DD6\u8DCC\u8DDB\u8DCB\u8DEA\u8DEB\u8DDF\u8DE3\u8DFC\u8E08\u8E09\u8DFF\u8E1D\u8E1E\u8E10\u8E1F\u8E42\u8E35\u8E30\u8E34\u8E4A"], + ["e740", "\u8E47\u8E49\u8E4C\u8E50\u8E48\u8E59\u8E64\u8E60\u8E2A\u8E63\u8E55\u8E76\u8E72\u8E7C\u8E81\u8E87\u8E85\u8E84\u8E8B\u8E8A\u8E93\u8E91\u8E94\u8E99\u8EAA\u8EA1\u8EAC\u8EB0\u8EC6\u8EB1\u8EBE\u8EC5\u8EC8\u8ECB\u8EDB\u8EE3\u8EFC\u8EFB\u8EEB\u8EFE\u8F0A\u8F05\u8F15\u8F12\u8F19\u8F13\u8F1C\u8F1F\u8F1B\u8F0C\u8F26\u8F33\u8F3B\u8F39\u8F45\u8F42\u8F3E\u8F4C\u8F49\u8F46\u8F4E\u8F57\u8F5C"], + ["e780", "\u8F62\u8F63\u8F64\u8F9C\u8F9F\u8FA3\u8FAD\u8FAF\u8FB7\u8FDA\u8FE5\u8FE2\u8FEA\u8FEF\u9087\u8FF4\u9005\u8FF9\u8FFA\u9011\u9015\u9021\u900D\u901E\u9016\u900B\u9027\u9036\u9035\u9039\u8FF8\u904F\u9050\u9051\u9052\u900E\u9049\u903E\u9056\u9058\u905E\u9068\u906F\u9076\u96A8\u9072\u9082\u907D\u9081\u9080\u908A\u9089\u908F\u90A8\u90AF\u90B1\u90B5\u90E2\u90E4\u6248\u90DB\u9102\u9112\u9119\u9132\u9130\u914A\u9156\u9158\u9163\u9165\u9169\u9173\u9172\u918B\u9189\u9182\u91A2\u91AB\u91AF\u91AA\u91B5\u91B4\u91BA\u91C0\u91C1\u91C9\u91CB\u91D0\u91D6\u91DF\u91E1\u91DB\u91FC\u91F5\u91F6\u921E\u91FF\u9214\u922C\u9215\u9211\u925E\u9257\u9245\u9249\u9264\u9248\u9295\u923F\u924B\u9250\u929C\u9296\u9293\u929B\u925A\u92CF\u92B9\u92B7\u92E9\u930F\u92FA\u9344\u932E"], + ["e840", "\u9319\u9322\u931A\u9323\u933A\u9335\u933B\u935C\u9360\u937C\u936E\u9356\u93B0\u93AC\u93AD\u9394\u93B9\u93D6\u93D7\u93E8\u93E5\u93D8\u93C3\u93DD\u93D0\u93C8\u93E4\u941A\u9414\u9413\u9403\u9407\u9410\u9436\u942B\u9435\u9421\u943A\u9441\u9452\u9444\u945B\u9460\u9462\u945E\u946A\u9229\u9470\u9475\u9477\u947D\u945A\u947C\u947E\u9481\u947F\u9582\u9587\u958A\u9594\u9596\u9598\u9599"], + ["e880", "\u95A0\u95A8\u95A7\u95AD\u95BC\u95BB\u95B9\u95BE\u95CA\u6FF6\u95C3\u95CD\u95CC\u95D5\u95D4\u95D6\u95DC\u95E1\u95E5\u95E2\u9621\u9628\u962E\u962F\u9642\u964C\u964F\u964B\u9677\u965C\u965E\u965D\u965F\u9666\u9672\u966C\u968D\u9698\u9695\u9697\u96AA\u96A7\u96B1\u96B2\u96B0\u96B4\u96B6\u96B8\u96B9\u96CE\u96CB\u96C9\u96CD\u894D\u96DC\u970D\u96D5\u96F9\u9704\u9706\u9708\u9713\u970E\u9711\u970F\u9716\u9719\u9724\u972A\u9730\u9739\u973D\u973E\u9744\u9746\u9748\u9742\u9749\u975C\u9760\u9764\u9766\u9768\u52D2\u976B\u9771\u9779\u9785\u977C\u9781\u977A\u9786\u978B\u978F\u9790\u979C\u97A8\u97A6\u97A3\u97B3\u97B4\u97C3\u97C6\u97C8\u97CB\u97DC\u97ED\u9F4F\u97F2\u7ADF\u97F6\u97F5\u980F\u980C\u9838\u9824\u9821\u9837\u983D\u9846\u984F\u984B\u986B\u986F\u9870"], + ["e940", "\u9871\u9874\u9873\u98AA\u98AF\u98B1\u98B6\u98C4\u98C3\u98C6\u98E9\u98EB\u9903\u9909\u9912\u9914\u9918\u9921\u991D\u991E\u9924\u9920\u992C\u992E\u993D\u993E\u9942\u9949\u9945\u9950\u994B\u9951\u9952\u994C\u9955\u9997\u9998\u99A5\u99AD\u99AE\u99BC\u99DF\u99DB\u99DD\u99D8\u99D1\u99ED\u99EE\u99F1\u99F2\u99FB\u99F8\u9A01\u9A0F\u9A05\u99E2\u9A19\u9A2B\u9A37\u9A45\u9A42\u9A40\u9A43"], + ["e980", "\u9A3E\u9A55\u9A4D\u9A5B\u9A57\u9A5F\u9A62\u9A65\u9A64\u9A69\u9A6B\u9A6A\u9AAD\u9AB0\u9ABC\u9AC0\u9ACF\u9AD1\u9AD3\u9AD4\u9ADE\u9ADF\u9AE2\u9AE3\u9AE6\u9AEF\u9AEB\u9AEE\u9AF4\u9AF1\u9AF7\u9AFB\u9B06\u9B18\u9B1A\u9B1F\u9B22\u9B23\u9B25\u9B27\u9B28\u9B29\u9B2A\u9B2E\u9B2F\u9B32\u9B44\u9B43\u9B4F\u9B4D\u9B4E\u9B51\u9B58\u9B74\u9B93\u9B83\u9B91\u9B96\u9B97\u9B9F\u9BA0\u9BA8\u9BB4\u9BC0\u9BCA\u9BB9\u9BC6\u9BCF\u9BD1\u9BD2\u9BE3\u9BE2\u9BE4\u9BD4\u9BE1\u9C3A\u9BF2\u9BF1\u9BF0\u9C15\u9C14\u9C09\u9C13\u9C0C\u9C06\u9C08\u9C12\u9C0A\u9C04\u9C2E\u9C1B\u9C25\u9C24\u9C21\u9C30\u9C47\u9C32\u9C46\u9C3E\u9C5A\u9C60\u9C67\u9C76\u9C78\u9CE7\u9CEC\u9CF0\u9D09\u9D08\u9CEB\u9D03\u9D06\u9D2A\u9D26\u9DAF\u9D23\u9D1F\u9D44\u9D15\u9D12\u9D41\u9D3F\u9D3E\u9D46\u9D48"], + ["ea40", "\u9D5D\u9D5E\u9D64\u9D51\u9D50\u9D59\u9D72\u9D89\u9D87\u9DAB\u9D6F\u9D7A\u9D9A\u9DA4\u9DA9\u9DB2\u9DC4\u9DC1\u9DBB\u9DB8\u9DBA\u9DC6\u9DCF\u9DC2\u9DD9\u9DD3\u9DF8\u9DE6\u9DED\u9DEF\u9DFD\u9E1A\u9E1B\u9E1E\u9E75\u9E79\u9E7D\u9E81\u9E88\u9E8B\u9E8C\u9E92\u9E95\u9E91\u9E9D\u9EA5\u9EA9\u9EB8\u9EAA\u9EAD\u9761\u9ECC\u9ECE\u9ECF\u9ED0\u9ED4\u9EDC\u9EDE\u9EDD\u9EE0\u9EE5\u9EE8\u9EEF"], + ["ea80", "\u9EF4\u9EF6\u9EF7\u9EF9\u9EFB\u9EFC\u9EFD\u9F07\u9F08\u76B7\u9F15\u9F21\u9F2C\u9F3E\u9F4A\u9F52\u9F54\u9F63\u9F5F\u9F60\u9F61\u9F66\u9F67\u9F6C\u9F6A\u9F77\u9F72\u9F76\u9F95\u9F9C\u9FA0\u582F\u69C7\u9059\u7464\u51DC\u7199"], + ["ed40", "\u7E8A\u891C\u9348\u9288\u84DC\u4FC9\u70BB\u6631\u68C8\u92F9\u66FB\u5F45\u4E28\u4EE1\u4EFC\u4F00\u4F03\u4F39\u4F56\u4F92\u4F8A\u4F9A\u4F94\u4FCD\u5040\u5022\u4FFF\u501E\u5046\u5070\u5042\u5094\u50F4\u50D8\u514A\u5164\u519D\u51BE\u51EC\u5215\u529C\u52A6\u52C0\u52DB\u5300\u5307\u5324\u5372\u5393\u53B2\u53DD\uFA0E\u549C\u548A\u54A9\u54FF\u5586\u5759\u5765\u57AC\u57C8\u57C7\uFA0F"], + ["ed80", "\uFA10\u589E\u58B2\u590B\u5953\u595B\u595D\u5963\u59A4\u59BA\u5B56\u5BC0\u752F\u5BD8\u5BEC\u5C1E\u5CA6\u5CBA\u5CF5\u5D27\u5D53\uFA11\u5D42\u5D6D\u5DB8\u5DB9\u5DD0\u5F21\u5F34\u5F67\u5FB7\u5FDE\u605D\u6085\u608A\u60DE\u60D5\u6120\u60F2\u6111\u6137\u6130\u6198\u6213\u62A6\u63F5\u6460\u649D\u64CE\u654E\u6600\u6615\u663B\u6609\u662E\u661E\u6624\u6665\u6657\u6659\uFA12\u6673\u6699\u66A0\u66B2\u66BF\u66FA\u670E\uF929\u6766\u67BB\u6852\u67C0\u6801\u6844\u68CF\uFA13\u6968\uFA14\u6998\u69E2\u6A30\u6A6B\u6A46\u6A73\u6A7E\u6AE2\u6AE4\u6BD6\u6C3F\u6C5C\u6C86\u6C6F\u6CDA\u6D04\u6D87\u6D6F\u6D96\u6DAC\u6DCF\u6DF8\u6DF2\u6DFC\u6E39\u6E5C\u6E27\u6E3C\u6EBF\u6F88\u6FB5\u6FF5\u7005\u7007\u7028\u7085\u70AB\u710F\u7104\u715C\u7146\u7147\uFA15\u71C1\u71FE\u72B1"], + ["ee40", "\u72BE\u7324\uFA16\u7377\u73BD\u73C9\u73D6\u73E3\u73D2\u7407\u73F5\u7426\u742A\u7429\u742E\u7462\u7489\u749F\u7501\u756F\u7682\u769C\u769E\u769B\u76A6\uFA17\u7746\u52AF\u7821\u784E\u7864\u787A\u7930\uFA18\uFA19\uFA1A\u7994\uFA1B\u799B\u7AD1\u7AE7\uFA1C\u7AEB\u7B9E\uFA1D\u7D48\u7D5C\u7DB7\u7DA0\u7DD6\u7E52\u7F47\u7FA1\uFA1E\u8301\u8362\u837F\u83C7\u83F6\u8448\u84B4\u8553\u8559"], + ["ee80", "\u856B\uFA1F\u85B0\uFA20\uFA21\u8807\u88F5\u8A12\u8A37\u8A79\u8AA7\u8ABE\u8ADF\uFA22\u8AF6\u8B53\u8B7F\u8CF0\u8CF4\u8D12\u8D76\uFA23\u8ECF\uFA24\uFA25\u9067\u90DE\uFA26\u9115\u9127\u91DA\u91D7\u91DE\u91ED\u91EE\u91E4\u91E5\u9206\u9210\u920A\u923A\u9240\u923C\u924E\u9259\u9251\u9239\u9267\u92A7\u9277\u9278\u92E7\u92D7\u92D9\u92D0\uFA27\u92D5\u92E0\u92D3\u9325\u9321\u92FB\uFA28\u931E\u92FF\u931D\u9302\u9370\u9357\u93A4\u93C6\u93DE\u93F8\u9431\u9445\u9448\u9592\uF9DC\uFA29\u969D\u96AF\u9733\u973B\u9743\u974D\u974F\u9751\u9755\u9857\u9865\uFA2A\uFA2B\u9927\uFA2C\u999E\u9A4E\u9AD9\u9ADC\u9B75\u9B72\u9B8F\u9BB1\u9BBB\u9C00\u9D70\u9D6B\uFA2D\u9E19\u9ED1"], + ["eeef", "\u2170", 9, "\uFFE2\uFFE4\uFF07\uFF02"], + ["f040", "\uE000", 62], + ["f080", "\uE03F", 124], + ["f140", "\uE0BC", 62], + ["f180", "\uE0FB", 124], + ["f240", "\uE178", 62], + ["f280", "\uE1B7", 124], + ["f340", "\uE234", 62], + ["f380", "\uE273", 124], + ["f440", "\uE2F0", 62], + ["f480", "\uE32F", 124], + ["f540", "\uE3AC", 62], + ["f580", "\uE3EB", 124], + ["f640", "\uE468", 62], + ["f680", "\uE4A7", 124], + ["f740", "\uE524", 62], + ["f780", "\uE563", 124], + ["f840", "\uE5E0", 62], + ["f880", "\uE61F", 124], + ["f940", "\uE69C"], + ["fa40", "\u2170", 9, "\u2160", 9, "\uFFE2\uFFE4\uFF07\uFF02\u3231\u2116\u2121\u2235\u7E8A\u891C\u9348\u9288\u84DC\u4FC9\u70BB\u6631\u68C8\u92F9\u66FB\u5F45\u4E28\u4EE1\u4EFC\u4F00\u4F03\u4F39\u4F56\u4F92\u4F8A\u4F9A\u4F94\u4FCD\u5040\u5022\u4FFF\u501E\u5046\u5070\u5042\u5094\u50F4\u50D8\u514A"], + ["fa80", "\u5164\u519D\u51BE\u51EC\u5215\u529C\u52A6\u52C0\u52DB\u5300\u5307\u5324\u5372\u5393\u53B2\u53DD\uFA0E\u549C\u548A\u54A9\u54FF\u5586\u5759\u5765\u57AC\u57C8\u57C7\uFA0F\uFA10\u589E\u58B2\u590B\u5953\u595B\u595D\u5963\u59A4\u59BA\u5B56\u5BC0\u752F\u5BD8\u5BEC\u5C1E\u5CA6\u5CBA\u5CF5\u5D27\u5D53\uFA11\u5D42\u5D6D\u5DB8\u5DB9\u5DD0\u5F21\u5F34\u5F67\u5FB7\u5FDE\u605D\u6085\u608A\u60DE\u60D5\u6120\u60F2\u6111\u6137\u6130\u6198\u6213\u62A6\u63F5\u6460\u649D\u64CE\u654E\u6600\u6615\u663B\u6609\u662E\u661E\u6624\u6665\u6657\u6659\uFA12\u6673\u6699\u66A0\u66B2\u66BF\u66FA\u670E\uF929\u6766\u67BB\u6852\u67C0\u6801\u6844\u68CF\uFA13\u6968\uFA14\u6998\u69E2\u6A30\u6A6B\u6A46\u6A73\u6A7E\u6AE2\u6AE4\u6BD6\u6C3F\u6C5C\u6C86\u6C6F\u6CDA\u6D04\u6D87\u6D6F"], + ["fb40", "\u6D96\u6DAC\u6DCF\u6DF8\u6DF2\u6DFC\u6E39\u6E5C\u6E27\u6E3C\u6EBF\u6F88\u6FB5\u6FF5\u7005\u7007\u7028\u7085\u70AB\u710F\u7104\u715C\u7146\u7147\uFA15\u71C1\u71FE\u72B1\u72BE\u7324\uFA16\u7377\u73BD\u73C9\u73D6\u73E3\u73D2\u7407\u73F5\u7426\u742A\u7429\u742E\u7462\u7489\u749F\u7501\u756F\u7682\u769C\u769E\u769B\u76A6\uFA17\u7746\u52AF\u7821\u784E\u7864\u787A\u7930\uFA18\uFA19"], + ["fb80", "\uFA1A\u7994\uFA1B\u799B\u7AD1\u7AE7\uFA1C\u7AEB\u7B9E\uFA1D\u7D48\u7D5C\u7DB7\u7DA0\u7DD6\u7E52\u7F47\u7FA1\uFA1E\u8301\u8362\u837F\u83C7\u83F6\u8448\u84B4\u8553\u8559\u856B\uFA1F\u85B0\uFA20\uFA21\u8807\u88F5\u8A12\u8A37\u8A79\u8AA7\u8ABE\u8ADF\uFA22\u8AF6\u8B53\u8B7F\u8CF0\u8CF4\u8D12\u8D76\uFA23\u8ECF\uFA24\uFA25\u9067\u90DE\uFA26\u9115\u9127\u91DA\u91D7\u91DE\u91ED\u91EE\u91E4\u91E5\u9206\u9210\u920A\u923A\u9240\u923C\u924E\u9259\u9251\u9239\u9267\u92A7\u9277\u9278\u92E7\u92D7\u92D9\u92D0\uFA27\u92D5\u92E0\u92D3\u9325\u9321\u92FB\uFA28\u931E\u92FF\u931D\u9302\u9370\u9357\u93A4\u93C6\u93DE\u93F8\u9431\u9445\u9448\u9592\uF9DC\uFA29\u969D\u96AF\u9733\u973B\u9743\u974D\u974F\u9751\u9755\u9857\u9865\uFA2A\uFA2B\u9927\uFA2C\u999E\u9A4E\u9AD9"], + ["fc40", "\u9ADC\u9B75\u9B72\u9B8F\u9BB1\u9BBB\u9C00\u9D70\u9D6B\uFA2D\u9E19\u9ED1"] + ]; + } +}); + +// node_modules/iconv-lite/encodings/tables/eucjp.json +var require_eucjp = __commonJS({ + "node_modules/iconv-lite/encodings/tables/eucjp.json"(exports2, module2) { + module2.exports = [ + ["0", "\0", 127], + ["8ea1", "\uFF61", 62], + ["a1a1", "\u3000\u3001\u3002\uFF0C\uFF0E\u30FB\uFF1A\uFF1B\uFF1F\uFF01\u309B\u309C\xB4\uFF40\xA8\uFF3E\uFFE3\uFF3F\u30FD\u30FE\u309D\u309E\u3003\u4EDD\u3005\u3006\u3007\u30FC\u2015\u2010\uFF0F\uFF3C\uFF5E\u2225\uFF5C\u2026\u2025\u2018\u2019\u201C\u201D\uFF08\uFF09\u3014\u3015\uFF3B\uFF3D\uFF5B\uFF5D\u3008", 9, "\uFF0B\uFF0D\xB1\xD7\xF7\uFF1D\u2260\uFF1C\uFF1E\u2266\u2267\u221E\u2234\u2642\u2640\xB0\u2032\u2033\u2103\uFFE5\uFF04\uFFE0\uFFE1\uFF05\uFF03\uFF06\uFF0A\uFF20\xA7\u2606\u2605\u25CB\u25CF\u25CE\u25C7"], + ["a2a1", "\u25C6\u25A1\u25A0\u25B3\u25B2\u25BD\u25BC\u203B\u3012\u2192\u2190\u2191\u2193\u3013"], + ["a2ba", "\u2208\u220B\u2286\u2287\u2282\u2283\u222A\u2229"], + ["a2ca", "\u2227\u2228\uFFE2\u21D2\u21D4\u2200\u2203"], + ["a2dc", "\u2220\u22A5\u2312\u2202\u2207\u2261\u2252\u226A\u226B\u221A\u223D\u221D\u2235\u222B\u222C"], + ["a2f2", "\u212B\u2030\u266F\u266D\u266A\u2020\u2021\xB6"], + ["a2fe", "\u25EF"], + ["a3b0", "\uFF10", 9], + ["a3c1", "\uFF21", 25], + ["a3e1", "\uFF41", 25], + ["a4a1", "\u3041", 82], + ["a5a1", "\u30A1", 85], + ["a6a1", "\u0391", 16, "\u03A3", 6], + ["a6c1", "\u03B1", 16, "\u03C3", 6], + ["a7a1", "\u0410", 5, "\u0401\u0416", 25], + ["a7d1", "\u0430", 5, "\u0451\u0436", 25], + ["a8a1", "\u2500\u2502\u250C\u2510\u2518\u2514\u251C\u252C\u2524\u2534\u253C\u2501\u2503\u250F\u2513\u251B\u2517\u2523\u2533\u252B\u253B\u254B\u2520\u252F\u2528\u2537\u253F\u251D\u2530\u2525\u2538\u2542"], + ["ada1", "\u2460", 19, "\u2160", 9], + ["adc0", "\u3349\u3314\u3322\u334D\u3318\u3327\u3303\u3336\u3351\u3357\u330D\u3326\u3323\u332B\u334A\u333B\u339C\u339D\u339E\u338E\u338F\u33C4\u33A1"], + ["addf", "\u337B\u301D\u301F\u2116\u33CD\u2121\u32A4", 4, "\u3231\u3232\u3239\u337E\u337D\u337C\u2252\u2261\u222B\u222E\u2211\u221A\u22A5\u2220\u221F\u22BF\u2235\u2229\u222A"], + ["b0a1", "\u4E9C\u5516\u5A03\u963F\u54C0\u611B\u6328\u59F6\u9022\u8475\u831C\u7A50\u60AA\u63E1\u6E25\u65ED\u8466\u82A6\u9BF5\u6893\u5727\u65A1\u6271\u5B9B\u59D0\u867B\u98F4\u7D62\u7DBE\u9B8E\u6216\u7C9F\u88B7\u5B89\u5EB5\u6309\u6697\u6848\u95C7\u978D\u674F\u4EE5\u4F0A\u4F4D\u4F9D\u5049\u56F2\u5937\u59D4\u5A01\u5C09\u60DF\u610F\u6170\u6613\u6905\u70BA\u754F\u7570\u79FB\u7DAD\u7DEF\u80C3\u840E\u8863\u8B02\u9055\u907A\u533B\u4E95\u4EA5\u57DF\u80B2\u90C1\u78EF\u4E00\u58F1\u6EA2\u9038\u7A32\u8328\u828B\u9C2F\u5141\u5370\u54BD\u54E1\u56E0\u59FB\u5F15\u98F2\u6DEB\u80E4\u852D"], + ["b1a1", "\u9662\u9670\u96A0\u97FB\u540B\u53F3\u5B87\u70CF\u7FBD\u8FC2\u96E8\u536F\u9D5C\u7ABA\u4E11\u7893\u81FC\u6E26\u5618\u5504\u6B1D\u851A\u9C3B\u59E5\u53A9\u6D66\u74DC\u958F\u5642\u4E91\u904B\u96F2\u834F\u990C\u53E1\u55B6\u5B30\u5F71\u6620\u66F3\u6804\u6C38\u6CF3\u6D29\u745B\u76C8\u7A4E\u9834\u82F1\u885B\u8A60\u92ED\u6DB2\u75AB\u76CA\u99C5\u60A6\u8B01\u8D8A\u95B2\u698E\u53AD\u5186\u5712\u5830\u5944\u5BB4\u5EF6\u6028\u63A9\u63F4\u6CBF\u6F14\u708E\u7114\u7159\u71D5\u733F\u7E01\u8276\u82D1\u8597\u9060\u925B\u9D1B\u5869\u65BC\u6C5A\u7525\u51F9\u592E\u5965\u5F80\u5FDC"], + ["b2a1", "\u62BC\u65FA\u6A2A\u6B27\u6BB4\u738B\u7FC1\u8956\u9D2C\u9D0E\u9EC4\u5CA1\u6C96\u837B\u5104\u5C4B\u61B6\u81C6\u6876\u7261\u4E59\u4FFA\u5378\u6069\u6E29\u7A4F\u97F3\u4E0B\u5316\u4EEE\u4F55\u4F3D\u4FA1\u4F73\u52A0\u53EF\u5609\u590F\u5AC1\u5BB6\u5BE1\u79D1\u6687\u679C\u67B6\u6B4C\u6CB3\u706B\u73C2\u798D\u79BE\u7A3C\u7B87\u82B1\u82DB\u8304\u8377\u83EF\u83D3\u8766\u8AB2\u5629\u8CA8\u8FE6\u904E\u971E\u868A\u4FC4\u5CE8\u6211\u7259\u753B\u81E5\u82BD\u86FE\u8CC0\u96C5\u9913\u99D5\u4ECB\u4F1A\u89E3\u56DE\u584A\u58CA\u5EFB\u5FEB\u602A\u6094\u6062\u61D0\u6212\u62D0\u6539"], + ["b3a1", "\u9B41\u6666\u68B0\u6D77\u7070\u754C\u7686\u7D75\u82A5\u87F9\u958B\u968E\u8C9D\u51F1\u52BE\u5916\u54B3\u5BB3\u5D16\u6168\u6982\u6DAF\u788D\u84CB\u8857\u8A72\u93A7\u9AB8\u6D6C\u99A8\u86D9\u57A3\u67FF\u86CE\u920E\u5283\u5687\u5404\u5ED3\u62E1\u64B9\u683C\u6838\u6BBB\u7372\u78BA\u7A6B\u899A\u89D2\u8D6B\u8F03\u90ED\u95A3\u9694\u9769\u5B66\u5CB3\u697D\u984D\u984E\u639B\u7B20\u6A2B\u6A7F\u68B6\u9C0D\u6F5F\u5272\u559D\u6070\u62EC\u6D3B\u6E07\u6ED1\u845B\u8910\u8F44\u4E14\u9C39\u53F6\u691B\u6A3A\u9784\u682A\u515C\u7AC3\u84B2\u91DC\u938C\u565B\u9D28\u6822\u8305\u8431"], + ["b4a1", "\u7CA5\u5208\u82C5\u74E6\u4E7E\u4F83\u51A0\u5BD2\u520A\u52D8\u52E7\u5DFB\u559A\u582A\u59E6\u5B8C\u5B98\u5BDB\u5E72\u5E79\u60A3\u611F\u6163\u61BE\u63DB\u6562\u67D1\u6853\u68FA\u6B3E\u6B53\u6C57\u6F22\u6F97\u6F45\u74B0\u7518\u76E3\u770B\u7AFF\u7BA1\u7C21\u7DE9\u7F36\u7FF0\u809D\u8266\u839E\u89B3\u8ACC\u8CAB\u9084\u9451\u9593\u9591\u95A2\u9665\u97D3\u9928\u8218\u4E38\u542B\u5CB8\u5DCC\u73A9\u764C\u773C\u5CA9\u7FEB\u8D0B\u96C1\u9811\u9854\u9858\u4F01\u4F0E\u5371\u559C\u5668\u57FA\u5947\u5B09\u5BC4\u5C90\u5E0C\u5E7E\u5FCC\u63EE\u673A\u65D7\u65E2\u671F\u68CB\u68C4"], + ["b5a1", "\u6A5F\u5E30\u6BC5\u6C17\u6C7D\u757F\u7948\u5B63\u7A00\u7D00\u5FBD\u898F\u8A18\u8CB4\u8D77\u8ECC\u8F1D\u98E2\u9A0E\u9B3C\u4E80\u507D\u5100\u5993\u5B9C\u622F\u6280\u64EC\u6B3A\u72A0\u7591\u7947\u7FA9\u87FB\u8ABC\u8B70\u63AC\u83CA\u97A0\u5409\u5403\u55AB\u6854\u6A58\u8A70\u7827\u6775\u9ECD\u5374\u5BA2\u811A\u8650\u9006\u4E18\u4E45\u4EC7\u4F11\u53CA\u5438\u5BAE\u5F13\u6025\u6551\u673D\u6C42\u6C72\u6CE3\u7078\u7403\u7A76\u7AAE\u7B08\u7D1A\u7CFE\u7D66\u65E7\u725B\u53BB\u5C45\u5DE8\u62D2\u62E0\u6319\u6E20\u865A\u8A31\u8DDD\u92F8\u6F01\u79A6\u9B5A\u4EA8\u4EAB\u4EAC"], + ["b6a1", "\u4F9B\u4FA0\u50D1\u5147\u7AF6\u5171\u51F6\u5354\u5321\u537F\u53EB\u55AC\u5883\u5CE1\u5F37\u5F4A\u602F\u6050\u606D\u631F\u6559\u6A4B\u6CC1\u72C2\u72ED\u77EF\u80F8\u8105\u8208\u854E\u90F7\u93E1\u97FF\u9957\u9A5A\u4EF0\u51DD\u5C2D\u6681\u696D\u5C40\u66F2\u6975\u7389\u6850\u7C81\u50C5\u52E4\u5747\u5DFE\u9326\u65A4\u6B23\u6B3D\u7434\u7981\u79BD\u7B4B\u7DCA\u82B9\u83CC\u887F\u895F\u8B39\u8FD1\u91D1\u541F\u9280\u4E5D\u5036\u53E5\u533A\u72D7\u7396\u77E9\u82E6\u8EAF\u99C6\u99C8\u99D2\u5177\u611A\u865E\u55B0\u7A7A\u5076\u5BD3\u9047\u9685\u4E32\u6ADB\u91E7\u5C51\u5C48"], + ["b7a1", "\u6398\u7A9F\u6C93\u9774\u8F61\u7AAA\u718A\u9688\u7C82\u6817\u7E70\u6851\u936C\u52F2\u541B\u85AB\u8A13\u7FA4\u8ECD\u90E1\u5366\u8888\u7941\u4FC2\u50BE\u5211\u5144\u5553\u572D\u73EA\u578B\u5951\u5F62\u5F84\u6075\u6176\u6167\u61A9\u63B2\u643A\u656C\u666F\u6842\u6E13\u7566\u7A3D\u7CFB\u7D4C\u7D99\u7E4B\u7F6B\u830E\u834A\u86CD\u8A08\u8A63\u8B66\u8EFD\u981A\u9D8F\u82B8\u8FCE\u9BE8\u5287\u621F\u6483\u6FC0\u9699\u6841\u5091\u6B20\u6C7A\u6F54\u7A74\u7D50\u8840\u8A23\u6708\u4EF6\u5039\u5026\u5065\u517C\u5238\u5263\u55A7\u570F\u5805\u5ACC\u5EFA\u61B2\u61F8\u62F3\u6372"], + ["b8a1", "\u691C\u6A29\u727D\u72AC\u732E\u7814\u786F\u7D79\u770C\u80A9\u898B\u8B19\u8CE2\u8ED2\u9063\u9375\u967A\u9855\u9A13\u9E78\u5143\u539F\u53B3\u5E7B\u5F26\u6E1B\u6E90\u7384\u73FE\u7D43\u8237\u8A00\u8AFA\u9650\u4E4E\u500B\u53E4\u547C\u56FA\u59D1\u5B64\u5DF1\u5EAB\u5F27\u6238\u6545\u67AF\u6E56\u72D0\u7CCA\u88B4\u80A1\u80E1\u83F0\u864E\u8A87\u8DE8\u9237\u96C7\u9867\u9F13\u4E94\u4E92\u4F0D\u5348\u5449\u543E\u5A2F\u5F8C\u5FA1\u609F\u68A7\u6A8E\u745A\u7881\u8A9E\u8AA4\u8B77\u9190\u4E5E\u9BC9\u4EA4\u4F7C\u4FAF\u5019\u5016\u5149\u516C\u529F\u52B9\u52FE\u539A\u53E3\u5411"], + ["b9a1", "\u540E\u5589\u5751\u57A2\u597D\u5B54\u5B5D\u5B8F\u5DE5\u5DE7\u5DF7\u5E78\u5E83\u5E9A\u5EB7\u5F18\u6052\u614C\u6297\u62D8\u63A7\u653B\u6602\u6643\u66F4\u676D\u6821\u6897\u69CB\u6C5F\u6D2A\u6D69\u6E2F\u6E9D\u7532\u7687\u786C\u7A3F\u7CE0\u7D05\u7D18\u7D5E\u7DB1\u8015\u8003\u80AF\u80B1\u8154\u818F\u822A\u8352\u884C\u8861\u8B1B\u8CA2\u8CFC\u90CA\u9175\u9271\u783F\u92FC\u95A4\u964D\u9805\u9999\u9AD8\u9D3B\u525B\u52AB\u53F7\u5408\u58D5\u62F7\u6FE0\u8C6A\u8F5F\u9EB9\u514B\u523B\u544A\u56FD\u7A40\u9177\u9D60\u9ED2\u7344\u6F09\u8170\u7511\u5FFD\u60DA\u9AA8\u72DB\u8FBC"], + ["baa1", "\u6B64\u9803\u4ECA\u56F0\u5764\u58BE\u5A5A\u6068\u61C7\u660F\u6606\u6839\u68B1\u6DF7\u75D5\u7D3A\u826E\u9B42\u4E9B\u4F50\u53C9\u5506\u5D6F\u5DE6\u5DEE\u67FB\u6C99\u7473\u7802\u8A50\u9396\u88DF\u5750\u5EA7\u632B\u50B5\u50AC\u518D\u6700\u54C9\u585E\u59BB\u5BB0\u5F69\u624D\u63A1\u683D\u6B73\u6E08\u707D\u91C7\u7280\u7815\u7826\u796D\u658E\u7D30\u83DC\u88C1\u8F09\u969B\u5264\u5728\u6750\u7F6A\u8CA1\u51B4\u5742\u962A\u583A\u698A\u80B4\u54B2\u5D0E\u57FC\u7895\u9DFA\u4F5C\u524A\u548B\u643E\u6628\u6714\u67F5\u7A84\u7B56\u7D22\u932F\u685C\u9BAD\u7B39\u5319\u518A\u5237"], + ["bba1", "\u5BDF\u62F6\u64AE\u64E6\u672D\u6BBA\u85A9\u96D1\u7690\u9BD6\u634C\u9306\u9BAB\u76BF\u6652\u4E09\u5098\u53C2\u5C71\u60E8\u6492\u6563\u685F\u71E6\u73CA\u7523\u7B97\u7E82\u8695\u8B83\u8CDB\u9178\u9910\u65AC\u66AB\u6B8B\u4ED5\u4ED4\u4F3A\u4F7F\u523A\u53F8\u53F2\u55E3\u56DB\u58EB\u59CB\u59C9\u59FF\u5B50\u5C4D\u5E02\u5E2B\u5FD7\u601D\u6307\u652F\u5B5C\u65AF\u65BD\u65E8\u679D\u6B62\u6B7B\u6C0F\u7345\u7949\u79C1\u7CF8\u7D19\u7D2B\u80A2\u8102\u81F3\u8996\u8A5E\u8A69\u8A66\u8A8C\u8AEE\u8CC7\u8CDC\u96CC\u98FC\u6B6F\u4E8B\u4F3C\u4F8D\u5150\u5B57\u5BFA\u6148\u6301\u6642"], + ["bca1", "\u6B21\u6ECB\u6CBB\u723E\u74BD\u75D4\u78C1\u793A\u800C\u8033\u81EA\u8494\u8F9E\u6C50\u9E7F\u5F0F\u8B58\u9D2B\u7AFA\u8EF8\u5B8D\u96EB\u4E03\u53F1\u57F7\u5931\u5AC9\u5BA4\u6089\u6E7F\u6F06\u75BE\u8CEA\u5B9F\u8500\u7BE0\u5072\u67F4\u829D\u5C61\u854A\u7E1E\u820E\u5199\u5C04\u6368\u8D66\u659C\u716E\u793E\u7D17\u8005\u8B1D\u8ECA\u906E\u86C7\u90AA\u501F\u52FA\u5C3A\u6753\u707C\u7235\u914C\u91C8\u932B\u82E5\u5BC2\u5F31\u60F9\u4E3B\u53D6\u5B88\u624B\u6731\u6B8A\u72E9\u73E0\u7A2E\u816B\u8DA3\u9152\u9996\u5112\u53D7\u546A\u5BFF\u6388\u6A39\u7DAC\u9700\u56DA\u53CE\u5468"], + ["bda1", "\u5B97\u5C31\u5DDE\u4FEE\u6101\u62FE\u6D32\u79C0\u79CB\u7D42\u7E4D\u7FD2\u81ED\u821F\u8490\u8846\u8972\u8B90\u8E74\u8F2F\u9031\u914B\u916C\u96C6\u919C\u4EC0\u4F4F\u5145\u5341\u5F93\u620E\u67D4\u6C41\u6E0B\u7363\u7E26\u91CD\u9283\u53D4\u5919\u5BBF\u6DD1\u795D\u7E2E\u7C9B\u587E\u719F\u51FA\u8853\u8FF0\u4FCA\u5CFB\u6625\u77AC\u7AE3\u821C\u99FF\u51C6\u5FAA\u65EC\u696F\u6B89\u6DF3\u6E96\u6F64\u76FE\u7D14\u5DE1\u9075\u9187\u9806\u51E6\u521D\u6240\u6691\u66D9\u6E1A\u5EB6\u7DD2\u7F72\u66F8\u85AF\u85F7\u8AF8\u52A9\u53D9\u5973\u5E8F\u5F90\u6055\u92E4\u9664\u50B7\u511F"], + ["bea1", "\u52DD\u5320\u5347\u53EC\u54E8\u5546\u5531\u5617\u5968\u59BE\u5A3C\u5BB5\u5C06\u5C0F\u5C11\u5C1A\u5E84\u5E8A\u5EE0\u5F70\u627F\u6284\u62DB\u638C\u6377\u6607\u660C\u662D\u6676\u677E\u68A2\u6A1F\u6A35\u6CBC\u6D88\u6E09\u6E58\u713C\u7126\u7167\u75C7\u7701\u785D\u7901\u7965\u79F0\u7AE0\u7B11\u7CA7\u7D39\u8096\u83D6\u848B\u8549\u885D\u88F3\u8A1F\u8A3C\u8A54\u8A73\u8C61\u8CDE\u91A4\u9266\u937E\u9418\u969C\u9798\u4E0A\u4E08\u4E1E\u4E57\u5197\u5270\u57CE\u5834\u58CC\u5B22\u5E38\u60C5\u64FE\u6761\u6756\u6D44\u72B6\u7573\u7A63\u84B8\u8B72\u91B8\u9320\u5631\u57F4\u98FE"], + ["bfa1", "\u62ED\u690D\u6B96\u71ED\u7E54\u8077\u8272\u89E6\u98DF\u8755\u8FB1\u5C3B\u4F38\u4FE1\u4FB5\u5507\u5A20\u5BDD\u5BE9\u5FC3\u614E\u632F\u65B0\u664B\u68EE\u699B\u6D78\u6DF1\u7533\u75B9\u771F\u795E\u79E6\u7D33\u81E3\u82AF\u85AA\u89AA\u8A3A\u8EAB\u8F9B\u9032\u91DD\u9707\u4EBA\u4EC1\u5203\u5875\u58EC\u5C0B\u751A\u5C3D\u814E\u8A0A\u8FC5\u9663\u976D\u7B25\u8ACF\u9808\u9162\u56F3\u53A8\u9017\u5439\u5782\u5E25\u63A8\u6C34\u708A\u7761\u7C8B\u7FE0\u8870\u9042\u9154\u9310\u9318\u968F\u745E\u9AC4\u5D07\u5D69\u6570\u67A2\u8DA8\u96DB\u636E\u6749\u6919\u83C5\u9817\u96C0\u88FE"], + ["c0a1", "\u6F84\u647A\u5BF8\u4E16\u702C\u755D\u662F\u51C4\u5236\u52E2\u59D3\u5F81\u6027\u6210\u653F\u6574\u661F\u6674\u68F2\u6816\u6B63\u6E05\u7272\u751F\u76DB\u7CBE\u8056\u58F0\u88FD\u897F\u8AA0\u8A93\u8ACB\u901D\u9192\u9752\u9759\u6589\u7A0E\u8106\u96BB\u5E2D\u60DC\u621A\u65A5\u6614\u6790\u77F3\u7A4D\u7C4D\u7E3E\u810A\u8CAC\u8D64\u8DE1\u8E5F\u78A9\u5207\u62D9\u63A5\u6442\u6298\u8A2D\u7A83\u7BC0\u8AAC\u96EA\u7D76\u820C\u8749\u4ED9\u5148\u5343\u5360\u5BA3\u5C02\u5C16\u5DDD\u6226\u6247\u64B0\u6813\u6834\u6CC9\u6D45\u6D17\u67D3\u6F5C\u714E\u717D\u65CB\u7A7F\u7BAD\u7DDA"], + ["c1a1", "\u7E4A\u7FA8\u817A\u821B\u8239\u85A6\u8A6E\u8CCE\u8DF5\u9078\u9077\u92AD\u9291\u9583\u9BAE\u524D\u5584\u6F38\u7136\u5168\u7985\u7E55\u81B3\u7CCE\u564C\u5851\u5CA8\u63AA\u66FE\u66FD\u695A\u72D9\u758F\u758E\u790E\u7956\u79DF\u7C97\u7D20\u7D44\u8607\u8A34\u963B\u9061\u9F20\u50E7\u5275\u53CC\u53E2\u5009\u55AA\u58EE\u594F\u723D\u5B8B\u5C64\u531D\u60E3\u60F3\u635C\u6383\u633F\u63BB\u64CD\u65E9\u66F9\u5DE3\u69CD\u69FD\u6F15\u71E5\u4E89\u75E9\u76F8\u7A93\u7CDF\u7DCF\u7D9C\u8061\u8349\u8358\u846C\u84BC\u85FB\u88C5\u8D70\u9001\u906D\u9397\u971C\u9A12\u50CF\u5897\u618E"], + ["c2a1", "\u81D3\u8535\u8D08\u9020\u4FC3\u5074\u5247\u5373\u606F\u6349\u675F\u6E2C\u8DB3\u901F\u4FD7\u5C5E\u8CCA\u65CF\u7D9A\u5352\u8896\u5176\u63C3\u5B58\u5B6B\u5C0A\u640D\u6751\u905C\u4ED6\u591A\u592A\u6C70\u8A51\u553E\u5815\u59A5\u60F0\u6253\u67C1\u8235\u6955\u9640\u99C4\u9A28\u4F53\u5806\u5BFE\u8010\u5CB1\u5E2F\u5F85\u6020\u614B\u6234\u66FF\u6CF0\u6EDE\u80CE\u817F\u82D4\u888B\u8CB8\u9000\u902E\u968A\u9EDB\u9BDB\u4EE3\u53F0\u5927\u7B2C\u918D\u984C\u9DF9\u6EDD\u7027\u5353\u5544\u5B85\u6258\u629E\u62D3\u6CA2\u6FEF\u7422\u8A17\u9438\u6FC1\u8AFE\u8338\u51E7\u86F8\u53EA"], + ["c3a1", "\u53E9\u4F46\u9054\u8FB0\u596A\u8131\u5DFD\u7AEA\u8FBF\u68DA\u8C37\u72F8\u9C48\u6A3D\u8AB0\u4E39\u5358\u5606\u5766\u62C5\u63A2\u65E6\u6B4E\u6DE1\u6E5B\u70AD\u77ED\u7AEF\u7BAA\u7DBB\u803D\u80C6\u86CB\u8A95\u935B\u56E3\u58C7\u5F3E\u65AD\u6696\u6A80\u6BB5\u7537\u8AC7\u5024\u77E5\u5730\u5F1B\u6065\u667A\u6C60\u75F4\u7A1A\u7F6E\u81F4\u8718\u9045\u99B3\u7BC9\u755C\u7AF9\u7B51\u84C4\u9010\u79E9\u7A92\u8336\u5AE1\u7740\u4E2D\u4EF2\u5B99\u5FE0\u62BD\u663C\u67F1\u6CE8\u866B\u8877\u8A3B\u914E\u92F3\u99D0\u6A17\u7026\u732A\u82E7\u8457\u8CAF\u4E01\u5146\u51CB\u558B\u5BF5"], + ["c4a1", "\u5E16\u5E33\u5E81\u5F14\u5F35\u5F6B\u5FB4\u61F2\u6311\u66A2\u671D\u6F6E\u7252\u753A\u773A\u8074\u8139\u8178\u8776\u8ABF\u8ADC\u8D85\u8DF3\u929A\u9577\u9802\u9CE5\u52C5\u6357\u76F4\u6715\u6C88\u73CD\u8CC3\u93AE\u9673\u6D25\u589C\u690E\u69CC\u8FFD\u939A\u75DB\u901A\u585A\u6802\u63B4\u69FB\u4F43\u6F2C\u67D8\u8FBB\u8526\u7DB4\u9354\u693F\u6F70\u576A\u58F7\u5B2C\u7D2C\u722A\u540A\u91E3\u9DB4\u4EAD\u4F4E\u505C\u5075\u5243\u8C9E\u5448\u5824\u5B9A\u5E1D\u5E95\u5EAD\u5EF7\u5F1F\u608C\u62B5\u633A\u63D0\u68AF\u6C40\u7887\u798E\u7A0B\u7DE0\u8247\u8A02\u8AE6\u8E44\u9013"], + ["c5a1", "\u90B8\u912D\u91D8\u9F0E\u6CE5\u6458\u64E2\u6575\u6EF4\u7684\u7B1B\u9069\u93D1\u6EBA\u54F2\u5FB9\u64A4\u8F4D\u8FED\u9244\u5178\u586B\u5929\u5C55\u5E97\u6DFB\u7E8F\u751C\u8CBC\u8EE2\u985B\u70B9\u4F1D\u6BBF\u6FB1\u7530\u96FB\u514E\u5410\u5835\u5857\u59AC\u5C60\u5F92\u6597\u675C\u6E21\u767B\u83DF\u8CED\u9014\u90FD\u934D\u7825\u783A\u52AA\u5EA6\u571F\u5974\u6012\u5012\u515A\u51AC\u51CD\u5200\u5510\u5854\u5858\u5957\u5B95\u5CF6\u5D8B\u60BC\u6295\u642D\u6771\u6843\u68BC\u68DF\u76D7\u6DD8\u6E6F\u6D9B\u706F\u71C8\u5F53\u75D8\u7977\u7B49\u7B54\u7B52\u7CD6\u7D71\u5230"], + ["c6a1", "\u8463\u8569\u85E4\u8A0E\u8B04\u8C46\u8E0F\u9003\u900F\u9419\u9676\u982D\u9A30\u95D8\u50CD\u52D5\u540C\u5802\u5C0E\u61A7\u649E\u6D1E\u77B3\u7AE5\u80F4\u8404\u9053\u9285\u5CE0\u9D07\u533F\u5F97\u5FB3\u6D9C\u7279\u7763\u79BF\u7BE4\u6BD2\u72EC\u8AAD\u6803\u6A61\u51F8\u7A81\u6934\u5C4A\u9CF6\u82EB\u5BC5\u9149\u701E\u5678\u5C6F\u60C7\u6566\u6C8C\u8C5A\u9041\u9813\u5451\u66C7\u920D\u5948\u90A3\u5185\u4E4D\u51EA\u8599\u8B0E\u7058\u637A\u934B\u6962\u99B4\u7E04\u7577\u5357\u6960\u8EDF\u96E3\u6C5D\u4E8C\u5C3C\u5F10\u8FE9\u5302\u8CD1\u8089\u8679\u5EFF\u65E5\u4E73\u5165"], + ["c7a1", "\u5982\u5C3F\u97EE\u4EFB\u598A\u5FCD\u8A8D\u6FE1\u79B0\u7962\u5BE7\u8471\u732B\u71B1\u5E74\u5FF5\u637B\u649A\u71C3\u7C98\u4E43\u5EFC\u4E4B\u57DC\u56A2\u60A9\u6FC3\u7D0D\u80FD\u8133\u81BF\u8FB2\u8997\u86A4\u5DF4\u628A\u64AD\u8987\u6777\u6CE2\u6D3E\u7436\u7834\u5A46\u7F75\u82AD\u99AC\u4FF3\u5EC3\u62DD\u6392\u6557\u676F\u76C3\u724C\u80CC\u80BA\u8F29\u914D\u500D\u57F9\u5A92\u6885\u6973\u7164\u72FD\u8CB7\u58F2\u8CE0\u966A\u9019\u877F\u79E4\u77E7\u8429\u4F2F\u5265\u535A\u62CD\u67CF\u6CCA\u767D\u7B94\u7C95\u8236\u8584\u8FEB\u66DD\u6F20\u7206\u7E1B\u83AB\u99C1\u9EA6"], + ["c8a1", "\u51FD\u7BB1\u7872\u7BB8\u8087\u7B48\u6AE8\u5E61\u808C\u7551\u7560\u516B\u9262\u6E8C\u767A\u9197\u9AEA\u4F10\u7F70\u629C\u7B4F\u95A5\u9CE9\u567A\u5859\u86E4\u96BC\u4F34\u5224\u534A\u53CD\u53DB\u5E06\u642C\u6591\u677F\u6C3E\u6C4E\u7248\u72AF\u73ED\u7554\u7E41\u822C\u85E9\u8CA9\u7BC4\u91C6\u7169\u9812\u98EF\u633D\u6669\u756A\u76E4\u78D0\u8543\u86EE\u532A\u5351\u5426\u5983\u5E87\u5F7C\u60B2\u6249\u6279\u62AB\u6590\u6BD4\u6CCC\u75B2\u76AE\u7891\u79D8\u7DCB\u7F77\u80A5\u88AB\u8AB9\u8CBB\u907F\u975E\u98DB\u6A0B\u7C38\u5099\u5C3E\u5FAE\u6787\u6BD8\u7435\u7709\u7F8E"], + ["c9a1", "\u9F3B\u67CA\u7A17\u5339\u758B\u9AED\u5F66\u819D\u83F1\u8098\u5F3C\u5FC5\u7562\u7B46\u903C\u6867\u59EB\u5A9B\u7D10\u767E\u8B2C\u4FF5\u5F6A\u6A19\u6C37\u6F02\u74E2\u7968\u8868\u8A55\u8C79\u5EDF\u63CF\u75C5\u79D2\u82D7\u9328\u92F2\u849C\u86ED\u9C2D\u54C1\u5F6C\u658C\u6D5C\u7015\u8CA7\u8CD3\u983B\u654F\u74F6\u4E0D\u4ED8\u57E0\u592B\u5A66\u5BCC\u51A8\u5E03\u5E9C\u6016\u6276\u6577\u65A7\u666E\u6D6E\u7236\u7B26\u8150\u819A\u8299\u8B5C\u8CA0\u8CE6\u8D74\u961C\u9644\u4FAE\u64AB\u6B66\u821E\u8461\u856A\u90E8\u5C01\u6953\u98A8\u847A\u8557\u4F0F\u526F\u5FA9\u5E45\u670D"], + ["caa1", "\u798F\u8179\u8907\u8986\u6DF5\u5F17\u6255\u6CB8\u4ECF\u7269\u9B92\u5206\u543B\u5674\u58B3\u61A4\u626E\u711A\u596E\u7C89\u7CDE\u7D1B\u96F0\u6587\u805E\u4E19\u4F75\u5175\u5840\u5E63\u5E73\u5F0A\u67C4\u4E26\u853D\u9589\u965B\u7C73\u9801\u50FB\u58C1\u7656\u78A7\u5225\u77A5\u8511\u7B86\u504F\u5909\u7247\u7BC7\u7DE8\u8FBA\u8FD4\u904D\u4FBF\u52C9\u5A29\u5F01\u97AD\u4FDD\u8217\u92EA\u5703\u6355\u6B69\u752B\u88DC\u8F14\u7A42\u52DF\u5893\u6155\u620A\u66AE\u6BCD\u7C3F\u83E9\u5023\u4FF8\u5305\u5446\u5831\u5949\u5B9D\u5CF0\u5CEF\u5D29\u5E96\u62B1\u6367\u653E\u65B9\u670B"], + ["cba1", "\u6CD5\u6CE1\u70F9\u7832\u7E2B\u80DE\u82B3\u840C\u84EC\u8702\u8912\u8A2A\u8C4A\u90A6\u92D2\u98FD\u9CF3\u9D6C\u4E4F\u4EA1\u508D\u5256\u574A\u59A8\u5E3D\u5FD8\u5FD9\u623F\u66B4\u671B\u67D0\u68D2\u5192\u7D21\u80AA\u81A8\u8B00\u8C8C\u8CBF\u927E\u9632\u5420\u982C\u5317\u50D5\u535C\u58A8\u64B2\u6734\u7267\u7766\u7A46\u91E6\u52C3\u6CA1\u6B86\u5800\u5E4C\u5954\u672C\u7FFB\u51E1\u76C6\u6469\u78E8\u9B54\u9EBB\u57CB\u59B9\u6627\u679A\u6BCE\u54E9\u69D9\u5E55\u819C\u6795\u9BAA\u67FE\u9C52\u685D\u4EA6\u4FE3\u53C8\u62B9\u672B\u6CAB\u8FC4\u4FAD\u7E6D\u9EBF\u4E07\u6162\u6E80"], + ["cca1", "\u6F2B\u8513\u5473\u672A\u9B45\u5DF3\u7B95\u5CAC\u5BC6\u871C\u6E4A\u84D1\u7A14\u8108\u5999\u7C8D\u6C11\u7720\u52D9\u5922\u7121\u725F\u77DB\u9727\u9D61\u690B\u5A7F\u5A18\u51A5\u540D\u547D\u660E\u76DF\u8FF7\u9298\u9CF4\u59EA\u725D\u6EC5\u514D\u68C9\u7DBF\u7DEC\u9762\u9EBA\u6478\u6A21\u8302\u5984\u5B5F\u6BDB\u731B\u76F2\u7DB2\u8017\u8499\u5132\u6728\u9ED9\u76EE\u6762\u52FF\u9905\u5C24\u623B\u7C7E\u8CB0\u554F\u60B6\u7D0B\u9580\u5301\u4E5F\u51B6\u591C\u723A\u8036\u91CE\u5F25\u77E2\u5384\u5F79\u7D04\u85AC\u8A33\u8E8D\u9756\u67F3\u85AE\u9453\u6109\u6108\u6CB9\u7652"], + ["cda1", "\u8AED\u8F38\u552F\u4F51\u512A\u52C7\u53CB\u5BA5\u5E7D\u60A0\u6182\u63D6\u6709\u67DA\u6E67\u6D8C\u7336\u7337\u7531\u7950\u88D5\u8A98\u904A\u9091\u90F5\u96C4\u878D\u5915\u4E88\u4F59\u4E0E\u8A89\u8F3F\u9810\u50AD\u5E7C\u5996\u5BB9\u5EB8\u63DA\u63FA\u64C1\u66DC\u694A\u69D8\u6D0B\u6EB6\u7194\u7528\u7AAF\u7F8A\u8000\u8449\u84C9\u8981\u8B21\u8E0A\u9065\u967D\u990A\u617E\u6291\u6B32\u6C83\u6D74\u7FCC\u7FFC\u6DC0\u7F85\u87BA\u88F8\u6765\u83B1\u983C\u96F7\u6D1B\u7D61\u843D\u916A\u4E71\u5375\u5D50\u6B04\u6FEB\u85CD\u862D\u89A7\u5229\u540F\u5C65\u674E\u68A8\u7406\u7483"], + ["cea1", "\u75E2\u88CF\u88E1\u91CC\u96E2\u9678\u5F8B\u7387\u7ACB\u844E\u63A0\u7565\u5289\u6D41\u6E9C\u7409\u7559\u786B\u7C92\u9686\u7ADC\u9F8D\u4FB6\u616E\u65C5\u865C\u4E86\u4EAE\u50DA\u4E21\u51CC\u5BEE\u6599\u6881\u6DBC\u731F\u7642\u77AD\u7A1C\u7CE7\u826F\u8AD2\u907C\u91CF\u9675\u9818\u529B\u7DD1\u502B\u5398\u6797\u6DCB\u71D0\u7433\u81E8\u8F2A\u96A3\u9C57\u9E9F\u7460\u5841\u6D99\u7D2F\u985E\u4EE4\u4F36\u4F8B\u51B7\u52B1\u5DBA\u601C\u73B2\u793C\u82D3\u9234\u96B7\u96F6\u970A\u9E97\u9F62\u66A6\u6B74\u5217\u52A3\u70C8\u88C2\u5EC9\u604B\u6190\u6F23\u7149\u7C3E\u7DF4\u806F"], + ["cfa1", "\u84EE\u9023\u932C\u5442\u9B6F\u6AD3\u7089\u8CC2\u8DEF\u9732\u52B4\u5A41\u5ECA\u5F04\u6717\u697C\u6994\u6D6A\u6F0F\u7262\u72FC\u7BED\u8001\u807E\u874B\u90CE\u516D\u9E93\u7984\u808B\u9332\u8AD6\u502D\u548C\u8A71\u6B6A\u8CC4\u8107\u60D1\u67A0\u9DF2\u4E99\u4E98\u9C10\u8A6B\u85C1\u8568\u6900\u6E7E\u7897\u8155"], + ["d0a1", "\u5F0C\u4E10\u4E15\u4E2A\u4E31\u4E36\u4E3C\u4E3F\u4E42\u4E56\u4E58\u4E82\u4E85\u8C6B\u4E8A\u8212\u5F0D\u4E8E\u4E9E\u4E9F\u4EA0\u4EA2\u4EB0\u4EB3\u4EB6\u4ECE\u4ECD\u4EC4\u4EC6\u4EC2\u4ED7\u4EDE\u4EED\u4EDF\u4EF7\u4F09\u4F5A\u4F30\u4F5B\u4F5D\u4F57\u4F47\u4F76\u4F88\u4F8F\u4F98\u4F7B\u4F69\u4F70\u4F91\u4F6F\u4F86\u4F96\u5118\u4FD4\u4FDF\u4FCE\u4FD8\u4FDB\u4FD1\u4FDA\u4FD0\u4FE4\u4FE5\u501A\u5028\u5014\u502A\u5025\u5005\u4F1C\u4FF6\u5021\u5029\u502C\u4FFE\u4FEF\u5011\u5006\u5043\u5047\u6703\u5055\u5050\u5048\u505A\u5056\u506C\u5078\u5080\u509A\u5085\u50B4\u50B2"], + ["d1a1", "\u50C9\u50CA\u50B3\u50C2\u50D6\u50DE\u50E5\u50ED\u50E3\u50EE\u50F9\u50F5\u5109\u5101\u5102\u5116\u5115\u5114\u511A\u5121\u513A\u5137\u513C\u513B\u513F\u5140\u5152\u514C\u5154\u5162\u7AF8\u5169\u516A\u516E\u5180\u5182\u56D8\u518C\u5189\u518F\u5191\u5193\u5195\u5196\u51A4\u51A6\u51A2\u51A9\u51AA\u51AB\u51B3\u51B1\u51B2\u51B0\u51B5\u51BD\u51C5\u51C9\u51DB\u51E0\u8655\u51E9\u51ED\u51F0\u51F5\u51FE\u5204\u520B\u5214\u520E\u5227\u522A\u522E\u5233\u5239\u524F\u5244\u524B\u524C\u525E\u5254\u526A\u5274\u5269\u5273\u527F\u527D\u528D\u5294\u5292\u5271\u5288\u5291\u8FA8"], + ["d2a1", "\u8FA7\u52AC\u52AD\u52BC\u52B5\u52C1\u52CD\u52D7\u52DE\u52E3\u52E6\u98ED\u52E0\u52F3\u52F5\u52F8\u52F9\u5306\u5308\u7538\u530D\u5310\u530F\u5315\u531A\u5323\u532F\u5331\u5333\u5338\u5340\u5346\u5345\u4E17\u5349\u534D\u51D6\u535E\u5369\u536E\u5918\u537B\u5377\u5382\u5396\u53A0\u53A6\u53A5\u53AE\u53B0\u53B6\u53C3\u7C12\u96D9\u53DF\u66FC\u71EE\u53EE\u53E8\u53ED\u53FA\u5401\u543D\u5440\u542C\u542D\u543C\u542E\u5436\u5429\u541D\u544E\u548F\u5475\u548E\u545F\u5471\u5477\u5470\u5492\u547B\u5480\u5476\u5484\u5490\u5486\u54C7\u54A2\u54B8\u54A5\u54AC\u54C4\u54C8\u54A8"], + ["d3a1", "\u54AB\u54C2\u54A4\u54BE\u54BC\u54D8\u54E5\u54E6\u550F\u5514\u54FD\u54EE\u54ED\u54FA\u54E2\u5539\u5540\u5563\u554C\u552E\u555C\u5545\u5556\u5557\u5538\u5533\u555D\u5599\u5580\u54AF\u558A\u559F\u557B\u557E\u5598\u559E\u55AE\u557C\u5583\u55A9\u5587\u55A8\u55DA\u55C5\u55DF\u55C4\u55DC\u55E4\u55D4\u5614\u55F7\u5616\u55FE\u55FD\u561B\u55F9\u564E\u5650\u71DF\u5634\u5636\u5632\u5638\u566B\u5664\u562F\u566C\u566A\u5686\u5680\u568A\u56A0\u5694\u568F\u56A5\u56AE\u56B6\u56B4\u56C2\u56BC\u56C1\u56C3\u56C0\u56C8\u56CE\u56D1\u56D3\u56D7\u56EE\u56F9\u5700\u56FF\u5704\u5709"], + ["d4a1", "\u5708\u570B\u570D\u5713\u5718\u5716\u55C7\u571C\u5726\u5737\u5738\u574E\u573B\u5740\u574F\u5769\u57C0\u5788\u5761\u577F\u5789\u5793\u57A0\u57B3\u57A4\u57AA\u57B0\u57C3\u57C6\u57D4\u57D2\u57D3\u580A\u57D6\u57E3\u580B\u5819\u581D\u5872\u5821\u5862\u584B\u5870\u6BC0\u5852\u583D\u5879\u5885\u58B9\u589F\u58AB\u58BA\u58DE\u58BB\u58B8\u58AE\u58C5\u58D3\u58D1\u58D7\u58D9\u58D8\u58E5\u58DC\u58E4\u58DF\u58EF\u58FA\u58F9\u58FB\u58FC\u58FD\u5902\u590A\u5910\u591B\u68A6\u5925\u592C\u592D\u5932\u5938\u593E\u7AD2\u5955\u5950\u594E\u595A\u5958\u5962\u5960\u5967\u596C\u5969"], + ["d5a1", "\u5978\u5981\u599D\u4F5E\u4FAB\u59A3\u59B2\u59C6\u59E8\u59DC\u598D\u59D9\u59DA\u5A25\u5A1F\u5A11\u5A1C\u5A09\u5A1A\u5A40\u5A6C\u5A49\u5A35\u5A36\u5A62\u5A6A\u5A9A\u5ABC\u5ABE\u5ACB\u5AC2\u5ABD\u5AE3\u5AD7\u5AE6\u5AE9\u5AD6\u5AFA\u5AFB\u5B0C\u5B0B\u5B16\u5B32\u5AD0\u5B2A\u5B36\u5B3E\u5B43\u5B45\u5B40\u5B51\u5B55\u5B5A\u5B5B\u5B65\u5B69\u5B70\u5B73\u5B75\u5B78\u6588\u5B7A\u5B80\u5B83\u5BA6\u5BB8\u5BC3\u5BC7\u5BC9\u5BD4\u5BD0\u5BE4\u5BE6\u5BE2\u5BDE\u5BE5\u5BEB\u5BF0\u5BF6\u5BF3\u5C05\u5C07\u5C08\u5C0D\u5C13\u5C20\u5C22\u5C28\u5C38\u5C39\u5C41\u5C46\u5C4E\u5C53"], + ["d6a1", "\u5C50\u5C4F\u5B71\u5C6C\u5C6E\u4E62\u5C76\u5C79\u5C8C\u5C91\u5C94\u599B\u5CAB\u5CBB\u5CB6\u5CBC\u5CB7\u5CC5\u5CBE\u5CC7\u5CD9\u5CE9\u5CFD\u5CFA\u5CED\u5D8C\u5CEA\u5D0B\u5D15\u5D17\u5D5C\u5D1F\u5D1B\u5D11\u5D14\u5D22\u5D1A\u5D19\u5D18\u5D4C\u5D52\u5D4E\u5D4B\u5D6C\u5D73\u5D76\u5D87\u5D84\u5D82\u5DA2\u5D9D\u5DAC\u5DAE\u5DBD\u5D90\u5DB7\u5DBC\u5DC9\u5DCD\u5DD3\u5DD2\u5DD6\u5DDB\u5DEB\u5DF2\u5DF5\u5E0B\u5E1A\u5E19\u5E11\u5E1B\u5E36\u5E37\u5E44\u5E43\u5E40\u5E4E\u5E57\u5E54\u5E5F\u5E62\u5E64\u5E47\u5E75\u5E76\u5E7A\u9EBC\u5E7F\u5EA0\u5EC1\u5EC2\u5EC8\u5ED0\u5ECF"], + ["d7a1", "\u5ED6\u5EE3\u5EDD\u5EDA\u5EDB\u5EE2\u5EE1\u5EE8\u5EE9\u5EEC\u5EF1\u5EF3\u5EF0\u5EF4\u5EF8\u5EFE\u5F03\u5F09\u5F5D\u5F5C\u5F0B\u5F11\u5F16\u5F29\u5F2D\u5F38\u5F41\u5F48\u5F4C\u5F4E\u5F2F\u5F51\u5F56\u5F57\u5F59\u5F61\u5F6D\u5F73\u5F77\u5F83\u5F82\u5F7F\u5F8A\u5F88\u5F91\u5F87\u5F9E\u5F99\u5F98\u5FA0\u5FA8\u5FAD\u5FBC\u5FD6\u5FFB\u5FE4\u5FF8\u5FF1\u5FDD\u60B3\u5FFF\u6021\u6060\u6019\u6010\u6029\u600E\u6031\u601B\u6015\u602B\u6026\u600F\u603A\u605A\u6041\u606A\u6077\u605F\u604A\u6046\u604D\u6063\u6043\u6064\u6042\u606C\u606B\u6059\u6081\u608D\u60E7\u6083\u609A"], + ["d8a1", "\u6084\u609B\u6096\u6097\u6092\u60A7\u608B\u60E1\u60B8\u60E0\u60D3\u60B4\u5FF0\u60BD\u60C6\u60B5\u60D8\u614D\u6115\u6106\u60F6\u60F7\u6100\u60F4\u60FA\u6103\u6121\u60FB\u60F1\u610D\u610E\u6147\u613E\u6128\u6127\u614A\u613F\u613C\u612C\u6134\u613D\u6142\u6144\u6173\u6177\u6158\u6159\u615A\u616B\u6174\u616F\u6165\u6171\u615F\u615D\u6153\u6175\u6199\u6196\u6187\u61AC\u6194\u619A\u618A\u6191\u61AB\u61AE\u61CC\u61CA\u61C9\u61F7\u61C8\u61C3\u61C6\u61BA\u61CB\u7F79\u61CD\u61E6\u61E3\u61F6\u61FA\u61F4\u61FF\u61FD\u61FC\u61FE\u6200\u6208\u6209\u620D\u620C\u6214\u621B"], + ["d9a1", "\u621E\u6221\u622A\u622E\u6230\u6232\u6233\u6241\u624E\u625E\u6263\u625B\u6260\u6268\u627C\u6282\u6289\u627E\u6292\u6293\u6296\u62D4\u6283\u6294\u62D7\u62D1\u62BB\u62CF\u62FF\u62C6\u64D4\u62C8\u62DC\u62CC\u62CA\u62C2\u62C7\u629B\u62C9\u630C\u62EE\u62F1\u6327\u6302\u6308\u62EF\u62F5\u6350\u633E\u634D\u641C\u634F\u6396\u638E\u6380\u63AB\u6376\u63A3\u638F\u6389\u639F\u63B5\u636B\u6369\u63BE\u63E9\u63C0\u63C6\u63E3\u63C9\u63D2\u63F6\u63C4\u6416\u6434\u6406\u6413\u6426\u6436\u651D\u6417\u6428\u640F\u6467\u646F\u6476\u644E\u652A\u6495\u6493\u64A5\u64A9\u6488\u64BC"], + ["daa1", "\u64DA\u64D2\u64C5\u64C7\u64BB\u64D8\u64C2\u64F1\u64E7\u8209\u64E0\u64E1\u62AC\u64E3\u64EF\u652C\u64F6\u64F4\u64F2\u64FA\u6500\u64FD\u6518\u651C\u6505\u6524\u6523\u652B\u6534\u6535\u6537\u6536\u6538\u754B\u6548\u6556\u6555\u654D\u6558\u655E\u655D\u6572\u6578\u6582\u6583\u8B8A\u659B\u659F\u65AB\u65B7\u65C3\u65C6\u65C1\u65C4\u65CC\u65D2\u65DB\u65D9\u65E0\u65E1\u65F1\u6772\u660A\u6603\u65FB\u6773\u6635\u6636\u6634\u661C\u664F\u6644\u6649\u6641\u665E\u665D\u6664\u6667\u6668\u665F\u6662\u6670\u6683\u6688\u668E\u6689\u6684\u6698\u669D\u66C1\u66B9\u66C9\u66BE\u66BC"], + ["dba1", "\u66C4\u66B8\u66D6\u66DA\u66E0\u663F\u66E6\u66E9\u66F0\u66F5\u66F7\u670F\u6716\u671E\u6726\u6727\u9738\u672E\u673F\u6736\u6741\u6738\u6737\u6746\u675E\u6760\u6759\u6763\u6764\u6789\u6770\u67A9\u677C\u676A\u678C\u678B\u67A6\u67A1\u6785\u67B7\u67EF\u67B4\u67EC\u67B3\u67E9\u67B8\u67E4\u67DE\u67DD\u67E2\u67EE\u67B9\u67CE\u67C6\u67E7\u6A9C\u681E\u6846\u6829\u6840\u684D\u6832\u684E\u68B3\u682B\u6859\u6863\u6877\u687F\u689F\u688F\u68AD\u6894\u689D\u689B\u6883\u6AAE\u68B9\u6874\u68B5\u68A0\u68BA\u690F\u688D\u687E\u6901\u68CA\u6908\u68D8\u6922\u6926\u68E1\u690C\u68CD"], + ["dca1", "\u68D4\u68E7\u68D5\u6936\u6912\u6904\u68D7\u68E3\u6925\u68F9\u68E0\u68EF\u6928\u692A\u691A\u6923\u6921\u68C6\u6979\u6977\u695C\u6978\u696B\u6954\u697E\u696E\u6939\u6974\u693D\u6959\u6930\u6961\u695E\u695D\u6981\u696A\u69B2\u69AE\u69D0\u69BF\u69C1\u69D3\u69BE\u69CE\u5BE8\u69CA\u69DD\u69BB\u69C3\u69A7\u6A2E\u6991\u69A0\u699C\u6995\u69B4\u69DE\u69E8\u6A02\u6A1B\u69FF\u6B0A\u69F9\u69F2\u69E7\u6A05\u69B1\u6A1E\u69ED\u6A14\u69EB\u6A0A\u6A12\u6AC1\u6A23\u6A13\u6A44\u6A0C\u6A72\u6A36\u6A78\u6A47\u6A62\u6A59\u6A66\u6A48\u6A38\u6A22\u6A90\u6A8D\u6AA0\u6A84\u6AA2\u6AA3"], + ["dda1", "\u6A97\u8617\u6ABB\u6AC3\u6AC2\u6AB8\u6AB3\u6AAC\u6ADE\u6AD1\u6ADF\u6AAA\u6ADA\u6AEA\u6AFB\u6B05\u8616\u6AFA\u6B12\u6B16\u9B31\u6B1F\u6B38\u6B37\u76DC\u6B39\u98EE\u6B47\u6B43\u6B49\u6B50\u6B59\u6B54\u6B5B\u6B5F\u6B61\u6B78\u6B79\u6B7F\u6B80\u6B84\u6B83\u6B8D\u6B98\u6B95\u6B9E\u6BA4\u6BAA\u6BAB\u6BAF\u6BB2\u6BB1\u6BB3\u6BB7\u6BBC\u6BC6\u6BCB\u6BD3\u6BDF\u6BEC\u6BEB\u6BF3\u6BEF\u9EBE\u6C08\u6C13\u6C14\u6C1B\u6C24\u6C23\u6C5E\u6C55\u6C62\u6C6A\u6C82\u6C8D\u6C9A\u6C81\u6C9B\u6C7E\u6C68\u6C73\u6C92\u6C90\u6CC4\u6CF1\u6CD3\u6CBD\u6CD7\u6CC5\u6CDD\u6CAE\u6CB1\u6CBE"], + ["dea1", "\u6CBA\u6CDB\u6CEF\u6CD9\u6CEA\u6D1F\u884D\u6D36\u6D2B\u6D3D\u6D38\u6D19\u6D35\u6D33\u6D12\u6D0C\u6D63\u6D93\u6D64\u6D5A\u6D79\u6D59\u6D8E\u6D95\u6FE4\u6D85\u6DF9\u6E15\u6E0A\u6DB5\u6DC7\u6DE6\u6DB8\u6DC6\u6DEC\u6DDE\u6DCC\u6DE8\u6DD2\u6DC5\u6DFA\u6DD9\u6DE4\u6DD5\u6DEA\u6DEE\u6E2D\u6E6E\u6E2E\u6E19\u6E72\u6E5F\u6E3E\u6E23\u6E6B\u6E2B\u6E76\u6E4D\u6E1F\u6E43\u6E3A\u6E4E\u6E24\u6EFF\u6E1D\u6E38\u6E82\u6EAA\u6E98\u6EC9\u6EB7\u6ED3\u6EBD\u6EAF\u6EC4\u6EB2\u6ED4\u6ED5\u6E8F\u6EA5\u6EC2\u6E9F\u6F41\u6F11\u704C\u6EEC\u6EF8\u6EFE\u6F3F\u6EF2\u6F31\u6EEF\u6F32\u6ECC"], + ["dfa1", "\u6F3E\u6F13\u6EF7\u6F86\u6F7A\u6F78\u6F81\u6F80\u6F6F\u6F5B\u6FF3\u6F6D\u6F82\u6F7C\u6F58\u6F8E\u6F91\u6FC2\u6F66\u6FB3\u6FA3\u6FA1\u6FA4\u6FB9\u6FC6\u6FAA\u6FDF\u6FD5\u6FEC\u6FD4\u6FD8\u6FF1\u6FEE\u6FDB\u7009\u700B\u6FFA\u7011\u7001\u700F\u6FFE\u701B\u701A\u6F74\u701D\u7018\u701F\u7030\u703E\u7032\u7051\u7063\u7099\u7092\u70AF\u70F1\u70AC\u70B8\u70B3\u70AE\u70DF\u70CB\u70DD\u70D9\u7109\u70FD\u711C\u7119\u7165\u7155\u7188\u7166\u7162\u714C\u7156\u716C\u718F\u71FB\u7184\u7195\u71A8\u71AC\u71D7\u71B9\u71BE\u71D2\u71C9\u71D4\u71CE\u71E0\u71EC\u71E7\u71F5\u71FC"], + ["e0a1", "\u71F9\u71FF\u720D\u7210\u721B\u7228\u722D\u722C\u7230\u7232\u723B\u723C\u723F\u7240\u7246\u724B\u7258\u7274\u727E\u7282\u7281\u7287\u7292\u7296\u72A2\u72A7\u72B9\u72B2\u72C3\u72C6\u72C4\u72CE\u72D2\u72E2\u72E0\u72E1\u72F9\u72F7\u500F\u7317\u730A\u731C\u7316\u731D\u7334\u732F\u7329\u7325\u733E\u734E\u734F\u9ED8\u7357\u736A\u7368\u7370\u7378\u7375\u737B\u737A\u73C8\u73B3\u73CE\u73BB\u73C0\u73E5\u73EE\u73DE\u74A2\u7405\u746F\u7425\u73F8\u7432\u743A\u7455\u743F\u745F\u7459\u7441\u745C\u7469\u7470\u7463\u746A\u7476\u747E\u748B\u749E\u74A7\u74CA\u74CF\u74D4\u73F1"], + ["e1a1", "\u74E0\u74E3\u74E7\u74E9\u74EE\u74F2\u74F0\u74F1\u74F8\u74F7\u7504\u7503\u7505\u750C\u750E\u750D\u7515\u7513\u751E\u7526\u752C\u753C\u7544\u754D\u754A\u7549\u755B\u7546\u755A\u7569\u7564\u7567\u756B\u756D\u7578\u7576\u7586\u7587\u7574\u758A\u7589\u7582\u7594\u759A\u759D\u75A5\u75A3\u75C2\u75B3\u75C3\u75B5\u75BD\u75B8\u75BC\u75B1\u75CD\u75CA\u75D2\u75D9\u75E3\u75DE\u75FE\u75FF\u75FC\u7601\u75F0\u75FA\u75F2\u75F3\u760B\u760D\u7609\u761F\u7627\u7620\u7621\u7622\u7624\u7634\u7630\u763B\u7647\u7648\u7646\u765C\u7658\u7661\u7662\u7668\u7669\u766A\u7667\u766C\u7670"], + ["e2a1", "\u7672\u7676\u7678\u767C\u7680\u7683\u7688\u768B\u768E\u7696\u7693\u7699\u769A\u76B0\u76B4\u76B8\u76B9\u76BA\u76C2\u76CD\u76D6\u76D2\u76DE\u76E1\u76E5\u76E7\u76EA\u862F\u76FB\u7708\u7707\u7704\u7729\u7724\u771E\u7725\u7726\u771B\u7737\u7738\u7747\u775A\u7768\u776B\u775B\u7765\u777F\u777E\u7779\u778E\u778B\u7791\u77A0\u779E\u77B0\u77B6\u77B9\u77BF\u77BC\u77BD\u77BB\u77C7\u77CD\u77D7\u77DA\u77DC\u77E3\u77EE\u77FC\u780C\u7812\u7926\u7820\u792A\u7845\u788E\u7874\u7886\u787C\u789A\u788C\u78A3\u78B5\u78AA\u78AF\u78D1\u78C6\u78CB\u78D4\u78BE\u78BC\u78C5\u78CA\u78EC"], + ["e3a1", "\u78E7\u78DA\u78FD\u78F4\u7907\u7912\u7911\u7919\u792C\u792B\u7940\u7960\u7957\u795F\u795A\u7955\u7953\u797A\u797F\u798A\u799D\u79A7\u9F4B\u79AA\u79AE\u79B3\u79B9\u79BA\u79C9\u79D5\u79E7\u79EC\u79E1\u79E3\u7A08\u7A0D\u7A18\u7A19\u7A20\u7A1F\u7980\u7A31\u7A3B\u7A3E\u7A37\u7A43\u7A57\u7A49\u7A61\u7A62\u7A69\u9F9D\u7A70\u7A79\u7A7D\u7A88\u7A97\u7A95\u7A98\u7A96\u7AA9\u7AC8\u7AB0\u7AB6\u7AC5\u7AC4\u7ABF\u9083\u7AC7\u7ACA\u7ACD\u7ACF\u7AD5\u7AD3\u7AD9\u7ADA\u7ADD\u7AE1\u7AE2\u7AE6\u7AED\u7AF0\u7B02\u7B0F\u7B0A\u7B06\u7B33\u7B18\u7B19\u7B1E\u7B35\u7B28\u7B36\u7B50"], + ["e4a1", "\u7B7A\u7B04\u7B4D\u7B0B\u7B4C\u7B45\u7B75\u7B65\u7B74\u7B67\u7B70\u7B71\u7B6C\u7B6E\u7B9D\u7B98\u7B9F\u7B8D\u7B9C\u7B9A\u7B8B\u7B92\u7B8F\u7B5D\u7B99\u7BCB\u7BC1\u7BCC\u7BCF\u7BB4\u7BC6\u7BDD\u7BE9\u7C11\u7C14\u7BE6\u7BE5\u7C60\u7C00\u7C07\u7C13\u7BF3\u7BF7\u7C17\u7C0D\u7BF6\u7C23\u7C27\u7C2A\u7C1F\u7C37\u7C2B\u7C3D\u7C4C\u7C43\u7C54\u7C4F\u7C40\u7C50\u7C58\u7C5F\u7C64\u7C56\u7C65\u7C6C\u7C75\u7C83\u7C90\u7CA4\u7CAD\u7CA2\u7CAB\u7CA1\u7CA8\u7CB3\u7CB2\u7CB1\u7CAE\u7CB9\u7CBD\u7CC0\u7CC5\u7CC2\u7CD8\u7CD2\u7CDC\u7CE2\u9B3B\u7CEF\u7CF2\u7CF4\u7CF6\u7CFA\u7D06"], + ["e5a1", "\u7D02\u7D1C\u7D15\u7D0A\u7D45\u7D4B\u7D2E\u7D32\u7D3F\u7D35\u7D46\u7D73\u7D56\u7D4E\u7D72\u7D68\u7D6E\u7D4F\u7D63\u7D93\u7D89\u7D5B\u7D8F\u7D7D\u7D9B\u7DBA\u7DAE\u7DA3\u7DB5\u7DC7\u7DBD\u7DAB\u7E3D\u7DA2\u7DAF\u7DDC\u7DB8\u7D9F\u7DB0\u7DD8\u7DDD\u7DE4\u7DDE\u7DFB\u7DF2\u7DE1\u7E05\u7E0A\u7E23\u7E21\u7E12\u7E31\u7E1F\u7E09\u7E0B\u7E22\u7E46\u7E66\u7E3B\u7E35\u7E39\u7E43\u7E37\u7E32\u7E3A\u7E67\u7E5D\u7E56\u7E5E\u7E59\u7E5A\u7E79\u7E6A\u7E69\u7E7C\u7E7B\u7E83\u7DD5\u7E7D\u8FAE\u7E7F\u7E88\u7E89\u7E8C\u7E92\u7E90\u7E93\u7E94\u7E96\u7E8E\u7E9B\u7E9C\u7F38\u7F3A"], + ["e6a1", "\u7F45\u7F4C\u7F4D\u7F4E\u7F50\u7F51\u7F55\u7F54\u7F58\u7F5F\u7F60\u7F68\u7F69\u7F67\u7F78\u7F82\u7F86\u7F83\u7F88\u7F87\u7F8C\u7F94\u7F9E\u7F9D\u7F9A\u7FA3\u7FAF\u7FB2\u7FB9\u7FAE\u7FB6\u7FB8\u8B71\u7FC5\u7FC6\u7FCA\u7FD5\u7FD4\u7FE1\u7FE6\u7FE9\u7FF3\u7FF9\u98DC\u8006\u8004\u800B\u8012\u8018\u8019\u801C\u8021\u8028\u803F\u803B\u804A\u8046\u8052\u8058\u805A\u805F\u8062\u8068\u8073\u8072\u8070\u8076\u8079\u807D\u807F\u8084\u8086\u8085\u809B\u8093\u809A\u80AD\u5190\u80AC\u80DB\u80E5\u80D9\u80DD\u80C4\u80DA\u80D6\u8109\u80EF\u80F1\u811B\u8129\u8123\u812F\u814B"], + ["e7a1", "\u968B\u8146\u813E\u8153\u8151\u80FC\u8171\u816E\u8165\u8166\u8174\u8183\u8188\u818A\u8180\u8182\u81A0\u8195\u81A4\u81A3\u815F\u8193\u81A9\u81B0\u81B5\u81BE\u81B8\u81BD\u81C0\u81C2\u81BA\u81C9\u81CD\u81D1\u81D9\u81D8\u81C8\u81DA\u81DF\u81E0\u81E7\u81FA\u81FB\u81FE\u8201\u8202\u8205\u8207\u820A\u820D\u8210\u8216\u8229\u822B\u8238\u8233\u8240\u8259\u8258\u825D\u825A\u825F\u8264\u8262\u8268\u826A\u826B\u822E\u8271\u8277\u8278\u827E\u828D\u8292\u82AB\u829F\u82BB\u82AC\u82E1\u82E3\u82DF\u82D2\u82F4\u82F3\u82FA\u8393\u8303\u82FB\u82F9\u82DE\u8306\u82DC\u8309\u82D9"], + ["e8a1", "\u8335\u8334\u8316\u8332\u8331\u8340\u8339\u8350\u8345\u832F\u832B\u8317\u8318\u8385\u839A\u83AA\u839F\u83A2\u8396\u8323\u838E\u8387\u838A\u837C\u83B5\u8373\u8375\u83A0\u8389\u83A8\u83F4\u8413\u83EB\u83CE\u83FD\u8403\u83D8\u840B\u83C1\u83F7\u8407\u83E0\u83F2\u840D\u8422\u8420\u83BD\u8438\u8506\u83FB\u846D\u842A\u843C\u855A\u8484\u8477\u846B\u84AD\u846E\u8482\u8469\u8446\u842C\u846F\u8479\u8435\u84CA\u8462\u84B9\u84BF\u849F\u84D9\u84CD\u84BB\u84DA\u84D0\u84C1\u84C6\u84D6\u84A1\u8521\u84FF\u84F4\u8517\u8518\u852C\u851F\u8515\u8514\u84FC\u8540\u8563\u8558\u8548"], + ["e9a1", "\u8541\u8602\u854B\u8555\u8580\u85A4\u8588\u8591\u858A\u85A8\u856D\u8594\u859B\u85EA\u8587\u859C\u8577\u857E\u8590\u85C9\u85BA\u85CF\u85B9\u85D0\u85D5\u85DD\u85E5\u85DC\u85F9\u860A\u8613\u860B\u85FE\u85FA\u8606\u8622\u861A\u8630\u863F\u864D\u4E55\u8654\u865F\u8667\u8671\u8693\u86A3\u86A9\u86AA\u868B\u868C\u86B6\u86AF\u86C4\u86C6\u86B0\u86C9\u8823\u86AB\u86D4\u86DE\u86E9\u86EC\u86DF\u86DB\u86EF\u8712\u8706\u8708\u8700\u8703\u86FB\u8711\u8709\u870D\u86F9\u870A\u8734\u873F\u8737\u873B\u8725\u8729\u871A\u8760\u875F\u8778\u874C\u874E\u8774\u8757\u8768\u876E\u8759"], + ["eaa1", "\u8753\u8763\u876A\u8805\u87A2\u879F\u8782\u87AF\u87CB\u87BD\u87C0\u87D0\u96D6\u87AB\u87C4\u87B3\u87C7\u87C6\u87BB\u87EF\u87F2\u87E0\u880F\u880D\u87FE\u87F6\u87F7\u880E\u87D2\u8811\u8816\u8815\u8822\u8821\u8831\u8836\u8839\u8827\u883B\u8844\u8842\u8852\u8859\u885E\u8862\u886B\u8881\u887E\u889E\u8875\u887D\u88B5\u8872\u8882\u8897\u8892\u88AE\u8899\u88A2\u888D\u88A4\u88B0\u88BF\u88B1\u88C3\u88C4\u88D4\u88D8\u88D9\u88DD\u88F9\u8902\u88FC\u88F4\u88E8\u88F2\u8904\u890C\u890A\u8913\u8943\u891E\u8925\u892A\u892B\u8941\u8944\u893B\u8936\u8938\u894C\u891D\u8960\u895E"], + ["eba1", "\u8966\u8964\u896D\u896A\u896F\u8974\u8977\u897E\u8983\u8988\u898A\u8993\u8998\u89A1\u89A9\u89A6\u89AC\u89AF\u89B2\u89BA\u89BD\u89BF\u89C0\u89DA\u89DC\u89DD\u89E7\u89F4\u89F8\u8A03\u8A16\u8A10\u8A0C\u8A1B\u8A1D\u8A25\u8A36\u8A41\u8A5B\u8A52\u8A46\u8A48\u8A7C\u8A6D\u8A6C\u8A62\u8A85\u8A82\u8A84\u8AA8\u8AA1\u8A91\u8AA5\u8AA6\u8A9A\u8AA3\u8AC4\u8ACD\u8AC2\u8ADA\u8AEB\u8AF3\u8AE7\u8AE4\u8AF1\u8B14\u8AE0\u8AE2\u8AF7\u8ADE\u8ADB\u8B0C\u8B07\u8B1A\u8AE1\u8B16\u8B10\u8B17\u8B20\u8B33\u97AB\u8B26\u8B2B\u8B3E\u8B28\u8B41\u8B4C\u8B4F\u8B4E\u8B49\u8B56\u8B5B\u8B5A\u8B6B"], + ["eca1", "\u8B5F\u8B6C\u8B6F\u8B74\u8B7D\u8B80\u8B8C\u8B8E\u8B92\u8B93\u8B96\u8B99\u8B9A\u8C3A\u8C41\u8C3F\u8C48\u8C4C\u8C4E\u8C50\u8C55\u8C62\u8C6C\u8C78\u8C7A\u8C82\u8C89\u8C85\u8C8A\u8C8D\u8C8E\u8C94\u8C7C\u8C98\u621D\u8CAD\u8CAA\u8CBD\u8CB2\u8CB3\u8CAE\u8CB6\u8CC8\u8CC1\u8CE4\u8CE3\u8CDA\u8CFD\u8CFA\u8CFB\u8D04\u8D05\u8D0A\u8D07\u8D0F\u8D0D\u8D10\u9F4E\u8D13\u8CCD\u8D14\u8D16\u8D67\u8D6D\u8D71\u8D73\u8D81\u8D99\u8DC2\u8DBE\u8DBA\u8DCF\u8DDA\u8DD6\u8DCC\u8DDB\u8DCB\u8DEA\u8DEB\u8DDF\u8DE3\u8DFC\u8E08\u8E09\u8DFF\u8E1D\u8E1E\u8E10\u8E1F\u8E42\u8E35\u8E30\u8E34\u8E4A"], + ["eda1", "\u8E47\u8E49\u8E4C\u8E50\u8E48\u8E59\u8E64\u8E60\u8E2A\u8E63\u8E55\u8E76\u8E72\u8E7C\u8E81\u8E87\u8E85\u8E84\u8E8B\u8E8A\u8E93\u8E91\u8E94\u8E99\u8EAA\u8EA1\u8EAC\u8EB0\u8EC6\u8EB1\u8EBE\u8EC5\u8EC8\u8ECB\u8EDB\u8EE3\u8EFC\u8EFB\u8EEB\u8EFE\u8F0A\u8F05\u8F15\u8F12\u8F19\u8F13\u8F1C\u8F1F\u8F1B\u8F0C\u8F26\u8F33\u8F3B\u8F39\u8F45\u8F42\u8F3E\u8F4C\u8F49\u8F46\u8F4E\u8F57\u8F5C\u8F62\u8F63\u8F64\u8F9C\u8F9F\u8FA3\u8FAD\u8FAF\u8FB7\u8FDA\u8FE5\u8FE2\u8FEA\u8FEF\u9087\u8FF4\u9005\u8FF9\u8FFA\u9011\u9015\u9021\u900D\u901E\u9016\u900B\u9027\u9036\u9035\u9039\u8FF8"], + ["eea1", "\u904F\u9050\u9051\u9052\u900E\u9049\u903E\u9056\u9058\u905E\u9068\u906F\u9076\u96A8\u9072\u9082\u907D\u9081\u9080\u908A\u9089\u908F\u90A8\u90AF\u90B1\u90B5\u90E2\u90E4\u6248\u90DB\u9102\u9112\u9119\u9132\u9130\u914A\u9156\u9158\u9163\u9165\u9169\u9173\u9172\u918B\u9189\u9182\u91A2\u91AB\u91AF\u91AA\u91B5\u91B4\u91BA\u91C0\u91C1\u91C9\u91CB\u91D0\u91D6\u91DF\u91E1\u91DB\u91FC\u91F5\u91F6\u921E\u91FF\u9214\u922C\u9215\u9211\u925E\u9257\u9245\u9249\u9264\u9248\u9295\u923F\u924B\u9250\u929C\u9296\u9293\u929B\u925A\u92CF\u92B9\u92B7\u92E9\u930F\u92FA\u9344\u932E"], + ["efa1", "\u9319\u9322\u931A\u9323\u933A\u9335\u933B\u935C\u9360\u937C\u936E\u9356\u93B0\u93AC\u93AD\u9394\u93B9\u93D6\u93D7\u93E8\u93E5\u93D8\u93C3\u93DD\u93D0\u93C8\u93E4\u941A\u9414\u9413\u9403\u9407\u9410\u9436\u942B\u9435\u9421\u943A\u9441\u9452\u9444\u945B\u9460\u9462\u945E\u946A\u9229\u9470\u9475\u9477\u947D\u945A\u947C\u947E\u9481\u947F\u9582\u9587\u958A\u9594\u9596\u9598\u9599\u95A0\u95A8\u95A7\u95AD\u95BC\u95BB\u95B9\u95BE\u95CA\u6FF6\u95C3\u95CD\u95CC\u95D5\u95D4\u95D6\u95DC\u95E1\u95E5\u95E2\u9621\u9628\u962E\u962F\u9642\u964C\u964F\u964B\u9677\u965C\u965E"], + ["f0a1", "\u965D\u965F\u9666\u9672\u966C\u968D\u9698\u9695\u9697\u96AA\u96A7\u96B1\u96B2\u96B0\u96B4\u96B6\u96B8\u96B9\u96CE\u96CB\u96C9\u96CD\u894D\u96DC\u970D\u96D5\u96F9\u9704\u9706\u9708\u9713\u970E\u9711\u970F\u9716\u9719\u9724\u972A\u9730\u9739\u973D\u973E\u9744\u9746\u9748\u9742\u9749\u975C\u9760\u9764\u9766\u9768\u52D2\u976B\u9771\u9779\u9785\u977C\u9781\u977A\u9786\u978B\u978F\u9790\u979C\u97A8\u97A6\u97A3\u97B3\u97B4\u97C3\u97C6\u97C8\u97CB\u97DC\u97ED\u9F4F\u97F2\u7ADF\u97F6\u97F5\u980F\u980C\u9838\u9824\u9821\u9837\u983D\u9846\u984F\u984B\u986B\u986F\u9870"], + ["f1a1", "\u9871\u9874\u9873\u98AA\u98AF\u98B1\u98B6\u98C4\u98C3\u98C6\u98E9\u98EB\u9903\u9909\u9912\u9914\u9918\u9921\u991D\u991E\u9924\u9920\u992C\u992E\u993D\u993E\u9942\u9949\u9945\u9950\u994B\u9951\u9952\u994C\u9955\u9997\u9998\u99A5\u99AD\u99AE\u99BC\u99DF\u99DB\u99DD\u99D8\u99D1\u99ED\u99EE\u99F1\u99F2\u99FB\u99F8\u9A01\u9A0F\u9A05\u99E2\u9A19\u9A2B\u9A37\u9A45\u9A42\u9A40\u9A43\u9A3E\u9A55\u9A4D\u9A5B\u9A57\u9A5F\u9A62\u9A65\u9A64\u9A69\u9A6B\u9A6A\u9AAD\u9AB0\u9ABC\u9AC0\u9ACF\u9AD1\u9AD3\u9AD4\u9ADE\u9ADF\u9AE2\u9AE3\u9AE6\u9AEF\u9AEB\u9AEE\u9AF4\u9AF1\u9AF7"], + ["f2a1", "\u9AFB\u9B06\u9B18\u9B1A\u9B1F\u9B22\u9B23\u9B25\u9B27\u9B28\u9B29\u9B2A\u9B2E\u9B2F\u9B32\u9B44\u9B43\u9B4F\u9B4D\u9B4E\u9B51\u9B58\u9B74\u9B93\u9B83\u9B91\u9B96\u9B97\u9B9F\u9BA0\u9BA8\u9BB4\u9BC0\u9BCA\u9BB9\u9BC6\u9BCF\u9BD1\u9BD2\u9BE3\u9BE2\u9BE4\u9BD4\u9BE1\u9C3A\u9BF2\u9BF1\u9BF0\u9C15\u9C14\u9C09\u9C13\u9C0C\u9C06\u9C08\u9C12\u9C0A\u9C04\u9C2E\u9C1B\u9C25\u9C24\u9C21\u9C30\u9C47\u9C32\u9C46\u9C3E\u9C5A\u9C60\u9C67\u9C76\u9C78\u9CE7\u9CEC\u9CF0\u9D09\u9D08\u9CEB\u9D03\u9D06\u9D2A\u9D26\u9DAF\u9D23\u9D1F\u9D44\u9D15\u9D12\u9D41\u9D3F\u9D3E\u9D46\u9D48"], + ["f3a1", "\u9D5D\u9D5E\u9D64\u9D51\u9D50\u9D59\u9D72\u9D89\u9D87\u9DAB\u9D6F\u9D7A\u9D9A\u9DA4\u9DA9\u9DB2\u9DC4\u9DC1\u9DBB\u9DB8\u9DBA\u9DC6\u9DCF\u9DC2\u9DD9\u9DD3\u9DF8\u9DE6\u9DED\u9DEF\u9DFD\u9E1A\u9E1B\u9E1E\u9E75\u9E79\u9E7D\u9E81\u9E88\u9E8B\u9E8C\u9E92\u9E95\u9E91\u9E9D\u9EA5\u9EA9\u9EB8\u9EAA\u9EAD\u9761\u9ECC\u9ECE\u9ECF\u9ED0\u9ED4\u9EDC\u9EDE\u9EDD\u9EE0\u9EE5\u9EE8\u9EEF\u9EF4\u9EF6\u9EF7\u9EF9\u9EFB\u9EFC\u9EFD\u9F07\u9F08\u76B7\u9F15\u9F21\u9F2C\u9F3E\u9F4A\u9F52\u9F54\u9F63\u9F5F\u9F60\u9F61\u9F66\u9F67\u9F6C\u9F6A\u9F77\u9F72\u9F76\u9F95\u9F9C\u9FA0"], + ["f4a1", "\u582F\u69C7\u9059\u7464\u51DC\u7199"], + ["f9a1", "\u7E8A\u891C\u9348\u9288\u84DC\u4FC9\u70BB\u6631\u68C8\u92F9\u66FB\u5F45\u4E28\u4EE1\u4EFC\u4F00\u4F03\u4F39\u4F56\u4F92\u4F8A\u4F9A\u4F94\u4FCD\u5040\u5022\u4FFF\u501E\u5046\u5070\u5042\u5094\u50F4\u50D8\u514A\u5164\u519D\u51BE\u51EC\u5215\u529C\u52A6\u52C0\u52DB\u5300\u5307\u5324\u5372\u5393\u53B2\u53DD\uFA0E\u549C\u548A\u54A9\u54FF\u5586\u5759\u5765\u57AC\u57C8\u57C7\uFA0F\uFA10\u589E\u58B2\u590B\u5953\u595B\u595D\u5963\u59A4\u59BA\u5B56\u5BC0\u752F\u5BD8\u5BEC\u5C1E\u5CA6\u5CBA\u5CF5\u5D27\u5D53\uFA11\u5D42\u5D6D\u5DB8\u5DB9\u5DD0\u5F21\u5F34\u5F67\u5FB7"], + ["faa1", "\u5FDE\u605D\u6085\u608A\u60DE\u60D5\u6120\u60F2\u6111\u6137\u6130\u6198\u6213\u62A6\u63F5\u6460\u649D\u64CE\u654E\u6600\u6615\u663B\u6609\u662E\u661E\u6624\u6665\u6657\u6659\uFA12\u6673\u6699\u66A0\u66B2\u66BF\u66FA\u670E\uF929\u6766\u67BB\u6852\u67C0\u6801\u6844\u68CF\uFA13\u6968\uFA14\u6998\u69E2\u6A30\u6A6B\u6A46\u6A73\u6A7E\u6AE2\u6AE4\u6BD6\u6C3F\u6C5C\u6C86\u6C6F\u6CDA\u6D04\u6D87\u6D6F\u6D96\u6DAC\u6DCF\u6DF8\u6DF2\u6DFC\u6E39\u6E5C\u6E27\u6E3C\u6EBF\u6F88\u6FB5\u6FF5\u7005\u7007\u7028\u7085\u70AB\u710F\u7104\u715C\u7146\u7147\uFA15\u71C1\u71FE\u72B1"], + ["fba1", "\u72BE\u7324\uFA16\u7377\u73BD\u73C9\u73D6\u73E3\u73D2\u7407\u73F5\u7426\u742A\u7429\u742E\u7462\u7489\u749F\u7501\u756F\u7682\u769C\u769E\u769B\u76A6\uFA17\u7746\u52AF\u7821\u784E\u7864\u787A\u7930\uFA18\uFA19\uFA1A\u7994\uFA1B\u799B\u7AD1\u7AE7\uFA1C\u7AEB\u7B9E\uFA1D\u7D48\u7D5C\u7DB7\u7DA0\u7DD6\u7E52\u7F47\u7FA1\uFA1E\u8301\u8362\u837F\u83C7\u83F6\u8448\u84B4\u8553\u8559\u856B\uFA1F\u85B0\uFA20\uFA21\u8807\u88F5\u8A12\u8A37\u8A79\u8AA7\u8ABE\u8ADF\uFA22\u8AF6\u8B53\u8B7F\u8CF0\u8CF4\u8D12\u8D76\uFA23\u8ECF\uFA24\uFA25\u9067\u90DE\uFA26\u9115\u9127\u91DA"], + ["fca1", "\u91D7\u91DE\u91ED\u91EE\u91E4\u91E5\u9206\u9210\u920A\u923A\u9240\u923C\u924E\u9259\u9251\u9239\u9267\u92A7\u9277\u9278\u92E7\u92D7\u92D9\u92D0\uFA27\u92D5\u92E0\u92D3\u9325\u9321\u92FB\uFA28\u931E\u92FF\u931D\u9302\u9370\u9357\u93A4\u93C6\u93DE\u93F8\u9431\u9445\u9448\u9592\uF9DC\uFA29\u969D\u96AF\u9733\u973B\u9743\u974D\u974F\u9751\u9755\u9857\u9865\uFA2A\uFA2B\u9927\uFA2C\u999E\u9A4E\u9AD9\u9ADC\u9B75\u9B72\u9B8F\u9BB1\u9BBB\u9C00\u9D70\u9D6B\uFA2D\u9E19\u9ED1"], + ["fcf1", "\u2170", 9, "\uFFE2\uFFE4\uFF07\uFF02"], + ["8fa2af", "\u02D8\u02C7\xB8\u02D9\u02DD\xAF\u02DB\u02DA\uFF5E\u0384\u0385"], + ["8fa2c2", "\xA1\xA6\xBF"], + ["8fa2eb", "\xBA\xAA\xA9\xAE\u2122\xA4\u2116"], + ["8fa6e1", "\u0386\u0388\u0389\u038A\u03AA"], + ["8fa6e7", "\u038C"], + ["8fa6e9", "\u038E\u03AB"], + ["8fa6ec", "\u038F"], + ["8fa6f1", "\u03AC\u03AD\u03AE\u03AF\u03CA\u0390\u03CC\u03C2\u03CD\u03CB\u03B0\u03CE"], + ["8fa7c2", "\u0402", 10, "\u040E\u040F"], + ["8fa7f2", "\u0452", 10, "\u045E\u045F"], + ["8fa9a1", "\xC6\u0110"], + ["8fa9a4", "\u0126"], + ["8fa9a6", "\u0132"], + ["8fa9a8", "\u0141\u013F"], + ["8fa9ab", "\u014A\xD8\u0152"], + ["8fa9af", "\u0166\xDE"], + ["8fa9c1", "\xE6\u0111\xF0\u0127\u0131\u0133\u0138\u0142\u0140\u0149\u014B\xF8\u0153\xDF\u0167\xFE"], + ["8faaa1", "\xC1\xC0\xC4\xC2\u0102\u01CD\u0100\u0104\xC5\xC3\u0106\u0108\u010C\xC7\u010A\u010E\xC9\xC8\xCB\xCA\u011A\u0116\u0112\u0118"], + ["8faaba", "\u011C\u011E\u0122\u0120\u0124\xCD\xCC\xCF\xCE\u01CF\u0130\u012A\u012E\u0128\u0134\u0136\u0139\u013D\u013B\u0143\u0147\u0145\xD1\xD3\xD2\xD6\xD4\u01D1\u0150\u014C\xD5\u0154\u0158\u0156\u015A\u015C\u0160\u015E\u0164\u0162\xDA\xD9\xDC\xDB\u016C\u01D3\u0170\u016A\u0172\u016E\u0168\u01D7\u01DB\u01D9\u01D5\u0174\xDD\u0178\u0176\u0179\u017D\u017B"], + ["8faba1", "\xE1\xE0\xE4\xE2\u0103\u01CE\u0101\u0105\xE5\xE3\u0107\u0109\u010D\xE7\u010B\u010F\xE9\xE8\xEB\xEA\u011B\u0117\u0113\u0119\u01F5\u011D\u011F"], + ["8fabbd", "\u0121\u0125\xED\xEC\xEF\xEE\u01D0"], + ["8fabc5", "\u012B\u012F\u0129\u0135\u0137\u013A\u013E\u013C\u0144\u0148\u0146\xF1\xF3\xF2\xF6\xF4\u01D2\u0151\u014D\xF5\u0155\u0159\u0157\u015B\u015D\u0161\u015F\u0165\u0163\xFA\xF9\xFC\xFB\u016D\u01D4\u0171\u016B\u0173\u016F\u0169\u01D8\u01DC\u01DA\u01D6\u0175\xFD\xFF\u0177\u017A\u017E\u017C"], + ["8fb0a1", "\u4E02\u4E04\u4E05\u4E0C\u4E12\u4E1F\u4E23\u4E24\u4E28\u4E2B\u4E2E\u4E2F\u4E30\u4E35\u4E40\u4E41\u4E44\u4E47\u4E51\u4E5A\u4E5C\u4E63\u4E68\u4E69\u4E74\u4E75\u4E79\u4E7F\u4E8D\u4E96\u4E97\u4E9D\u4EAF\u4EB9\u4EC3\u4ED0\u4EDA\u4EDB\u4EE0\u4EE1\u4EE2\u4EE8\u4EEF\u4EF1\u4EF3\u4EF5\u4EFD\u4EFE\u4EFF\u4F00\u4F02\u4F03\u4F08\u4F0B\u4F0C\u4F12\u4F15\u4F16\u4F17\u4F19\u4F2E\u4F31\u4F60\u4F33\u4F35\u4F37\u4F39\u4F3B\u4F3E\u4F40\u4F42\u4F48\u4F49\u4F4B\u4F4C\u4F52\u4F54\u4F56\u4F58\u4F5F\u4F63\u4F6A\u4F6C\u4F6E\u4F71\u4F77\u4F78\u4F79\u4F7A\u4F7D\u4F7E\u4F81\u4F82\u4F84"], + ["8fb1a1", "\u4F85\u4F89\u4F8A\u4F8C\u4F8E\u4F90\u4F92\u4F93\u4F94\u4F97\u4F99\u4F9A\u4F9E\u4F9F\u4FB2\u4FB7\u4FB9\u4FBB\u4FBC\u4FBD\u4FBE\u4FC0\u4FC1\u4FC5\u4FC6\u4FC8\u4FC9\u4FCB\u4FCC\u4FCD\u4FCF\u4FD2\u4FDC\u4FE0\u4FE2\u4FF0\u4FF2\u4FFC\u4FFD\u4FFF\u5000\u5001\u5004\u5007\u500A\u500C\u500E\u5010\u5013\u5017\u5018\u501B\u501C\u501D\u501E\u5022\u5027\u502E\u5030\u5032\u5033\u5035\u5040\u5041\u5042\u5045\u5046\u504A\u504C\u504E\u5051\u5052\u5053\u5057\u5059\u505F\u5060\u5062\u5063\u5066\u5067\u506A\u506D\u5070\u5071\u503B\u5081\u5083\u5084\u5086\u508A\u508E\u508F\u5090"], + ["8fb2a1", "\u5092\u5093\u5094\u5096\u509B\u509C\u509E", 4, "\u50AA\u50AF\u50B0\u50B9\u50BA\u50BD\u50C0\u50C3\u50C4\u50C7\u50CC\u50CE\u50D0\u50D3\u50D4\u50D8\u50DC\u50DD\u50DF\u50E2\u50E4\u50E6\u50E8\u50E9\u50EF\u50F1\u50F6\u50FA\u50FE\u5103\u5106\u5107\u5108\u510B\u510C\u510D\u510E\u50F2\u5110\u5117\u5119\u511B\u511C\u511D\u511E\u5123\u5127\u5128\u512C\u512D\u512F\u5131\u5133\u5134\u5135\u5138\u5139\u5142\u514A\u514F\u5153\u5155\u5157\u5158\u515F\u5164\u5166\u517E\u5183\u5184\u518B\u518E\u5198\u519D\u51A1\u51A3\u51AD\u51B8\u51BA\u51BC\u51BE\u51BF\u51C2"], + ["8fb3a1", "\u51C8\u51CF\u51D1\u51D2\u51D3\u51D5\u51D8\u51DE\u51E2\u51E5\u51EE\u51F2\u51F3\u51F4\u51F7\u5201\u5202\u5205\u5212\u5213\u5215\u5216\u5218\u5222\u5228\u5231\u5232\u5235\u523C\u5245\u5249\u5255\u5257\u5258\u525A\u525C\u525F\u5260\u5261\u5266\u526E\u5277\u5278\u5279\u5280\u5282\u5285\u528A\u528C\u5293\u5295\u5296\u5297\u5298\u529A\u529C\u52A4\u52A5\u52A6\u52A7\u52AF\u52B0\u52B6\u52B7\u52B8\u52BA\u52BB\u52BD\u52C0\u52C4\u52C6\u52C8\u52CC\u52CF\u52D1\u52D4\u52D6\u52DB\u52DC\u52E1\u52E5\u52E8\u52E9\u52EA\u52EC\u52F0\u52F1\u52F4\u52F6\u52F7\u5300\u5303\u530A\u530B"], + ["8fb4a1", "\u530C\u5311\u5313\u5318\u531B\u531C\u531E\u531F\u5325\u5327\u5328\u5329\u532B\u532C\u532D\u5330\u5332\u5335\u533C\u533D\u533E\u5342\u534C\u534B\u5359\u535B\u5361\u5363\u5365\u536C\u536D\u5372\u5379\u537E\u5383\u5387\u5388\u538E\u5393\u5394\u5399\u539D\u53A1\u53A4\u53AA\u53AB\u53AF\u53B2\u53B4\u53B5\u53B7\u53B8\u53BA\u53BD\u53C0\u53C5\u53CF\u53D2\u53D3\u53D5\u53DA\u53DD\u53DE\u53E0\u53E6\u53E7\u53F5\u5402\u5413\u541A\u5421\u5427\u5428\u542A\u542F\u5431\u5434\u5435\u5443\u5444\u5447\u544D\u544F\u545E\u5462\u5464\u5466\u5467\u5469\u546B\u546D\u546E\u5474\u547F"], + ["8fb5a1", "\u5481\u5483\u5485\u5488\u5489\u548D\u5491\u5495\u5496\u549C\u549F\u54A1\u54A6\u54A7\u54A9\u54AA\u54AD\u54AE\u54B1\u54B7\u54B9\u54BA\u54BB\u54BF\u54C6\u54CA\u54CD\u54CE\u54E0\u54EA\u54EC\u54EF\u54F6\u54FC\u54FE\u54FF\u5500\u5501\u5505\u5508\u5509\u550C\u550D\u550E\u5515\u552A\u552B\u5532\u5535\u5536\u553B\u553C\u553D\u5541\u5547\u5549\u554A\u554D\u5550\u5551\u5558\u555A\u555B\u555E\u5560\u5561\u5564\u5566\u557F\u5581\u5582\u5586\u5588\u558E\u558F\u5591\u5592\u5593\u5594\u5597\u55A3\u55A4\u55AD\u55B2\u55BF\u55C1\u55C3\u55C6\u55C9\u55CB\u55CC\u55CE\u55D1\u55D2"], + ["8fb6a1", "\u55D3\u55D7\u55D8\u55DB\u55DE\u55E2\u55E9\u55F6\u55FF\u5605\u5608\u560A\u560D", 5, "\u5619\u562C\u5630\u5633\u5635\u5637\u5639\u563B\u563C\u563D\u563F\u5640\u5641\u5643\u5644\u5646\u5649\u564B\u564D\u564F\u5654\u565E\u5660\u5661\u5662\u5663\u5666\u5669\u566D\u566F\u5671\u5672\u5675\u5684\u5685\u5688\u568B\u568C\u5695\u5699\u569A\u569D\u569E\u569F\u56A6\u56A7\u56A8\u56A9\u56AB\u56AC\u56AD\u56B1\u56B3\u56B7\u56BE\u56C5\u56C9\u56CA\u56CB\u56CF\u56D0\u56CC\u56CD\u56D9\u56DC\u56DD\u56DF\u56E1\u56E4", 4, "\u56F1\u56EB\u56ED"], + ["8fb7a1", "\u56F6\u56F7\u5701\u5702\u5707\u570A\u570C\u5711\u5715\u571A\u571B\u571D\u5720\u5722\u5723\u5724\u5725\u5729\u572A\u572C\u572E\u572F\u5733\u5734\u573D\u573E\u573F\u5745\u5746\u574C\u574D\u5752\u5762\u5765\u5767\u5768\u576B\u576D", 4, "\u5773\u5774\u5775\u5777\u5779\u577A\u577B\u577C\u577E\u5781\u5783\u578C\u5794\u5797\u5799\u579A\u579C\u579D\u579E\u579F\u57A1\u5795\u57A7\u57A8\u57A9\u57AC\u57B8\u57BD\u57C7\u57C8\u57CC\u57CF\u57D5\u57DD\u57DE\u57E4\u57E6\u57E7\u57E9\u57ED\u57F0\u57F5\u57F6\u57F8\u57FD\u57FE\u57FF\u5803\u5804\u5808\u5809\u57E1"], + ["8fb8a1", "\u580C\u580D\u581B\u581E\u581F\u5820\u5826\u5827\u582D\u5832\u5839\u583F\u5849\u584C\u584D\u584F\u5850\u5855\u585F\u5861\u5864\u5867\u5868\u5878\u587C\u587F\u5880\u5881\u5887\u5888\u5889\u588A\u588C\u588D\u588F\u5890\u5894\u5896\u589D\u58A0\u58A1\u58A2\u58A6\u58A9\u58B1\u58B2\u58C4\u58BC\u58C2\u58C8\u58CD\u58CE\u58D0\u58D2\u58D4\u58D6\u58DA\u58DD\u58E1\u58E2\u58E9\u58F3\u5905\u5906\u590B\u590C\u5912\u5913\u5914\u8641\u591D\u5921\u5923\u5924\u5928\u592F\u5930\u5933\u5935\u5936\u593F\u5943\u5946\u5952\u5953\u5959\u595B\u595D\u595E\u595F\u5961\u5963\u596B\u596D"], + ["8fb9a1", "\u596F\u5972\u5975\u5976\u5979\u597B\u597C\u598B\u598C\u598E\u5992\u5995\u5997\u599F\u59A4\u59A7\u59AD\u59AE\u59AF\u59B0\u59B3\u59B7\u59BA\u59BC\u59C1\u59C3\u59C4\u59C8\u59CA\u59CD\u59D2\u59DD\u59DE\u59DF\u59E3\u59E4\u59E7\u59EE\u59EF\u59F1\u59F2\u59F4\u59F7\u5A00\u5A04\u5A0C\u5A0D\u5A0E\u5A12\u5A13\u5A1E\u5A23\u5A24\u5A27\u5A28\u5A2A\u5A2D\u5A30\u5A44\u5A45\u5A47\u5A48\u5A4C\u5A50\u5A55\u5A5E\u5A63\u5A65\u5A67\u5A6D\u5A77\u5A7A\u5A7B\u5A7E\u5A8B\u5A90\u5A93\u5A96\u5A99\u5A9C\u5A9E\u5A9F\u5AA0\u5AA2\u5AA7\u5AAC\u5AB1\u5AB2\u5AB3\u5AB5\u5AB8\u5ABA\u5ABB\u5ABF"], + ["8fbaa1", "\u5AC4\u5AC6\u5AC8\u5ACF\u5ADA\u5ADC\u5AE0\u5AE5\u5AEA\u5AEE\u5AF5\u5AF6\u5AFD\u5B00\u5B01\u5B08\u5B17\u5B34\u5B19\u5B1B\u5B1D\u5B21\u5B25\u5B2D\u5B38\u5B41\u5B4B\u5B4C\u5B52\u5B56\u5B5E\u5B68\u5B6E\u5B6F\u5B7C\u5B7D\u5B7E\u5B7F\u5B81\u5B84\u5B86\u5B8A\u5B8E\u5B90\u5B91\u5B93\u5B94\u5B96\u5BA8\u5BA9\u5BAC\u5BAD\u5BAF\u5BB1\u5BB2\u5BB7\u5BBA\u5BBC\u5BC0\u5BC1\u5BCD\u5BCF\u5BD6", 4, "\u5BE0\u5BEF\u5BF1\u5BF4\u5BFD\u5C0C\u5C17\u5C1E\u5C1F\u5C23\u5C26\u5C29\u5C2B\u5C2C\u5C2E\u5C30\u5C32\u5C35\u5C36\u5C59\u5C5A\u5C5C\u5C62\u5C63\u5C67\u5C68\u5C69"], + ["8fbba1", "\u5C6D\u5C70\u5C74\u5C75\u5C7A\u5C7B\u5C7C\u5C7D\u5C87\u5C88\u5C8A\u5C8F\u5C92\u5C9D\u5C9F\u5CA0\u5CA2\u5CA3\u5CA6\u5CAA\u5CB2\u5CB4\u5CB5\u5CBA\u5CC9\u5CCB\u5CD2\u5CDD\u5CD7\u5CEE\u5CF1\u5CF2\u5CF4\u5D01\u5D06\u5D0D\u5D12\u5D2B\u5D23\u5D24\u5D26\u5D27\u5D31\u5D34\u5D39\u5D3D\u5D3F\u5D42\u5D43\u5D46\u5D48\u5D55\u5D51\u5D59\u5D4A\u5D5F\u5D60\u5D61\u5D62\u5D64\u5D6A\u5D6D\u5D70\u5D79\u5D7A\u5D7E\u5D7F\u5D81\u5D83\u5D88\u5D8A\u5D92\u5D93\u5D94\u5D95\u5D99\u5D9B\u5D9F\u5DA0\u5DA7\u5DAB\u5DB0\u5DB4\u5DB8\u5DB9\u5DC3\u5DC7\u5DCB\u5DD0\u5DCE\u5DD8\u5DD9\u5DE0\u5DE4"], + ["8fbca1", "\u5DE9\u5DF8\u5DF9\u5E00\u5E07\u5E0D\u5E12\u5E14\u5E15\u5E18\u5E1F\u5E20\u5E2E\u5E28\u5E32\u5E35\u5E3E\u5E4B\u5E50\u5E49\u5E51\u5E56\u5E58\u5E5B\u5E5C\u5E5E\u5E68\u5E6A", 4, "\u5E70\u5E80\u5E8B\u5E8E\u5EA2\u5EA4\u5EA5\u5EA8\u5EAA\u5EAC\u5EB1\u5EB3\u5EBD\u5EBE\u5EBF\u5EC6\u5ECC\u5ECB\u5ECE\u5ED1\u5ED2\u5ED4\u5ED5\u5EDC\u5EDE\u5EE5\u5EEB\u5F02\u5F06\u5F07\u5F08\u5F0E\u5F19\u5F1C\u5F1D\u5F21\u5F22\u5F23\u5F24\u5F28\u5F2B\u5F2C\u5F2E\u5F30\u5F34\u5F36\u5F3B\u5F3D\u5F3F\u5F40\u5F44\u5F45\u5F47\u5F4D\u5F50\u5F54\u5F58\u5F5B\u5F60\u5F63\u5F64\u5F67"], + ["8fbda1", "\u5F6F\u5F72\u5F74\u5F75\u5F78\u5F7A\u5F7D\u5F7E\u5F89\u5F8D\u5F8F\u5F96\u5F9C\u5F9D\u5FA2\u5FA7\u5FAB\u5FA4\u5FAC\u5FAF\u5FB0\u5FB1\u5FB8\u5FC4\u5FC7\u5FC8\u5FC9\u5FCB\u5FD0", 4, "\u5FDE\u5FE1\u5FE2\u5FE8\u5FE9\u5FEA\u5FEC\u5FED\u5FEE\u5FEF\u5FF2\u5FF3\u5FF6\u5FFA\u5FFC\u6007\u600A\u600D\u6013\u6014\u6017\u6018\u601A\u601F\u6024\u602D\u6033\u6035\u6040\u6047\u6048\u6049\u604C\u6051\u6054\u6056\u6057\u605D\u6061\u6067\u6071\u607E\u607F\u6082\u6086\u6088\u608A\u608E\u6091\u6093\u6095\u6098\u609D\u609E\u60A2\u60A4\u60A5\u60A8\u60B0\u60B1\u60B7"], + ["8fbea1", "\u60BB\u60BE\u60C2\u60C4\u60C8\u60C9\u60CA\u60CB\u60CE\u60CF\u60D4\u60D5\u60D9\u60DB\u60DD\u60DE\u60E2\u60E5\u60F2\u60F5\u60F8\u60FC\u60FD\u6102\u6107\u610A\u610C\u6110", 4, "\u6116\u6117\u6119\u611C\u611E\u6122\u612A\u612B\u6130\u6131\u6135\u6136\u6137\u6139\u6141\u6145\u6146\u6149\u615E\u6160\u616C\u6172\u6178\u617B\u617C\u617F\u6180\u6181\u6183\u6184\u618B\u618D\u6192\u6193\u6197\u6198\u619C\u619D\u619F\u61A0\u61A5\u61A8\u61AA\u61AD\u61B8\u61B9\u61BC\u61C0\u61C1\u61C2\u61CE\u61CF\u61D5\u61DC\u61DD\u61DE\u61DF\u61E1\u61E2\u61E7\u61E9\u61E5"], + ["8fbfa1", "\u61EC\u61ED\u61EF\u6201\u6203\u6204\u6207\u6213\u6215\u621C\u6220\u6222\u6223\u6227\u6229\u622B\u6239\u623D\u6242\u6243\u6244\u6246\u624C\u6250\u6251\u6252\u6254\u6256\u625A\u625C\u6264\u626D\u626F\u6273\u627A\u627D\u628D\u628E\u628F\u6290\u62A6\u62A8\u62B3\u62B6\u62B7\u62BA\u62BE\u62BF\u62C4\u62CE\u62D5\u62D6\u62DA\u62EA\u62F2\u62F4\u62FC\u62FD\u6303\u6304\u630A\u630B\u630D\u6310\u6313\u6316\u6318\u6329\u632A\u632D\u6335\u6336\u6339\u633C\u6341\u6342\u6343\u6344\u6346\u634A\u634B\u634E\u6352\u6353\u6354\u6358\u635B\u6365\u6366\u636C\u636D\u6371\u6374\u6375"], + ["8fc0a1", "\u6378\u637C\u637D\u637F\u6382\u6384\u6387\u638A\u6390\u6394\u6395\u6399\u639A\u639E\u63A4\u63A6\u63AD\u63AE\u63AF\u63BD\u63C1\u63C5\u63C8\u63CE\u63D1\u63D3\u63D4\u63D5\u63DC\u63E0\u63E5\u63EA\u63EC\u63F2\u63F3\u63F5\u63F8\u63F9\u6409\u640A\u6410\u6412\u6414\u6418\u641E\u6420\u6422\u6424\u6425\u6429\u642A\u642F\u6430\u6435\u643D\u643F\u644B\u644F\u6451\u6452\u6453\u6454\u645A\u645B\u645C\u645D\u645F\u6460\u6461\u6463\u646D\u6473\u6474\u647B\u647D\u6485\u6487\u648F\u6490\u6491\u6498\u6499\u649B\u649D\u649F\u64A1\u64A3\u64A6\u64A8\u64AC\u64B3\u64BD\u64BE\u64BF"], + ["8fc1a1", "\u64C4\u64C9\u64CA\u64CB\u64CC\u64CE\u64D0\u64D1\u64D5\u64D7\u64E4\u64E5\u64E9\u64EA\u64ED\u64F0\u64F5\u64F7\u64FB\u64FF\u6501\u6504\u6508\u6509\u650A\u650F\u6513\u6514\u6516\u6519\u651B\u651E\u651F\u6522\u6526\u6529\u652E\u6531\u653A\u653C\u653D\u6543\u6547\u6549\u6550\u6552\u6554\u655F\u6560\u6567\u656B\u657A\u657D\u6581\u6585\u658A\u6592\u6595\u6598\u659D\u65A0\u65A3\u65A6\u65AE\u65B2\u65B3\u65B4\u65BF\u65C2\u65C8\u65C9\u65CE\u65D0\u65D4\u65D6\u65D8\u65DF\u65F0\u65F2\u65F4\u65F5\u65F9\u65FE\u65FF\u6600\u6604\u6608\u6609\u660D\u6611\u6612\u6615\u6616\u661D"], + ["8fc2a1", "\u661E\u6621\u6622\u6623\u6624\u6626\u6629\u662A\u662B\u662C\u662E\u6630\u6631\u6633\u6639\u6637\u6640\u6645\u6646\u664A\u664C\u6651\u664E\u6657\u6658\u6659\u665B\u665C\u6660\u6661\u66FB\u666A\u666B\u666C\u667E\u6673\u6675\u667F\u6677\u6678\u6679\u667B\u6680\u667C\u668B\u668C\u668D\u6690\u6692\u6699\u669A\u669B\u669C\u669F\u66A0\u66A4\u66AD\u66B1\u66B2\u66B5\u66BB\u66BF\u66C0\u66C2\u66C3\u66C8\u66CC\u66CE\u66CF\u66D4\u66DB\u66DF\u66E8\u66EB\u66EC\u66EE\u66FA\u6705\u6707\u670E\u6713\u6719\u671C\u6720\u6722\u6733\u673E\u6745\u6747\u6748\u674C\u6754\u6755\u675D"], + ["8fc3a1", "\u6766\u676C\u676E\u6774\u6776\u677B\u6781\u6784\u678E\u678F\u6791\u6793\u6796\u6798\u6799\u679B\u67B0\u67B1\u67B2\u67B5\u67BB\u67BC\u67BD\u67F9\u67C0\u67C2\u67C3\u67C5\u67C8\u67C9\u67D2\u67D7\u67D9\u67DC\u67E1\u67E6\u67F0\u67F2\u67F6\u67F7\u6852\u6814\u6819\u681D\u681F\u6828\u6827\u682C\u682D\u682F\u6830\u6831\u6833\u683B\u683F\u6844\u6845\u684A\u684C\u6855\u6857\u6858\u685B\u686B\u686E", 4, "\u6875\u6879\u687A\u687B\u687C\u6882\u6884\u6886\u6888\u6896\u6898\u689A\u689C\u68A1\u68A3\u68A5\u68A9\u68AA\u68AE\u68B2\u68BB\u68C5\u68C8\u68CC\u68CF"], + ["8fc4a1", "\u68D0\u68D1\u68D3\u68D6\u68D9\u68DC\u68DD\u68E5\u68E8\u68EA\u68EB\u68EC\u68ED\u68F0\u68F1\u68F5\u68F6\u68FB\u68FC\u68FD\u6906\u6909\u690A\u6910\u6911\u6913\u6916\u6917\u6931\u6933\u6935\u6938\u693B\u6942\u6945\u6949\u694E\u6957\u695B\u6963\u6964\u6965\u6966\u6968\u6969\u696C\u6970\u6971\u6972\u697A\u697B\u697F\u6980\u698D\u6992\u6996\u6998\u69A1\u69A5\u69A6\u69A8\u69AB\u69AD\u69AF\u69B7\u69B8\u69BA\u69BC\u69C5\u69C8\u69D1\u69D6\u69D7\u69E2\u69E5\u69EE\u69EF\u69F1\u69F3\u69F5\u69FE\u6A00\u6A01\u6A03\u6A0F\u6A11\u6A15\u6A1A\u6A1D\u6A20\u6A24\u6A28\u6A30\u6A32"], + ["8fc5a1", "\u6A34\u6A37\u6A3B\u6A3E\u6A3F\u6A45\u6A46\u6A49\u6A4A\u6A4E\u6A50\u6A51\u6A52\u6A55\u6A56\u6A5B\u6A64\u6A67\u6A6A\u6A71\u6A73\u6A7E\u6A81\u6A83\u6A86\u6A87\u6A89\u6A8B\u6A91\u6A9B\u6A9D\u6A9E\u6A9F\u6AA5\u6AAB\u6AAF\u6AB0\u6AB1\u6AB4\u6ABD\u6ABE\u6ABF\u6AC6\u6AC9\u6AC8\u6ACC\u6AD0\u6AD4\u6AD5\u6AD6\u6ADC\u6ADD\u6AE4\u6AE7\u6AEC\u6AF0\u6AF1\u6AF2\u6AFC\u6AFD\u6B02\u6B03\u6B06\u6B07\u6B09\u6B0F\u6B10\u6B11\u6B17\u6B1B\u6B1E\u6B24\u6B28\u6B2B\u6B2C\u6B2F\u6B35\u6B36\u6B3B\u6B3F\u6B46\u6B4A\u6B4D\u6B52\u6B56\u6B58\u6B5D\u6B60\u6B67\u6B6B\u6B6E\u6B70\u6B75\u6B7D"], + ["8fc6a1", "\u6B7E\u6B82\u6B85\u6B97\u6B9B\u6B9F\u6BA0\u6BA2\u6BA3\u6BA8\u6BA9\u6BAC\u6BAD\u6BAE\u6BB0\u6BB8\u6BB9\u6BBD\u6BBE\u6BC3\u6BC4\u6BC9\u6BCC\u6BD6\u6BDA\u6BE1\u6BE3\u6BE6\u6BE7\u6BEE\u6BF1\u6BF7\u6BF9\u6BFF\u6C02\u6C04\u6C05\u6C09\u6C0D\u6C0E\u6C10\u6C12\u6C19\u6C1F\u6C26\u6C27\u6C28\u6C2C\u6C2E\u6C33\u6C35\u6C36\u6C3A\u6C3B\u6C3F\u6C4A\u6C4B\u6C4D\u6C4F\u6C52\u6C54\u6C59\u6C5B\u6C5C\u6C6B\u6C6D\u6C6F\u6C74\u6C76\u6C78\u6C79\u6C7B\u6C85\u6C86\u6C87\u6C89\u6C94\u6C95\u6C97\u6C98\u6C9C\u6C9F\u6CB0\u6CB2\u6CB4\u6CC2\u6CC6\u6CCD\u6CCF\u6CD0\u6CD1\u6CD2\u6CD4\u6CD6"], + ["8fc7a1", "\u6CDA\u6CDC\u6CE0\u6CE7\u6CE9\u6CEB\u6CEC\u6CEE\u6CF2\u6CF4\u6D04\u6D07\u6D0A\u6D0E\u6D0F\u6D11\u6D13\u6D1A\u6D26\u6D27\u6D28\u6C67\u6D2E\u6D2F\u6D31\u6D39\u6D3C\u6D3F\u6D57\u6D5E\u6D5F\u6D61\u6D65\u6D67\u6D6F\u6D70\u6D7C\u6D82\u6D87\u6D91\u6D92\u6D94\u6D96\u6D97\u6D98\u6DAA\u6DAC\u6DB4\u6DB7\u6DB9\u6DBD\u6DBF\u6DC4\u6DC8\u6DCA\u6DCE\u6DCF\u6DD6\u6DDB\u6DDD\u6DDF\u6DE0\u6DE2\u6DE5\u6DE9\u6DEF\u6DF0\u6DF4\u6DF6\u6DFC\u6E00\u6E04\u6E1E\u6E22\u6E27\u6E32\u6E36\u6E39\u6E3B\u6E3C\u6E44\u6E45\u6E48\u6E49\u6E4B\u6E4F\u6E51\u6E52\u6E53\u6E54\u6E57\u6E5C\u6E5D\u6E5E"], + ["8fc8a1", "\u6E62\u6E63\u6E68\u6E73\u6E7B\u6E7D\u6E8D\u6E93\u6E99\u6EA0\u6EA7\u6EAD\u6EAE\u6EB1\u6EB3\u6EBB\u6EBF\u6EC0\u6EC1\u6EC3\u6EC7\u6EC8\u6ECA\u6ECD\u6ECE\u6ECF\u6EEB\u6EED\u6EEE\u6EF9\u6EFB\u6EFD\u6F04\u6F08\u6F0A\u6F0C\u6F0D\u6F16\u6F18\u6F1A\u6F1B\u6F26\u6F29\u6F2A\u6F2F\u6F30\u6F33\u6F36\u6F3B\u6F3C\u6F2D\u6F4F\u6F51\u6F52\u6F53\u6F57\u6F59\u6F5A\u6F5D\u6F5E\u6F61\u6F62\u6F68\u6F6C\u6F7D\u6F7E\u6F83\u6F87\u6F88\u6F8B\u6F8C\u6F8D\u6F90\u6F92\u6F93\u6F94\u6F96\u6F9A\u6F9F\u6FA0\u6FA5\u6FA6\u6FA7\u6FA8\u6FAE\u6FAF\u6FB0\u6FB5\u6FB6\u6FBC\u6FC5\u6FC7\u6FC8\u6FCA"], + ["8fc9a1", "\u6FDA\u6FDE\u6FE8\u6FE9\u6FF0\u6FF5\u6FF9\u6FFC\u6FFD\u7000\u7005\u7006\u7007\u700D\u7017\u7020\u7023\u702F\u7034\u7037\u7039\u703C\u7043\u7044\u7048\u7049\u704A\u704B\u7054\u7055\u705D\u705E\u704E\u7064\u7065\u706C\u706E\u7075\u7076\u707E\u7081\u7085\u7086\u7094", 4, "\u709B\u70A4\u70AB\u70B0\u70B1\u70B4\u70B7\u70CA\u70D1\u70D3\u70D4\u70D5\u70D6\u70D8\u70DC\u70E4\u70FA\u7103", 4, "\u710B\u710C\u710F\u711E\u7120\u712B\u712D\u712F\u7130\u7131\u7138\u7141\u7145\u7146\u7147\u714A\u714B\u7150\u7152\u7157\u715A\u715C\u715E\u7160"], + ["8fcaa1", "\u7168\u7179\u7180\u7185\u7187\u718C\u7192\u719A\u719B\u71A0\u71A2\u71AF\u71B0\u71B2\u71B3\u71BA\u71BF\u71C0\u71C1\u71C4\u71CB\u71CC\u71D3\u71D6\u71D9\u71DA\u71DC\u71F8\u71FE\u7200\u7207\u7208\u7209\u7213\u7217\u721A\u721D\u721F\u7224\u722B\u722F\u7234\u7238\u7239\u7241\u7242\u7243\u7245\u724E\u724F\u7250\u7253\u7255\u7256\u725A\u725C\u725E\u7260\u7263\u7268\u726B\u726E\u726F\u7271\u7277\u7278\u727B\u727C\u727F\u7284\u7289\u728D\u728E\u7293\u729B\u72A8\u72AD\u72AE\u72B1\u72B4\u72BE\u72C1\u72C7\u72C9\u72CC\u72D5\u72D6\u72D8\u72DF\u72E5\u72F3\u72F4\u72FA\u72FB"], + ["8fcba1", "\u72FE\u7302\u7304\u7305\u7307\u730B\u730D\u7312\u7313\u7318\u7319\u731E\u7322\u7324\u7327\u7328\u732C\u7331\u7332\u7335\u733A\u733B\u733D\u7343\u734D\u7350\u7352\u7356\u7358\u735D\u735E\u735F\u7360\u7366\u7367\u7369\u736B\u736C\u736E\u736F\u7371\u7377\u7379\u737C\u7380\u7381\u7383\u7385\u7386\u738E\u7390\u7393\u7395\u7397\u7398\u739C\u739E\u739F\u73A0\u73A2\u73A5\u73A6\u73AA\u73AB\u73AD\u73B5\u73B7\u73B9\u73BC\u73BD\u73BF\u73C5\u73C6\u73C9\u73CB\u73CC\u73CF\u73D2\u73D3\u73D6\u73D9\u73DD\u73E1\u73E3\u73E6\u73E7\u73E9\u73F4\u73F5\u73F7\u73F9\u73FA\u73FB\u73FD"], + ["8fcca1", "\u73FF\u7400\u7401\u7404\u7407\u740A\u7411\u741A\u741B\u7424\u7426\u7428", 9, "\u7439\u7440\u7443\u7444\u7446\u7447\u744B\u744D\u7451\u7452\u7457\u745D\u7462\u7466\u7467\u7468\u746B\u746D\u746E\u7471\u7472\u7480\u7481\u7485\u7486\u7487\u7489\u748F\u7490\u7491\u7492\u7498\u7499\u749A\u749C\u749F\u74A0\u74A1\u74A3\u74A6\u74A8\u74A9\u74AA\u74AB\u74AE\u74AF\u74B1\u74B2\u74B5\u74B9\u74BB\u74BF\u74C8\u74C9\u74CC\u74D0\u74D3\u74D8\u74DA\u74DB\u74DE\u74DF\u74E4\u74E8\u74EA\u74EB\u74EF\u74F4\u74FA\u74FB\u74FC\u74FF\u7506"], + ["8fcda1", "\u7512\u7516\u7517\u7520\u7521\u7524\u7527\u7529\u752A\u752F\u7536\u7539\u753D\u753E\u753F\u7540\u7543\u7547\u7548\u754E\u7550\u7552\u7557\u755E\u755F\u7561\u756F\u7571\u7579", 5, "\u7581\u7585\u7590\u7592\u7593\u7595\u7599\u759C\u75A2\u75A4\u75B4\u75BA\u75BF\u75C0\u75C1\u75C4\u75C6\u75CC\u75CE\u75CF\u75D7\u75DC\u75DF\u75E0\u75E1\u75E4\u75E7\u75EC\u75EE\u75EF\u75F1\u75F9\u7600\u7602\u7603\u7604\u7607\u7608\u760A\u760C\u760F\u7612\u7613\u7615\u7616\u7619\u761B\u761C\u761D\u761E\u7623\u7625\u7626\u7629\u762D\u7632\u7633\u7635\u7638\u7639"], + ["8fcea1", "\u763A\u763C\u764A\u7640\u7641\u7643\u7644\u7645\u7649\u764B\u7655\u7659\u765F\u7664\u7665\u766D\u766E\u766F\u7671\u7674\u7681\u7685\u768C\u768D\u7695\u769B\u769C\u769D\u769F\u76A0\u76A2", 6, "\u76AA\u76AD\u76BD\u76C1\u76C5\u76C9\u76CB\u76CC\u76CE\u76D4\u76D9\u76E0\u76E6\u76E8\u76EC\u76F0\u76F1\u76F6\u76F9\u76FC\u7700\u7706\u770A\u770E\u7712\u7714\u7715\u7717\u7719\u771A\u771C\u7722\u7728\u772D\u772E\u772F\u7734\u7735\u7736\u7739\u773D\u773E\u7742\u7745\u7746\u774A\u774D\u774E\u774F\u7752\u7756\u7757\u775C\u775E\u775F\u7760\u7762"], + ["8fcfa1", "\u7764\u7767\u776A\u776C\u7770\u7772\u7773\u7774\u777A\u777D\u7780\u7784\u778C\u778D\u7794\u7795\u7796\u779A\u779F\u77A2\u77A7\u77AA\u77AE\u77AF\u77B1\u77B5\u77BE\u77C3\u77C9\u77D1\u77D2\u77D5\u77D9\u77DE\u77DF\u77E0\u77E4\u77E6\u77EA\u77EC\u77F0\u77F1\u77F4\u77F8\u77FB\u7805\u7806\u7809\u780D\u780E\u7811\u781D\u7821\u7822\u7823\u782D\u782E\u7830\u7835\u7837\u7843\u7844\u7847\u7848\u784C\u784E\u7852\u785C\u785E\u7860\u7861\u7863\u7864\u7868\u786A\u786E\u787A\u787E\u788A\u788F\u7894\u7898\u78A1\u789D\u789E\u789F\u78A4\u78A8\u78AC\u78AD\u78B0\u78B1\u78B2\u78B3"], + ["8fd0a1", "\u78BB\u78BD\u78BF\u78C7\u78C8\u78C9\u78CC\u78CE\u78D2\u78D3\u78D5\u78D6\u78E4\u78DB\u78DF\u78E0\u78E1\u78E6\u78EA\u78F2\u78F3\u7900\u78F6\u78F7\u78FA\u78FB\u78FF\u7906\u790C\u7910\u791A\u791C\u791E\u791F\u7920\u7925\u7927\u7929\u792D\u7931\u7934\u7935\u793B\u793D\u793F\u7944\u7945\u7946\u794A\u794B\u794F\u7951\u7954\u7958\u795B\u795C\u7967\u7969\u796B\u7972\u7979\u797B\u797C\u797E\u798B\u798C\u7991\u7993\u7994\u7995\u7996\u7998\u799B\u799C\u79A1\u79A8\u79A9\u79AB\u79AF\u79B1\u79B4\u79B8\u79BB\u79C2\u79C4\u79C7\u79C8\u79CA\u79CF\u79D4\u79D6\u79DA\u79DD\u79DE"], + ["8fd1a1", "\u79E0\u79E2\u79E5\u79EA\u79EB\u79ED\u79F1\u79F8\u79FC\u7A02\u7A03\u7A07\u7A09\u7A0A\u7A0C\u7A11\u7A15\u7A1B\u7A1E\u7A21\u7A27\u7A2B\u7A2D\u7A2F\u7A30\u7A34\u7A35\u7A38\u7A39\u7A3A\u7A44\u7A45\u7A47\u7A48\u7A4C\u7A55\u7A56\u7A59\u7A5C\u7A5D\u7A5F\u7A60\u7A65\u7A67\u7A6A\u7A6D\u7A75\u7A78\u7A7E\u7A80\u7A82\u7A85\u7A86\u7A8A\u7A8B\u7A90\u7A91\u7A94\u7A9E\u7AA0\u7AA3\u7AAC\u7AB3\u7AB5\u7AB9\u7ABB\u7ABC\u7AC6\u7AC9\u7ACC\u7ACE\u7AD1\u7ADB\u7AE8\u7AE9\u7AEB\u7AEC\u7AF1\u7AF4\u7AFB\u7AFD\u7AFE\u7B07\u7B14\u7B1F\u7B23\u7B27\u7B29\u7B2A\u7B2B\u7B2D\u7B2E\u7B2F\u7B30"], + ["8fd2a1", "\u7B31\u7B34\u7B3D\u7B3F\u7B40\u7B41\u7B47\u7B4E\u7B55\u7B60\u7B64\u7B66\u7B69\u7B6A\u7B6D\u7B6F\u7B72\u7B73\u7B77\u7B84\u7B89\u7B8E\u7B90\u7B91\u7B96\u7B9B\u7B9E\u7BA0\u7BA5\u7BAC\u7BAF\u7BB0\u7BB2\u7BB5\u7BB6\u7BBA\u7BBB\u7BBC\u7BBD\u7BC2\u7BC5\u7BC8\u7BCA\u7BD4\u7BD6\u7BD7\u7BD9\u7BDA\u7BDB\u7BE8\u7BEA\u7BF2\u7BF4\u7BF5\u7BF8\u7BF9\u7BFA\u7BFC\u7BFE\u7C01\u7C02\u7C03\u7C04\u7C06\u7C09\u7C0B\u7C0C\u7C0E\u7C0F\u7C19\u7C1B\u7C20\u7C25\u7C26\u7C28\u7C2C\u7C31\u7C33\u7C34\u7C36\u7C39\u7C3A\u7C46\u7C4A\u7C55\u7C51\u7C52\u7C53\u7C59", 5], + ["8fd3a1", "\u7C61\u7C63\u7C67\u7C69\u7C6D\u7C6E\u7C70\u7C72\u7C79\u7C7C\u7C7D\u7C86\u7C87\u7C8F\u7C94\u7C9E\u7CA0\u7CA6\u7CB0\u7CB6\u7CB7\u7CBA\u7CBB\u7CBC\u7CBF\u7CC4\u7CC7\u7CC8\u7CC9\u7CCD\u7CCF\u7CD3\u7CD4\u7CD5\u7CD7\u7CD9\u7CDA\u7CDD\u7CE6\u7CE9\u7CEB\u7CF5\u7D03\u7D07\u7D08\u7D09\u7D0F\u7D11\u7D12\u7D13\u7D16\u7D1D\u7D1E\u7D23\u7D26\u7D2A\u7D2D\u7D31\u7D3C\u7D3D\u7D3E\u7D40\u7D41\u7D47\u7D48\u7D4D\u7D51\u7D53\u7D57\u7D59\u7D5A\u7D5C\u7D5D\u7D65\u7D67\u7D6A\u7D70\u7D78\u7D7A\u7D7B\u7D7F\u7D81\u7D82\u7D83\u7D85\u7D86\u7D88\u7D8B\u7D8C\u7D8D\u7D91\u7D96\u7D97\u7D9D"], + ["8fd4a1", "\u7D9E\u7DA6\u7DA7\u7DAA\u7DB3\u7DB6\u7DB7\u7DB9\u7DC2", 4, "\u7DCC\u7DCD\u7DCE\u7DD7\u7DD9\u7E00\u7DE2\u7DE5\u7DE6\u7DEA\u7DEB\u7DED\u7DF1\u7DF5\u7DF6\u7DF9\u7DFA\u7E08\u7E10\u7E11\u7E15\u7E17\u7E1C\u7E1D\u7E20\u7E27\u7E28\u7E2C\u7E2D\u7E2F\u7E33\u7E36\u7E3F\u7E44\u7E45\u7E47\u7E4E\u7E50\u7E52\u7E58\u7E5F\u7E61\u7E62\u7E65\u7E6B\u7E6E\u7E6F\u7E73\u7E78\u7E7E\u7E81\u7E86\u7E87\u7E8A\u7E8D\u7E91\u7E95\u7E98\u7E9A\u7E9D\u7E9E\u7F3C\u7F3B\u7F3D\u7F3E\u7F3F\u7F43\u7F44\u7F47\u7F4F\u7F52\u7F53\u7F5B\u7F5C\u7F5D\u7F61\u7F63\u7F64\u7F65\u7F66\u7F6D"], + ["8fd5a1", "\u7F71\u7F7D\u7F7E\u7F7F\u7F80\u7F8B\u7F8D\u7F8F\u7F90\u7F91\u7F96\u7F97\u7F9C\u7FA1\u7FA2\u7FA6\u7FAA\u7FAD\u7FB4\u7FBC\u7FBF\u7FC0\u7FC3\u7FC8\u7FCE\u7FCF\u7FDB\u7FDF\u7FE3\u7FE5\u7FE8\u7FEC\u7FEE\u7FEF\u7FF2\u7FFA\u7FFD\u7FFE\u7FFF\u8007\u8008\u800A\u800D\u800E\u800F\u8011\u8013\u8014\u8016\u801D\u801E\u801F\u8020\u8024\u8026\u802C\u802E\u8030\u8034\u8035\u8037\u8039\u803A\u803C\u803E\u8040\u8044\u8060\u8064\u8066\u806D\u8071\u8075\u8081\u8088\u808E\u809C\u809E\u80A6\u80A7\u80AB\u80B8\u80B9\u80C8\u80CD\u80CF\u80D2\u80D4\u80D5\u80D7\u80D8\u80E0\u80ED\u80EE"], + ["8fd6a1", "\u80F0\u80F2\u80F3\u80F6\u80F9\u80FA\u80FE\u8103\u810B\u8116\u8117\u8118\u811C\u811E\u8120\u8124\u8127\u812C\u8130\u8135\u813A\u813C\u8145\u8147\u814A\u814C\u8152\u8157\u8160\u8161\u8167\u8168\u8169\u816D\u816F\u8177\u8181\u8190\u8184\u8185\u8186\u818B\u818E\u8196\u8198\u819B\u819E\u81A2\u81AE\u81B2\u81B4\u81BB\u81CB\u81C3\u81C5\u81CA\u81CE\u81CF\u81D5\u81D7\u81DB\u81DD\u81DE\u81E1\u81E4\u81EB\u81EC\u81F0\u81F1\u81F2\u81F5\u81F6\u81F8\u81F9\u81FD\u81FF\u8200\u8203\u820F\u8213\u8214\u8219\u821A\u821D\u8221\u8222\u8228\u8232\u8234\u823A\u8243\u8244\u8245\u8246"], + ["8fd7a1", "\u824B\u824E\u824F\u8251\u8256\u825C\u8260\u8263\u8267\u826D\u8274\u827B\u827D\u827F\u8280\u8281\u8283\u8284\u8287\u8289\u828A\u828E\u8291\u8294\u8296\u8298\u829A\u829B\u82A0\u82A1\u82A3\u82A4\u82A7\u82A8\u82A9\u82AA\u82AE\u82B0\u82B2\u82B4\u82B7\u82BA\u82BC\u82BE\u82BF\u82C6\u82D0\u82D5\u82DA\u82E0\u82E2\u82E4\u82E8\u82EA\u82ED\u82EF\u82F6\u82F7\u82FD\u82FE\u8300\u8301\u8307\u8308\u830A\u830B\u8354\u831B\u831D\u831E\u831F\u8321\u8322\u832C\u832D\u832E\u8330\u8333\u8337\u833A\u833C\u833D\u8342\u8343\u8344\u8347\u834D\u834E\u8351\u8355\u8356\u8357\u8370\u8378"], + ["8fd8a1", "\u837D\u837F\u8380\u8382\u8384\u8386\u838D\u8392\u8394\u8395\u8398\u8399\u839B\u839C\u839D\u83A6\u83A7\u83A9\u83AC\u83BE\u83BF\u83C0\u83C7\u83C9\u83CF\u83D0\u83D1\u83D4\u83DD\u8353\u83E8\u83EA\u83F6\u83F8\u83F9\u83FC\u8401\u8406\u840A\u840F\u8411\u8415\u8419\u83AD\u842F\u8439\u8445\u8447\u8448\u844A\u844D\u844F\u8451\u8452\u8456\u8458\u8459\u845A\u845C\u8460\u8464\u8465\u8467\u846A\u8470\u8473\u8474\u8476\u8478\u847C\u847D\u8481\u8485\u8492\u8493\u8495\u849E\u84A6\u84A8\u84A9\u84AA\u84AF\u84B1\u84B4\u84BA\u84BD\u84BE\u84C0\u84C2\u84C7\u84C8\u84CC\u84CF\u84D3"], + ["8fd9a1", "\u84DC\u84E7\u84EA\u84EF\u84F0\u84F1\u84F2\u84F7\u8532\u84FA\u84FB\u84FD\u8502\u8503\u8507\u850C\u850E\u8510\u851C\u851E\u8522\u8523\u8524\u8525\u8527\u852A\u852B\u852F\u8533\u8534\u8536\u853F\u8546\u854F", 4, "\u8556\u8559\u855C", 6, "\u8564\u856B\u856F\u8579\u857A\u857B\u857D\u857F\u8581\u8585\u8586\u8589\u858B\u858C\u858F\u8593\u8598\u859D\u859F\u85A0\u85A2\u85A5\u85A7\u85B4\u85B6\u85B7\u85B8\u85BC\u85BD\u85BE\u85BF\u85C2\u85C7\u85CA\u85CB\u85CE\u85AD\u85D8\u85DA\u85DF\u85E0\u85E6\u85E8\u85ED\u85F3\u85F6\u85FC"], + ["8fdaa1", "\u85FF\u8600\u8604\u8605\u860D\u860E\u8610\u8611\u8612\u8618\u8619\u861B\u861E\u8621\u8627\u8629\u8636\u8638\u863A\u863C\u863D\u8640\u8642\u8646\u8652\u8653\u8656\u8657\u8658\u8659\u865D\u8660", 4, "\u8669\u866C\u866F\u8675\u8676\u8677\u867A\u868D\u8691\u8696\u8698\u869A\u869C\u86A1\u86A6\u86A7\u86A8\u86AD\u86B1\u86B3\u86B4\u86B5\u86B7\u86B8\u86B9\u86BF\u86C0\u86C1\u86C3\u86C5\u86D1\u86D2\u86D5\u86D7\u86DA\u86DC\u86E0\u86E3\u86E5\u86E7\u8688\u86FA\u86FC\u86FD\u8704\u8705\u8707\u870B\u870E\u870F\u8710\u8713\u8714\u8719\u871E\u871F\u8721\u8723"], + ["8fdba1", "\u8728\u872E\u872F\u8731\u8732\u8739\u873A\u873C\u873D\u873E\u8740\u8743\u8745\u874D\u8758\u875D\u8761\u8764\u8765\u876F\u8771\u8772\u877B\u8783", 6, "\u878B\u878C\u8790\u8793\u8795\u8797\u8798\u8799\u879E\u87A0\u87A3\u87A7\u87AC\u87AD\u87AE\u87B1\u87B5\u87BE\u87BF\u87C1\u87C8\u87C9\u87CA\u87CE\u87D5\u87D6\u87D9\u87DA\u87DC\u87DF\u87E2\u87E3\u87E4\u87EA\u87EB\u87ED\u87F1\u87F3\u87F8\u87FA\u87FF\u8801\u8803\u8806\u8809\u880A\u880B\u8810\u8819\u8812\u8813\u8814\u8818\u881A\u881B\u881C\u881E\u881F\u8828\u882D\u882E\u8830\u8832\u8835"], + ["8fdca1", "\u883A\u883C\u8841\u8843\u8845\u8848\u8849\u884A\u884B\u884E\u8851\u8855\u8856\u8858\u885A\u885C\u885F\u8860\u8864\u8869\u8871\u8879\u887B\u8880\u8898\u889A\u889B\u889C\u889F\u88A0\u88A8\u88AA\u88BA\u88BD\u88BE\u88C0\u88CA", 4, "\u88D1\u88D2\u88D3\u88DB\u88DE\u88E7\u88EF\u88F0\u88F1\u88F5\u88F7\u8901\u8906\u890D\u890E\u890F\u8915\u8916\u8918\u8919\u891A\u891C\u8920\u8926\u8927\u8928\u8930\u8931\u8932\u8935\u8939\u893A\u893E\u8940\u8942\u8945\u8946\u8949\u894F\u8952\u8957\u895A\u895B\u895C\u8961\u8962\u8963\u896B\u896E\u8970\u8973\u8975\u897A"], + ["8fdda1", "\u897B\u897C\u897D\u8989\u898D\u8990\u8994\u8995\u899B\u899C\u899F\u89A0\u89A5\u89B0\u89B4\u89B5\u89B6\u89B7\u89BC\u89D4", 4, "\u89E5\u89E9\u89EB\u89ED\u89F1\u89F3\u89F6\u89F9\u89FD\u89FF\u8A04\u8A05\u8A07\u8A0F\u8A11\u8A12\u8A14\u8A15\u8A1E\u8A20\u8A22\u8A24\u8A26\u8A2B\u8A2C\u8A2F\u8A35\u8A37\u8A3D\u8A3E\u8A40\u8A43\u8A45\u8A47\u8A49\u8A4D\u8A4E\u8A53\u8A56\u8A57\u8A58\u8A5C\u8A5D\u8A61\u8A65\u8A67\u8A75\u8A76\u8A77\u8A79\u8A7A\u8A7B\u8A7E\u8A7F\u8A80\u8A83\u8A86\u8A8B\u8A8F\u8A90\u8A92\u8A96\u8A97\u8A99\u8A9F\u8AA7\u8AA9\u8AAE\u8AAF\u8AB3"], + ["8fdea1", "\u8AB6\u8AB7\u8ABB\u8ABE\u8AC3\u8AC6\u8AC8\u8AC9\u8ACA\u8AD1\u8AD3\u8AD4\u8AD5\u8AD7\u8ADD\u8ADF\u8AEC\u8AF0\u8AF4\u8AF5\u8AF6\u8AFC\u8AFF\u8B05\u8B06\u8B0B\u8B11\u8B1C\u8B1E\u8B1F\u8B0A\u8B2D\u8B30\u8B37\u8B3C\u8B42", 4, "\u8B48\u8B52\u8B53\u8B54\u8B59\u8B4D\u8B5E\u8B63\u8B6D\u8B76\u8B78\u8B79\u8B7C\u8B7E\u8B81\u8B84\u8B85\u8B8B\u8B8D\u8B8F\u8B94\u8B95\u8B9C\u8B9E\u8B9F\u8C38\u8C39\u8C3D\u8C3E\u8C45\u8C47\u8C49\u8C4B\u8C4F\u8C51\u8C53\u8C54\u8C57\u8C58\u8C5B\u8C5D\u8C59\u8C63\u8C64\u8C66\u8C68\u8C69\u8C6D\u8C73\u8C75\u8C76\u8C7B\u8C7E\u8C86"], + ["8fdfa1", "\u8C87\u8C8B\u8C90\u8C92\u8C93\u8C99\u8C9B\u8C9C\u8CA4\u8CB9\u8CBA\u8CC5\u8CC6\u8CC9\u8CCB\u8CCF\u8CD6\u8CD5\u8CD9\u8CDD\u8CE1\u8CE8\u8CEC\u8CEF\u8CF0\u8CF2\u8CF5\u8CF7\u8CF8\u8CFE\u8CFF\u8D01\u8D03\u8D09\u8D12\u8D17\u8D1B\u8D65\u8D69\u8D6C\u8D6E\u8D7F\u8D82\u8D84\u8D88\u8D8D\u8D90\u8D91\u8D95\u8D9E\u8D9F\u8DA0\u8DA6\u8DAB\u8DAC\u8DAF\u8DB2\u8DB5\u8DB7\u8DB9\u8DBB\u8DC0\u8DC5\u8DC6\u8DC7\u8DC8\u8DCA\u8DCE\u8DD1\u8DD4\u8DD5\u8DD7\u8DD9\u8DE4\u8DE5\u8DE7\u8DEC\u8DF0\u8DBC\u8DF1\u8DF2\u8DF4\u8DFD\u8E01\u8E04\u8E05\u8E06\u8E0B\u8E11\u8E14\u8E16\u8E20\u8E21\u8E22"], + ["8fe0a1", "\u8E23\u8E26\u8E27\u8E31\u8E33\u8E36\u8E37\u8E38\u8E39\u8E3D\u8E40\u8E41\u8E4B\u8E4D\u8E4E\u8E4F\u8E54\u8E5B\u8E5C\u8E5D\u8E5E\u8E61\u8E62\u8E69\u8E6C\u8E6D\u8E6F\u8E70\u8E71\u8E79\u8E7A\u8E7B\u8E82\u8E83\u8E89\u8E90\u8E92\u8E95\u8E9A\u8E9B\u8E9D\u8E9E\u8EA2\u8EA7\u8EA9\u8EAD\u8EAE\u8EB3\u8EB5\u8EBA\u8EBB\u8EC0\u8EC1\u8EC3\u8EC4\u8EC7\u8ECF\u8ED1\u8ED4\u8EDC\u8EE8\u8EEE\u8EF0\u8EF1\u8EF7\u8EF9\u8EFA\u8EED\u8F00\u8F02\u8F07\u8F08\u8F0F\u8F10\u8F16\u8F17\u8F18\u8F1E\u8F20\u8F21\u8F23\u8F25\u8F27\u8F28\u8F2C\u8F2D\u8F2E\u8F34\u8F35\u8F36\u8F37\u8F3A\u8F40\u8F41"], + ["8fe1a1", "\u8F43\u8F47\u8F4F\u8F51", 4, "\u8F58\u8F5D\u8F5E\u8F65\u8F9D\u8FA0\u8FA1\u8FA4\u8FA5\u8FA6\u8FB5\u8FB6\u8FB8\u8FBE\u8FC0\u8FC1\u8FC6\u8FCA\u8FCB\u8FCD\u8FD0\u8FD2\u8FD3\u8FD5\u8FE0\u8FE3\u8FE4\u8FE8\u8FEE\u8FF1\u8FF5\u8FF6\u8FFB\u8FFE\u9002\u9004\u9008\u900C\u9018\u901B\u9028\u9029\u902F\u902A\u902C\u902D\u9033\u9034\u9037\u903F\u9043\u9044\u904C\u905B\u905D\u9062\u9066\u9067\u906C\u9070\u9074\u9079\u9085\u9088\u908B\u908C\u908E\u9090\u9095\u9097\u9098\u9099\u909B\u90A0\u90A1\u90A2\u90A5\u90B0\u90B2\u90B3\u90B4\u90B6\u90BD\u90CC\u90BE\u90C3"], + ["8fe2a1", "\u90C4\u90C5\u90C7\u90C8\u90D5\u90D7\u90D8\u90D9\u90DC\u90DD\u90DF\u90E5\u90D2\u90F6\u90EB\u90EF\u90F0\u90F4\u90FE\u90FF\u9100\u9104\u9105\u9106\u9108\u910D\u9110\u9114\u9116\u9117\u9118\u911A\u911C\u911E\u9120\u9125\u9122\u9123\u9127\u9129\u912E\u912F\u9131\u9134\u9136\u9137\u9139\u913A\u913C\u913D\u9143\u9147\u9148\u914F\u9153\u9157\u9159\u915A\u915B\u9161\u9164\u9167\u916D\u9174\u9179\u917A\u917B\u9181\u9183\u9185\u9186\u918A\u918E\u9191\u9193\u9194\u9195\u9198\u919E\u91A1\u91A6\u91A8\u91AC\u91AD\u91AE\u91B0\u91B1\u91B2\u91B3\u91B6\u91BB\u91BC\u91BD\u91BF"], + ["8fe3a1", "\u91C2\u91C3\u91C5\u91D3\u91D4\u91D7\u91D9\u91DA\u91DE\u91E4\u91E5\u91E9\u91EA\u91EC", 5, "\u91F7\u91F9\u91FB\u91FD\u9200\u9201\u9204\u9205\u9206\u9207\u9209\u920A\u920C\u9210\u9212\u9213\u9216\u9218\u921C\u921D\u9223\u9224\u9225\u9226\u9228\u922E\u922F\u9230\u9233\u9235\u9236\u9238\u9239\u923A\u923C\u923E\u9240\u9242\u9243\u9246\u9247\u924A\u924D\u924E\u924F\u9251\u9258\u9259\u925C\u925D\u9260\u9261\u9265\u9267\u9268\u9269\u926E\u926F\u9270\u9275", 4, "\u927B\u927C\u927D\u927F\u9288\u9289\u928A\u928D\u928E\u9292\u9297"], + ["8fe4a1", "\u9299\u929F\u92A0\u92A4\u92A5\u92A7\u92A8\u92AB\u92AF\u92B2\u92B6\u92B8\u92BA\u92BB\u92BC\u92BD\u92BF", 4, "\u92C5\u92C6\u92C7\u92C8\u92CB\u92CC\u92CD\u92CE\u92D0\u92D3\u92D5\u92D7\u92D8\u92D9\u92DC\u92DD\u92DF\u92E0\u92E1\u92E3\u92E5\u92E7\u92E8\u92EC\u92EE\u92F0\u92F9\u92FB\u92FF\u9300\u9302\u9308\u930D\u9311\u9314\u9315\u931C\u931D\u931E\u931F\u9321\u9324\u9325\u9327\u9329\u932A\u9333\u9334\u9336\u9337\u9347\u9348\u9349\u9350\u9351\u9352\u9355\u9357\u9358\u935A\u935E\u9364\u9365\u9367\u9369\u936A\u936D\u936F\u9370\u9371\u9373\u9374\u9376"], + ["8fe5a1", "\u937A\u937D\u937F\u9380\u9381\u9382\u9388\u938A\u938B\u938D\u938F\u9392\u9395\u9398\u939B\u939E\u93A1\u93A3\u93A4\u93A6\u93A8\u93AB\u93B4\u93B5\u93B6\u93BA\u93A9\u93C1\u93C4\u93C5\u93C6\u93C7\u93C9", 4, "\u93D3\u93D9\u93DC\u93DE\u93DF\u93E2\u93E6\u93E7\u93F9\u93F7\u93F8\u93FA\u93FB\u93FD\u9401\u9402\u9404\u9408\u9409\u940D\u940E\u940F\u9415\u9416\u9417\u941F\u942E\u942F\u9431\u9432\u9433\u9434\u943B\u943F\u943D\u9443\u9445\u9448\u944A\u944C\u9455\u9459\u945C\u945F\u9461\u9463\u9468\u946B\u946D\u946E\u946F\u9471\u9472\u9484\u9483\u9578\u9579"], + ["8fe6a1", "\u957E\u9584\u9588\u958C\u958D\u958E\u959D\u959E\u959F\u95A1\u95A6\u95A9\u95AB\u95AC\u95B4\u95B6\u95BA\u95BD\u95BF\u95C6\u95C8\u95C9\u95CB\u95D0\u95D1\u95D2\u95D3\u95D9\u95DA\u95DD\u95DE\u95DF\u95E0\u95E4\u95E6\u961D\u961E\u9622\u9624\u9625\u9626\u962C\u9631\u9633\u9637\u9638\u9639\u963A\u963C\u963D\u9641\u9652\u9654\u9656\u9657\u9658\u9661\u966E\u9674\u967B\u967C\u967E\u967F\u9681\u9682\u9683\u9684\u9689\u9691\u9696\u969A\u969D\u969F\u96A4\u96A5\u96A6\u96A9\u96AE\u96AF\u96B3\u96BA\u96CA\u96D2\u5DB2\u96D8\u96DA\u96DD\u96DE\u96DF\u96E9\u96EF\u96F1\u96FA\u9702"], + ["8fe7a1", "\u9703\u9705\u9709\u971A\u971B\u971D\u9721\u9722\u9723\u9728\u9731\u9733\u9741\u9743\u974A\u974E\u974F\u9755\u9757\u9758\u975A\u975B\u9763\u9767\u976A\u976E\u9773\u9776\u9777\u9778\u977B\u977D\u977F\u9780\u9789\u9795\u9796\u9797\u9799\u979A\u979E\u979F\u97A2\u97AC\u97AE\u97B1\u97B2\u97B5\u97B6\u97B8\u97B9\u97BA\u97BC\u97BE\u97BF\u97C1\u97C4\u97C5\u97C7\u97C9\u97CA\u97CC\u97CD\u97CE\u97D0\u97D1\u97D4\u97D7\u97D8\u97D9\u97DD\u97DE\u97E0\u97DB\u97E1\u97E4\u97EF\u97F1\u97F4\u97F7\u97F8\u97FA\u9807\u980A\u9819\u980D\u980E\u9814\u9816\u981C\u981E\u9820\u9823\u9826"], + ["8fe8a1", "\u982B\u982E\u982F\u9830\u9832\u9833\u9835\u9825\u983E\u9844\u9847\u984A\u9851\u9852\u9853\u9856\u9857\u9859\u985A\u9862\u9863\u9865\u9866\u986A\u986C\u98AB\u98AD\u98AE\u98B0\u98B4\u98B7\u98B8\u98BA\u98BB\u98BF\u98C2\u98C5\u98C8\u98CC\u98E1\u98E3\u98E5\u98E6\u98E7\u98EA\u98F3\u98F6\u9902\u9907\u9908\u9911\u9915\u9916\u9917\u991A\u991B\u991C\u991F\u9922\u9926\u9927\u992B\u9931", 4, "\u9939\u993A\u993B\u993C\u9940\u9941\u9946\u9947\u9948\u994D\u994E\u9954\u9958\u9959\u995B\u995C\u995E\u995F\u9960\u999B\u999D\u999F\u99A6\u99B0\u99B1\u99B2\u99B5"], + ["8fe9a1", "\u99B9\u99BA\u99BD\u99BF\u99C3\u99C9\u99D3\u99D4\u99D9\u99DA\u99DC\u99DE\u99E7\u99EA\u99EB\u99EC\u99F0\u99F4\u99F5\u99F9\u99FD\u99FE\u9A02\u9A03\u9A04\u9A0B\u9A0C\u9A10\u9A11\u9A16\u9A1E\u9A20\u9A22\u9A23\u9A24\u9A27\u9A2D\u9A2E\u9A33\u9A35\u9A36\u9A38\u9A47\u9A41\u9A44\u9A4A\u9A4B\u9A4C\u9A4E\u9A51\u9A54\u9A56\u9A5D\u9AAA\u9AAC\u9AAE\u9AAF\u9AB2\u9AB4\u9AB5\u9AB6\u9AB9\u9ABB\u9ABE\u9ABF\u9AC1\u9AC3\u9AC6\u9AC8\u9ACE\u9AD0\u9AD2\u9AD5\u9AD6\u9AD7\u9ADB\u9ADC\u9AE0\u9AE4\u9AE5\u9AE7\u9AE9\u9AEC\u9AF2\u9AF3\u9AF5\u9AF9\u9AFA\u9AFD\u9AFF", 4], + ["8feaa1", "\u9B04\u9B05\u9B08\u9B09\u9B0B\u9B0C\u9B0D\u9B0E\u9B10\u9B12\u9B16\u9B19\u9B1B\u9B1C\u9B20\u9B26\u9B2B\u9B2D\u9B33\u9B34\u9B35\u9B37\u9B39\u9B3A\u9B3D\u9B48\u9B4B\u9B4C\u9B55\u9B56\u9B57\u9B5B\u9B5E\u9B61\u9B63\u9B65\u9B66\u9B68\u9B6A", 4, "\u9B73\u9B75\u9B77\u9B78\u9B79\u9B7F\u9B80\u9B84\u9B85\u9B86\u9B87\u9B89\u9B8A\u9B8B\u9B8D\u9B8F\u9B90\u9B94\u9B9A\u9B9D\u9B9E\u9BA6\u9BA7\u9BA9\u9BAC\u9BB0\u9BB1\u9BB2\u9BB7\u9BB8\u9BBB\u9BBC\u9BBE\u9BBF\u9BC1\u9BC7\u9BC8\u9BCE\u9BD0\u9BD7\u9BD8\u9BDD\u9BDF\u9BE5\u9BE7\u9BEA\u9BEB\u9BEF\u9BF3\u9BF7\u9BF8"], + ["8feba1", "\u9BF9\u9BFA\u9BFD\u9BFF\u9C00\u9C02\u9C0B\u9C0F\u9C11\u9C16\u9C18\u9C19\u9C1A\u9C1C\u9C1E\u9C22\u9C23\u9C26", 4, "\u9C31\u9C35\u9C36\u9C37\u9C3D\u9C41\u9C43\u9C44\u9C45\u9C49\u9C4A\u9C4E\u9C4F\u9C50\u9C53\u9C54\u9C56\u9C58\u9C5B\u9C5D\u9C5E\u9C5F\u9C63\u9C69\u9C6A\u9C5C\u9C6B\u9C68\u9C6E\u9C70\u9C72\u9C75\u9C77\u9C7B\u9CE6\u9CF2\u9CF7\u9CF9\u9D0B\u9D02\u9D11\u9D17\u9D18\u9D1C\u9D1D\u9D1E\u9D2F\u9D30\u9D32\u9D33\u9D34\u9D3A\u9D3C\u9D45\u9D3D\u9D42\u9D43\u9D47\u9D4A\u9D53\u9D54\u9D5F\u9D63\u9D62\u9D65\u9D69\u9D6A\u9D6B\u9D70\u9D76\u9D77\u9D7B"], + ["8feca1", "\u9D7C\u9D7E\u9D83\u9D84\u9D86\u9D8A\u9D8D\u9D8E\u9D92\u9D93\u9D95\u9D96\u9D97\u9D98\u9DA1\u9DAA\u9DAC\u9DAE\u9DB1\u9DB5\u9DB9\u9DBC\u9DBF\u9DC3\u9DC7\u9DC9\u9DCA\u9DD4\u9DD5\u9DD6\u9DD7\u9DDA\u9DDE\u9DDF\u9DE0\u9DE5\u9DE7\u9DE9\u9DEB\u9DEE\u9DF0\u9DF3\u9DF4\u9DFE\u9E0A\u9E02\u9E07\u9E0E\u9E10\u9E11\u9E12\u9E15\u9E16\u9E19\u9E1C\u9E1D\u9E7A\u9E7B\u9E7C\u9E80\u9E82\u9E83\u9E84\u9E85\u9E87\u9E8E\u9E8F\u9E96\u9E98\u9E9B\u9E9E\u9EA4\u9EA8\u9EAC\u9EAE\u9EAF\u9EB0\u9EB3\u9EB4\u9EB5\u9EC6\u9EC8\u9ECB\u9ED5\u9EDF\u9EE4\u9EE7\u9EEC\u9EED\u9EEE\u9EF0\u9EF1\u9EF2\u9EF5"], + ["8feda1", "\u9EF8\u9EFF\u9F02\u9F03\u9F09\u9F0F\u9F10\u9F11\u9F12\u9F14\u9F16\u9F17\u9F19\u9F1A\u9F1B\u9F1F\u9F22\u9F26\u9F2A\u9F2B\u9F2F\u9F31\u9F32\u9F34\u9F37\u9F39\u9F3A\u9F3C\u9F3D\u9F3F\u9F41\u9F43", 4, "\u9F53\u9F55\u9F56\u9F57\u9F58\u9F5A\u9F5D\u9F5E\u9F68\u9F69\u9F6D", 4, "\u9F73\u9F75\u9F7A\u9F7D\u9F8F\u9F90\u9F91\u9F92\u9F94\u9F96\u9F97\u9F9E\u9FA1\u9FA2\u9FA3\u9FA5"] + ]; + } +}); + +// node_modules/iconv-lite/encodings/tables/cp936.json +var require_cp936 = __commonJS({ + "node_modules/iconv-lite/encodings/tables/cp936.json"(exports2, module2) { + module2.exports = [ + ["0", "\0", 127, "\u20AC"], + ["8140", "\u4E02\u4E04\u4E05\u4E06\u4E0F\u4E12\u4E17\u4E1F\u4E20\u4E21\u4E23\u4E26\u4E29\u4E2E\u4E2F\u4E31\u4E33\u4E35\u4E37\u4E3C\u4E40\u4E41\u4E42\u4E44\u4E46\u4E4A\u4E51\u4E55\u4E57\u4E5A\u4E5B\u4E62\u4E63\u4E64\u4E65\u4E67\u4E68\u4E6A", 5, "\u4E72\u4E74", 9, "\u4E7F", 6, "\u4E87\u4E8A"], + ["8180", "\u4E90\u4E96\u4E97\u4E99\u4E9C\u4E9D\u4E9E\u4EA3\u4EAA\u4EAF\u4EB0\u4EB1\u4EB4\u4EB6\u4EB7\u4EB8\u4EB9\u4EBC\u4EBD\u4EBE\u4EC8\u4ECC\u4ECF\u4ED0\u4ED2\u4EDA\u4EDB\u4EDC\u4EE0\u4EE2\u4EE6\u4EE7\u4EE9\u4EED\u4EEE\u4EEF\u4EF1\u4EF4\u4EF8\u4EF9\u4EFA\u4EFC\u4EFE\u4F00\u4F02", 6, "\u4F0B\u4F0C\u4F12", 4, "\u4F1C\u4F1D\u4F21\u4F23\u4F28\u4F29\u4F2C\u4F2D\u4F2E\u4F31\u4F33\u4F35\u4F37\u4F39\u4F3B\u4F3E", 4, "\u4F44\u4F45\u4F47", 5, "\u4F52\u4F54\u4F56\u4F61\u4F62\u4F66\u4F68\u4F6A\u4F6B\u4F6D\u4F6E\u4F71\u4F72\u4F75\u4F77\u4F78\u4F79\u4F7A\u4F7D\u4F80\u4F81\u4F82\u4F85\u4F86\u4F87\u4F8A\u4F8C\u4F8E\u4F90\u4F92\u4F93\u4F95\u4F96\u4F98\u4F99\u4F9A\u4F9C\u4F9E\u4F9F\u4FA1\u4FA2"], + ["8240", "\u4FA4\u4FAB\u4FAD\u4FB0", 4, "\u4FB6", 8, "\u4FC0\u4FC1\u4FC2\u4FC6\u4FC7\u4FC8\u4FC9\u4FCB\u4FCC\u4FCD\u4FD2", 4, "\u4FD9\u4FDB\u4FE0\u4FE2\u4FE4\u4FE5\u4FE7\u4FEB\u4FEC\u4FF0\u4FF2\u4FF4\u4FF5\u4FF6\u4FF7\u4FF9\u4FFB\u4FFC\u4FFD\u4FFF", 11], + ["8280", "\u500B\u500E\u5010\u5011\u5013\u5015\u5016\u5017\u501B\u501D\u501E\u5020\u5022\u5023\u5024\u5027\u502B\u502F", 10, "\u503B\u503D\u503F\u5040\u5041\u5042\u5044\u5045\u5046\u5049\u504A\u504B\u504D\u5050", 4, "\u5056\u5057\u5058\u5059\u505B\u505D", 7, "\u5066", 5, "\u506D", 8, "\u5078\u5079\u507A\u507C\u507D\u5081\u5082\u5083\u5084\u5086\u5087\u5089\u508A\u508B\u508C\u508E", 20, "\u50A4\u50A6\u50AA\u50AB\u50AD", 4, "\u50B3", 6, "\u50BC"], + ["8340", "\u50BD", 17, "\u50D0", 5, "\u50D7\u50D8\u50D9\u50DB", 10, "\u50E8\u50E9\u50EA\u50EB\u50EF\u50F0\u50F1\u50F2\u50F4\u50F6", 4, "\u50FC", 9, "\u5108"], + ["8380", "\u5109\u510A\u510C", 5, "\u5113", 13, "\u5122", 28, "\u5142\u5147\u514A\u514C\u514E\u514F\u5150\u5152\u5153\u5157\u5158\u5159\u515B\u515D", 4, "\u5163\u5164\u5166\u5167\u5169\u516A\u516F\u5172\u517A\u517E\u517F\u5183\u5184\u5186\u5187\u518A\u518B\u518E\u518F\u5190\u5191\u5193\u5194\u5198\u519A\u519D\u519E\u519F\u51A1\u51A3\u51A6", 4, "\u51AD\u51AE\u51B4\u51B8\u51B9\u51BA\u51BE\u51BF\u51C1\u51C2\u51C3\u51C5\u51C8\u51CA\u51CD\u51CE\u51D0\u51D2", 5], + ["8440", "\u51D8\u51D9\u51DA\u51DC\u51DE\u51DF\u51E2\u51E3\u51E5", 5, "\u51EC\u51EE\u51F1\u51F2\u51F4\u51F7\u51FE\u5204\u5205\u5209\u520B\u520C\u520F\u5210\u5213\u5214\u5215\u521C\u521E\u521F\u5221\u5222\u5223\u5225\u5226\u5227\u522A\u522C\u522F\u5231\u5232\u5234\u5235\u523C\u523E\u5244", 5, "\u524B\u524E\u524F\u5252\u5253\u5255\u5257\u5258"], + ["8480", "\u5259\u525A\u525B\u525D\u525F\u5260\u5262\u5263\u5264\u5266\u5268\u526B\u526C\u526D\u526E\u5270\u5271\u5273", 9, "\u527E\u5280\u5283", 4, "\u5289", 6, "\u5291\u5292\u5294", 6, "\u529C\u52A4\u52A5\u52A6\u52A7\u52AE\u52AF\u52B0\u52B4", 9, "\u52C0\u52C1\u52C2\u52C4\u52C5\u52C6\u52C8\u52CA\u52CC\u52CD\u52CE\u52CF\u52D1\u52D3\u52D4\u52D5\u52D7\u52D9", 5, "\u52E0\u52E1\u52E2\u52E3\u52E5", 10, "\u52F1", 7, "\u52FB\u52FC\u52FD\u5301\u5302\u5303\u5304\u5307\u5309\u530A\u530B\u530C\u530E"], + ["8540", "\u5311\u5312\u5313\u5314\u5318\u531B\u531C\u531E\u531F\u5322\u5324\u5325\u5327\u5328\u5329\u532B\u532C\u532D\u532F", 9, "\u533C\u533D\u5340\u5342\u5344\u5346\u534B\u534C\u534D\u5350\u5354\u5358\u5359\u535B\u535D\u5365\u5368\u536A\u536C\u536D\u5372\u5376\u5379\u537B\u537C\u537D\u537E\u5380\u5381\u5383\u5387\u5388\u538A\u538E\u538F"], + ["8580", "\u5390", 4, "\u5396\u5397\u5399\u539B\u539C\u539E\u53A0\u53A1\u53A4\u53A7\u53AA\u53AB\u53AC\u53AD\u53AF", 6, "\u53B7\u53B8\u53B9\u53BA\u53BC\u53BD\u53BE\u53C0\u53C3", 4, "\u53CE\u53CF\u53D0\u53D2\u53D3\u53D5\u53DA\u53DC\u53DD\u53DE\u53E1\u53E2\u53E7\u53F4\u53FA\u53FE\u53FF\u5400\u5402\u5405\u5407\u540B\u5414\u5418\u5419\u541A\u541C\u5422\u5424\u5425\u542A\u5430\u5433\u5436\u5437\u543A\u543D\u543F\u5441\u5442\u5444\u5445\u5447\u5449\u544C\u544D\u544E\u544F\u5451\u545A\u545D", 4, "\u5463\u5465\u5467\u5469", 7, "\u5474\u5479\u547A\u547E\u547F\u5481\u5483\u5485\u5487\u5488\u5489\u548A\u548D\u5491\u5493\u5497\u5498\u549C\u549E\u549F\u54A0\u54A1"], + ["8640", "\u54A2\u54A5\u54AE\u54B0\u54B2\u54B5\u54B6\u54B7\u54B9\u54BA\u54BC\u54BE\u54C3\u54C5\u54CA\u54CB\u54D6\u54D8\u54DB\u54E0", 4, "\u54EB\u54EC\u54EF\u54F0\u54F1\u54F4", 5, "\u54FB\u54FE\u5500\u5502\u5503\u5504\u5505\u5508\u550A", 4, "\u5512\u5513\u5515", 5, "\u551C\u551D\u551E\u551F\u5521\u5525\u5526"], + ["8680", "\u5528\u5529\u552B\u552D\u5532\u5534\u5535\u5536\u5538\u5539\u553A\u553B\u553D\u5540\u5542\u5545\u5547\u5548\u554B", 4, "\u5551\u5552\u5553\u5554\u5557", 4, "\u555D\u555E\u555F\u5560\u5562\u5563\u5568\u5569\u556B\u556F", 5, "\u5579\u557A\u557D\u557F\u5585\u5586\u558C\u558D\u558E\u5590\u5592\u5593\u5595\u5596\u5597\u559A\u559B\u559E\u55A0", 6, "\u55A8", 8, "\u55B2\u55B4\u55B6\u55B8\u55BA\u55BC\u55BF", 4, "\u55C6\u55C7\u55C8\u55CA\u55CB\u55CE\u55CF\u55D0\u55D5\u55D7", 4, "\u55DE\u55E0\u55E2\u55E7\u55E9\u55ED\u55EE\u55F0\u55F1\u55F4\u55F6\u55F8", 4, "\u55FF\u5602\u5603\u5604\u5605"], + ["8740", "\u5606\u5607\u560A\u560B\u560D\u5610", 7, "\u5619\u561A\u561C\u561D\u5620\u5621\u5622\u5625\u5626\u5628\u5629\u562A\u562B\u562E\u562F\u5630\u5633\u5635\u5637\u5638\u563A\u563C\u563D\u563E\u5640", 11, "\u564F", 4, "\u5655\u5656\u565A\u565B\u565D", 4], + ["8780", "\u5663\u5665\u5666\u5667\u566D\u566E\u566F\u5670\u5672\u5673\u5674\u5675\u5677\u5678\u5679\u567A\u567D", 7, "\u5687", 6, "\u5690\u5691\u5692\u5694", 14, "\u56A4", 10, "\u56B0", 6, "\u56B8\u56B9\u56BA\u56BB\u56BD", 12, "\u56CB", 8, "\u56D5\u56D6\u56D8\u56D9\u56DC\u56E3\u56E5", 5, "\u56EC\u56EE\u56EF\u56F2\u56F3\u56F6\u56F7\u56F8\u56FB\u56FC\u5700\u5701\u5702\u5705\u5707\u570B", 6], + ["8840", "\u5712", 9, "\u571D\u571E\u5720\u5721\u5722\u5724\u5725\u5726\u5727\u572B\u5731\u5732\u5734", 4, "\u573C\u573D\u573F\u5741\u5743\u5744\u5745\u5746\u5748\u5749\u574B\u5752", 4, "\u5758\u5759\u5762\u5763\u5765\u5767\u576C\u576E\u5770\u5771\u5772\u5774\u5775\u5778\u5779\u577A\u577D\u577E\u577F\u5780"], + ["8880", "\u5781\u5787\u5788\u5789\u578A\u578D", 4, "\u5794", 6, "\u579C\u579D\u579E\u579F\u57A5\u57A8\u57AA\u57AC\u57AF\u57B0\u57B1\u57B3\u57B5\u57B6\u57B7\u57B9", 8, "\u57C4", 6, "\u57CC\u57CD\u57D0\u57D1\u57D3\u57D6\u57D7\u57DB\u57DC\u57DE\u57E1\u57E2\u57E3\u57E5", 7, "\u57EE\u57F0\u57F1\u57F2\u57F3\u57F5\u57F6\u57F7\u57FB\u57FC\u57FE\u57FF\u5801\u5803\u5804\u5805\u5808\u5809\u580A\u580C\u580E\u580F\u5810\u5812\u5813\u5814\u5816\u5817\u5818\u581A\u581B\u581C\u581D\u581F\u5822\u5823\u5825", 4, "\u582B", 4, "\u5831\u5832\u5833\u5834\u5836", 7], + ["8940", "\u583E", 5, "\u5845", 6, "\u584E\u584F\u5850\u5852\u5853\u5855\u5856\u5857\u5859", 4, "\u585F", 5, "\u5866", 4, "\u586D", 16, "\u587F\u5882\u5884\u5886\u5887\u5888\u588A\u588B\u588C"], + ["8980", "\u588D", 4, "\u5894", 4, "\u589B\u589C\u589D\u58A0", 7, "\u58AA", 17, "\u58BD\u58BE\u58BF\u58C0\u58C2\u58C3\u58C4\u58C6", 10, "\u58D2\u58D3\u58D4\u58D6", 13, "\u58E5", 5, "\u58ED\u58EF\u58F1\u58F2\u58F4\u58F5\u58F7\u58F8\u58FA", 7, "\u5903\u5905\u5906\u5908", 4, "\u590E\u5910\u5911\u5912\u5913\u5917\u5918\u591B\u591D\u591E\u5920\u5921\u5922\u5923\u5926\u5928\u592C\u5930\u5932\u5933\u5935\u5936\u593B"], + ["8a40", "\u593D\u593E\u593F\u5940\u5943\u5945\u5946\u594A\u594C\u594D\u5950\u5952\u5953\u5959\u595B", 4, "\u5961\u5963\u5964\u5966", 12, "\u5975\u5977\u597A\u597B\u597C\u597E\u597F\u5980\u5985\u5989\u598B\u598C\u598E\u598F\u5990\u5991\u5994\u5995\u5998\u599A\u599B\u599C\u599D\u599F\u59A0\u59A1\u59A2\u59A6"], + ["8a80", "\u59A7\u59AC\u59AD\u59B0\u59B1\u59B3", 5, "\u59BA\u59BC\u59BD\u59BF", 6, "\u59C7\u59C8\u59C9\u59CC\u59CD\u59CE\u59CF\u59D5\u59D6\u59D9\u59DB\u59DE", 4, "\u59E4\u59E6\u59E7\u59E9\u59EA\u59EB\u59ED", 11, "\u59FA\u59FC\u59FD\u59FE\u5A00\u5A02\u5A0A\u5A0B\u5A0D\u5A0E\u5A0F\u5A10\u5A12\u5A14\u5A15\u5A16\u5A17\u5A19\u5A1A\u5A1B\u5A1D\u5A1E\u5A21\u5A22\u5A24\u5A26\u5A27\u5A28\u5A2A", 6, "\u5A33\u5A35\u5A37", 4, "\u5A3D\u5A3E\u5A3F\u5A41", 4, "\u5A47\u5A48\u5A4B", 9, "\u5A56\u5A57\u5A58\u5A59\u5A5B", 5], + ["8b40", "\u5A61\u5A63\u5A64\u5A65\u5A66\u5A68\u5A69\u5A6B", 8, "\u5A78\u5A79\u5A7B\u5A7C\u5A7D\u5A7E\u5A80", 17, "\u5A93", 6, "\u5A9C", 13, "\u5AAB\u5AAC"], + ["8b80", "\u5AAD", 4, "\u5AB4\u5AB6\u5AB7\u5AB9", 4, "\u5ABF\u5AC0\u5AC3", 5, "\u5ACA\u5ACB\u5ACD", 4, "\u5AD3\u5AD5\u5AD7\u5AD9\u5ADA\u5ADB\u5ADD\u5ADE\u5ADF\u5AE2\u5AE4\u5AE5\u5AE7\u5AE8\u5AEA\u5AEC", 4, "\u5AF2", 22, "\u5B0A", 11, "\u5B18", 25, "\u5B33\u5B35\u5B36\u5B38", 7, "\u5B41", 6], + ["8c40", "\u5B48", 7, "\u5B52\u5B56\u5B5E\u5B60\u5B61\u5B67\u5B68\u5B6B\u5B6D\u5B6E\u5B6F\u5B72\u5B74\u5B76\u5B77\u5B78\u5B79\u5B7B\u5B7C\u5B7E\u5B7F\u5B82\u5B86\u5B8A\u5B8D\u5B8E\u5B90\u5B91\u5B92\u5B94\u5B96\u5B9F\u5BA7\u5BA8\u5BA9\u5BAC\u5BAD\u5BAE\u5BAF\u5BB1\u5BB2\u5BB7\u5BBA\u5BBB\u5BBC\u5BC0\u5BC1\u5BC3\u5BC8\u5BC9\u5BCA\u5BCB\u5BCD\u5BCE\u5BCF"], + ["8c80", "\u5BD1\u5BD4", 8, "\u5BE0\u5BE2\u5BE3\u5BE6\u5BE7\u5BE9", 4, "\u5BEF\u5BF1", 6, "\u5BFD\u5BFE\u5C00\u5C02\u5C03\u5C05\u5C07\u5C08\u5C0B\u5C0C\u5C0D\u5C0E\u5C10\u5C12\u5C13\u5C17\u5C19\u5C1B\u5C1E\u5C1F\u5C20\u5C21\u5C23\u5C26\u5C28\u5C29\u5C2A\u5C2B\u5C2D\u5C2E\u5C2F\u5C30\u5C32\u5C33\u5C35\u5C36\u5C37\u5C43\u5C44\u5C46\u5C47\u5C4C\u5C4D\u5C52\u5C53\u5C54\u5C56\u5C57\u5C58\u5C5A\u5C5B\u5C5C\u5C5D\u5C5F\u5C62\u5C64\u5C67", 6, "\u5C70\u5C72", 6, "\u5C7B\u5C7C\u5C7D\u5C7E\u5C80\u5C83", 4, "\u5C89\u5C8A\u5C8B\u5C8E\u5C8F\u5C92\u5C93\u5C95\u5C9D", 4, "\u5CA4", 4], + ["8d40", "\u5CAA\u5CAE\u5CAF\u5CB0\u5CB2\u5CB4\u5CB6\u5CB9\u5CBA\u5CBB\u5CBC\u5CBE\u5CC0\u5CC2\u5CC3\u5CC5", 5, "\u5CCC", 5, "\u5CD3", 5, "\u5CDA", 6, "\u5CE2\u5CE3\u5CE7\u5CE9\u5CEB\u5CEC\u5CEE\u5CEF\u5CF1", 9, "\u5CFC", 4], + ["8d80", "\u5D01\u5D04\u5D05\u5D08", 5, "\u5D0F", 4, "\u5D15\u5D17\u5D18\u5D19\u5D1A\u5D1C\u5D1D\u5D1F", 4, "\u5D25\u5D28\u5D2A\u5D2B\u5D2C\u5D2F", 4, "\u5D35", 7, "\u5D3F", 7, "\u5D48\u5D49\u5D4D", 10, "\u5D59\u5D5A\u5D5C\u5D5E", 10, "\u5D6A\u5D6D\u5D6E\u5D70\u5D71\u5D72\u5D73\u5D75", 12, "\u5D83", 21, "\u5D9A\u5D9B\u5D9C\u5D9E\u5D9F\u5DA0"], + ["8e40", "\u5DA1", 21, "\u5DB8", 12, "\u5DC6", 6, "\u5DCE", 12, "\u5DDC\u5DDF\u5DE0\u5DE3\u5DE4\u5DEA\u5DEC\u5DED"], + ["8e80", "\u5DF0\u5DF5\u5DF6\u5DF8", 4, "\u5DFF\u5E00\u5E04\u5E07\u5E09\u5E0A\u5E0B\u5E0D\u5E0E\u5E12\u5E13\u5E17\u5E1E", 7, "\u5E28", 4, "\u5E2F\u5E30\u5E32", 4, "\u5E39\u5E3A\u5E3E\u5E3F\u5E40\u5E41\u5E43\u5E46", 5, "\u5E4D", 6, "\u5E56", 4, "\u5E5C\u5E5D\u5E5F\u5E60\u5E63", 14, "\u5E75\u5E77\u5E79\u5E7E\u5E81\u5E82\u5E83\u5E85\u5E88\u5E89\u5E8C\u5E8D\u5E8E\u5E92\u5E98\u5E9B\u5E9D\u5EA1\u5EA2\u5EA3\u5EA4\u5EA8", 4, "\u5EAE", 4, "\u5EB4\u5EBA\u5EBB\u5EBC\u5EBD\u5EBF", 6], + ["8f40", "\u5EC6\u5EC7\u5EC8\u5ECB", 5, "\u5ED4\u5ED5\u5ED7\u5ED8\u5ED9\u5EDA\u5EDC", 11, "\u5EE9\u5EEB", 8, "\u5EF5\u5EF8\u5EF9\u5EFB\u5EFC\u5EFD\u5F05\u5F06\u5F07\u5F09\u5F0C\u5F0D\u5F0E\u5F10\u5F12\u5F14\u5F16\u5F19\u5F1A\u5F1C\u5F1D\u5F1E\u5F21\u5F22\u5F23\u5F24"], + ["8f80", "\u5F28\u5F2B\u5F2C\u5F2E\u5F30\u5F32", 6, "\u5F3B\u5F3D\u5F3E\u5F3F\u5F41", 14, "\u5F51\u5F54\u5F59\u5F5A\u5F5B\u5F5C\u5F5E\u5F5F\u5F60\u5F63\u5F65\u5F67\u5F68\u5F6B\u5F6E\u5F6F\u5F72\u5F74\u5F75\u5F76\u5F78\u5F7A\u5F7D\u5F7E\u5F7F\u5F83\u5F86\u5F8D\u5F8E\u5F8F\u5F91\u5F93\u5F94\u5F96\u5F9A\u5F9B\u5F9D\u5F9E\u5F9F\u5FA0\u5FA2", 5, "\u5FA9\u5FAB\u5FAC\u5FAF", 5, "\u5FB6\u5FB8\u5FB9\u5FBA\u5FBB\u5FBE", 4, "\u5FC7\u5FC8\u5FCA\u5FCB\u5FCE\u5FD3\u5FD4\u5FD5\u5FDA\u5FDB\u5FDC\u5FDE\u5FDF\u5FE2\u5FE3\u5FE5\u5FE6\u5FE8\u5FE9\u5FEC\u5FEF\u5FF0\u5FF2\u5FF3\u5FF4\u5FF6\u5FF7\u5FF9\u5FFA\u5FFC\u6007"], + ["9040", "\u6008\u6009\u600B\u600C\u6010\u6011\u6013\u6017\u6018\u601A\u601E\u601F\u6022\u6023\u6024\u602C\u602D\u602E\u6030", 4, "\u6036", 4, "\u603D\u603E\u6040\u6044", 6, "\u604C\u604E\u604F\u6051\u6053\u6054\u6056\u6057\u6058\u605B\u605C\u605E\u605F\u6060\u6061\u6065\u6066\u606E\u6071\u6072\u6074\u6075\u6077\u607E\u6080"], + ["9080", "\u6081\u6082\u6085\u6086\u6087\u6088\u608A\u608B\u608E\u608F\u6090\u6091\u6093\u6095\u6097\u6098\u6099\u609C\u609E\u60A1\u60A2\u60A4\u60A5\u60A7\u60A9\u60AA\u60AE\u60B0\u60B3\u60B5\u60B6\u60B7\u60B9\u60BA\u60BD", 7, "\u60C7\u60C8\u60C9\u60CC", 4, "\u60D2\u60D3\u60D4\u60D6\u60D7\u60D9\u60DB\u60DE\u60E1", 4, "\u60EA\u60F1\u60F2\u60F5\u60F7\u60F8\u60FB", 4, "\u6102\u6103\u6104\u6105\u6107\u610A\u610B\u610C\u6110", 4, "\u6116\u6117\u6118\u6119\u611B\u611C\u611D\u611E\u6121\u6122\u6125\u6128\u6129\u612A\u612C", 18, "\u6140", 6], + ["9140", "\u6147\u6149\u614B\u614D\u614F\u6150\u6152\u6153\u6154\u6156", 6, "\u615E\u615F\u6160\u6161\u6163\u6164\u6165\u6166\u6169", 6, "\u6171\u6172\u6173\u6174\u6176\u6178", 18, "\u618C\u618D\u618F", 4, "\u6195"], + ["9180", "\u6196", 6, "\u619E", 8, "\u61AA\u61AB\u61AD", 9, "\u61B8", 5, "\u61BF\u61C0\u61C1\u61C3", 4, "\u61C9\u61CC", 4, "\u61D3\u61D5", 16, "\u61E7", 13, "\u61F6", 8, "\u6200", 5, "\u6207\u6209\u6213\u6214\u6219\u621C\u621D\u621E\u6220\u6223\u6226\u6227\u6228\u6229\u622B\u622D\u622F\u6230\u6231\u6232\u6235\u6236\u6238", 4, "\u6242\u6244\u6245\u6246\u624A"], + ["9240", "\u624F\u6250\u6255\u6256\u6257\u6259\u625A\u625C", 6, "\u6264\u6265\u6268\u6271\u6272\u6274\u6275\u6277\u6278\u627A\u627B\u627D\u6281\u6282\u6283\u6285\u6286\u6287\u6288\u628B", 5, "\u6294\u6299\u629C\u629D\u629E\u62A3\u62A6\u62A7\u62A9\u62AA\u62AD\u62AE\u62AF\u62B0\u62B2\u62B3\u62B4\u62B6\u62B7\u62B8\u62BA\u62BE\u62C0\u62C1"], + ["9280", "\u62C3\u62CB\u62CF\u62D1\u62D5\u62DD\u62DE\u62E0\u62E1\u62E4\u62EA\u62EB\u62F0\u62F2\u62F5\u62F8\u62F9\u62FA\u62FB\u6300\u6303\u6304\u6305\u6306\u630A\u630B\u630C\u630D\u630F\u6310\u6312\u6313\u6314\u6315\u6317\u6318\u6319\u631C\u6326\u6327\u6329\u632C\u632D\u632E\u6330\u6331\u6333", 5, "\u633B\u633C\u633E\u633F\u6340\u6341\u6344\u6347\u6348\u634A\u6351\u6352\u6353\u6354\u6356", 7, "\u6360\u6364\u6365\u6366\u6368\u636A\u636B\u636C\u636F\u6370\u6372\u6373\u6374\u6375\u6378\u6379\u637C\u637D\u637E\u637F\u6381\u6383\u6384\u6385\u6386\u638B\u638D\u6391\u6393\u6394\u6395\u6397\u6399", 6, "\u63A1\u63A4\u63A6\u63AB\u63AF\u63B1\u63B2\u63B5\u63B6\u63B9\u63BB\u63BD\u63BF\u63C0"], + ["9340", "\u63C1\u63C2\u63C3\u63C5\u63C7\u63C8\u63CA\u63CB\u63CC\u63D1\u63D3\u63D4\u63D5\u63D7", 6, "\u63DF\u63E2\u63E4", 4, "\u63EB\u63EC\u63EE\u63EF\u63F0\u63F1\u63F3\u63F5\u63F7\u63F9\u63FA\u63FB\u63FC\u63FE\u6403\u6404\u6406", 4, "\u640D\u640E\u6411\u6412\u6415", 5, "\u641D\u641F\u6422\u6423\u6424"], + ["9380", "\u6425\u6427\u6428\u6429\u642B\u642E", 5, "\u6435", 4, "\u643B\u643C\u643E\u6440\u6442\u6443\u6449\u644B", 6, "\u6453\u6455\u6456\u6457\u6459", 4, "\u645F", 7, "\u6468\u646A\u646B\u646C\u646E", 9, "\u647B", 6, "\u6483\u6486\u6488", 8, "\u6493\u6494\u6497\u6498\u649A\u649B\u649C\u649D\u649F", 4, "\u64A5\u64A6\u64A7\u64A8\u64AA\u64AB\u64AF\u64B1\u64B2\u64B3\u64B4\u64B6\u64B9\u64BB\u64BD\u64BE\u64BF\u64C1\u64C3\u64C4\u64C6", 6, "\u64CF\u64D1\u64D3\u64D4\u64D5\u64D6\u64D9\u64DA"], + ["9440", "\u64DB\u64DC\u64DD\u64DF\u64E0\u64E1\u64E3\u64E5\u64E7", 24, "\u6501", 7, "\u650A", 7, "\u6513", 4, "\u6519", 8], + ["9480", "\u6522\u6523\u6524\u6526", 4, "\u652C\u652D\u6530\u6531\u6532\u6533\u6537\u653A\u653C\u653D\u6540", 4, "\u6546\u6547\u654A\u654B\u654D\u654E\u6550\u6552\u6553\u6554\u6557\u6558\u655A\u655C\u655F\u6560\u6561\u6564\u6565\u6567\u6568\u6569\u656A\u656D\u656E\u656F\u6571\u6573\u6575\u6576\u6578", 14, "\u6588\u6589\u658A\u658D\u658E\u658F\u6592\u6594\u6595\u6596\u6598\u659A\u659D\u659E\u65A0\u65A2\u65A3\u65A6\u65A8\u65AA\u65AC\u65AE\u65B1", 7, "\u65BA\u65BB\u65BE\u65BF\u65C0\u65C2\u65C7\u65C8\u65C9\u65CA\u65CD\u65D0\u65D1\u65D3\u65D4\u65D5\u65D8", 7, "\u65E1\u65E3\u65E4\u65EA\u65EB"], + ["9540", "\u65F2\u65F3\u65F4\u65F5\u65F8\u65F9\u65FB", 4, "\u6601\u6604\u6605\u6607\u6608\u6609\u660B\u660D\u6610\u6611\u6612\u6616\u6617\u6618\u661A\u661B\u661C\u661E\u6621\u6622\u6623\u6624\u6626\u6629\u662A\u662B\u662C\u662E\u6630\u6632\u6633\u6637", 4, "\u663D\u663F\u6640\u6642\u6644", 6, "\u664D\u664E\u6650\u6651\u6658"], + ["9580", "\u6659\u665B\u665C\u665D\u665E\u6660\u6662\u6663\u6665\u6667\u6669", 4, "\u6671\u6672\u6673\u6675\u6678\u6679\u667B\u667C\u667D\u667F\u6680\u6681\u6683\u6685\u6686\u6688\u6689\u668A\u668B\u668D\u668E\u668F\u6690\u6692\u6693\u6694\u6695\u6698", 4, "\u669E", 8, "\u66A9", 4, "\u66AF", 4, "\u66B5\u66B6\u66B7\u66B8\u66BA\u66BB\u66BC\u66BD\u66BF", 25, "\u66DA\u66DE", 7, "\u66E7\u66E8\u66EA", 5, "\u66F1\u66F5\u66F6\u66F8\u66FA\u66FB\u66FD\u6701\u6702\u6703"], + ["9640", "\u6704\u6705\u6706\u6707\u670C\u670E\u670F\u6711\u6712\u6713\u6716\u6718\u6719\u671A\u671C\u671E\u6720", 5, "\u6727\u6729\u672E\u6730\u6732\u6733\u6736\u6737\u6738\u6739\u673B\u673C\u673E\u673F\u6741\u6744\u6745\u6747\u674A\u674B\u674D\u6752\u6754\u6755\u6757", 4, "\u675D\u6762\u6763\u6764\u6766\u6767\u676B\u676C\u676E\u6771\u6774\u6776"], + ["9680", "\u6778\u6779\u677A\u677B\u677D\u6780\u6782\u6783\u6785\u6786\u6788\u678A\u678C\u678D\u678E\u678F\u6791\u6792\u6793\u6794\u6796\u6799\u679B\u679F\u67A0\u67A1\u67A4\u67A6\u67A9\u67AC\u67AE\u67B1\u67B2\u67B4\u67B9", 7, "\u67C2\u67C5", 9, "\u67D5\u67D6\u67D7\u67DB\u67DF\u67E1\u67E3\u67E4\u67E6\u67E7\u67E8\u67EA\u67EB\u67ED\u67EE\u67F2\u67F5", 7, "\u67FE\u6801\u6802\u6803\u6804\u6806\u680D\u6810\u6812\u6814\u6815\u6818", 4, "\u681E\u681F\u6820\u6822", 6, "\u682B", 6, "\u6834\u6835\u6836\u683A\u683B\u683F\u6847\u684B\u684D\u684F\u6852\u6856", 5], + ["9740", "\u685C\u685D\u685E\u685F\u686A\u686C", 7, "\u6875\u6878", 8, "\u6882\u6884\u6887", 7, "\u6890\u6891\u6892\u6894\u6895\u6896\u6898", 9, "\u68A3\u68A4\u68A5\u68A9\u68AA\u68AB\u68AC\u68AE\u68B1\u68B2\u68B4\u68B6\u68B7\u68B8"], + ["9780", "\u68B9", 6, "\u68C1\u68C3", 5, "\u68CA\u68CC\u68CE\u68CF\u68D0\u68D1\u68D3\u68D4\u68D6\u68D7\u68D9\u68DB", 4, "\u68E1\u68E2\u68E4", 9, "\u68EF\u68F2\u68F3\u68F4\u68F6\u68F7\u68F8\u68FB\u68FD\u68FE\u68FF\u6900\u6902\u6903\u6904\u6906", 4, "\u690C\u690F\u6911\u6913", 11, "\u6921\u6922\u6923\u6925", 7, "\u692E\u692F\u6931\u6932\u6933\u6935\u6936\u6937\u6938\u693A\u693B\u693C\u693E\u6940\u6941\u6943", 16, "\u6955\u6956\u6958\u6959\u695B\u695C\u695F"], + ["9840", "\u6961\u6962\u6964\u6965\u6967\u6968\u6969\u696A\u696C\u696D\u696F\u6970\u6972", 4, "\u697A\u697B\u697D\u697E\u697F\u6981\u6983\u6985\u698A\u698B\u698C\u698E", 5, "\u6996\u6997\u6999\u699A\u699D", 9, "\u69A9\u69AA\u69AC\u69AE\u69AF\u69B0\u69B2\u69B3\u69B5\u69B6\u69B8\u69B9\u69BA\u69BC\u69BD"], + ["9880", "\u69BE\u69BF\u69C0\u69C2", 7, "\u69CB\u69CD\u69CF\u69D1\u69D2\u69D3\u69D5", 5, "\u69DC\u69DD\u69DE\u69E1", 11, "\u69EE\u69EF\u69F0\u69F1\u69F3", 9, "\u69FE\u6A00", 9, "\u6A0B", 11, "\u6A19", 5, "\u6A20\u6A22", 5, "\u6A29\u6A2B\u6A2C\u6A2D\u6A2E\u6A30\u6A32\u6A33\u6A34\u6A36", 6, "\u6A3F", 4, "\u6A45\u6A46\u6A48", 7, "\u6A51", 6, "\u6A5A"], + ["9940", "\u6A5C", 4, "\u6A62\u6A63\u6A64\u6A66", 10, "\u6A72", 6, "\u6A7A\u6A7B\u6A7D\u6A7E\u6A7F\u6A81\u6A82\u6A83\u6A85", 8, "\u6A8F\u6A92", 4, "\u6A98", 7, "\u6AA1", 5], + ["9980", "\u6AA7\u6AA8\u6AAA\u6AAD", 114, "\u6B25\u6B26\u6B28", 6], + ["9a40", "\u6B2F\u6B30\u6B31\u6B33\u6B34\u6B35\u6B36\u6B38\u6B3B\u6B3C\u6B3D\u6B3F\u6B40\u6B41\u6B42\u6B44\u6B45\u6B48\u6B4A\u6B4B\u6B4D", 11, "\u6B5A", 7, "\u6B68\u6B69\u6B6B", 13, "\u6B7A\u6B7D\u6B7E\u6B7F\u6B80\u6B85\u6B88"], + ["9a80", "\u6B8C\u6B8E\u6B8F\u6B90\u6B91\u6B94\u6B95\u6B97\u6B98\u6B99\u6B9C", 4, "\u6BA2", 7, "\u6BAB", 7, "\u6BB6\u6BB8", 6, "\u6BC0\u6BC3\u6BC4\u6BC6", 4, "\u6BCC\u6BCE\u6BD0\u6BD1\u6BD8\u6BDA\u6BDC", 4, "\u6BE2", 7, "\u6BEC\u6BED\u6BEE\u6BF0\u6BF1\u6BF2\u6BF4\u6BF6\u6BF7\u6BF8\u6BFA\u6BFB\u6BFC\u6BFE", 6, "\u6C08", 4, "\u6C0E\u6C12\u6C17\u6C1C\u6C1D\u6C1E\u6C20\u6C23\u6C25\u6C2B\u6C2C\u6C2D\u6C31\u6C33\u6C36\u6C37\u6C39\u6C3A\u6C3B\u6C3C\u6C3E\u6C3F\u6C43\u6C44\u6C45\u6C48\u6C4B", 4, "\u6C51\u6C52\u6C53\u6C56\u6C58"], + ["9b40", "\u6C59\u6C5A\u6C62\u6C63\u6C65\u6C66\u6C67\u6C6B", 4, "\u6C71\u6C73\u6C75\u6C77\u6C78\u6C7A\u6C7B\u6C7C\u6C7F\u6C80\u6C84\u6C87\u6C8A\u6C8B\u6C8D\u6C8E\u6C91\u6C92\u6C95\u6C96\u6C97\u6C98\u6C9A\u6C9C\u6C9D\u6C9E\u6CA0\u6CA2\u6CA8\u6CAC\u6CAF\u6CB0\u6CB4\u6CB5\u6CB6\u6CB7\u6CBA\u6CC0\u6CC1\u6CC2\u6CC3\u6CC6\u6CC7\u6CC8\u6CCB\u6CCD\u6CCE\u6CCF\u6CD1\u6CD2\u6CD8"], + ["9b80", "\u6CD9\u6CDA\u6CDC\u6CDD\u6CDF\u6CE4\u6CE6\u6CE7\u6CE9\u6CEC\u6CED\u6CF2\u6CF4\u6CF9\u6CFF\u6D00\u6D02\u6D03\u6D05\u6D06\u6D08\u6D09\u6D0A\u6D0D\u6D0F\u6D10\u6D11\u6D13\u6D14\u6D15\u6D16\u6D18\u6D1C\u6D1D\u6D1F", 5, "\u6D26\u6D28\u6D29\u6D2C\u6D2D\u6D2F\u6D30\u6D34\u6D36\u6D37\u6D38\u6D3A\u6D3F\u6D40\u6D42\u6D44\u6D49\u6D4C\u6D50\u6D55\u6D56\u6D57\u6D58\u6D5B\u6D5D\u6D5F\u6D61\u6D62\u6D64\u6D65\u6D67\u6D68\u6D6B\u6D6C\u6D6D\u6D70\u6D71\u6D72\u6D73\u6D75\u6D76\u6D79\u6D7A\u6D7B\u6D7D", 4, "\u6D83\u6D84\u6D86\u6D87\u6D8A\u6D8B\u6D8D\u6D8F\u6D90\u6D92\u6D96", 4, "\u6D9C\u6DA2\u6DA5\u6DAC\u6DAD\u6DB0\u6DB1\u6DB3\u6DB4\u6DB6\u6DB7\u6DB9", 5, "\u6DC1\u6DC2\u6DC3\u6DC8\u6DC9\u6DCA"], + ["9c40", "\u6DCD\u6DCE\u6DCF\u6DD0\u6DD2\u6DD3\u6DD4\u6DD5\u6DD7\u6DDA\u6DDB\u6DDC\u6DDF\u6DE2\u6DE3\u6DE5\u6DE7\u6DE8\u6DE9\u6DEA\u6DED\u6DEF\u6DF0\u6DF2\u6DF4\u6DF5\u6DF6\u6DF8\u6DFA\u6DFD", 7, "\u6E06\u6E07\u6E08\u6E09\u6E0B\u6E0F\u6E12\u6E13\u6E15\u6E18\u6E19\u6E1B\u6E1C\u6E1E\u6E1F\u6E22\u6E26\u6E27\u6E28\u6E2A\u6E2C\u6E2E\u6E30\u6E31\u6E33\u6E35"], + ["9c80", "\u6E36\u6E37\u6E39\u6E3B", 7, "\u6E45", 7, "\u6E4F\u6E50\u6E51\u6E52\u6E55\u6E57\u6E59\u6E5A\u6E5C\u6E5D\u6E5E\u6E60", 10, "\u6E6C\u6E6D\u6E6F", 14, "\u6E80\u6E81\u6E82\u6E84\u6E87\u6E88\u6E8A", 4, "\u6E91", 6, "\u6E99\u6E9A\u6E9B\u6E9D\u6E9E\u6EA0\u6EA1\u6EA3\u6EA4\u6EA6\u6EA8\u6EA9\u6EAB\u6EAC\u6EAD\u6EAE\u6EB0\u6EB3\u6EB5\u6EB8\u6EB9\u6EBC\u6EBE\u6EBF\u6EC0\u6EC3\u6EC4\u6EC5\u6EC6\u6EC8\u6EC9\u6ECA\u6ECC\u6ECD\u6ECE\u6ED0\u6ED2\u6ED6\u6ED8\u6ED9\u6EDB\u6EDC\u6EDD\u6EE3\u6EE7\u6EEA", 5], + ["9d40", "\u6EF0\u6EF1\u6EF2\u6EF3\u6EF5\u6EF6\u6EF7\u6EF8\u6EFA", 7, "\u6F03\u6F04\u6F05\u6F07\u6F08\u6F0A", 4, "\u6F10\u6F11\u6F12\u6F16", 9, "\u6F21\u6F22\u6F23\u6F25\u6F26\u6F27\u6F28\u6F2C\u6F2E\u6F30\u6F32\u6F34\u6F35\u6F37", 6, "\u6F3F\u6F40\u6F41\u6F42"], + ["9d80", "\u6F43\u6F44\u6F45\u6F48\u6F49\u6F4A\u6F4C\u6F4E", 9, "\u6F59\u6F5A\u6F5B\u6F5D\u6F5F\u6F60\u6F61\u6F63\u6F64\u6F65\u6F67", 5, "\u6F6F\u6F70\u6F71\u6F73\u6F75\u6F76\u6F77\u6F79\u6F7B\u6F7D", 6, "\u6F85\u6F86\u6F87\u6F8A\u6F8B\u6F8F", 12, "\u6F9D\u6F9E\u6F9F\u6FA0\u6FA2", 4, "\u6FA8", 10, "\u6FB4\u6FB5\u6FB7\u6FB8\u6FBA", 5, "\u6FC1\u6FC3", 5, "\u6FCA", 6, "\u6FD3", 10, "\u6FDF\u6FE2\u6FE3\u6FE4\u6FE5"], + ["9e40", "\u6FE6", 7, "\u6FF0", 32, "\u7012", 7, "\u701C", 6, "\u7024", 6], + ["9e80", "\u702B", 9, "\u7036\u7037\u7038\u703A", 17, "\u704D\u704E\u7050", 13, "\u705F", 11, "\u706E\u7071\u7072\u7073\u7074\u7077\u7079\u707A\u707B\u707D\u7081\u7082\u7083\u7084\u7086\u7087\u7088\u708B\u708C\u708D\u708F\u7090\u7091\u7093\u7097\u7098\u709A\u709B\u709E", 12, "\u70B0\u70B2\u70B4\u70B5\u70B6\u70BA\u70BE\u70BF\u70C4\u70C5\u70C6\u70C7\u70C9\u70CB", 12, "\u70DA"], + ["9f40", "\u70DC\u70DD\u70DE\u70E0\u70E1\u70E2\u70E3\u70E5\u70EA\u70EE\u70F0", 6, "\u70F8\u70FA\u70FB\u70FC\u70FE", 10, "\u710B", 4, "\u7111\u7112\u7114\u7117\u711B", 10, "\u7127", 7, "\u7132\u7133\u7134"], + ["9f80", "\u7135\u7137", 13, "\u7146\u7147\u7148\u7149\u714B\u714D\u714F", 12, "\u715D\u715F", 4, "\u7165\u7169", 4, "\u716F\u7170\u7171\u7174\u7175\u7176\u7177\u7179\u717B\u717C\u717E", 5, "\u7185", 4, "\u718B\u718C\u718D\u718E\u7190\u7191\u7192\u7193\u7195\u7196\u7197\u719A", 4, "\u71A1", 6, "\u71A9\u71AA\u71AB\u71AD", 5, "\u71B4\u71B6\u71B7\u71B8\u71BA", 8, "\u71C4", 9, "\u71CF", 4], + ["a040", "\u71D6", 9, "\u71E1\u71E2\u71E3\u71E4\u71E6\u71E8", 5, "\u71EF", 9, "\u71FA", 11, "\u7207", 19], + ["a080", "\u721B\u721C\u721E", 9, "\u7229\u722B\u722D\u722E\u722F\u7232\u7233\u7234\u723A\u723C\u723E\u7240", 6, "\u7249\u724A\u724B\u724E\u724F\u7250\u7251\u7253\u7254\u7255\u7257\u7258\u725A\u725C\u725E\u7260\u7263\u7264\u7265\u7268\u726A\u726B\u726C\u726D\u7270\u7271\u7273\u7274\u7276\u7277\u7278\u727B\u727C\u727D\u7282\u7283\u7285", 4, "\u728C\u728E\u7290\u7291\u7293", 11, "\u72A0", 11, "\u72AE\u72B1\u72B2\u72B3\u72B5\u72BA", 6, "\u72C5\u72C6\u72C7\u72C9\u72CA\u72CB\u72CC\u72CF\u72D1\u72D3\u72D4\u72D5\u72D6\u72D8\u72DA\u72DB"], + ["a1a1", "\u3000\u3001\u3002\xB7\u02C9\u02C7\xA8\u3003\u3005\u2014\uFF5E\u2016\u2026\u2018\u2019\u201C\u201D\u3014\u3015\u3008", 7, "\u3016\u3017\u3010\u3011\xB1\xD7\xF7\u2236\u2227\u2228\u2211\u220F\u222A\u2229\u2208\u2237\u221A\u22A5\u2225\u2220\u2312\u2299\u222B\u222E\u2261\u224C\u2248\u223D\u221D\u2260\u226E\u226F\u2264\u2265\u221E\u2235\u2234\u2642\u2640\xB0\u2032\u2033\u2103\uFF04\xA4\uFFE0\uFFE1\u2030\xA7\u2116\u2606\u2605\u25CB\u25CF\u25CE\u25C7\u25C6\u25A1\u25A0\u25B3\u25B2\u203B\u2192\u2190\u2191\u2193\u3013"], + ["a2a1", "\u2170", 9], + ["a2b1", "\u2488", 19, "\u2474", 19, "\u2460", 9], + ["a2e5", "\u3220", 9], + ["a2f1", "\u2160", 11], + ["a3a1", "\uFF01\uFF02\uFF03\uFFE5\uFF05", 88, "\uFFE3"], + ["a4a1", "\u3041", 82], + ["a5a1", "\u30A1", 85], + ["a6a1", "\u0391", 16, "\u03A3", 6], + ["a6c1", "\u03B1", 16, "\u03C3", 6], + ["a6e0", "\uFE35\uFE36\uFE39\uFE3A\uFE3F\uFE40\uFE3D\uFE3E\uFE41\uFE42\uFE43\uFE44"], + ["a6ee", "\uFE3B\uFE3C\uFE37\uFE38\uFE31"], + ["a6f4", "\uFE33\uFE34"], + ["a7a1", "\u0410", 5, "\u0401\u0416", 25], + ["a7d1", "\u0430", 5, "\u0451\u0436", 25], + ["a840", "\u02CA\u02CB\u02D9\u2013\u2015\u2025\u2035\u2105\u2109\u2196\u2197\u2198\u2199\u2215\u221F\u2223\u2252\u2266\u2267\u22BF\u2550", 35, "\u2581", 6], + ["a880", "\u2588", 7, "\u2593\u2594\u2595\u25BC\u25BD\u25E2\u25E3\u25E4\u25E5\u2609\u2295\u3012\u301D\u301E"], + ["a8a1", "\u0101\xE1\u01CE\xE0\u0113\xE9\u011B\xE8\u012B\xED\u01D0\xEC\u014D\xF3\u01D2\xF2\u016B\xFA\u01D4\xF9\u01D6\u01D8\u01DA\u01DC\xFC\xEA\u0251"], + ["a8bd", "\u0144\u0148"], + ["a8c0", "\u0261"], + ["a8c5", "\u3105", 36], + ["a940", "\u3021", 8, "\u32A3\u338E\u338F\u339C\u339D\u339E\u33A1\u33C4\u33CE\u33D1\u33D2\u33D5\uFE30\uFFE2\uFFE4"], + ["a959", "\u2121\u3231"], + ["a95c", "\u2010"], + ["a960", "\u30FC\u309B\u309C\u30FD\u30FE\u3006\u309D\u309E\uFE49", 9, "\uFE54\uFE55\uFE56\uFE57\uFE59", 8], + ["a980", "\uFE62", 4, "\uFE68\uFE69\uFE6A\uFE6B"], + ["a996", "\u3007"], + ["a9a4", "\u2500", 75], + ["aa40", "\u72DC\u72DD\u72DF\u72E2", 5, "\u72EA\u72EB\u72F5\u72F6\u72F9\u72FD\u72FE\u72FF\u7300\u7302\u7304", 5, "\u730B\u730C\u730D\u730F\u7310\u7311\u7312\u7314\u7318\u7319\u731A\u731F\u7320\u7323\u7324\u7326\u7327\u7328\u732D\u732F\u7330\u7332\u7333\u7335\u7336\u733A\u733B\u733C\u733D\u7340", 8], + ["aa80", "\u7349\u734A\u734B\u734C\u734E\u734F\u7351\u7353\u7354\u7355\u7356\u7358", 7, "\u7361", 10, "\u736E\u7370\u7371"], + ["ab40", "\u7372", 11, "\u737F", 4, "\u7385\u7386\u7388\u738A\u738C\u738D\u738F\u7390\u7392\u7393\u7394\u7395\u7397\u7398\u7399\u739A\u739C\u739D\u739E\u73A0\u73A1\u73A3", 5, "\u73AA\u73AC\u73AD\u73B1\u73B4\u73B5\u73B6\u73B8\u73B9\u73BC\u73BD\u73BE\u73BF\u73C1\u73C3", 4], + ["ab80", "\u73CB\u73CC\u73CE\u73D2", 6, "\u73DA\u73DB\u73DC\u73DD\u73DF\u73E1\u73E2\u73E3\u73E4\u73E6\u73E8\u73EA\u73EB\u73EC\u73EE\u73EF\u73F0\u73F1\u73F3", 4], + ["ac40", "\u73F8", 10, "\u7404\u7407\u7408\u740B\u740C\u740D\u740E\u7411", 8, "\u741C", 5, "\u7423\u7424\u7427\u7429\u742B\u742D\u742F\u7431\u7432\u7437", 4, "\u743D\u743E\u743F\u7440\u7442", 11], + ["ac80", "\u744E", 6, "\u7456\u7458\u745D\u7460", 12, "\u746E\u746F\u7471", 4, "\u7478\u7479\u747A"], + ["ad40", "\u747B\u747C\u747D\u747F\u7482\u7484\u7485\u7486\u7488\u7489\u748A\u748C\u748D\u748F\u7491", 10, "\u749D\u749F", 7, "\u74AA", 15, "\u74BB", 12], + ["ad80", "\u74C8", 9, "\u74D3", 8, "\u74DD\u74DF\u74E1\u74E5\u74E7", 6, "\u74F0\u74F1\u74F2"], + ["ae40", "\u74F3\u74F5\u74F8", 6, "\u7500\u7501\u7502\u7503\u7505", 7, "\u750E\u7510\u7512\u7514\u7515\u7516\u7517\u751B\u751D\u751E\u7520", 4, "\u7526\u7527\u752A\u752E\u7534\u7536\u7539\u753C\u753D\u753F\u7541\u7542\u7543\u7544\u7546\u7547\u7549\u754A\u754D\u7550\u7551\u7552\u7553\u7555\u7556\u7557\u7558"], + ["ae80", "\u755D", 7, "\u7567\u7568\u7569\u756B", 6, "\u7573\u7575\u7576\u7577\u757A", 4, "\u7580\u7581\u7582\u7584\u7585\u7587"], + ["af40", "\u7588\u7589\u758A\u758C\u758D\u758E\u7590\u7593\u7595\u7598\u759B\u759C\u759E\u75A2\u75A6", 4, "\u75AD\u75B6\u75B7\u75BA\u75BB\u75BF\u75C0\u75C1\u75C6\u75CB\u75CC\u75CE\u75CF\u75D0\u75D1\u75D3\u75D7\u75D9\u75DA\u75DC\u75DD\u75DF\u75E0\u75E1\u75E5\u75E9\u75EC\u75ED\u75EE\u75EF\u75F2\u75F3\u75F5\u75F6\u75F7\u75F8\u75FA\u75FB\u75FD\u75FE\u7602\u7604\u7606\u7607"], + ["af80", "\u7608\u7609\u760B\u760D\u760E\u760F\u7611\u7612\u7613\u7614\u7616\u761A\u761C\u761D\u761E\u7621\u7623\u7627\u7628\u762C\u762E\u762F\u7631\u7632\u7636\u7637\u7639\u763A\u763B\u763D\u7641\u7642\u7644"], + ["b040", "\u7645", 6, "\u764E", 5, "\u7655\u7657", 4, "\u765D\u765F\u7660\u7661\u7662\u7664", 6, "\u766C\u766D\u766E\u7670", 7, "\u7679\u767A\u767C\u767F\u7680\u7681\u7683\u7685\u7689\u768A\u768C\u768D\u768F\u7690\u7692\u7694\u7695\u7697\u7698\u769A\u769B"], + ["b080", "\u769C", 7, "\u76A5", 8, "\u76AF\u76B0\u76B3\u76B5", 9, "\u76C0\u76C1\u76C3\u554A\u963F\u57C3\u6328\u54CE\u5509\u54C0\u7691\u764C\u853C\u77EE\u827E\u788D\u7231\u9698\u978D\u6C28\u5B89\u4FFA\u6309\u6697\u5CB8\u80FA\u6848\u80AE\u6602\u76CE\u51F9\u6556\u71AC\u7FF1\u8884\u50B2\u5965\u61CA\u6FB3\u82AD\u634C\u6252\u53ED\u5427\u7B06\u516B\u75A4\u5DF4\u62D4\u8DCB\u9776\u628A\u8019\u575D\u9738\u7F62\u7238\u767D\u67CF\u767E\u6446\u4F70\u8D25\u62DC\u7A17\u6591\u73ED\u642C\u6273\u822C\u9881\u677F\u7248\u626E\u62CC\u4F34\u74E3\u534A\u529E\u7ECA\u90A6\u5E2E\u6886\u699C\u8180\u7ED1\u68D2\u78C5\u868C\u9551\u508D\u8C24\u82DE\u80DE\u5305\u8912\u5265"], + ["b140", "\u76C4\u76C7\u76C9\u76CB\u76CC\u76D3\u76D5\u76D9\u76DA\u76DC\u76DD\u76DE\u76E0", 4, "\u76E6", 7, "\u76F0\u76F3\u76F5\u76F6\u76F7\u76FA\u76FB\u76FD\u76FF\u7700\u7702\u7703\u7705\u7706\u770A\u770C\u770E", 10, "\u771B\u771C\u771D\u771E\u7721\u7723\u7724\u7725\u7727\u772A\u772B"], + ["b180", "\u772C\u772E\u7730", 4, "\u7739\u773B\u773D\u773E\u773F\u7742\u7744\u7745\u7746\u7748", 7, "\u7752", 7, "\u775C\u8584\u96F9\u4FDD\u5821\u9971\u5B9D\u62B1\u62A5\u66B4\u8C79\u9C8D\u7206\u676F\u7891\u60B2\u5351\u5317\u8F88\u80CC\u8D1D\u94A1\u500D\u72C8\u5907\u60EB\u7119\u88AB\u5954\u82EF\u672C\u7B28\u5D29\u7EF7\u752D\u6CF5\u8E66\u8FF8\u903C\u9F3B\u6BD4\u9119\u7B14\u5F7C\u78A7\u84D6\u853D\u6BD5\u6BD9\u6BD6\u5E01\u5E87\u75F9\u95ED\u655D\u5F0A\u5FC5\u8F9F\u58C1\u81C2\u907F\u965B\u97AD\u8FB9\u7F16\u8D2C\u6241\u4FBF\u53D8\u535E\u8FA8\u8FA9\u8FAB\u904D\u6807\u5F6A\u8198\u8868\u9CD6\u618B\u522B\u762A\u5F6C\u658C\u6FD2\u6EE8\u5BBE\u6448\u5175\u51B0\u67C4\u4E19\u79C9\u997C\u70B3"], + ["b240", "\u775D\u775E\u775F\u7760\u7764\u7767\u7769\u776A\u776D", 11, "\u777A\u777B\u777C\u7781\u7782\u7783\u7786", 5, "\u778F\u7790\u7793", 11, "\u77A1\u77A3\u77A4\u77A6\u77A8\u77AB\u77AD\u77AE\u77AF\u77B1\u77B2\u77B4\u77B6", 4], + ["b280", "\u77BC\u77BE\u77C0", 12, "\u77CE", 8, "\u77D8\u77D9\u77DA\u77DD", 4, "\u77E4\u75C5\u5E76\u73BB\u83E0\u64AD\u62E8\u94B5\u6CE2\u535A\u52C3\u640F\u94C2\u7B94\u4F2F\u5E1B\u8236\u8116\u818A\u6E24\u6CCA\u9A73\u6355\u535C\u54FA\u8865\u57E0\u4E0D\u5E03\u6B65\u7C3F\u90E8\u6016\u64E6\u731C\u88C1\u6750\u624D\u8D22\u776C\u8E29\u91C7\u5F69\u83DC\u8521\u9910\u53C2\u8695\u6B8B\u60ED\u60E8\u707F\u82CD\u8231\u4ED3\u6CA7\u85CF\u64CD\u7CD9\u69FD\u66F9\u8349\u5395\u7B56\u4FA7\u518C\u6D4B\u5C42\u8E6D\u63D2\u53C9\u832C\u8336\u67E5\u78B4\u643D\u5BDF\u5C94\u5DEE\u8BE7\u62C6\u67F4\u8C7A\u6400\u63BA\u8749\u998B\u8C17\u7F20\u94F2\u4EA7\u9610\u98A4\u660C\u7316"], + ["b340", "\u77E6\u77E8\u77EA\u77EF\u77F0\u77F1\u77F2\u77F4\u77F5\u77F7\u77F9\u77FA\u77FB\u77FC\u7803", 5, "\u780A\u780B\u780E\u780F\u7810\u7813\u7815\u7819\u781B\u781E\u7820\u7821\u7822\u7824\u7828\u782A\u782B\u782E\u782F\u7831\u7832\u7833\u7835\u7836\u783D\u783F\u7841\u7842\u7843\u7844\u7846\u7848\u7849\u784A\u784B\u784D\u784F\u7851\u7853\u7854\u7858\u7859\u785A"], + ["b380", "\u785B\u785C\u785E", 11, "\u786F", 7, "\u7878\u7879\u787A\u787B\u787D", 6, "\u573A\u5C1D\u5E38\u957F\u507F\u80A0\u5382\u655E\u7545\u5531\u5021\u8D85\u6284\u949E\u671D\u5632\u6F6E\u5DE2\u5435\u7092\u8F66\u626F\u64A4\u63A3\u5F7B\u6F88\u90F4\u81E3\u8FB0\u5C18\u6668\u5FF1\u6C89\u9648\u8D81\u886C\u6491\u79F0\u57CE\u6A59\u6210\u5448\u4E58\u7A0B\u60E9\u6F84\u8BDA\u627F\u901E\u9A8B\u79E4\u5403\u75F4\u6301\u5319\u6C60\u8FDF\u5F1B\u9A70\u803B\u9F7F\u4F88\u5C3A\u8D64\u7FC5\u65A5\u70BD\u5145\u51B2\u866B\u5D07\u5BA0\u62BD\u916C\u7574\u8E0C\u7A20\u6101\u7B79\u4EC7\u7EF8\u7785\u4E11\u81ED\u521D\u51FA\u6A71\u53A8\u8E87\u9504\u96CF\u6EC1\u9664\u695A"], + ["b440", "\u7884\u7885\u7886\u7888\u788A\u788B\u788F\u7890\u7892\u7894\u7895\u7896\u7899\u789D\u789E\u78A0\u78A2\u78A4\u78A6\u78A8", 7, "\u78B5\u78B6\u78B7\u78B8\u78BA\u78BB\u78BC\u78BD\u78BF\u78C0\u78C2\u78C3\u78C4\u78C6\u78C7\u78C8\u78CC\u78CD\u78CE\u78CF\u78D1\u78D2\u78D3\u78D6\u78D7\u78D8\u78DA", 9], + ["b480", "\u78E4\u78E5\u78E6\u78E7\u78E9\u78EA\u78EB\u78ED", 4, "\u78F3\u78F5\u78F6\u78F8\u78F9\u78FB", 5, "\u7902\u7903\u7904\u7906", 6, "\u7840\u50A8\u77D7\u6410\u89E6\u5904\u63E3\u5DDD\u7A7F\u693D\u4F20\u8239\u5598\u4E32\u75AE\u7A97\u5E62\u5E8A\u95EF\u521B\u5439\u708A\u6376\u9524\u5782\u6625\u693F\u9187\u5507\u6DF3\u7EAF\u8822\u6233\u7EF0\u75B5\u8328\u78C1\u96CC\u8F9E\u6148\u74F7\u8BCD\u6B64\u523A\u8D50\u6B21\u806A\u8471\u56F1\u5306\u4ECE\u4E1B\u51D1\u7C97\u918B\u7C07\u4FC3\u8E7F\u7BE1\u7A9C\u6467\u5D14\u50AC\u8106\u7601\u7CB9\u6DEC\u7FE0\u6751\u5B58\u5BF8\u78CB\u64AE\u6413\u63AA\u632B\u9519\u642D\u8FBE\u7B54\u7629\u6253\u5927\u5446\u6B79\u50A3\u6234\u5E26\u6B86\u4EE3\u8D37\u888B\u5F85\u902E"], + ["b540", "\u790D", 5, "\u7914", 9, "\u791F", 4, "\u7925", 14, "\u7935", 4, "\u793D\u793F\u7942\u7943\u7944\u7945\u7947\u794A", 8, "\u7954\u7955\u7958\u7959\u7961\u7963"], + ["b580", "\u7964\u7966\u7969\u796A\u796B\u796C\u796E\u7970", 6, "\u7979\u797B", 4, "\u7982\u7983\u7986\u7987\u7988\u7989\u798B\u798C\u798D\u798E\u7990\u7991\u7992\u6020\u803D\u62C5\u4E39\u5355\u90F8\u63B8\u80C6\u65E6\u6C2E\u4F46\u60EE\u6DE1\u8BDE\u5F39\u86CB\u5F53\u6321\u515A\u8361\u6863\u5200\u6363\u8E48\u5012\u5C9B\u7977\u5BFC\u5230\u7A3B\u60BC\u9053\u76D7\u5FB7\u5F97\u7684\u8E6C\u706F\u767B\u7B49\u77AA\u51F3\u9093\u5824\u4F4E\u6EF4\u8FEA\u654C\u7B1B\u72C4\u6DA4\u7FDF\u5AE1\u62B5\u5E95\u5730\u8482\u7B2C\u5E1D\u5F1F\u9012\u7F14\u98A0\u6382\u6EC7\u7898\u70B9\u5178\u975B\u57AB\u7535\u4F43\u7538\u5E97\u60E6\u5960\u6DC0\u6BBF\u7889\u53FC\u96D5\u51CB\u5201\u6389\u540A\u9493\u8C03\u8DCC\u7239\u789F\u8776\u8FED\u8C0D\u53E0"], + ["b640", "\u7993", 6, "\u799B", 11, "\u79A8", 10, "\u79B4", 4, "\u79BC\u79BF\u79C2\u79C4\u79C5\u79C7\u79C8\u79CA\u79CC\u79CE\u79CF\u79D0\u79D3\u79D4\u79D6\u79D7\u79D9", 5, "\u79E0\u79E1\u79E2\u79E5\u79E8\u79EA"], + ["b680", "\u79EC\u79EE\u79F1", 6, "\u79F9\u79FA\u79FC\u79FE\u79FF\u7A01\u7A04\u7A05\u7A07\u7A08\u7A09\u7A0A\u7A0C\u7A0F", 4, "\u7A15\u7A16\u7A18\u7A19\u7A1B\u7A1C\u4E01\u76EF\u53EE\u9489\u9876\u9F0E\u952D\u5B9A\u8BA2\u4E22\u4E1C\u51AC\u8463\u61C2\u52A8\u680B\u4F97\u606B\u51BB\u6D1E\u515C\u6296\u6597\u9661\u8C46\u9017\u75D8\u90FD\u7763\u6BD2\u728A\u72EC\u8BFB\u5835\u7779\u8D4C\u675C\u9540\u809A\u5EA6\u6E21\u5992\u7AEF\u77ED\u953B\u6BB5\u65AD\u7F0E\u5806\u5151\u961F\u5BF9\u58A9\u5428\u8E72\u6566\u987F\u56E4\u949D\u76FE\u9041\u6387\u54C6\u591A\u593A\u579B\u8EB2\u6735\u8DFA\u8235\u5241\u60F0\u5815\u86FE\u5CE8\u9E45\u4FC4\u989D\u8BB9\u5A25\u6076\u5384\u627C\u904F\u9102\u997F\u6069\u800C\u513F\u8033\u5C14\u9975\u6D31\u4E8C"], + ["b740", "\u7A1D\u7A1F\u7A21\u7A22\u7A24", 14, "\u7A34\u7A35\u7A36\u7A38\u7A3A\u7A3E\u7A40", 5, "\u7A47", 9, "\u7A52", 4, "\u7A58", 16], + ["b780", "\u7A69", 6, "\u7A71\u7A72\u7A73\u7A75\u7A7B\u7A7C\u7A7D\u7A7E\u7A82\u7A85\u7A87\u7A89\u7A8A\u7A8B\u7A8C\u7A8E\u7A8F\u7A90\u7A93\u7A94\u7A99\u7A9A\u7A9B\u7A9E\u7AA1\u7AA2\u8D30\u53D1\u7F5A\u7B4F\u4F10\u4E4F\u9600\u6CD5\u73D0\u85E9\u5E06\u756A\u7FFB\u6A0A\u77FE\u9492\u7E41\u51E1\u70E6\u53CD\u8FD4\u8303\u8D29\u72AF\u996D\u6CDB\u574A\u82B3\u65B9\u80AA\u623F\u9632\u59A8\u4EFF\u8BBF\u7EBA\u653E\u83F2\u975E\u5561\u98DE\u80A5\u532A\u8BFD\u5420\u80BA\u5E9F\u6CB8\u8D39\u82AC\u915A\u5429\u6C1B\u5206\u7EB7\u575F\u711A\u6C7E\u7C89\u594B\u4EFD\u5FFF\u6124\u7CAA\u4E30\u5C01\u67AB\u8702\u5CF0\u950B\u98CE\u75AF\u70FD\u9022\u51AF\u7F1D\u8BBD\u5949\u51E4\u4F5B\u5426\u592B\u6577\u80A4\u5B75\u6276\u62C2\u8F90\u5E45\u6C1F\u7B26\u4F0F\u4FD8\u670D"], + ["b840", "\u7AA3\u7AA4\u7AA7\u7AA9\u7AAA\u7AAB\u7AAE", 4, "\u7AB4", 10, "\u7AC0", 10, "\u7ACC", 9, "\u7AD7\u7AD8\u7ADA\u7ADB\u7ADC\u7ADD\u7AE1\u7AE2\u7AE4\u7AE7", 5, "\u7AEE\u7AF0\u7AF1\u7AF2\u7AF3"], + ["b880", "\u7AF4", 4, "\u7AFB\u7AFC\u7AFE\u7B00\u7B01\u7B02\u7B05\u7B07\u7B09\u7B0C\u7B0D\u7B0E\u7B10\u7B12\u7B13\u7B16\u7B17\u7B18\u7B1A\u7B1C\u7B1D\u7B1F\u7B21\u7B22\u7B23\u7B27\u7B29\u7B2D\u6D6E\u6DAA\u798F\u88B1\u5F17\u752B\u629A\u8F85\u4FEF\u91DC\u65A7\u812F\u8151\u5E9C\u8150\u8D74\u526F\u8986\u8D4B\u590D\u5085\u4ED8\u961C\u7236\u8179\u8D1F\u5BCC\u8BA3\u9644\u5987\u7F1A\u5490\u5676\u560E\u8BE5\u6539\u6982\u9499\u76D6\u6E89\u5E72\u7518\u6746\u67D1\u7AFF\u809D\u8D76\u611F\u79C6\u6562\u8D63\u5188\u521A\u94A2\u7F38\u809B\u7EB2\u5C97\u6E2F\u6760\u7BD9\u768B\u9AD8\u818F\u7F94\u7CD5\u641E\u9550\u7A3F\u544A\u54E5\u6B4C\u6401\u6208\u9E3D\u80F3\u7599\u5272\u9769\u845B\u683C\u86E4\u9601\u9694\u94EC\u4E2A\u5404\u7ED9\u6839\u8DDF\u8015\u66F4\u5E9A\u7FB9"], + ["b940", "\u7B2F\u7B30\u7B32\u7B34\u7B35\u7B36\u7B37\u7B39\u7B3B\u7B3D\u7B3F", 5, "\u7B46\u7B48\u7B4A\u7B4D\u7B4E\u7B53\u7B55\u7B57\u7B59\u7B5C\u7B5E\u7B5F\u7B61\u7B63", 10, "\u7B6F\u7B70\u7B73\u7B74\u7B76\u7B78\u7B7A\u7B7C\u7B7D\u7B7F\u7B81\u7B82\u7B83\u7B84\u7B86", 6, "\u7B8E\u7B8F"], + ["b980", "\u7B91\u7B92\u7B93\u7B96\u7B98\u7B99\u7B9A\u7B9B\u7B9E\u7B9F\u7BA0\u7BA3\u7BA4\u7BA5\u7BAE\u7BAF\u7BB0\u7BB2\u7BB3\u7BB5\u7BB6\u7BB7\u7BB9", 7, "\u7BC2\u7BC3\u7BC4\u57C2\u803F\u6897\u5DE5\u653B\u529F\u606D\u9F9A\u4F9B\u8EAC\u516C\u5BAB\u5F13\u5DE9\u6C5E\u62F1\u8D21\u5171\u94A9\u52FE\u6C9F\u82DF\u72D7\u57A2\u6784\u8D2D\u591F\u8F9C\u83C7\u5495\u7B8D\u4F30\u6CBD\u5B64\u59D1\u9F13\u53E4\u86CA\u9AA8\u8C37\u80A1\u6545\u987E\u56FA\u96C7\u522E\u74DC\u5250\u5BE1\u6302\u8902\u4E56\u62D0\u602A\u68FA\u5173\u5B98\u51A0\u89C2\u7BA1\u9986\u7F50\u60EF\u704C\u8D2F\u5149\u5E7F\u901B\u7470\u89C4\u572D\u7845\u5F52\u9F9F\u95FA\u8F68\u9B3C\u8BE1\u7678\u6842\u67DC\u8DEA\u8D35\u523D\u8F8A\u6EDA\u68CD\u9505\u90ED\u56FD\u679C\u88F9\u8FC7\u54C8"], + ["ba40", "\u7BC5\u7BC8\u7BC9\u7BCA\u7BCB\u7BCD\u7BCE\u7BCF\u7BD0\u7BD2\u7BD4", 4, "\u7BDB\u7BDC\u7BDE\u7BDF\u7BE0\u7BE2\u7BE3\u7BE4\u7BE7\u7BE8\u7BE9\u7BEB\u7BEC\u7BED\u7BEF\u7BF0\u7BF2", 4, "\u7BF8\u7BF9\u7BFA\u7BFB\u7BFD\u7BFF", 7, "\u7C08\u7C09\u7C0A\u7C0D\u7C0E\u7C10", 5, "\u7C17\u7C18\u7C19"], + ["ba80", "\u7C1A", 4, "\u7C20", 5, "\u7C28\u7C29\u7C2B", 12, "\u7C39", 5, "\u7C42\u9AB8\u5B69\u6D77\u6C26\u4EA5\u5BB3\u9A87\u9163\u61A8\u90AF\u97E9\u542B\u6DB5\u5BD2\u51FD\u558A\u7F55\u7FF0\u64BC\u634D\u65F1\u61BE\u608D\u710A\u6C57\u6C49\u592F\u676D\u822A\u58D5\u568E\u8C6A\u6BEB\u90DD\u597D\u8017\u53F7\u6D69\u5475\u559D\u8377\u83CF\u6838\u79BE\u548C\u4F55\u5408\u76D2\u8C89\u9602\u6CB3\u6DB8\u8D6B\u8910\u9E64\u8D3A\u563F\u9ED1\u75D5\u5F88\u72E0\u6068\u54FC\u4EA8\u6A2A\u8861\u6052\u8F70\u54C4\u70D8\u8679\u9E3F\u6D2A\u5B8F\u5F18\u7EA2\u5589\u4FAF\u7334\u543C\u539A\u5019\u540E\u547C\u4E4E\u5FFD\u745A\u58F6\u846B\u80E1\u8774\u72D0\u7CCA\u6E56"], + ["bb40", "\u7C43", 9, "\u7C4E", 36, "\u7C75", 5, "\u7C7E", 9], + ["bb80", "\u7C88\u7C8A", 6, "\u7C93\u7C94\u7C96\u7C99\u7C9A\u7C9B\u7CA0\u7CA1\u7CA3\u7CA6\u7CA7\u7CA8\u7CA9\u7CAB\u7CAC\u7CAD\u7CAF\u7CB0\u7CB4", 4, "\u7CBA\u7CBB\u5F27\u864E\u552C\u62A4\u4E92\u6CAA\u6237\u82B1\u54D7\u534E\u733E\u6ED1\u753B\u5212\u5316\u8BDD\u69D0\u5F8A\u6000\u6DEE\u574F\u6B22\u73AF\u6853\u8FD8\u7F13\u6362\u60A3\u5524\u75EA\u8C62\u7115\u6DA3\u5BA6\u5E7B\u8352\u614C\u9EC4\u78FA\u8757\u7C27\u7687\u51F0\u60F6\u714C\u6643\u5E4C\u604D\u8C0E\u7070\u6325\u8F89\u5FBD\u6062\u86D4\u56DE\u6BC1\u6094\u6167\u5349\u60E0\u6666\u8D3F\u79FD\u4F1A\u70E9\u6C47\u8BB3\u8BF2\u7ED8\u8364\u660F\u5A5A\u9B42\u6D51\u6DF7\u8C41\u6D3B\u4F19\u706B\u83B7\u6216\u60D1\u970D\u8D27\u7978\u51FB\u573E\u57FA\u673A\u7578\u7A3D\u79EF\u7B95"], + ["bc40", "\u7CBF\u7CC0\u7CC2\u7CC3\u7CC4\u7CC6\u7CC9\u7CCB\u7CCE", 6, "\u7CD8\u7CDA\u7CDB\u7CDD\u7CDE\u7CE1", 6, "\u7CE9", 5, "\u7CF0", 7, "\u7CF9\u7CFA\u7CFC", 13, "\u7D0B", 5], + ["bc80", "\u7D11", 14, "\u7D21\u7D23\u7D24\u7D25\u7D26\u7D28\u7D29\u7D2A\u7D2C\u7D2D\u7D2E\u7D30", 6, "\u808C\u9965\u8FF9\u6FC0\u8BA5\u9E21\u59EC\u7EE9\u7F09\u5409\u6781\u68D8\u8F91\u7C4D\u96C6\u53CA\u6025\u75BE\u6C72\u5373\u5AC9\u7EA7\u6324\u51E0\u810A\u5DF1\u84DF\u6280\u5180\u5B63\u4F0E\u796D\u5242\u60B8\u6D4E\u5BC4\u5BC2\u8BA1\u8BB0\u65E2\u5FCC\u9645\u5993\u7EE7\u7EAA\u5609\u67B7\u5939\u4F73\u5BB6\u52A0\u835A\u988A\u8D3E\u7532\u94BE\u5047\u7A3C\u4EF7\u67B6\u9A7E\u5AC1\u6B7C\u76D1\u575A\u5C16\u7B3A\u95F4\u714E\u517C\u80A9\u8270\u5978\u7F04\u8327\u68C0\u67EC\u78B1\u7877\u62E3\u6361\u7B80\u4FED\u526A\u51CF\u8350\u69DB\u9274\u8DF5\u8D31\u89C1\u952E\u7BAD\u4EF6"], + ["bd40", "\u7D37", 54, "\u7D6F", 7], + ["bd80", "\u7D78", 32, "\u5065\u8230\u5251\u996F\u6E10\u6E85\u6DA7\u5EFA\u50F5\u59DC\u5C06\u6D46\u6C5F\u7586\u848B\u6868\u5956\u8BB2\u5320\u9171\u964D\u8549\u6912\u7901\u7126\u80F6\u4EA4\u90CA\u6D47\u9A84\u5A07\u56BC\u6405\u94F0\u77EB\u4FA5\u811A\u72E1\u89D2\u997A\u7F34\u7EDE\u527F\u6559\u9175\u8F7F\u8F83\u53EB\u7A96\u63ED\u63A5\u7686\u79F8\u8857\u9636\u622A\u52AB\u8282\u6854\u6770\u6377\u776B\u7AED\u6D01\u7ED3\u89E3\u59D0\u6212\u85C9\u82A5\u754C\u501F\u4ECB\u75A5\u8BEB\u5C4A\u5DFE\u7B4B\u65A4\u91D1\u4ECA\u6D25\u895F\u7D27\u9526\u4EC5\u8C28\u8FDB\u9773\u664B\u7981\u8FD1\u70EC\u6D78"], + ["be40", "\u7D99", 12, "\u7DA7", 6, "\u7DAF", 42], + ["be80", "\u7DDA", 32, "\u5C3D\u52B2\u8346\u5162\u830E\u775B\u6676\u9CB8\u4EAC\u60CA\u7CBE\u7CB3\u7ECF\u4E95\u8B66\u666F\u9888\u9759\u5883\u656C\u955C\u5F84\u75C9\u9756\u7ADF\u7ADE\u51C0\u70AF\u7A98\u63EA\u7A76\u7EA0\u7396\u97ED\u4E45\u7078\u4E5D\u9152\u53A9\u6551\u65E7\u81FC\u8205\u548E\u5C31\u759A\u97A0\u62D8\u72D9\u75BD\u5C45\u9A79\u83CA\u5C40\u5480\u77E9\u4E3E\u6CAE\u805A\u62D2\u636E\u5DE8\u5177\u8DDD\u8E1E\u952F\u4FF1\u53E5\u60E7\u70AC\u5267\u6350\u9E43\u5A1F\u5026\u7737\u5377\u7EE2\u6485\u652B\u6289\u6398\u5014\u7235\u89C9\u51B3\u8BC0\u7EDD\u5747\u83CC\u94A7\u519B\u541B\u5CFB"], + ["bf40", "\u7DFB", 62], + ["bf80", "\u7E3A\u7E3C", 4, "\u7E42", 4, "\u7E48", 21, "\u4FCA\u7AE3\u6D5A\u90E1\u9A8F\u5580\u5496\u5361\u54AF\u5F00\u63E9\u6977\u51EF\u6168\u520A\u582A\u52D8\u574E\u780D\u770B\u5EB7\u6177\u7CE0\u625B\u6297\u4EA2\u7095\u8003\u62F7\u70E4\u9760\u5777\u82DB\u67EF\u68F5\u78D5\u9897\u79D1\u58F3\u54B3\u53EF\u6E34\u514B\u523B\u5BA2\u8BFE\u80AF\u5543\u57A6\u6073\u5751\u542D\u7A7A\u6050\u5B54\u63A7\u62A0\u53E3\u6263\u5BC7\u67AF\u54ED\u7A9F\u82E6\u9177\u5E93\u88E4\u5938\u57AE\u630E\u8DE8\u80EF\u5757\u7B77\u4FA9\u5FEB\u5BBD\u6B3E\u5321\u7B50\u72C2\u6846\u77FF\u7736\u65F7\u51B5\u4E8F\u76D4\u5CBF\u7AA5\u8475\u594E\u9B41\u5080"], + ["c040", "\u7E5E", 35, "\u7E83", 23, "\u7E9C\u7E9D\u7E9E"], + ["c080", "\u7EAE\u7EB4\u7EBB\u7EBC\u7ED6\u7EE4\u7EEC\u7EF9\u7F0A\u7F10\u7F1E\u7F37\u7F39\u7F3B", 6, "\u7F43\u7F46", 9, "\u7F52\u7F53\u9988\u6127\u6E83\u5764\u6606\u6346\u56F0\u62EC\u6269\u5ED3\u9614\u5783\u62C9\u5587\u8721\u814A\u8FA3\u5566\u83B1\u6765\u8D56\u84DD\u5A6A\u680F\u62E6\u7BEE\u9611\u5170\u6F9C\u8C30\u63FD\u89C8\u61D2\u7F06\u70C2\u6EE5\u7405\u6994\u72FC\u5ECA\u90CE\u6717\u6D6A\u635E\u52B3\u7262\u8001\u4F6C\u59E5\u916A\u70D9\u6D9D\u52D2\u4E50\u96F7\u956D\u857E\u78CA\u7D2F\u5121\u5792\u64C2\u808B\u7C7B\u6CEA\u68F1\u695E\u51B7\u5398\u68A8\u7281\u9ECE\u7BF1\u72F8\u79BB\u6F13\u7406\u674E\u91CC\u9CA4\u793C\u8389\u8354\u540F\u6817\u4E3D\u5389\u52B1\u783E\u5386\u5229\u5088\u4F8B\u4FD0"], + ["c140", "\u7F56\u7F59\u7F5B\u7F5C\u7F5D\u7F5E\u7F60\u7F63", 4, "\u7F6B\u7F6C\u7F6D\u7F6F\u7F70\u7F73\u7F75\u7F76\u7F77\u7F78\u7F7A\u7F7B\u7F7C\u7F7D\u7F7F\u7F80\u7F82", 7, "\u7F8B\u7F8D\u7F8F", 4, "\u7F95", 4, "\u7F9B\u7F9C\u7FA0\u7FA2\u7FA3\u7FA5\u7FA6\u7FA8", 6, "\u7FB1"], + ["c180", "\u7FB3", 4, "\u7FBA\u7FBB\u7FBE\u7FC0\u7FC2\u7FC3\u7FC4\u7FC6\u7FC7\u7FC8\u7FC9\u7FCB\u7FCD\u7FCF", 4, "\u7FD6\u7FD7\u7FD9", 5, "\u7FE2\u7FE3\u75E2\u7ACB\u7C92\u6CA5\u96B6\u529B\u7483\u54E9\u4FE9\u8054\u83B2\u8FDE\u9570\u5EC9\u601C\u6D9F\u5E18\u655B\u8138\u94FE\u604B\u70BC\u7EC3\u7CAE\u51C9\u6881\u7CB1\u826F\u4E24\u8F86\u91CF\u667E\u4EAE\u8C05\u64A9\u804A\u50DA\u7597\u71CE\u5BE5\u8FBD\u6F66\u4E86\u6482\u9563\u5ED6\u6599\u5217\u88C2\u70C8\u52A3\u730E\u7433\u6797\u78F7\u9716\u4E34\u90BB\u9CDE\u6DCB\u51DB\u8D41\u541D\u62CE\u73B2\u83F1\u96F6\u9F84\u94C3\u4F36\u7F9A\u51CC\u7075\u9675\u5CAD\u9886\u53E6\u4EE4\u6E9C\u7409\u69B4\u786B\u998F\u7559\u5218\u7624\u6D41\u67F3\u516D\u9F99\u804B\u5499\u7B3C\u7ABF"], + ["c240", "\u7FE4\u7FE7\u7FE8\u7FEA\u7FEB\u7FEC\u7FED\u7FEF\u7FF2\u7FF4", 6, "\u7FFD\u7FFE\u7FFF\u8002\u8007\u8008\u8009\u800A\u800E\u800F\u8011\u8013\u801A\u801B\u801D\u801E\u801F\u8021\u8023\u8024\u802B", 5, "\u8032\u8034\u8039\u803A\u803C\u803E\u8040\u8041\u8044\u8045\u8047\u8048\u8049\u804E\u804F\u8050\u8051\u8053\u8055\u8056\u8057"], + ["c280", "\u8059\u805B", 13, "\u806B", 5, "\u8072", 11, "\u9686\u5784\u62E2\u9647\u697C\u5A04\u6402\u7BD3\u6F0F\u964B\u82A6\u5362\u9885\u5E90\u7089\u63B3\u5364\u864F\u9C81\u9E93\u788C\u9732\u8DEF\u8D42\u9E7F\u6F5E\u7984\u5F55\u9646\u622E\u9A74\u5415\u94DD\u4FA3\u65C5\u5C65\u5C61\u7F15\u8651\u6C2F\u5F8B\u7387\u6EE4\u7EFF\u5CE6\u631B\u5B6A\u6EE6\u5375\u4E71\u63A0\u7565\u62A1\u8F6E\u4F26\u4ED1\u6CA6\u7EB6\u8BBA\u841D\u87BA\u7F57\u903B\u9523\u7BA9\u9AA1\u88F8\u843D\u6D1B\u9A86\u7EDC\u5988\u9EBB\u739B\u7801\u8682\u9A6C\u9A82\u561B\u5417\u57CB\u4E70\u9EA6\u5356\u8FC8\u8109\u7792\u9992\u86EE\u6EE1\u8513\u66FC\u6162\u6F2B"], + ["c340", "\u807E\u8081\u8082\u8085\u8088\u808A\u808D", 5, "\u8094\u8095\u8097\u8099\u809E\u80A3\u80A6\u80A7\u80A8\u80AC\u80B0\u80B3\u80B5\u80B6\u80B8\u80B9\u80BB\u80C5\u80C7", 4, "\u80CF", 6, "\u80D8\u80DF\u80E0\u80E2\u80E3\u80E6\u80EE\u80F5\u80F7\u80F9\u80FB\u80FE\u80FF\u8100\u8101\u8103\u8104\u8105\u8107\u8108\u810B"], + ["c380", "\u810C\u8115\u8117\u8119\u811B\u811C\u811D\u811F", 12, "\u812D\u812E\u8130\u8133\u8134\u8135\u8137\u8139", 4, "\u813F\u8C29\u8292\u832B\u76F2\u6C13\u5FD9\u83BD\u732B\u8305\u951A\u6BDB\u77DB\u94C6\u536F\u8302\u5192\u5E3D\u8C8C\u8D38\u4E48\u73AB\u679A\u6885\u9176\u9709\u7164\u6CA1\u7709\u5A92\u9541\u6BCF\u7F8E\u6627\u5BD0\u59B9\u5A9A\u95E8\u95F7\u4EEC\u840C\u8499\u6AAC\u76DF\u9530\u731B\u68A6\u5B5F\u772F\u919A\u9761\u7CDC\u8FF7\u8C1C\u5F25\u7C73\u79D8\u89C5\u6CCC\u871C\u5BC6\u5E42\u68C9\u7720\u7EF5\u5195\u514D\u52C9\u5A29\u7F05\u9762\u82D7\u63CF\u7784\u85D0\u79D2\u6E3A\u5E99\u5999\u8511\u706D\u6C11\u62BF\u76BF\u654F\u60AF\u95FD\u660E\u879F\u9E23\u94ED\u540D\u547D\u8C2C\u6478"], + ["c440", "\u8140", 5, "\u8147\u8149\u814D\u814E\u814F\u8152\u8156\u8157\u8158\u815B", 4, "\u8161\u8162\u8163\u8164\u8166\u8168\u816A\u816B\u816C\u816F\u8172\u8173\u8175\u8176\u8177\u8178\u8181\u8183", 4, "\u8189\u818B\u818C\u818D\u818E\u8190\u8192", 5, "\u8199\u819A\u819E", 4, "\u81A4\u81A5"], + ["c480", "\u81A7\u81A9\u81AB", 7, "\u81B4", 5, "\u81BC\u81BD\u81BE\u81BF\u81C4\u81C5\u81C7\u81C8\u81C9\u81CB\u81CD", 6, "\u6479\u8611\u6A21\u819C\u78E8\u6469\u9B54\u62B9\u672B\u83AB\u58A8\u9ED8\u6CAB\u6F20\u5BDE\u964C\u8C0B\u725F\u67D0\u62C7\u7261\u4EA9\u59C6\u6BCD\u5893\u66AE\u5E55\u52DF\u6155\u6728\u76EE\u7766\u7267\u7A46\u62FF\u54EA\u5450\u94A0\u90A3\u5A1C\u7EB3\u6C16\u4E43\u5976\u8010\u5948\u5357\u7537\u96BE\u56CA\u6320\u8111\u607C\u95F9\u6DD6\u5462\u9981\u5185\u5AE9\u80FD\u59AE\u9713\u502A\u6CE5\u5C3C\u62DF\u4F60\u533F\u817B\u9006\u6EBA\u852B\u62C8\u5E74\u78BE\u64B5\u637B\u5FF5\u5A18\u917F\u9E1F\u5C3F\u634F\u8042\u5B7D\u556E\u954A\u954D\u6D85\u60A8\u67E0\u72DE\u51DD\u5B81"], + ["c540", "\u81D4", 14, "\u81E4\u81E5\u81E6\u81E8\u81E9\u81EB\u81EE", 4, "\u81F5", 5, "\u81FD\u81FF\u8203\u8207", 4, "\u820E\u820F\u8211\u8213\u8215", 5, "\u821D\u8220\u8224\u8225\u8226\u8227\u8229\u822E\u8232\u823A\u823C\u823D\u823F"], + ["c580", "\u8240\u8241\u8242\u8243\u8245\u8246\u8248\u824A\u824C\u824D\u824E\u8250", 7, "\u8259\u825B\u825C\u825D\u825E\u8260", 7, "\u8269\u62E7\u6CDE\u725B\u626D\u94AE\u7EBD\u8113\u6D53\u519C\u5F04\u5974\u52AA\u6012\u5973\u6696\u8650\u759F\u632A\u61E6\u7CEF\u8BFA\u54E6\u6B27\u9E25\u6BB4\u85D5\u5455\u5076\u6CA4\u556A\u8DB4\u722C\u5E15\u6015\u7436\u62CD\u6392\u724C\u5F98\u6E43\u6D3E\u6500\u6F58\u76D8\u78D0\u76FC\u7554\u5224\u53DB\u4E53\u5E9E\u65C1\u802A\u80D6\u629B\u5486\u5228\u70AE\u888D\u8DD1\u6CE1\u5478\u80DA\u57F9\u88F4\u8D54\u966A\u914D\u4F69\u6C9B\u55B7\u76C6\u7830\u62A8\u70F9\u6F8E\u5F6D\u84EC\u68DA\u787C\u7BF7\u81A8\u670B\u9E4F\u6367\u78B0\u576F\u7812\u9739\u6279\u62AB\u5288\u7435\u6BD7"], + ["c640", "\u826A\u826B\u826C\u826D\u8271\u8275\u8276\u8277\u8278\u827B\u827C\u8280\u8281\u8283\u8285\u8286\u8287\u8289\u828C\u8290\u8293\u8294\u8295\u8296\u829A\u829B\u829E\u82A0\u82A2\u82A3\u82A7\u82B2\u82B5\u82B6\u82BA\u82BB\u82BC\u82BF\u82C0\u82C2\u82C3\u82C5\u82C6\u82C9\u82D0\u82D6\u82D9\u82DA\u82DD\u82E2\u82E7\u82E8\u82E9\u82EA\u82EC\u82ED\u82EE\u82F0\u82F2\u82F3\u82F5\u82F6\u82F8"], + ["c680", "\u82FA\u82FC", 4, "\u830A\u830B\u830D\u8310\u8312\u8313\u8316\u8318\u8319\u831D", 9, "\u8329\u832A\u832E\u8330\u8332\u8337\u833B\u833D\u5564\u813E\u75B2\u76AE\u5339\u75DE\u50FB\u5C41\u8B6C\u7BC7\u504F\u7247\u9A97\u98D8\u6F02\u74E2\u7968\u6487\u77A5\u62FC\u9891\u8D2B\u54C1\u8058\u4E52\u576A\u82F9\u840D\u5E73\u51ED\u74F6\u8BC4\u5C4F\u5761\u6CFC\u9887\u5A46\u7834\u9B44\u8FEB\u7C95\u5256\u6251\u94FA\u4EC6\u8386\u8461\u83E9\u84B2\u57D4\u6734\u5703\u666E\u6D66\u8C31\u66DD\u7011\u671F\u6B3A\u6816\u621A\u59BB\u4E03\u51C4\u6F06\u67D2\u6C8F\u5176\u68CB\u5947\u6B67\u7566\u5D0E\u8110\u9F50\u65D7\u7948\u7941\u9A91\u8D77\u5C82\u4E5E\u4F01\u542F\u5951\u780C\u5668\u6C14\u8FC4\u5F03\u6C7D\u6CE3\u8BAB\u6390"], + ["c740", "\u833E\u833F\u8341\u8342\u8344\u8345\u8348\u834A", 4, "\u8353\u8355", 4, "\u835D\u8362\u8370", 6, "\u8379\u837A\u837E", 6, "\u8387\u8388\u838A\u838B\u838C\u838D\u838F\u8390\u8391\u8394\u8395\u8396\u8397\u8399\u839A\u839D\u839F\u83A1", 6, "\u83AC\u83AD\u83AE"], + ["c780", "\u83AF\u83B5\u83BB\u83BE\u83BF\u83C2\u83C3\u83C4\u83C6\u83C8\u83C9\u83CB\u83CD\u83CE\u83D0\u83D1\u83D2\u83D3\u83D5\u83D7\u83D9\u83DA\u83DB\u83DE\u83E2\u83E3\u83E4\u83E6\u83E7\u83E8\u83EB\u83EC\u83ED\u6070\u6D3D\u7275\u6266\u948E\u94C5\u5343\u8FC1\u7B7E\u4EDF\u8C26\u4E7E\u9ED4\u94B1\u94B3\u524D\u6F5C\u9063\u6D45\u8C34\u5811\u5D4C\u6B20\u6B49\u67AA\u545B\u8154\u7F8C\u5899\u8537\u5F3A\u62A2\u6A47\u9539\u6572\u6084\u6865\u77A7\u4E54\u4FA8\u5DE7\u9798\u64AC\u7FD8\u5CED\u4FCF\u7A8D\u5207\u8304\u4E14\u602F\u7A83\u94A6\u4FB5\u4EB2\u79E6\u7434\u52E4\u82B9\u64D2\u79BD\u5BDD\u6C81\u9752\u8F7B\u6C22\u503E\u537F\u6E05\u64CE\u6674\u6C30\u60C5\u9877\u8BF7\u5E86\u743C\u7A77\u79CB\u4E18\u90B1\u7403\u6C42\u56DA\u914B\u6CC5\u8D8B\u533A\u86C6\u66F2\u8EAF\u5C48\u9A71\u6E20"], + ["c840", "\u83EE\u83EF\u83F3", 4, "\u83FA\u83FB\u83FC\u83FE\u83FF\u8400\u8402\u8405\u8407\u8408\u8409\u840A\u8410\u8412", 5, "\u8419\u841A\u841B\u841E", 5, "\u8429", 7, "\u8432", 5, "\u8439\u843A\u843B\u843E", 7, "\u8447\u8448\u8449"], + ["c880", "\u844A", 6, "\u8452", 4, "\u8458\u845D\u845E\u845F\u8460\u8462\u8464", 4, "\u846A\u846E\u846F\u8470\u8472\u8474\u8477\u8479\u847B\u847C\u53D6\u5A36\u9F8B\u8DA3\u53BB\u5708\u98A7\u6743\u919B\u6CC9\u5168\u75CA\u62F3\u72AC\u5238\u529D\u7F3A\u7094\u7638\u5374\u9E4A\u69B7\u786E\u96C0\u88D9\u7FA4\u7136\u71C3\u5189\u67D3\u74E4\u58E4\u6518\u56B7\u8BA9\u9976\u6270\u7ED5\u60F9\u70ED\u58EC\u4EC1\u4EBA\u5FCD\u97E7\u4EFB\u8BA4\u5203\u598A\u7EAB\u6254\u4ECD\u65E5\u620E\u8338\u84C9\u8363\u878D\u7194\u6EB6\u5BB9\u7ED2\u5197\u63C9\u67D4\u8089\u8339\u8815\u5112\u5B7A\u5982\u8FB1\u4E73\u6C5D\u5165\u8925\u8F6F\u962E\u854A\u745E\u9510\u95F0\u6DA6\u82E5\u5F31\u6492\u6D12\u8428\u816E\u9CC3\u585E\u8D5B\u4E09\u53C1"], + ["c940", "\u847D", 4, "\u8483\u8484\u8485\u8486\u848A\u848D\u848F", 7, "\u8498\u849A\u849B\u849D\u849E\u849F\u84A0\u84A2", 12, "\u84B0\u84B1\u84B3\u84B5\u84B6\u84B7\u84BB\u84BC\u84BE\u84C0\u84C2\u84C3\u84C5\u84C6\u84C7\u84C8\u84CB\u84CC\u84CE\u84CF\u84D2\u84D4\u84D5\u84D7"], + ["c980", "\u84D8", 4, "\u84DE\u84E1\u84E2\u84E4\u84E7", 4, "\u84ED\u84EE\u84EF\u84F1", 10, "\u84FD\u84FE\u8500\u8501\u8502\u4F1E\u6563\u6851\u55D3\u4E27\u6414\u9A9A\u626B\u5AC2\u745F\u8272\u6DA9\u68EE\u50E7\u838E\u7802\u6740\u5239\u6C99\u7EB1\u50BB\u5565\u715E\u7B5B\u6652\u73CA\u82EB\u6749\u5C71\u5220\u717D\u886B\u95EA\u9655\u64C5\u8D61\u81B3\u5584\u6C55\u6247\u7F2E\u5892\u4F24\u5546\u8D4F\u664C\u4E0A\u5C1A\u88F3\u68A2\u634E\u7A0D\u70E7\u828D\u52FA\u97F6\u5C11\u54E8\u90B5\u7ECD\u5962\u8D4A\u86C7\u820C\u820D\u8D66\u6444\u5C04\u6151\u6D89\u793E\u8BBE\u7837\u7533\u547B\u4F38\u8EAB\u6DF1\u5A20\u7EC5\u795E\u6C88\u5BA1\u5A76\u751A\u80BE\u614E\u6E17\u58F0\u751F\u7525\u7272\u5347\u7EF3"], + ["ca40", "\u8503", 8, "\u850D\u850E\u850F\u8510\u8512\u8514\u8515\u8516\u8518\u8519\u851B\u851C\u851D\u851E\u8520\u8522", 8, "\u852D", 9, "\u853E", 4, "\u8544\u8545\u8546\u8547\u854B", 10], + ["ca80", "\u8557\u8558\u855A\u855B\u855C\u855D\u855F", 4, "\u8565\u8566\u8567\u8569", 8, "\u8573\u8575\u8576\u8577\u8578\u857C\u857D\u857F\u8580\u8581\u7701\u76DB\u5269\u80DC\u5723\u5E08\u5931\u72EE\u65BD\u6E7F\u8BD7\u5C38\u8671\u5341\u77F3\u62FE\u65F6\u4EC0\u98DF\u8680\u5B9E\u8BC6\u53F2\u77E2\u4F7F\u5C4E\u9A76\u59CB\u5F0F\u793A\u58EB\u4E16\u67FF\u4E8B\u62ED\u8A93\u901D\u52BF\u662F\u55DC\u566C\u9002\u4ED5\u4F8D\u91CA\u9970\u6C0F\u5E02\u6043\u5BA4\u89C6\u8BD5\u6536\u624B\u9996\u5B88\u5BFF\u6388\u552E\u53D7\u7626\u517D\u852C\u67A2\u68B3\u6B8A\u6292\u8F93\u53D4\u8212\u6DD1\u758F\u4E66\u8D4E\u5B70\u719F\u85AF\u6691\u66D9\u7F72\u8700\u9ECD\u9F20\u5C5E\u672F\u8FF0\u6811\u675F\u620D\u7AD6\u5885\u5EB6\u6570\u6F31"], + ["cb40", "\u8582\u8583\u8586\u8588", 6, "\u8590", 10, "\u859D", 6, "\u85A5\u85A6\u85A7\u85A9\u85AB\u85AC\u85AD\u85B1", 5, "\u85B8\u85BA", 6, "\u85C2", 6, "\u85CA", 4, "\u85D1\u85D2"], + ["cb80", "\u85D4\u85D6", 5, "\u85DD", 6, "\u85E5\u85E6\u85E7\u85E8\u85EA", 14, "\u6055\u5237\u800D\u6454\u8870\u7529\u5E05\u6813\u62F4\u971C\u53CC\u723D\u8C01\u6C34\u7761\u7A0E\u542E\u77AC\u987A\u821C\u8BF4\u7855\u6714\u70C1\u65AF\u6495\u5636\u601D\u79C1\u53F8\u4E1D\u6B7B\u8086\u5BFA\u55E3\u56DB\u4F3A\u4F3C\u9972\u5DF3\u677E\u8038\u6002\u9882\u9001\u5B8B\u8BBC\u8BF5\u641C\u8258\u64DE\u55FD\u82CF\u9165\u4FD7\u7D20\u901F\u7C9F\u50F3\u5851\u6EAF\u5BBF\u8BC9\u8083\u9178\u849C\u7B97\u867D\u968B\u968F\u7EE5\u9AD3\u788E\u5C81\u7A57\u9042\u96A7\u795F\u5B59\u635F\u7B0B\u84D1\u68AD\u5506\u7F29\u7410\u7D22\u9501\u6240\u584C\u4ED6\u5B83\u5979\u5854"], + ["cc40", "\u85F9\u85FA\u85FC\u85FD\u85FE\u8600", 4, "\u8606", 10, "\u8612\u8613\u8614\u8615\u8617", 15, "\u8628\u862A", 13, "\u8639\u863A\u863B\u863D\u863E\u863F\u8640"], + ["cc80", "\u8641", 11, "\u8652\u8653\u8655", 4, "\u865B\u865C\u865D\u865F\u8660\u8661\u8663", 7, "\u736D\u631E\u8E4B\u8E0F\u80CE\u82D4\u62AC\u53F0\u6CF0\u915E\u592A\u6001\u6C70\u574D\u644A\u8D2A\u762B\u6EE9\u575B\u6A80\u75F0\u6F6D\u8C2D\u8C08\u5766\u6BEF\u8892\u78B3\u63A2\u53F9\u70AD\u6C64\u5858\u642A\u5802\u68E0\u819B\u5510\u7CD6\u5018\u8EBA\u6DCC\u8D9F\u70EB\u638F\u6D9B\u6ED4\u7EE6\u8404\u6843\u9003\u6DD8\u9676\u8BA8\u5957\u7279\u85E4\u817E\u75BC\u8A8A\u68AF\u5254\u8E22\u9511\u63D0\u9898\u8E44\u557C\u4F53\u66FF\u568F\u60D5\u6D95\u5243\u5C49\u5929\u6DFB\u586B\u7530\u751C\u606C\u8214\u8146\u6311\u6761\u8FE2\u773A\u8DF3\u8D34\u94C1\u5E16\u5385\u542C\u70C3"], + ["cd40", "\u866D\u866F\u8670\u8672", 6, "\u8683", 6, "\u868E", 4, "\u8694\u8696", 5, "\u869E", 4, "\u86A5\u86A6\u86AB\u86AD\u86AE\u86B2\u86B3\u86B7\u86B8\u86B9\u86BB", 4, "\u86C1\u86C2\u86C3\u86C5\u86C8\u86CC\u86CD\u86D2\u86D3\u86D5\u86D6\u86D7\u86DA\u86DC"], + ["cd80", "\u86DD\u86E0\u86E1\u86E2\u86E3\u86E5\u86E6\u86E7\u86E8\u86EA\u86EB\u86EC\u86EF\u86F5\u86F6\u86F7\u86FA\u86FB\u86FC\u86FD\u86FF\u8701\u8704\u8705\u8706\u870B\u870C\u870E\u870F\u8710\u8711\u8714\u8716\u6C40\u5EF7\u505C\u4EAD\u5EAD\u633A\u8247\u901A\u6850\u916E\u77B3\u540C\u94DC\u5F64\u7AE5\u6876\u6345\u7B52\u7EDF\u75DB\u5077\u6295\u5934\u900F\u51F8\u79C3\u7A81\u56FE\u5F92\u9014\u6D82\u5C60\u571F\u5410\u5154\u6E4D\u56E2\u63A8\u9893\u817F\u8715\u892A\u9000\u541E\u5C6F\u81C0\u62D6\u6258\u8131\u9E35\u9640\u9A6E\u9A7C\u692D\u59A5\u62D3\u553E\u6316\u54C7\u86D9\u6D3C\u5A03\u74E6\u889C\u6B6A\u5916\u8C4C\u5F2F\u6E7E\u73A9\u987D\u4E38\u70F7\u5B8C\u7897\u633D\u665A\u7696\u60CB\u5B9B\u5A49\u4E07\u8155\u6C6A\u738B\u4EA1\u6789\u7F51\u5F80\u65FA\u671B\u5FD8\u5984\u5A01"], + ["ce40", "\u8719\u871B\u871D\u871F\u8720\u8724\u8726\u8727\u8728\u872A\u872B\u872C\u872D\u872F\u8730\u8732\u8733\u8735\u8736\u8738\u8739\u873A\u873C\u873D\u8740", 6, "\u874A\u874B\u874D\u874F\u8750\u8751\u8752\u8754\u8755\u8756\u8758\u875A", 5, "\u8761\u8762\u8766", 7, "\u876F\u8771\u8772\u8773\u8775"], + ["ce80", "\u8777\u8778\u8779\u877A\u877F\u8780\u8781\u8784\u8786\u8787\u8789\u878A\u878C\u878E", 4, "\u8794\u8795\u8796\u8798", 6, "\u87A0", 4, "\u5DCD\u5FAE\u5371\u97E6\u8FDD\u6845\u56F4\u552F\u60DF\u4E3A\u6F4D\u7EF4\u82C7\u840E\u59D4\u4F1F\u4F2A\u5C3E\u7EAC\u672A\u851A\u5473\u754F\u80C3\u5582\u9B4F\u4F4D\u6E2D\u8C13\u5C09\u6170\u536B\u761F\u6E29\u868A\u6587\u95FB\u7EB9\u543B\u7A33\u7D0A\u95EE\u55E1\u7FC1\u74EE\u631D\u8717\u6DA1\u7A9D\u6211\u65A1\u5367\u63E1\u6C83\u5DEB\u545C\u94A8\u4E4C\u6C61\u8BEC\u5C4B\u65E0\u829C\u68A7\u543E\u5434\u6BCB\u6B66\u4E94\u6342\u5348\u821E\u4F0D\u4FAE\u575E\u620A\u96FE\u6664\u7269\u52FF\u52A1\u609F\u8BEF\u6614\u7199\u6790\u897F\u7852\u77FD\u6670\u563B\u5438\u9521\u727A"], + ["cf40", "\u87A5\u87A6\u87A7\u87A9\u87AA\u87AE\u87B0\u87B1\u87B2\u87B4\u87B6\u87B7\u87B8\u87B9\u87BB\u87BC\u87BE\u87BF\u87C1", 4, "\u87C7\u87C8\u87C9\u87CC", 4, "\u87D4", 6, "\u87DC\u87DD\u87DE\u87DF\u87E1\u87E2\u87E3\u87E4\u87E6\u87E7\u87E8\u87E9\u87EB\u87EC\u87ED\u87EF", 9], + ["cf80", "\u87FA\u87FB\u87FC\u87FD\u87FF\u8800\u8801\u8802\u8804", 5, "\u880B", 7, "\u8814\u8817\u8818\u8819\u881A\u881C", 4, "\u8823\u7A00\u606F\u5E0C\u6089\u819D\u5915\u60DC\u7184\u70EF\u6EAA\u6C50\u7280\u6A84\u88AD\u5E2D\u4E60\u5AB3\u559C\u94E3\u6D17\u7CFB\u9699\u620F\u7EC6\u778E\u867E\u5323\u971E\u8F96\u6687\u5CE1\u4FA0\u72ED\u4E0B\u53A6\u590F\u5413\u6380\u9528\u5148\u4ED9\u9C9C\u7EA4\u54B8\u8D24\u8854\u8237\u95F2\u6D8E\u5F26\u5ACC\u663E\u9669\u73B0\u732E\u53BF\u817A\u9985\u7FA1\u5BAA\u9677\u9650\u7EBF\u76F8\u53A2\u9576\u9999\u7BB1\u8944\u6E58\u4E61\u7FD4\u7965\u8BE6\u60F3\u54CD\u4EAB\u9879\u5DF7\u6A61\u50CF\u5411\u8C61\u8427\u785D\u9704\u524A\u54EE\u56A3\u9500\u6D88\u5BB5\u6DC6\u6653"], + ["d040", "\u8824", 13, "\u8833", 5, "\u883A\u883B\u883D\u883E\u883F\u8841\u8842\u8843\u8846", 5, "\u884E", 5, "\u8855\u8856\u8858\u885A", 6, "\u8866\u8867\u886A\u886D\u886F\u8871\u8873\u8874\u8875\u8876\u8878\u8879\u887A"], + ["d080", "\u887B\u887C\u8880\u8883\u8886\u8887\u8889\u888A\u888C\u888E\u888F\u8890\u8891\u8893\u8894\u8895\u8897", 4, "\u889D", 4, "\u88A3\u88A5", 5, "\u5C0F\u5B5D\u6821\u8096\u5578\u7B11\u6548\u6954\u4E9B\u6B47\u874E\u978B\u534F\u631F\u643A\u90AA\u659C\u80C1\u8C10\u5199\u68B0\u5378\u87F9\u61C8\u6CC4\u6CFB\u8C22\u5C51\u85AA\u82AF\u950C\u6B23\u8F9B\u65B0\u5FFB\u5FC3\u4FE1\u8845\u661F\u8165\u7329\u60FA\u5174\u5211\u578B\u5F62\u90A2\u884C\u9192\u5E78\u674F\u6027\u59D3\u5144\u51F6\u80F8\u5308\u6C79\u96C4\u718A\u4F11\u4FEE\u7F9E\u673D\u55C5\u9508\u79C0\u8896\u7EE3\u589F\u620C\u9700\u865A\u5618\u987B\u5F90\u8BB8\u84C4\u9157\u53D9\u65ED\u5E8F\u755C\u6064\u7D6E\u5A7F\u7EEA\u7EED\u8F69\u55A7\u5BA3\u60AC\u65CB\u7384"], + ["d140", "\u88AC\u88AE\u88AF\u88B0\u88B2", 4, "\u88B8\u88B9\u88BA\u88BB\u88BD\u88BE\u88BF\u88C0\u88C3\u88C4\u88C7\u88C8\u88CA\u88CB\u88CC\u88CD\u88CF\u88D0\u88D1\u88D3\u88D6\u88D7\u88DA", 4, "\u88E0\u88E1\u88E6\u88E7\u88E9", 6, "\u88F2\u88F5\u88F6\u88F7\u88FA\u88FB\u88FD\u88FF\u8900\u8901\u8903", 5], + ["d180", "\u8909\u890B", 4, "\u8911\u8914", 4, "\u891C", 4, "\u8922\u8923\u8924\u8926\u8927\u8928\u8929\u892C\u892D\u892E\u892F\u8931\u8932\u8933\u8935\u8937\u9009\u7663\u7729\u7EDA\u9774\u859B\u5B66\u7A74\u96EA\u8840\u52CB\u718F\u5FAA\u65EC\u8BE2\u5BFB\u9A6F\u5DE1\u6B89\u6C5B\u8BAD\u8BAF\u900A\u8FC5\u538B\u62BC\u9E26\u9E2D\u5440\u4E2B\u82BD\u7259\u869C\u5D16\u8859\u6DAF\u96C5\u54D1\u4E9A\u8BB6\u7109\u54BD\u9609\u70DF\u6DF9\u76D0\u4E25\u7814\u8712\u5CA9\u5EF6\u8A00\u989C\u960E\u708E\u6CBF\u5944\u63A9\u773C\u884D\u6F14\u8273\u5830\u71D5\u538C\u781A\u96C1\u5501\u5F66\u7130\u5BB4\u8C1A\u9A8C\u6B83\u592E\u9E2F\u79E7\u6768\u626C\u4F6F\u75A1\u7F8A\u6D0B\u9633\u6C27\u4EF0\u75D2\u517B\u6837\u6F3E\u9080\u8170\u5996\u7476"], + ["d240", "\u8938", 8, "\u8942\u8943\u8945", 24, "\u8960", 5, "\u8967", 19, "\u897C"], + ["d280", "\u897D\u897E\u8980\u8982\u8984\u8985\u8987", 26, "\u6447\u5C27\u9065\u7A91\u8C23\u59DA\u54AC\u8200\u836F\u8981\u8000\u6930\u564E\u8036\u7237\u91CE\u51B6\u4E5F\u9875\u6396\u4E1A\u53F6\u66F3\u814B\u591C\u6DB2\u4E00\u58F9\u533B\u63D6\u94F1\u4F9D\u4F0A\u8863\u9890\u5937\u9057\u79FB\u4EEA\u80F0\u7591\u6C82\u5B9C\u59E8\u5F5D\u6905\u8681\u501A\u5DF2\u4E59\u77E3\u4EE5\u827A\u6291\u6613\u9091\u5C79\u4EBF\u5F79\u81C6\u9038\u8084\u75AB\u4EA6\u88D4\u610F\u6BC5\u5FC6\u4E49\u76CA\u6EA2\u8BE3\u8BAE\u8C0A\u8BD1\u5F02\u7FFC\u7FCC\u7ECE\u8335\u836B\u56E0\u6BB7\u97F3\u9634\u59FB\u541F\u94F6\u6DEB\u5BC5\u996E\u5C39\u5F15\u9690"], + ["d340", "\u89A2", 30, "\u89C3\u89CD\u89D3\u89D4\u89D5\u89D7\u89D8\u89D9\u89DB\u89DD\u89DF\u89E0\u89E1\u89E2\u89E4\u89E7\u89E8\u89E9\u89EA\u89EC\u89ED\u89EE\u89F0\u89F1\u89F2\u89F4", 6], + ["d380", "\u89FB", 4, "\u8A01", 5, "\u8A08", 21, "\u5370\u82F1\u6A31\u5A74\u9E70\u5E94\u7F28\u83B9\u8424\u8425\u8367\u8747\u8FCE\u8D62\u76C8\u5F71\u9896\u786C\u6620\u54DF\u62E5\u4F63\u81C3\u75C8\u5EB8\u96CD\u8E0A\u86F9\u548F\u6CF3\u6D8C\u6C38\u607F\u52C7\u7528\u5E7D\u4F18\u60A0\u5FE7\u5C24\u7531\u90AE\u94C0\u72B9\u6CB9\u6E38\u9149\u6709\u53CB\u53F3\u4F51\u91C9\u8BF1\u53C8\u5E7C\u8FC2\u6DE4\u4E8E\u76C2\u6986\u865E\u611A\u8206\u4F59\u4FDE\u903E\u9C7C\u6109\u6E1D\u6E14\u9685\u4E88\u5A31\u96E8\u4E0E\u5C7F\u79B9\u5B87\u8BED\u7FBD\u7389\u57DF\u828B\u90C1\u5401\u9047\u55BB\u5CEA\u5FA1\u6108\u6B32\u72F1\u80B2\u8A89"], + ["d440", "\u8A1E", 31, "\u8A3F", 8, "\u8A49", 21], + ["d480", "\u8A5F", 25, "\u8A7A", 6, "\u6D74\u5BD3\u88D5\u9884\u8C6B\u9A6D\u9E33\u6E0A\u51A4\u5143\u57A3\u8881\u539F\u63F4\u8F95\u56ED\u5458\u5706\u733F\u6E90\u7F18\u8FDC\u82D1\u613F\u6028\u9662\u66F0\u7EA6\u8D8A\u8DC3\u94A5\u5CB3\u7CA4\u6708\u60A6\u9605\u8018\u4E91\u90E7\u5300\u9668\u5141\u8FD0\u8574\u915D\u6655\u97F5\u5B55\u531D\u7838\u6742\u683D\u54C9\u707E\u5BB0\u8F7D\u518D\u5728\u54B1\u6512\u6682\u8D5E\u8D43\u810F\u846C\u906D\u7CDF\u51FF\u85FB\u67A3\u65E9\u6FA1\u86A4\u8E81\u566A\u9020\u7682\u7076\u71E5\u8D23\u62E9\u5219\u6CFD\u8D3C\u600E\u589E\u618E\u66FE\u8D60\u624E\u55B3\u6E23\u672D\u8F67"], + ["d540", "\u8A81", 7, "\u8A8B", 7, "\u8A94", 46], + ["d580", "\u8AC3", 32, "\u94E1\u95F8\u7728\u6805\u69A8\u548B\u4E4D\u70B8\u8BC8\u6458\u658B\u5B85\u7A84\u503A\u5BE8\u77BB\u6BE1\u8A79\u7C98\u6CBE\u76CF\u65A9\u8F97\u5D2D\u5C55\u8638\u6808\u5360\u6218\u7AD9\u6E5B\u7EFD\u6A1F\u7AE0\u5F70\u6F33\u5F20\u638C\u6DA8\u6756\u4E08\u5E10\u8D26\u4ED7\u80C0\u7634\u969C\u62DB\u662D\u627E\u6CBC\u8D75\u7167\u7F69\u5146\u8087\u53EC\u906E\u6298\u54F2\u86F0\u8F99\u8005\u9517\u8517\u8FD9\u6D59\u73CD\u659F\u771F\u7504\u7827\u81FB\u8D1E\u9488\u4FA6\u6795\u75B9\u8BCA\u9707\u632F\u9547\u9635\u84B8\u6323\u7741\u5F81\u72F0\u4E89\u6014\u6574\u62EF\u6B63\u653F"], + ["d640", "\u8AE4", 34, "\u8B08", 27], + ["d680", "\u8B24\u8B25\u8B27", 30, "\u5E27\u75C7\u90D1\u8BC1\u829D\u679D\u652F\u5431\u8718\u77E5\u80A2\u8102\u6C41\u4E4B\u7EC7\u804C\u76F4\u690D\u6B96\u6267\u503C\u4F84\u5740\u6307\u6B62\u8DBE\u53EA\u65E8\u7EB8\u5FD7\u631A\u63B7\u81F3\u81F4\u7F6E\u5E1C\u5CD9\u5236\u667A\u79E9\u7A1A\u8D28\u7099\u75D4\u6EDE\u6CBB\u7A92\u4E2D\u76C5\u5FE0\u949F\u8877\u7EC8\u79CD\u80BF\u91CD\u4EF2\u4F17\u821F\u5468\u5DDE\u6D32\u8BCC\u7CA5\u8F74\u8098\u5E1A\u5492\u76B1\u5B99\u663C\u9AA4\u73E0\u682A\u86DB\u6731\u732A\u8BF8\u8BDB\u9010\u7AF9\u70DB\u716E\u62C4\u77A9\u5631\u4E3B\u8457\u67F1\u52A9\u86C0\u8D2E\u94F8\u7B51"], + ["d740", "\u8B46", 31, "\u8B67", 4, "\u8B6D", 25], + ["d780", "\u8B87", 24, "\u8BAC\u8BB1\u8BBB\u8BC7\u8BD0\u8BEA\u8C09\u8C1E\u4F4F\u6CE8\u795D\u9A7B\u6293\u722A\u62FD\u4E13\u7816\u8F6C\u64B0\u8D5A\u7BC6\u6869\u5E84\u88C5\u5986\u649E\u58EE\u72B6\u690E\u9525\u8FFD\u8D58\u5760\u7F00\u8C06\u51C6\u6349\u62D9\u5353\u684C\u7422\u8301\u914C\u5544\u7740\u707C\u6D4A\u5179\u54A8\u8D44\u59FF\u6ECB\u6DC4\u5B5C\u7D2B\u4ED4\u7C7D\u6ED3\u5B50\u81EA\u6E0D\u5B57\u9B03\u68D5\u8E2A\u5B97\u7EFC\u603B\u7EB5\u90B9\u8D70\u594F\u63CD\u79DF\u8DB3\u5352\u65CF\u7956\u8BC5\u963B\u7EC4\u94BB\u7E82\u5634\u9189\u6700\u7F6A\u5C0A\u9075\u6628\u5DE6\u4F50\u67DE\u505A\u4F5C\u5750\u5EA7"], + ["d840", "\u8C38", 8, "\u8C42\u8C43\u8C44\u8C45\u8C48\u8C4A\u8C4B\u8C4D", 7, "\u8C56\u8C57\u8C58\u8C59\u8C5B", 5, "\u8C63", 6, "\u8C6C", 6, "\u8C74\u8C75\u8C76\u8C77\u8C7B", 6, "\u8C83\u8C84\u8C86\u8C87"], + ["d880", "\u8C88\u8C8B\u8C8D", 6, "\u8C95\u8C96\u8C97\u8C99", 20, "\u4E8D\u4E0C\u5140\u4E10\u5EFF\u5345\u4E15\u4E98\u4E1E\u9B32\u5B6C\u5669\u4E28\u79BA\u4E3F\u5315\u4E47\u592D\u723B\u536E\u6C10\u56DF\u80E4\u9997\u6BD3\u777E\u9F17\u4E36\u4E9F\u9F10\u4E5C\u4E69\u4E93\u8288\u5B5B\u556C\u560F\u4EC4\u538D\u539D\u53A3\u53A5\u53AE\u9765\u8D5D\u531A\u53F5\u5326\u532E\u533E\u8D5C\u5366\u5363\u5202\u5208\u520E\u522D\u5233\u523F\u5240\u524C\u525E\u5261\u525C\u84AF\u527D\u5282\u5281\u5290\u5293\u5182\u7F54\u4EBB\u4EC3\u4EC9\u4EC2\u4EE8\u4EE1\u4EEB\u4EDE\u4F1B\u4EF3\u4F22\u4F64\u4EF5\u4F25\u4F27\u4F09\u4F2B\u4F5E\u4F67\u6538\u4F5A\u4F5D"], + ["d940", "\u8CAE", 62], + ["d980", "\u8CED", 32, "\u4F5F\u4F57\u4F32\u4F3D\u4F76\u4F74\u4F91\u4F89\u4F83\u4F8F\u4F7E\u4F7B\u4FAA\u4F7C\u4FAC\u4F94\u4FE6\u4FE8\u4FEA\u4FC5\u4FDA\u4FE3\u4FDC\u4FD1\u4FDF\u4FF8\u5029\u504C\u4FF3\u502C\u500F\u502E\u502D\u4FFE\u501C\u500C\u5025\u5028\u507E\u5043\u5055\u5048\u504E\u506C\u507B\u50A5\u50A7\u50A9\u50BA\u50D6\u5106\u50ED\u50EC\u50E6\u50EE\u5107\u510B\u4EDD\u6C3D\u4F58\u4F65\u4FCE\u9FA0\u6C46\u7C74\u516E\u5DFD\u9EC9\u9998\u5181\u5914\u52F9\u530D\u8A07\u5310\u51EB\u5919\u5155\u4EA0\u5156\u4EB3\u886E\u88A4\u4EB5\u8114\u88D2\u7980\u5B34\u8803\u7FB8\u51AB\u51B1\u51BD\u51BC"], + ["da40", "\u8D0E", 14, "\u8D20\u8D51\u8D52\u8D57\u8D5F\u8D65\u8D68\u8D69\u8D6A\u8D6C\u8D6E\u8D6F\u8D71\u8D72\u8D78", 8, "\u8D82\u8D83\u8D86\u8D87\u8D88\u8D89\u8D8C", 4, "\u8D92\u8D93\u8D95", 9, "\u8DA0\u8DA1"], + ["da80", "\u8DA2\u8DA4", 12, "\u8DB2\u8DB6\u8DB7\u8DB9\u8DBB\u8DBD\u8DC0\u8DC1\u8DC2\u8DC5\u8DC7\u8DC8\u8DC9\u8DCA\u8DCD\u8DD0\u8DD2\u8DD3\u8DD4\u51C7\u5196\u51A2\u51A5\u8BA0\u8BA6\u8BA7\u8BAA\u8BB4\u8BB5\u8BB7\u8BC2\u8BC3\u8BCB\u8BCF\u8BCE\u8BD2\u8BD3\u8BD4\u8BD6\u8BD8\u8BD9\u8BDC\u8BDF\u8BE0\u8BE4\u8BE8\u8BE9\u8BEE\u8BF0\u8BF3\u8BF6\u8BF9\u8BFC\u8BFF\u8C00\u8C02\u8C04\u8C07\u8C0C\u8C0F\u8C11\u8C12\u8C14\u8C15\u8C16\u8C19\u8C1B\u8C18\u8C1D\u8C1F\u8C20\u8C21\u8C25\u8C27\u8C2A\u8C2B\u8C2E\u8C2F\u8C32\u8C33\u8C35\u8C36\u5369\u537A\u961D\u9622\u9621\u9631\u962A\u963D\u963C\u9642\u9649\u9654\u965F\u9667\u966C\u9672\u9674\u9688\u968D\u9697\u96B0\u9097\u909B\u909D\u9099\u90AC\u90A1\u90B4\u90B3\u90B6\u90BA"], + ["db40", "\u8DD5\u8DD8\u8DD9\u8DDC\u8DE0\u8DE1\u8DE2\u8DE5\u8DE6\u8DE7\u8DE9\u8DED\u8DEE\u8DF0\u8DF1\u8DF2\u8DF4\u8DF6\u8DFC\u8DFE", 6, "\u8E06\u8E07\u8E08\u8E0B\u8E0D\u8E0E\u8E10\u8E11\u8E12\u8E13\u8E15", 7, "\u8E20\u8E21\u8E24", 4, "\u8E2B\u8E2D\u8E30\u8E32\u8E33\u8E34\u8E36\u8E37\u8E38\u8E3B\u8E3C\u8E3E"], + ["db80", "\u8E3F\u8E43\u8E45\u8E46\u8E4C", 4, "\u8E53", 5, "\u8E5A", 11, "\u8E67\u8E68\u8E6A\u8E6B\u8E6E\u8E71\u90B8\u90B0\u90CF\u90C5\u90BE\u90D0\u90C4\u90C7\u90D3\u90E6\u90E2\u90DC\u90D7\u90DB\u90EB\u90EF\u90FE\u9104\u9122\u911E\u9123\u9131\u912F\u9139\u9143\u9146\u520D\u5942\u52A2\u52AC\u52AD\u52BE\u54FF\u52D0\u52D6\u52F0\u53DF\u71EE\u77CD\u5EF4\u51F5\u51FC\u9B2F\u53B6\u5F01\u755A\u5DEF\u574C\u57A9\u57A1\u587E\u58BC\u58C5\u58D1\u5729\u572C\u572A\u5733\u5739\u572E\u572F\u575C\u573B\u5742\u5769\u5785\u576B\u5786\u577C\u577B\u5768\u576D\u5776\u5773\u57AD\u57A4\u578C\u57B2\u57CF\u57A7\u57B4\u5793\u57A0\u57D5\u57D8\u57DA\u57D9\u57D2\u57B8\u57F4\u57EF\u57F8\u57E4\u57DD"], + ["dc40", "\u8E73\u8E75\u8E77", 4, "\u8E7D\u8E7E\u8E80\u8E82\u8E83\u8E84\u8E86\u8E88", 6, "\u8E91\u8E92\u8E93\u8E95", 6, "\u8E9D\u8E9F", 11, "\u8EAD\u8EAE\u8EB0\u8EB1\u8EB3", 6, "\u8EBB", 7], + ["dc80", "\u8EC3", 10, "\u8ECF", 21, "\u580B\u580D\u57FD\u57ED\u5800\u581E\u5819\u5844\u5820\u5865\u586C\u5881\u5889\u589A\u5880\u99A8\u9F19\u61FF\u8279\u827D\u827F\u828F\u828A\u82A8\u8284\u828E\u8291\u8297\u8299\u82AB\u82B8\u82BE\u82B0\u82C8\u82CA\u82E3\u8298\u82B7\u82AE\u82CB\u82CC\u82C1\u82A9\u82B4\u82A1\u82AA\u829F\u82C4\u82CE\u82A4\u82E1\u8309\u82F7\u82E4\u830F\u8307\u82DC\u82F4\u82D2\u82D8\u830C\u82FB\u82D3\u8311\u831A\u8306\u8314\u8315\u82E0\u82D5\u831C\u8351\u835B\u835C\u8308\u8392\u833C\u8334\u8331\u839B\u835E\u832F\u834F\u8347\u8343\u835F\u8340\u8317\u8360\u832D\u833A\u8333\u8366\u8365"], + ["dd40", "\u8EE5", 62], + ["dd80", "\u8F24", 32, "\u8368\u831B\u8369\u836C\u836A\u836D\u836E\u83B0\u8378\u83B3\u83B4\u83A0\u83AA\u8393\u839C\u8385\u837C\u83B6\u83A9\u837D\u83B8\u837B\u8398\u839E\u83A8\u83BA\u83BC\u83C1\u8401\u83E5\u83D8\u5807\u8418\u840B\u83DD\u83FD\u83D6\u841C\u8438\u8411\u8406\u83D4\u83DF\u840F\u8403\u83F8\u83F9\u83EA\u83C5\u83C0\u8426\u83F0\u83E1\u845C\u8451\u845A\u8459\u8473\u8487\u8488\u847A\u8489\u8478\u843C\u8446\u8469\u8476\u848C\u848E\u8431\u846D\u84C1\u84CD\u84D0\u84E6\u84BD\u84D3\u84CA\u84BF\u84BA\u84E0\u84A1\u84B9\u84B4\u8497\u84E5\u84E3\u850C\u750D\u8538\u84F0\u8539\u851F\u853A"], + ["de40", "\u8F45", 32, "\u8F6A\u8F80\u8F8C\u8F92\u8F9D\u8FA0\u8FA1\u8FA2\u8FA4\u8FA5\u8FA6\u8FA7\u8FAA\u8FAC\u8FAD\u8FAE\u8FAF\u8FB2\u8FB3\u8FB4\u8FB5\u8FB7\u8FB8\u8FBA\u8FBB\u8FBC\u8FBF\u8FC0\u8FC3\u8FC6"], + ["de80", "\u8FC9", 4, "\u8FCF\u8FD2\u8FD6\u8FD7\u8FDA\u8FE0\u8FE1\u8FE3\u8FE7\u8FEC\u8FEF\u8FF1\u8FF2\u8FF4\u8FF5\u8FF6\u8FFA\u8FFB\u8FFC\u8FFE\u8FFF\u9007\u9008\u900C\u900E\u9013\u9015\u9018\u8556\u853B\u84FF\u84FC\u8559\u8548\u8568\u8564\u855E\u857A\u77A2\u8543\u8572\u857B\u85A4\u85A8\u8587\u858F\u8579\u85AE\u859C\u8585\u85B9\u85B7\u85B0\u85D3\u85C1\u85DC\u85FF\u8627\u8605\u8629\u8616\u863C\u5EFE\u5F08\u593C\u5941\u8037\u5955\u595A\u5958\u530F\u5C22\u5C25\u5C2C\u5C34\u624C\u626A\u629F\u62BB\u62CA\u62DA\u62D7\u62EE\u6322\u62F6\u6339\u634B\u6343\u63AD\u63F6\u6371\u637A\u638E\u63B4\u636D\u63AC\u638A\u6369\u63AE\u63BC\u63F2\u63F8\u63E0\u63FF\u63C4\u63DE\u63CE\u6452\u63C6\u63BE\u6445\u6441\u640B\u641B\u6420\u640C\u6426\u6421\u645E\u6484\u646D\u6496"], + ["df40", "\u9019\u901C\u9023\u9024\u9025\u9027", 5, "\u9030", 4, "\u9037\u9039\u903A\u903D\u903F\u9040\u9043\u9045\u9046\u9048", 4, "\u904E\u9054\u9055\u9056\u9059\u905A\u905C", 5, "\u9064\u9066\u9067\u9069\u906A\u906B\u906C\u906F", 4, "\u9076", 6, "\u907E\u9081"], + ["df80", "\u9084\u9085\u9086\u9087\u9089\u908A\u908C", 4, "\u9092\u9094\u9096\u9098\u909A\u909C\u909E\u909F\u90A0\u90A4\u90A5\u90A7\u90A8\u90A9\u90AB\u90AD\u90B2\u90B7\u90BC\u90BD\u90BF\u90C0\u647A\u64B7\u64B8\u6499\u64BA\u64C0\u64D0\u64D7\u64E4\u64E2\u6509\u6525\u652E\u5F0B\u5FD2\u7519\u5F11\u535F\u53F1\u53FD\u53E9\u53E8\u53FB\u5412\u5416\u5406\u544B\u5452\u5453\u5454\u5456\u5443\u5421\u5457\u5459\u5423\u5432\u5482\u5494\u5477\u5471\u5464\u549A\u549B\u5484\u5476\u5466\u549D\u54D0\u54AD\u54C2\u54B4\u54D2\u54A7\u54A6\u54D3\u54D4\u5472\u54A3\u54D5\u54BB\u54BF\u54CC\u54D9\u54DA\u54DC\u54A9\u54AA\u54A4\u54DD\u54CF\u54DE\u551B\u54E7\u5520\u54FD\u5514\u54F3\u5522\u5523\u550F\u5511\u5527\u552A\u5567\u558F\u55B5\u5549\u556D\u5541\u5555\u553F\u5550\u553C"], + ["e040", "\u90C2\u90C3\u90C6\u90C8\u90C9\u90CB\u90CC\u90CD\u90D2\u90D4\u90D5\u90D6\u90D8\u90D9\u90DA\u90DE\u90DF\u90E0\u90E3\u90E4\u90E5\u90E9\u90EA\u90EC\u90EE\u90F0\u90F1\u90F2\u90F3\u90F5\u90F6\u90F7\u90F9\u90FA\u90FB\u90FC\u90FF\u9100\u9101\u9103\u9105", 19, "\u911A\u911B\u911C"], + ["e080", "\u911D\u911F\u9120\u9121\u9124", 10, "\u9130\u9132", 6, "\u913A", 8, "\u9144\u5537\u5556\u5575\u5576\u5577\u5533\u5530\u555C\u558B\u55D2\u5583\u55B1\u55B9\u5588\u5581\u559F\u557E\u55D6\u5591\u557B\u55DF\u55BD\u55BE\u5594\u5599\u55EA\u55F7\u55C9\u561F\u55D1\u55EB\u55EC\u55D4\u55E6\u55DD\u55C4\u55EF\u55E5\u55F2\u55F3\u55CC\u55CD\u55E8\u55F5\u55E4\u8F94\u561E\u5608\u560C\u5601\u5624\u5623\u55FE\u5600\u5627\u562D\u5658\u5639\u5657\u562C\u564D\u5662\u5659\u565C\u564C\u5654\u5686\u5664\u5671\u566B\u567B\u567C\u5685\u5693\u56AF\u56D4\u56D7\u56DD\u56E1\u56F5\u56EB\u56F9\u56FF\u5704\u570A\u5709\u571C\u5E0F\u5E19\u5E14\u5E11\u5E31\u5E3B\u5E3C"], + ["e140", "\u9145\u9147\u9148\u9151\u9153\u9154\u9155\u9156\u9158\u9159\u915B\u915C\u915F\u9160\u9166\u9167\u9168\u916B\u916D\u9173\u917A\u917B\u917C\u9180", 4, "\u9186\u9188\u918A\u918E\u918F\u9193", 6, "\u919C", 5, "\u91A4", 5, "\u91AB\u91AC\u91B0\u91B1\u91B2\u91B3\u91B6\u91B7\u91B8\u91B9\u91BB"], + ["e180", "\u91BC", 10, "\u91C8\u91CB\u91D0\u91D2", 9, "\u91DD", 8, "\u5E37\u5E44\u5E54\u5E5B\u5E5E\u5E61\u5C8C\u5C7A\u5C8D\u5C90\u5C96\u5C88\u5C98\u5C99\u5C91\u5C9A\u5C9C\u5CB5\u5CA2\u5CBD\u5CAC\u5CAB\u5CB1\u5CA3\u5CC1\u5CB7\u5CC4\u5CD2\u5CE4\u5CCB\u5CE5\u5D02\u5D03\u5D27\u5D26\u5D2E\u5D24\u5D1E\u5D06\u5D1B\u5D58\u5D3E\u5D34\u5D3D\u5D6C\u5D5B\u5D6F\u5D5D\u5D6B\u5D4B\u5D4A\u5D69\u5D74\u5D82\u5D99\u5D9D\u8C73\u5DB7\u5DC5\u5F73\u5F77\u5F82\u5F87\u5F89\u5F8C\u5F95\u5F99\u5F9C\u5FA8\u5FAD\u5FB5\u5FBC\u8862\u5F61\u72AD\u72B0\u72B4\u72B7\u72B8\u72C3\u72C1\u72CE\u72CD\u72D2\u72E8\u72EF\u72E9\u72F2\u72F4\u72F7\u7301\u72F3\u7303\u72FA"], + ["e240", "\u91E6", 62], + ["e280", "\u9225", 32, "\u72FB\u7317\u7313\u7321\u730A\u731E\u731D\u7315\u7322\u7339\u7325\u732C\u7338\u7331\u7350\u734D\u7357\u7360\u736C\u736F\u737E\u821B\u5925\u98E7\u5924\u5902\u9963\u9967", 5, "\u9974\u9977\u997D\u9980\u9984\u9987\u998A\u998D\u9990\u9991\u9993\u9994\u9995\u5E80\u5E91\u5E8B\u5E96\u5EA5\u5EA0\u5EB9\u5EB5\u5EBE\u5EB3\u8D53\u5ED2\u5ED1\u5EDB\u5EE8\u5EEA\u81BA\u5FC4\u5FC9\u5FD6\u5FCF\u6003\u5FEE\u6004\u5FE1\u5FE4\u5FFE\u6005\u6006\u5FEA\u5FED\u5FF8\u6019\u6035\u6026\u601B\u600F\u600D\u6029\u602B\u600A\u603F\u6021\u6078\u6079\u607B\u607A\u6042"], + ["e340", "\u9246", 45, "\u9275", 16], + ["e380", "\u9286", 7, "\u928F", 24, "\u606A\u607D\u6096\u609A\u60AD\u609D\u6083\u6092\u608C\u609B\u60EC\u60BB\u60B1\u60DD\u60D8\u60C6\u60DA\u60B4\u6120\u6126\u6115\u6123\u60F4\u6100\u610E\u612B\u614A\u6175\u61AC\u6194\u61A7\u61B7\u61D4\u61F5\u5FDD\u96B3\u95E9\u95EB\u95F1\u95F3\u95F5\u95F6\u95FC\u95FE\u9603\u9604\u9606\u9608\u960A\u960B\u960C\u960D\u960F\u9612\u9615\u9616\u9617\u9619\u961A\u4E2C\u723F\u6215\u6C35\u6C54\u6C5C\u6C4A\u6CA3\u6C85\u6C90\u6C94\u6C8C\u6C68\u6C69\u6C74\u6C76\u6C86\u6CA9\u6CD0\u6CD4\u6CAD\u6CF7\u6CF8\u6CF1\u6CD7\u6CB2\u6CE0\u6CD6\u6CFA\u6CEB\u6CEE\u6CB1\u6CD3\u6CEF\u6CFE"], + ["e440", "\u92A8", 5, "\u92AF", 24, "\u92C9", 31], + ["e480", "\u92E9", 32, "\u6D39\u6D27\u6D0C\u6D43\u6D48\u6D07\u6D04\u6D19\u6D0E\u6D2B\u6D4D\u6D2E\u6D35\u6D1A\u6D4F\u6D52\u6D54\u6D33\u6D91\u6D6F\u6D9E\u6DA0\u6D5E\u6D93\u6D94\u6D5C\u6D60\u6D7C\u6D63\u6E1A\u6DC7\u6DC5\u6DDE\u6E0E\u6DBF\u6DE0\u6E11\u6DE6\u6DDD\u6DD9\u6E16\u6DAB\u6E0C\u6DAE\u6E2B\u6E6E\u6E4E\u6E6B\u6EB2\u6E5F\u6E86\u6E53\u6E54\u6E32\u6E25\u6E44\u6EDF\u6EB1\u6E98\u6EE0\u6F2D\u6EE2\u6EA5\u6EA7\u6EBD\u6EBB\u6EB7\u6ED7\u6EB4\u6ECF\u6E8F\u6EC2\u6E9F\u6F62\u6F46\u6F47\u6F24\u6F15\u6EF9\u6F2F\u6F36\u6F4B\u6F74\u6F2A\u6F09\u6F29\u6F89\u6F8D\u6F8C\u6F78\u6F72\u6F7C\u6F7A\u6FD1"], + ["e540", "\u930A", 51, "\u933F", 10], + ["e580", "\u934A", 31, "\u936B\u6FC9\u6FA7\u6FB9\u6FB6\u6FC2\u6FE1\u6FEE\u6FDE\u6FE0\u6FEF\u701A\u7023\u701B\u7039\u7035\u704F\u705E\u5B80\u5B84\u5B95\u5B93\u5BA5\u5BB8\u752F\u9A9E\u6434\u5BE4\u5BEE\u8930\u5BF0\u8E47\u8B07\u8FB6\u8FD3\u8FD5\u8FE5\u8FEE\u8FE4\u8FE9\u8FE6\u8FF3\u8FE8\u9005\u9004\u900B\u9026\u9011\u900D\u9016\u9021\u9035\u9036\u902D\u902F\u9044\u9051\u9052\u9050\u9068\u9058\u9062\u905B\u66B9\u9074\u907D\u9082\u9088\u9083\u908B\u5F50\u5F57\u5F56\u5F58\u5C3B\u54AB\u5C50\u5C59\u5B71\u5C63\u5C66\u7FBC\u5F2A\u5F29\u5F2D\u8274\u5F3C\u9B3B\u5C6E\u5981\u5983\u598D\u59A9\u59AA\u59A3"], + ["e640", "\u936C", 34, "\u9390", 27], + ["e680", "\u93AC", 29, "\u93CB\u93CC\u93CD\u5997\u59CA\u59AB\u599E\u59A4\u59D2\u59B2\u59AF\u59D7\u59BE\u5A05\u5A06\u59DD\u5A08\u59E3\u59D8\u59F9\u5A0C\u5A09\u5A32\u5A34\u5A11\u5A23\u5A13\u5A40\u5A67\u5A4A\u5A55\u5A3C\u5A62\u5A75\u80EC\u5AAA\u5A9B\u5A77\u5A7A\u5ABE\u5AEB\u5AB2\u5AD2\u5AD4\u5AB8\u5AE0\u5AE3\u5AF1\u5AD6\u5AE6\u5AD8\u5ADC\u5B09\u5B17\u5B16\u5B32\u5B37\u5B40\u5C15\u5C1C\u5B5A\u5B65\u5B73\u5B51\u5B53\u5B62\u9A75\u9A77\u9A78\u9A7A\u9A7F\u9A7D\u9A80\u9A81\u9A85\u9A88\u9A8A\u9A90\u9A92\u9A93\u9A96\u9A98\u9A9B\u9A9C\u9A9D\u9A9F\u9AA0\u9AA2\u9AA3\u9AA5\u9AA7\u7E9F\u7EA1\u7EA3\u7EA5\u7EA8\u7EA9"], + ["e740", "\u93CE", 7, "\u93D7", 54], + ["e780", "\u940E", 32, "\u7EAD\u7EB0\u7EBE\u7EC0\u7EC1\u7EC2\u7EC9\u7ECB\u7ECC\u7ED0\u7ED4\u7ED7\u7EDB\u7EE0\u7EE1\u7EE8\u7EEB\u7EEE\u7EEF\u7EF1\u7EF2\u7F0D\u7EF6\u7EFA\u7EFB\u7EFE\u7F01\u7F02\u7F03\u7F07\u7F08\u7F0B\u7F0C\u7F0F\u7F11\u7F12\u7F17\u7F19\u7F1C\u7F1B\u7F1F\u7F21", 6, "\u7F2A\u7F2B\u7F2C\u7F2D\u7F2F", 4, "\u7F35\u5E7A\u757F\u5DDB\u753E\u9095\u738E\u7391\u73AE\u73A2\u739F\u73CF\u73C2\u73D1\u73B7\u73B3\u73C0\u73C9\u73C8\u73E5\u73D9\u987C\u740A\u73E9\u73E7\u73DE\u73BA\u73F2\u740F\u742A\u745B\u7426\u7425\u7428\u7430\u742E\u742C"], + ["e840", "\u942F", 14, "\u943F", 43, "\u946C\u946D\u946E\u946F"], + ["e880", "\u9470", 20, "\u9491\u9496\u9498\u94C7\u94CF\u94D3\u94D4\u94DA\u94E6\u94FB\u951C\u9520\u741B\u741A\u7441\u745C\u7457\u7455\u7459\u7477\u746D\u747E\u749C\u748E\u7480\u7481\u7487\u748B\u749E\u74A8\u74A9\u7490\u74A7\u74D2\u74BA\u97EA\u97EB\u97EC\u674C\u6753\u675E\u6748\u6769\u67A5\u6787\u676A\u6773\u6798\u67A7\u6775\u67A8\u679E\u67AD\u678B\u6777\u677C\u67F0\u6809\u67D8\u680A\u67E9\u67B0\u680C\u67D9\u67B5\u67DA\u67B3\u67DD\u6800\u67C3\u67B8\u67E2\u680E\u67C1\u67FD\u6832\u6833\u6860\u6861\u684E\u6862\u6844\u6864\u6883\u681D\u6855\u6866\u6841\u6867\u6840\u683E\u684A\u6849\u6829\u68B5\u688F\u6874\u6877\u6893\u686B\u68C2\u696E\u68FC\u691F\u6920\u68F9"], + ["e940", "\u9527\u9533\u953D\u9543\u9548\u954B\u9555\u955A\u9560\u956E\u9574\u9575\u9577", 7, "\u9580", 42], + ["e980", "\u95AB", 32, "\u6924\u68F0\u690B\u6901\u6957\u68E3\u6910\u6971\u6939\u6960\u6942\u695D\u6984\u696B\u6980\u6998\u6978\u6934\u69CC\u6987\u6988\u69CE\u6989\u6966\u6963\u6979\u699B\u69A7\u69BB\u69AB\u69AD\u69D4\u69B1\u69C1\u69CA\u69DF\u6995\u69E0\u698D\u69FF\u6A2F\u69ED\u6A17\u6A18\u6A65\u69F2\u6A44\u6A3E\u6AA0\u6A50\u6A5B\u6A35\u6A8E\u6A79\u6A3D\u6A28\u6A58\u6A7C\u6A91\u6A90\u6AA9\u6A97\u6AAB\u7337\u7352\u6B81\u6B82\u6B87\u6B84\u6B92\u6B93\u6B8D\u6B9A\u6B9B\u6BA1\u6BAA\u8F6B\u8F6D\u8F71\u8F72\u8F73\u8F75\u8F76\u8F78\u8F77\u8F79\u8F7A\u8F7C\u8F7E\u8F81\u8F82\u8F84\u8F87\u8F8B"], + ["ea40", "\u95CC", 27, "\u95EC\u95FF\u9607\u9613\u9618\u961B\u961E\u9620\u9623", 6, "\u962B\u962C\u962D\u962F\u9630\u9637\u9638\u9639\u963A\u963E\u9641\u9643\u964A\u964E\u964F\u9651\u9652\u9653\u9656\u9657"], + ["ea80", "\u9658\u9659\u965A\u965C\u965D\u965E\u9660\u9663\u9665\u9666\u966B\u966D", 4, "\u9673\u9678", 12, "\u9687\u9689\u968A\u8F8D\u8F8E\u8F8F\u8F98\u8F9A\u8ECE\u620B\u6217\u621B\u621F\u6222\u6221\u6225\u6224\u622C\u81E7\u74EF\u74F4\u74FF\u750F\u7511\u7513\u6534\u65EE\u65EF\u65F0\u660A\u6619\u6772\u6603\u6615\u6600\u7085\u66F7\u661D\u6634\u6631\u6636\u6635\u8006\u665F\u6654\u6641\u664F\u6656\u6661\u6657\u6677\u6684\u668C\u66A7\u669D\u66BE\u66DB\u66DC\u66E6\u66E9\u8D32\u8D33\u8D36\u8D3B\u8D3D\u8D40\u8D45\u8D46\u8D48\u8D49\u8D47\u8D4D\u8D55\u8D59\u89C7\u89CA\u89CB\u89CC\u89CE\u89CF\u89D0\u89D1\u726E\u729F\u725D\u7266\u726F\u727E\u727F\u7284\u728B\u728D\u728F\u7292\u6308\u6332\u63B0"], + ["eb40", "\u968C\u968E\u9691\u9692\u9693\u9695\u9696\u969A\u969B\u969D", 9, "\u96A8", 7, "\u96B1\u96B2\u96B4\u96B5\u96B7\u96B8\u96BA\u96BB\u96BF\u96C2\u96C3\u96C8\u96CA\u96CB\u96D0\u96D1\u96D3\u96D4\u96D6", 9, "\u96E1", 6, "\u96EB"], + ["eb80", "\u96EC\u96ED\u96EE\u96F0\u96F1\u96F2\u96F4\u96F5\u96F8\u96FA\u96FB\u96FC\u96FD\u96FF\u9702\u9703\u9705\u970A\u970B\u970C\u9710\u9711\u9712\u9714\u9715\u9717", 4, "\u971D\u971F\u9720\u643F\u64D8\u8004\u6BEA\u6BF3\u6BFD\u6BF5\u6BF9\u6C05\u6C07\u6C06\u6C0D\u6C15\u6C18\u6C19\u6C1A\u6C21\u6C29\u6C24\u6C2A\u6C32\u6535\u6555\u656B\u724D\u7252\u7256\u7230\u8662\u5216\u809F\u809C\u8093\u80BC\u670A\u80BD\u80B1\u80AB\u80AD\u80B4\u80B7\u80E7\u80E8\u80E9\u80EA\u80DB\u80C2\u80C4\u80D9\u80CD\u80D7\u6710\u80DD\u80EB\u80F1\u80F4\u80ED\u810D\u810E\u80F2\u80FC\u6715\u8112\u8C5A\u8136\u811E\u812C\u8118\u8132\u8148\u814C\u8153\u8174\u8159\u815A\u8171\u8160\u8169\u817C\u817D\u816D\u8167\u584D\u5AB5\u8188\u8182\u8191\u6ED5\u81A3\u81AA\u81CC\u6726\u81CA\u81BB"], + ["ec40", "\u9721", 8, "\u972B\u972C\u972E\u972F\u9731\u9733", 4, "\u973A\u973B\u973C\u973D\u973F", 18, "\u9754\u9755\u9757\u9758\u975A\u975C\u975D\u975F\u9763\u9764\u9766\u9767\u9768\u976A", 7], + ["ec80", "\u9772\u9775\u9777", 4, "\u977D", 7, "\u9786", 4, "\u978C\u978E\u978F\u9790\u9793\u9795\u9796\u9797\u9799", 4, "\u81C1\u81A6\u6B24\u6B37\u6B39\u6B43\u6B46\u6B59\u98D1\u98D2\u98D3\u98D5\u98D9\u98DA\u6BB3\u5F40\u6BC2\u89F3\u6590\u9F51\u6593\u65BC\u65C6\u65C4\u65C3\u65CC\u65CE\u65D2\u65D6\u7080\u709C\u7096\u709D\u70BB\u70C0\u70B7\u70AB\u70B1\u70E8\u70CA\u7110\u7113\u7116\u712F\u7131\u7173\u715C\u7168\u7145\u7172\u714A\u7178\u717A\u7198\u71B3\u71B5\u71A8\u71A0\u71E0\u71D4\u71E7\u71F9\u721D\u7228\u706C\u7118\u7166\u71B9\u623E\u623D\u6243\u6248\u6249\u793B\u7940\u7946\u7949\u795B\u795C\u7953\u795A\u7962\u7957\u7960\u796F\u7967\u797A\u7985\u798A\u799A\u79A7\u79B3\u5FD1\u5FD0"], + ["ed40", "\u979E\u979F\u97A1\u97A2\u97A4", 6, "\u97AC\u97AE\u97B0\u97B1\u97B3\u97B5", 46], + ["ed80", "\u97E4\u97E5\u97E8\u97EE", 4, "\u97F4\u97F7", 23, "\u603C\u605D\u605A\u6067\u6041\u6059\u6063\u60AB\u6106\u610D\u615D\u61A9\u619D\u61CB\u61D1\u6206\u8080\u807F\u6C93\u6CF6\u6DFC\u77F6\u77F8\u7800\u7809\u7817\u7818\u7811\u65AB\u782D\u781C\u781D\u7839\u783A\u783B\u781F\u783C\u7825\u782C\u7823\u7829\u784E\u786D\u7856\u7857\u7826\u7850\u7847\u784C\u786A\u789B\u7893\u789A\u7887\u789C\u78A1\u78A3\u78B2\u78B9\u78A5\u78D4\u78D9\u78C9\u78EC\u78F2\u7905\u78F4\u7913\u7924\u791E\u7934\u9F9B\u9EF9\u9EFB\u9EFC\u76F1\u7704\u770D\u76F9\u7707\u7708\u771A\u7722\u7719\u772D\u7726\u7735\u7738\u7750\u7751\u7747\u7743\u775A\u7768"], + ["ee40", "\u980F", 62], + ["ee80", "\u984E", 32, "\u7762\u7765\u777F\u778D\u777D\u7780\u778C\u7791\u779F\u77A0\u77B0\u77B5\u77BD\u753A\u7540\u754E\u754B\u7548\u755B\u7572\u7579\u7583\u7F58\u7F61\u7F5F\u8A48\u7F68\u7F74\u7F71\u7F79\u7F81\u7F7E\u76CD\u76E5\u8832\u9485\u9486\u9487\u948B\u948A\u948C\u948D\u948F\u9490\u9494\u9497\u9495\u949A\u949B\u949C\u94A3\u94A4\u94AB\u94AA\u94AD\u94AC\u94AF\u94B0\u94B2\u94B4\u94B6", 4, "\u94BC\u94BD\u94BF\u94C4\u94C8", 6, "\u94D0\u94D1\u94D2\u94D5\u94D6\u94D7\u94D9\u94D8\u94DB\u94DE\u94DF\u94E0\u94E2\u94E4\u94E5\u94E7\u94E8\u94EA"], + ["ef40", "\u986F", 5, "\u988B\u988E\u9892\u9895\u9899\u98A3\u98A8", 37, "\u98CF\u98D0\u98D4\u98D6\u98D7\u98DB\u98DC\u98DD\u98E0", 4], + ["ef80", "\u98E5\u98E6\u98E9", 30, "\u94E9\u94EB\u94EE\u94EF\u94F3\u94F4\u94F5\u94F7\u94F9\u94FC\u94FD\u94FF\u9503\u9502\u9506\u9507\u9509\u950A\u950D\u950E\u950F\u9512", 4, "\u9518\u951B\u951D\u951E\u951F\u9522\u952A\u952B\u9529\u952C\u9531\u9532\u9534\u9536\u9537\u9538\u953C\u953E\u953F\u9542\u9535\u9544\u9545\u9546\u9549\u954C\u954E\u954F\u9552\u9553\u9554\u9556\u9557\u9558\u9559\u955B\u955E\u955F\u955D\u9561\u9562\u9564", 8, "\u956F\u9571\u9572\u9573\u953A\u77E7\u77EC\u96C9\u79D5\u79ED\u79E3\u79EB\u7A06\u5D47\u7A03\u7A02\u7A1E\u7A14"], + ["f040", "\u9908", 4, "\u990E\u990F\u9911", 28, "\u992F", 26], + ["f080", "\u994A", 9, "\u9956", 12, "\u9964\u9966\u9973\u9978\u9979\u997B\u997E\u9982\u9983\u9989\u7A39\u7A37\u7A51\u9ECF\u99A5\u7A70\u7688\u768E\u7693\u7699\u76A4\u74DE\u74E0\u752C\u9E20\u9E22\u9E28", 4, "\u9E32\u9E31\u9E36\u9E38\u9E37\u9E39\u9E3A\u9E3E\u9E41\u9E42\u9E44\u9E46\u9E47\u9E48\u9E49\u9E4B\u9E4C\u9E4E\u9E51\u9E55\u9E57\u9E5A\u9E5B\u9E5C\u9E5E\u9E63\u9E66", 6, "\u9E71\u9E6D\u9E73\u7592\u7594\u7596\u75A0\u759D\u75AC\u75A3\u75B3\u75B4\u75B8\u75C4\u75B1\u75B0\u75C3\u75C2\u75D6\u75CD\u75E3\u75E8\u75E6\u75E4\u75EB\u75E7\u7603\u75F1\u75FC\u75FF\u7610\u7600\u7605\u760C\u7617\u760A\u7625\u7618\u7615\u7619"], + ["f140", "\u998C\u998E\u999A", 10, "\u99A6\u99A7\u99A9", 47], + ["f180", "\u99D9", 32, "\u761B\u763C\u7622\u7620\u7640\u762D\u7630\u763F\u7635\u7643\u763E\u7633\u764D\u765E\u7654\u765C\u7656\u766B\u766F\u7FCA\u7AE6\u7A78\u7A79\u7A80\u7A86\u7A88\u7A95\u7AA6\u7AA0\u7AAC\u7AA8\u7AAD\u7AB3\u8864\u8869\u8872\u887D\u887F\u8882\u88A2\u88C6\u88B7\u88BC\u88C9\u88E2\u88CE\u88E3\u88E5\u88F1\u891A\u88FC\u88E8\u88FE\u88F0\u8921\u8919\u8913\u891B\u890A\u8934\u892B\u8936\u8941\u8966\u897B\u758B\u80E5\u76B2\u76B4\u77DC\u8012\u8014\u8016\u801C\u8020\u8022\u8025\u8026\u8027\u8029\u8028\u8031\u800B\u8035\u8043\u8046\u804D\u8052\u8069\u8071\u8983\u9878\u9880\u9883"], + ["f240", "\u99FA", 62], + ["f280", "\u9A39", 32, "\u9889\u988C\u988D\u988F\u9894\u989A\u989B\u989E\u989F\u98A1\u98A2\u98A5\u98A6\u864D\u8654\u866C\u866E\u867F\u867A\u867C\u867B\u86A8\u868D\u868B\u86AC\u869D\u86A7\u86A3\u86AA\u8693\u86A9\u86B6\u86C4\u86B5\u86CE\u86B0\u86BA\u86B1\u86AF\u86C9\u86CF\u86B4\u86E9\u86F1\u86F2\u86ED\u86F3\u86D0\u8713\u86DE\u86F4\u86DF\u86D8\u86D1\u8703\u8707\u86F8\u8708\u870A\u870D\u8709\u8723\u873B\u871E\u8725\u872E\u871A\u873E\u8748\u8734\u8731\u8729\u8737\u873F\u8782\u8722\u877D\u877E\u877B\u8760\u8770\u874C\u876E\u878B\u8753\u8763\u877C\u8764\u8759\u8765\u8793\u87AF\u87A8\u87D2"], + ["f340", "\u9A5A", 17, "\u9A72\u9A83\u9A89\u9A8D\u9A8E\u9A94\u9A95\u9A99\u9AA6\u9AA9", 6, "\u9AB2\u9AB3\u9AB4\u9AB5\u9AB9\u9ABB\u9ABD\u9ABE\u9ABF\u9AC3\u9AC4\u9AC6", 4, "\u9ACD\u9ACE\u9ACF\u9AD0\u9AD2\u9AD4\u9AD5\u9AD6\u9AD7\u9AD9\u9ADA\u9ADB\u9ADC"], + ["f380", "\u9ADD\u9ADE\u9AE0\u9AE2\u9AE3\u9AE4\u9AE5\u9AE7\u9AE8\u9AE9\u9AEA\u9AEC\u9AEE\u9AF0", 8, "\u9AFA\u9AFC", 6, "\u9B04\u9B05\u9B06\u87C6\u8788\u8785\u87AD\u8797\u8783\u87AB\u87E5\u87AC\u87B5\u87B3\u87CB\u87D3\u87BD\u87D1\u87C0\u87CA\u87DB\u87EA\u87E0\u87EE\u8816\u8813\u87FE\u880A\u881B\u8821\u8839\u883C\u7F36\u7F42\u7F44\u7F45\u8210\u7AFA\u7AFD\u7B08\u7B03\u7B04\u7B15\u7B0A\u7B2B\u7B0F\u7B47\u7B38\u7B2A\u7B19\u7B2E\u7B31\u7B20\u7B25\u7B24\u7B33\u7B3E\u7B1E\u7B58\u7B5A\u7B45\u7B75\u7B4C\u7B5D\u7B60\u7B6E\u7B7B\u7B62\u7B72\u7B71\u7B90\u7BA6\u7BA7\u7BB8\u7BAC\u7B9D\u7BA8\u7B85\u7BAA\u7B9C\u7BA2\u7BAB\u7BB4\u7BD1\u7BC1\u7BCC\u7BDD\u7BDA\u7BE5\u7BE6\u7BEA\u7C0C\u7BFE\u7BFC\u7C0F\u7C16\u7C0B"], + ["f440", "\u9B07\u9B09", 5, "\u9B10\u9B11\u9B12\u9B14", 10, "\u9B20\u9B21\u9B22\u9B24", 10, "\u9B30\u9B31\u9B33", 7, "\u9B3D\u9B3E\u9B3F\u9B40\u9B46\u9B4A\u9B4B\u9B4C\u9B4E\u9B50\u9B52\u9B53\u9B55", 5], + ["f480", "\u9B5B", 32, "\u7C1F\u7C2A\u7C26\u7C38\u7C41\u7C40\u81FE\u8201\u8202\u8204\u81EC\u8844\u8221\u8222\u8223\u822D\u822F\u8228\u822B\u8238\u823B\u8233\u8234\u823E\u8244\u8249\u824B\u824F\u825A\u825F\u8268\u887E\u8885\u8888\u88D8\u88DF\u895E\u7F9D\u7F9F\u7FA7\u7FAF\u7FB0\u7FB2\u7C7C\u6549\u7C91\u7C9D\u7C9C\u7C9E\u7CA2\u7CB2\u7CBC\u7CBD\u7CC1\u7CC7\u7CCC\u7CCD\u7CC8\u7CC5\u7CD7\u7CE8\u826E\u66A8\u7FBF\u7FCE\u7FD5\u7FE5\u7FE1\u7FE6\u7FE9\u7FEE\u7FF3\u7CF8\u7D77\u7DA6\u7DAE\u7E47\u7E9B\u9EB8\u9EB4\u8D73\u8D84\u8D94\u8D91\u8DB1\u8D67\u8D6D\u8C47\u8C49\u914A\u9150\u914E\u914F\u9164"], + ["f540", "\u9B7C", 62], + ["f580", "\u9BBB", 32, "\u9162\u9161\u9170\u9169\u916F\u917D\u917E\u9172\u9174\u9179\u918C\u9185\u9190\u918D\u9191\u91A2\u91A3\u91AA\u91AD\u91AE\u91AF\u91B5\u91B4\u91BA\u8C55\u9E7E\u8DB8\u8DEB\u8E05\u8E59\u8E69\u8DB5\u8DBF\u8DBC\u8DBA\u8DC4\u8DD6\u8DD7\u8DDA\u8DDE\u8DCE\u8DCF\u8DDB\u8DC6\u8DEC\u8DF7\u8DF8\u8DE3\u8DF9\u8DFB\u8DE4\u8E09\u8DFD\u8E14\u8E1D\u8E1F\u8E2C\u8E2E\u8E23\u8E2F\u8E3A\u8E40\u8E39\u8E35\u8E3D\u8E31\u8E49\u8E41\u8E42\u8E51\u8E52\u8E4A\u8E70\u8E76\u8E7C\u8E6F\u8E74\u8E85\u8E8F\u8E94\u8E90\u8E9C\u8E9E\u8C78\u8C82\u8C8A\u8C85\u8C98\u8C94\u659B\u89D6\u89DE\u89DA\u89DC"], + ["f640", "\u9BDC", 62], + ["f680", "\u9C1B", 32, "\u89E5\u89EB\u89EF\u8A3E\u8B26\u9753\u96E9\u96F3\u96EF\u9706\u9701\u9708\u970F\u970E\u972A\u972D\u9730\u973E\u9F80\u9F83\u9F85", 5, "\u9F8C\u9EFE\u9F0B\u9F0D\u96B9\u96BC\u96BD\u96CE\u96D2\u77BF\u96E0\u928E\u92AE\u92C8\u933E\u936A\u93CA\u938F\u943E\u946B\u9C7F\u9C82\u9C85\u9C86\u9C87\u9C88\u7A23\u9C8B\u9C8E\u9C90\u9C91\u9C92\u9C94\u9C95\u9C9A\u9C9B\u9C9E", 5, "\u9CA5", 4, "\u9CAB\u9CAD\u9CAE\u9CB0", 7, "\u9CBA\u9CBB\u9CBC\u9CBD\u9CC4\u9CC5\u9CC6\u9CC7\u9CCA\u9CCB"], + ["f740", "\u9C3C", 62], + ["f780", "\u9C7B\u9C7D\u9C7E\u9C80\u9C83\u9C84\u9C89\u9C8A\u9C8C\u9C8F\u9C93\u9C96\u9C97\u9C98\u9C99\u9C9D\u9CAA\u9CAC\u9CAF\u9CB9\u9CBE", 4, "\u9CC8\u9CC9\u9CD1\u9CD2\u9CDA\u9CDB\u9CE0\u9CE1\u9CCC", 4, "\u9CD3\u9CD4\u9CD5\u9CD7\u9CD8\u9CD9\u9CDC\u9CDD\u9CDF\u9CE2\u977C\u9785\u9791\u9792\u9794\u97AF\u97AB\u97A3\u97B2\u97B4\u9AB1\u9AB0\u9AB7\u9E58\u9AB6\u9ABA\u9ABC\u9AC1\u9AC0\u9AC5\u9AC2\u9ACB\u9ACC\u9AD1\u9B45\u9B43\u9B47\u9B49\u9B48\u9B4D\u9B51\u98E8\u990D\u992E\u9955\u9954\u9ADF\u9AE1\u9AE6\u9AEF\u9AEB\u9AFB\u9AED\u9AF9\u9B08\u9B0F\u9B13\u9B1F\u9B23\u9EBD\u9EBE\u7E3B\u9E82\u9E87\u9E88\u9E8B\u9E92\u93D6\u9E9D\u9E9F\u9EDB\u9EDC\u9EDD\u9EE0\u9EDF\u9EE2\u9EE9\u9EE7\u9EE5\u9EEA\u9EEF\u9F22\u9F2C\u9F2F\u9F39\u9F37\u9F3D\u9F3E\u9F44"], + ["f840", "\u9CE3", 62], + ["f880", "\u9D22", 32], + ["f940", "\u9D43", 62], + ["f980", "\u9D82", 32], + ["fa40", "\u9DA3", 62], + ["fa80", "\u9DE2", 32], + ["fb40", "\u9E03", 27, "\u9E24\u9E27\u9E2E\u9E30\u9E34\u9E3B\u9E3C\u9E40\u9E4D\u9E50\u9E52\u9E53\u9E54\u9E56\u9E59\u9E5D\u9E5F\u9E60\u9E61\u9E62\u9E65\u9E6E\u9E6F\u9E72\u9E74", 9, "\u9E80"], + ["fb80", "\u9E81\u9E83\u9E84\u9E85\u9E86\u9E89\u9E8A\u9E8C", 5, "\u9E94", 8, "\u9E9E\u9EA0", 5, "\u9EA7\u9EA8\u9EA9\u9EAA"], + ["fc40", "\u9EAB", 8, "\u9EB5\u9EB6\u9EB7\u9EB9\u9EBA\u9EBC\u9EBF", 4, "\u9EC5\u9EC6\u9EC7\u9EC8\u9ECA\u9ECB\u9ECC\u9ED0\u9ED2\u9ED3\u9ED5\u9ED6\u9ED7\u9ED9\u9EDA\u9EDE\u9EE1\u9EE3\u9EE4\u9EE6\u9EE8\u9EEB\u9EEC\u9EED\u9EEE\u9EF0", 8, "\u9EFA\u9EFD\u9EFF", 6], + ["fc80", "\u9F06", 4, "\u9F0C\u9F0F\u9F11\u9F12\u9F14\u9F15\u9F16\u9F18\u9F1A", 5, "\u9F21\u9F23", 8, "\u9F2D\u9F2E\u9F30\u9F31"], + ["fd40", "\u9F32", 4, "\u9F38\u9F3A\u9F3C\u9F3F", 4, "\u9F45", 10, "\u9F52", 38], + ["fd80", "\u9F79", 5, "\u9F81\u9F82\u9F8D", 11, "\u9F9C\u9F9D\u9F9E\u9FA1", 4, "\uF92C\uF979\uF995\uF9E7\uF9F1"], + ["fe40", "\uFA0C\uFA0D\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA18\uFA1F\uFA20\uFA21\uFA23\uFA24\uFA27\uFA28\uFA29"] + ]; + } +}); + +// node_modules/iconv-lite/encodings/tables/gbk-added.json +var require_gbk_added = __commonJS({ + "node_modules/iconv-lite/encodings/tables/gbk-added.json"(exports2, module2) { + module2.exports = [ + ["a140", "\uE4C6", 62], + ["a180", "\uE505", 32], + ["a240", "\uE526", 62], + ["a280", "\uE565", 32], + ["a2ab", "\uE766", 5], + ["a2e3", "\u20AC\uE76D"], + ["a2ef", "\uE76E\uE76F"], + ["a2fd", "\uE770\uE771"], + ["a340", "\uE586", 62], + ["a380", "\uE5C5", 31, "\u3000"], + ["a440", "\uE5E6", 62], + ["a480", "\uE625", 32], + ["a4f4", "\uE772", 10], + ["a540", "\uE646", 62], + ["a580", "\uE685", 32], + ["a5f7", "\uE77D", 7], + ["a640", "\uE6A6", 62], + ["a680", "\uE6E5", 32], + ["a6b9", "\uE785", 7], + ["a6d9", "\uE78D", 6], + ["a6ec", "\uE794\uE795"], + ["a6f3", "\uE796"], + ["a6f6", "\uE797", 8], + ["a740", "\uE706", 62], + ["a780", "\uE745", 32], + ["a7c2", "\uE7A0", 14], + ["a7f2", "\uE7AF", 12], + ["a896", "\uE7BC", 10], + ["a8bc", "\uE7C7"], + ["a8bf", "\u01F9"], + ["a8c1", "\uE7C9\uE7CA\uE7CB\uE7CC"], + ["a8ea", "\uE7CD", 20], + ["a958", "\uE7E2"], + ["a95b", "\uE7E3"], + ["a95d", "\uE7E4\uE7E5\uE7E6"], + ["a989", "\u303E\u2FF0", 11], + ["a997", "\uE7F4", 12], + ["a9f0", "\uE801", 14], + ["aaa1", "\uE000", 93], + ["aba1", "\uE05E", 93], + ["aca1", "\uE0BC", 93], + ["ada1", "\uE11A", 93], + ["aea1", "\uE178", 93], + ["afa1", "\uE1D6", 93], + ["d7fa", "\uE810", 4], + ["f8a1", "\uE234", 93], + ["f9a1", "\uE292", 93], + ["faa1", "\uE2F0", 93], + ["fba1", "\uE34E", 93], + ["fca1", "\uE3AC", 93], + ["fda1", "\uE40A", 93], + ["fe50", "\u2E81\uE816\uE817\uE818\u2E84\u3473\u3447\u2E88\u2E8B\uE81E\u359E\u361A\u360E\u2E8C\u2E97\u396E\u3918\uE826\u39CF\u39DF\u3A73\u39D0\uE82B\uE82C\u3B4E\u3C6E\u3CE0\u2EA7\uE831\uE832\u2EAA\u4056\u415F\u2EAE\u4337\u2EB3\u2EB6\u2EB7\uE83B\u43B1\u43AC\u2EBB\u43DD\u44D6\u4661\u464C\uE843"], + ["fe80", "\u4723\u4729\u477C\u478D\u2ECA\u4947\u497A\u497D\u4982\u4983\u4985\u4986\u499F\u499B\u49B7\u49B6\uE854\uE855\u4CA3\u4C9F\u4CA0\u4CA1\u4C77\u4CA2\u4D13", 6, "\u4DAE\uE864\uE468", 93] + ]; + } +}); + +// node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +var require_gb18030_ranges = __commonJS({ + "node_modules/iconv-lite/encodings/tables/gb18030-ranges.json"(exports2, module2) { + module2.exports = { uChars: [128, 165, 169, 178, 184, 216, 226, 235, 238, 244, 248, 251, 253, 258, 276, 284, 300, 325, 329, 334, 364, 463, 465, 467, 469, 471, 473, 475, 477, 506, 594, 610, 712, 716, 730, 930, 938, 962, 970, 1026, 1104, 1106, 8209, 8215, 8218, 8222, 8231, 8241, 8244, 8246, 8252, 8365, 8452, 8454, 8458, 8471, 8482, 8556, 8570, 8596, 8602, 8713, 8720, 8722, 8726, 8731, 8737, 8740, 8742, 8748, 8751, 8760, 8766, 8777, 8781, 8787, 8802, 8808, 8816, 8854, 8858, 8870, 8896, 8979, 9322, 9372, 9548, 9588, 9616, 9622, 9634, 9652, 9662, 9672, 9676, 9680, 9702, 9735, 9738, 9793, 9795, 11906, 11909, 11913, 11917, 11928, 11944, 11947, 11951, 11956, 11960, 11964, 11979, 12284, 12292, 12312, 12319, 12330, 12351, 12436, 12447, 12535, 12543, 12586, 12842, 12850, 12964, 13200, 13215, 13218, 13253, 13263, 13267, 13270, 13384, 13428, 13727, 13839, 13851, 14617, 14703, 14801, 14816, 14964, 15183, 15471, 15585, 16471, 16736, 17208, 17325, 17330, 17374, 17623, 17997, 18018, 18212, 18218, 18301, 18318, 18760, 18811, 18814, 18820, 18823, 18844, 18848, 18872, 19576, 19620, 19738, 19887, 40870, 59244, 59336, 59367, 59413, 59417, 59423, 59431, 59437, 59443, 59452, 59460, 59478, 59493, 63789, 63866, 63894, 63976, 63986, 64016, 64018, 64021, 64025, 64034, 64037, 64042, 65074, 65093, 65107, 65112, 65127, 65132, 65375, 65510, 65536], gbChars: [0, 36, 38, 45, 50, 81, 89, 95, 96, 100, 103, 104, 105, 109, 126, 133, 148, 172, 175, 179, 208, 306, 307, 308, 309, 310, 311, 312, 313, 341, 428, 443, 544, 545, 558, 741, 742, 749, 750, 805, 819, 820, 7922, 7924, 7925, 7927, 7934, 7943, 7944, 7945, 7950, 8062, 8148, 8149, 8152, 8164, 8174, 8236, 8240, 8262, 8264, 8374, 8380, 8381, 8384, 8388, 8390, 8392, 8393, 8394, 8396, 8401, 8406, 8416, 8419, 8424, 8437, 8439, 8445, 8482, 8485, 8496, 8521, 8603, 8936, 8946, 9046, 9050, 9063, 9066, 9076, 9092, 9100, 9108, 9111, 9113, 9131, 9162, 9164, 9218, 9219, 11329, 11331, 11334, 11336, 11346, 11361, 11363, 11366, 11370, 11372, 11375, 11389, 11682, 11686, 11687, 11692, 11694, 11714, 11716, 11723, 11725, 11730, 11736, 11982, 11989, 12102, 12336, 12348, 12350, 12384, 12393, 12395, 12397, 12510, 12553, 12851, 12962, 12973, 13738, 13823, 13919, 13933, 14080, 14298, 14585, 14698, 15583, 15847, 16318, 16434, 16438, 16481, 16729, 17102, 17122, 17315, 17320, 17402, 17418, 17859, 17909, 17911, 17915, 17916, 17936, 17939, 17961, 18664, 18703, 18814, 18962, 19043, 33469, 33470, 33471, 33484, 33485, 33490, 33497, 33501, 33505, 33513, 33520, 33536, 33550, 37845, 37921, 37948, 38029, 38038, 38064, 38065, 38066, 38069, 38075, 38076, 38078, 39108, 39109, 39113, 39114, 39115, 39116, 39265, 39394, 189e3] }; + } +}); + +// node_modules/iconv-lite/encodings/tables/cp949.json +var require_cp949 = __commonJS({ + "node_modules/iconv-lite/encodings/tables/cp949.json"(exports2, module2) { + module2.exports = [ + ["0", "\0", 127], + ["8141", "\uAC02\uAC03\uAC05\uAC06\uAC0B", 4, "\uAC18\uAC1E\uAC1F\uAC21\uAC22\uAC23\uAC25", 6, "\uAC2E\uAC32\uAC33\uAC34"], + ["8161", "\uAC35\uAC36\uAC37\uAC3A\uAC3B\uAC3D\uAC3E\uAC3F\uAC41", 9, "\uAC4C\uAC4E", 5, "\uAC55"], + ["8181", "\uAC56\uAC57\uAC59\uAC5A\uAC5B\uAC5D", 18, "\uAC72\uAC73\uAC75\uAC76\uAC79\uAC7B", 4, "\uAC82\uAC87\uAC88\uAC8D\uAC8E\uAC8F\uAC91\uAC92\uAC93\uAC95", 6, "\uAC9E\uACA2", 5, "\uACAB\uACAD\uACAE\uACB1", 6, "\uACBA\uACBE\uACBF\uACC0\uACC2\uACC3\uACC5\uACC6\uACC7\uACC9\uACCA\uACCB\uACCD", 7, "\uACD6\uACD8", 7, "\uACE2\uACE3\uACE5\uACE6\uACE9\uACEB\uACED\uACEE\uACF2\uACF4\uACF7", 4, "\uACFE\uACFF\uAD01\uAD02\uAD03\uAD05\uAD07", 4, "\uAD0E\uAD10\uAD12\uAD13"], + ["8241", "\uAD14\uAD15\uAD16\uAD17\uAD19\uAD1A\uAD1B\uAD1D\uAD1E\uAD1F\uAD21", 7, "\uAD2A\uAD2B\uAD2E", 5], + ["8261", "\uAD36\uAD37\uAD39\uAD3A\uAD3B\uAD3D", 6, "\uAD46\uAD48\uAD4A", 5, "\uAD51\uAD52\uAD53\uAD55\uAD56\uAD57"], + ["8281", "\uAD59", 7, "\uAD62\uAD64", 7, "\uAD6E\uAD6F\uAD71\uAD72\uAD77\uAD78\uAD79\uAD7A\uAD7E\uAD80\uAD83", 4, "\uAD8A\uAD8B\uAD8D\uAD8E\uAD8F\uAD91", 10, "\uAD9E", 5, "\uADA5", 17, "\uADB8", 7, "\uADC2\uADC3\uADC5\uADC6\uADC7\uADC9", 6, "\uADD2\uADD4", 7, "\uADDD\uADDE\uADDF\uADE1\uADE2\uADE3\uADE5", 18], + ["8341", "\uADFA\uADFB\uADFD\uADFE\uAE02", 5, "\uAE0A\uAE0C\uAE0E", 5, "\uAE15", 7], + ["8361", "\uAE1D", 18, "\uAE32\uAE33\uAE35\uAE36\uAE39\uAE3B\uAE3C"], + ["8381", "\uAE3D\uAE3E\uAE3F\uAE42\uAE44\uAE47\uAE48\uAE49\uAE4B\uAE4F\uAE51\uAE52\uAE53\uAE55\uAE57", 4, "\uAE5E\uAE62\uAE63\uAE64\uAE66\uAE67\uAE6A\uAE6B\uAE6D\uAE6E\uAE6F\uAE71", 6, "\uAE7A\uAE7E", 5, "\uAE86", 5, "\uAE8D", 46, "\uAEBF\uAEC1\uAEC2\uAEC3\uAEC5", 6, "\uAECE\uAED2", 5, "\uAEDA\uAEDB\uAEDD", 8], + ["8441", "\uAEE6\uAEE7\uAEE9\uAEEA\uAEEC\uAEEE", 5, "\uAEF5\uAEF6\uAEF7\uAEF9\uAEFA\uAEFB\uAEFD", 8], + ["8461", "\uAF06\uAF09\uAF0A\uAF0B\uAF0C\uAF0E\uAF0F\uAF11", 18], + ["8481", "\uAF24", 7, "\uAF2E\uAF2F\uAF31\uAF33\uAF35", 6, "\uAF3E\uAF40\uAF44\uAF45\uAF46\uAF47\uAF4A", 5, "\uAF51", 10, "\uAF5E", 5, "\uAF66", 18, "\uAF7A", 5, "\uAF81\uAF82\uAF83\uAF85\uAF86\uAF87\uAF89", 6, "\uAF92\uAF93\uAF94\uAF96", 5, "\uAF9D", 26, "\uAFBA\uAFBB\uAFBD\uAFBE"], + ["8541", "\uAFBF\uAFC1", 5, "\uAFCA\uAFCC\uAFCF", 4, "\uAFD5", 6, "\uAFDD", 4], + ["8561", "\uAFE2", 5, "\uAFEA", 5, "\uAFF2\uAFF3\uAFF5\uAFF6\uAFF7\uAFF9", 6, "\uB002\uB003"], + ["8581", "\uB005", 6, "\uB00D\uB00E\uB00F\uB011\uB012\uB013\uB015", 6, "\uB01E", 9, "\uB029", 26, "\uB046\uB047\uB049\uB04B\uB04D\uB04F\uB050\uB051\uB052\uB056\uB058\uB05A\uB05B\uB05C\uB05E", 29, "\uB07E\uB07F\uB081\uB082\uB083\uB085", 6, "\uB08E\uB090\uB092", 5, "\uB09B\uB09D\uB09E\uB0A3\uB0A4"], + ["8641", "\uB0A5\uB0A6\uB0A7\uB0AA\uB0B0\uB0B2\uB0B6\uB0B7\uB0B9\uB0BA\uB0BB\uB0BD", 6, "\uB0C6\uB0CA", 5, "\uB0D2"], + ["8661", "\uB0D3\uB0D5\uB0D6\uB0D7\uB0D9", 6, "\uB0E1\uB0E2\uB0E3\uB0E4\uB0E6", 10], + ["8681", "\uB0F1", 22, "\uB10A\uB10D\uB10E\uB10F\uB111\uB114\uB115\uB116\uB117\uB11A\uB11E", 4, "\uB126\uB127\uB129\uB12A\uB12B\uB12D", 6, "\uB136\uB13A", 5, "\uB142\uB143\uB145\uB146\uB147\uB149", 6, "\uB152\uB153\uB156\uB157\uB159\uB15A\uB15B\uB15D\uB15E\uB15F\uB161", 22, "\uB17A\uB17B\uB17D\uB17E\uB17F\uB181\uB183", 4, "\uB18A\uB18C\uB18E\uB18F\uB190\uB191\uB195\uB196\uB197\uB199\uB19A\uB19B\uB19D"], + ["8741", "\uB19E", 9, "\uB1A9", 15], + ["8761", "\uB1B9", 18, "\uB1CD\uB1CE\uB1CF\uB1D1\uB1D2\uB1D3\uB1D5"], + ["8781", "\uB1D6", 5, "\uB1DE\uB1E0", 7, "\uB1EA\uB1EB\uB1ED\uB1EE\uB1EF\uB1F1", 7, "\uB1FA\uB1FC\uB1FE", 5, "\uB206\uB207\uB209\uB20A\uB20D", 6, "\uB216\uB218\uB21A", 5, "\uB221", 18, "\uB235", 6, "\uB23D", 26, "\uB259\uB25A\uB25B\uB25D\uB25E\uB25F\uB261", 6, "\uB26A", 4], + ["8841", "\uB26F", 4, "\uB276", 5, "\uB27D", 6, "\uB286\uB287\uB288\uB28A", 4], + ["8861", "\uB28F\uB292\uB293\uB295\uB296\uB297\uB29B", 4, "\uB2A2\uB2A4\uB2A7\uB2A8\uB2A9\uB2AB\uB2AD\uB2AE\uB2AF\uB2B1\uB2B2\uB2B3\uB2B5\uB2B6\uB2B7"], + ["8881", "\uB2B8", 15, "\uB2CA\uB2CB\uB2CD\uB2CE\uB2CF\uB2D1\uB2D3", 4, "\uB2DA\uB2DC\uB2DE\uB2DF\uB2E0\uB2E1\uB2E3\uB2E7\uB2E9\uB2EA\uB2F0\uB2F1\uB2F2\uB2F6\uB2FC\uB2FD\uB2FE\uB302\uB303\uB305\uB306\uB307\uB309", 6, "\uB312\uB316", 5, "\uB31D", 54, "\uB357\uB359\uB35A\uB35D\uB360\uB361\uB362\uB363"], + ["8941", "\uB366\uB368\uB36A\uB36C\uB36D\uB36F\uB372\uB373\uB375\uB376\uB377\uB379", 6, "\uB382\uB386", 5, "\uB38D"], + ["8961", "\uB38E\uB38F\uB391\uB392\uB393\uB395", 10, "\uB3A2", 5, "\uB3A9\uB3AA\uB3AB\uB3AD"], + ["8981", "\uB3AE", 21, "\uB3C6\uB3C7\uB3C9\uB3CA\uB3CD\uB3CF\uB3D1\uB3D2\uB3D3\uB3D6\uB3D8\uB3DA\uB3DC\uB3DE\uB3DF\uB3E1\uB3E2\uB3E3\uB3E5\uB3E6\uB3E7\uB3E9", 18, "\uB3FD", 18, "\uB411", 6, "\uB419\uB41A\uB41B\uB41D\uB41E\uB41F\uB421", 6, "\uB42A\uB42C", 7, "\uB435", 15], + ["8a41", "\uB445", 10, "\uB452\uB453\uB455\uB456\uB457\uB459", 6, "\uB462\uB464\uB466"], + ["8a61", "\uB467", 4, "\uB46D", 18, "\uB481\uB482"], + ["8a81", "\uB483", 4, "\uB489", 19, "\uB49E", 5, "\uB4A5\uB4A6\uB4A7\uB4A9\uB4AA\uB4AB\uB4AD", 7, "\uB4B6\uB4B8\uB4BA", 5, "\uB4C1\uB4C2\uB4C3\uB4C5\uB4C6\uB4C7\uB4C9", 6, "\uB4D1\uB4D2\uB4D3\uB4D4\uB4D6", 5, "\uB4DE\uB4DF\uB4E1\uB4E2\uB4E5\uB4E7", 4, "\uB4EE\uB4F0\uB4F2", 5, "\uB4F9", 26, "\uB516\uB517\uB519\uB51A\uB51D"], + ["8b41", "\uB51E", 5, "\uB526\uB52B", 4, "\uB532\uB533\uB535\uB536\uB537\uB539", 6, "\uB542\uB546"], + ["8b61", "\uB547\uB548\uB549\uB54A\uB54E\uB54F\uB551\uB552\uB553\uB555", 6, "\uB55E\uB562", 8], + ["8b81", "\uB56B", 52, "\uB5A2\uB5A3\uB5A5\uB5A6\uB5A7\uB5A9\uB5AC\uB5AD\uB5AE\uB5AF\uB5B2\uB5B6", 4, "\uB5BE\uB5BF\uB5C1\uB5C2\uB5C3\uB5C5", 6, "\uB5CE\uB5D2", 5, "\uB5D9", 18, "\uB5ED", 18], + ["8c41", "\uB600", 15, "\uB612\uB613\uB615\uB616\uB617\uB619", 4], + ["8c61", "\uB61E", 6, "\uB626", 5, "\uB62D", 6, "\uB635", 5], + ["8c81", "\uB63B", 12, "\uB649", 26, "\uB665\uB666\uB667\uB669", 50, "\uB69E\uB69F\uB6A1\uB6A2\uB6A3\uB6A5", 5, "\uB6AD\uB6AE\uB6AF\uB6B0\uB6B2", 16], + ["8d41", "\uB6C3", 16, "\uB6D5", 8], + ["8d61", "\uB6DE", 17, "\uB6F1\uB6F2\uB6F3\uB6F5\uB6F6\uB6F7\uB6F9\uB6FA"], + ["8d81", "\uB6FB", 4, "\uB702\uB703\uB704\uB706", 33, "\uB72A\uB72B\uB72D\uB72E\uB731", 6, "\uB73A\uB73C", 7, "\uB745\uB746\uB747\uB749\uB74A\uB74B\uB74D", 6, "\uB756", 9, "\uB761\uB762\uB763\uB765\uB766\uB767\uB769", 6, "\uB772\uB774\uB776", 5, "\uB77E\uB77F\uB781\uB782\uB783\uB785", 6, "\uB78E\uB793\uB794\uB795\uB79A\uB79B\uB79D\uB79E"], + ["8e41", "\uB79F\uB7A1", 6, "\uB7AA\uB7AE", 5, "\uB7B6\uB7B7\uB7B9", 8], + ["8e61", "\uB7C2", 4, "\uB7C8\uB7CA", 19], + ["8e81", "\uB7DE", 13, "\uB7EE\uB7EF\uB7F1\uB7F2\uB7F3\uB7F5", 6, "\uB7FE\uB802", 4, "\uB80A\uB80B\uB80D\uB80E\uB80F\uB811", 6, "\uB81A\uB81C\uB81E", 5, "\uB826\uB827\uB829\uB82A\uB82B\uB82D", 6, "\uB836\uB83A", 5, "\uB841\uB842\uB843\uB845", 11, "\uB852\uB854", 7, "\uB85E\uB85F\uB861\uB862\uB863\uB865", 6, "\uB86E\uB870\uB872", 5, "\uB879\uB87A\uB87B\uB87D", 7], + ["8f41", "\uB885", 7, "\uB88E", 17], + ["8f61", "\uB8A0", 7, "\uB8A9", 6, "\uB8B1\uB8B2\uB8B3\uB8B5\uB8B6\uB8B7\uB8B9", 4], + ["8f81", "\uB8BE\uB8BF\uB8C2\uB8C4\uB8C6", 5, "\uB8CD\uB8CE\uB8CF\uB8D1\uB8D2\uB8D3\uB8D5", 7, "\uB8DE\uB8E0\uB8E2", 5, "\uB8EA\uB8EB\uB8ED\uB8EE\uB8EF\uB8F1", 6, "\uB8FA\uB8FC\uB8FE", 5, "\uB905", 18, "\uB919", 6, "\uB921", 26, "\uB93E\uB93F\uB941\uB942\uB943\uB945", 6, "\uB94D\uB94E\uB950\uB952", 5], + ["9041", "\uB95A\uB95B\uB95D\uB95E\uB95F\uB961", 6, "\uB96A\uB96C\uB96E", 5, "\uB976\uB977\uB979\uB97A\uB97B\uB97D"], + ["9061", "\uB97E", 5, "\uB986\uB988\uB98B\uB98C\uB98F", 15], + ["9081", "\uB99F", 12, "\uB9AE\uB9AF\uB9B1\uB9B2\uB9B3\uB9B5", 6, "\uB9BE\uB9C0\uB9C2", 5, "\uB9CA\uB9CB\uB9CD\uB9D3", 4, "\uB9DA\uB9DC\uB9DF\uB9E0\uB9E2\uB9E6\uB9E7\uB9E9\uB9EA\uB9EB\uB9ED", 6, "\uB9F6\uB9FB", 4, "\uBA02", 5, "\uBA09", 11, "\uBA16", 33, "\uBA3A\uBA3B\uBA3D\uBA3E\uBA3F\uBA41\uBA43\uBA44\uBA45\uBA46"], + ["9141", "\uBA47\uBA4A\uBA4C\uBA4F\uBA50\uBA51\uBA52\uBA56\uBA57\uBA59\uBA5A\uBA5B\uBA5D", 6, "\uBA66\uBA6A", 5], + ["9161", "\uBA72\uBA73\uBA75\uBA76\uBA77\uBA79", 9, "\uBA86\uBA88\uBA89\uBA8A\uBA8B\uBA8D", 5], + ["9181", "\uBA93", 20, "\uBAAA\uBAAD\uBAAE\uBAAF\uBAB1\uBAB3", 4, "\uBABA\uBABC\uBABE", 5, "\uBAC5\uBAC6\uBAC7\uBAC9", 14, "\uBADA", 33, "\uBAFD\uBAFE\uBAFF\uBB01\uBB02\uBB03\uBB05", 7, "\uBB0E\uBB10\uBB12", 5, "\uBB19\uBB1A\uBB1B\uBB1D\uBB1E\uBB1F\uBB21", 6], + ["9241", "\uBB28\uBB2A\uBB2C", 7, "\uBB37\uBB39\uBB3A\uBB3F", 4, "\uBB46\uBB48\uBB4A\uBB4B\uBB4C\uBB4E\uBB51\uBB52"], + ["9261", "\uBB53\uBB55\uBB56\uBB57\uBB59", 7, "\uBB62\uBB64", 7, "\uBB6D", 4], + ["9281", "\uBB72", 21, "\uBB89\uBB8A\uBB8B\uBB8D\uBB8E\uBB8F\uBB91", 18, "\uBBA5\uBBA6\uBBA7\uBBA9\uBBAA\uBBAB\uBBAD", 6, "\uBBB5\uBBB6\uBBB8", 7, "\uBBC1\uBBC2\uBBC3\uBBC5\uBBC6\uBBC7\uBBC9", 6, "\uBBD1\uBBD2\uBBD4", 35, "\uBBFA\uBBFB\uBBFD\uBBFE\uBC01"], + ["9341", "\uBC03", 4, "\uBC0A\uBC0E\uBC10\uBC12\uBC13\uBC19\uBC1A\uBC20\uBC21\uBC22\uBC23\uBC26\uBC28\uBC2A\uBC2B\uBC2C\uBC2E\uBC2F\uBC32\uBC33\uBC35"], + ["9361", "\uBC36\uBC37\uBC39", 6, "\uBC42\uBC46\uBC47\uBC48\uBC4A\uBC4B\uBC4E\uBC4F\uBC51", 8], + ["9381", "\uBC5A\uBC5B\uBC5C\uBC5E", 37, "\uBC86\uBC87\uBC89\uBC8A\uBC8D\uBC8F", 4, "\uBC96\uBC98\uBC9B", 4, "\uBCA2\uBCA3\uBCA5\uBCA6\uBCA9", 6, "\uBCB2\uBCB6", 5, "\uBCBE\uBCBF\uBCC1\uBCC2\uBCC3\uBCC5", 7, "\uBCCE\uBCD2\uBCD3\uBCD4\uBCD6\uBCD7\uBCD9\uBCDA\uBCDB\uBCDD", 22, "\uBCF7\uBCF9\uBCFA\uBCFB\uBCFD"], + ["9441", "\uBCFE", 5, "\uBD06\uBD08\uBD0A", 5, "\uBD11\uBD12\uBD13\uBD15", 8], + ["9461", "\uBD1E", 5, "\uBD25", 6, "\uBD2D", 12], + ["9481", "\uBD3A", 5, "\uBD41", 6, "\uBD4A\uBD4B\uBD4D\uBD4E\uBD4F\uBD51", 6, "\uBD5A", 9, "\uBD65\uBD66\uBD67\uBD69", 22, "\uBD82\uBD83\uBD85\uBD86\uBD8B", 4, "\uBD92\uBD94\uBD96\uBD97\uBD98\uBD9B\uBD9D", 6, "\uBDA5", 10, "\uBDB1", 6, "\uBDB9", 24], + ["9541", "\uBDD2\uBDD3\uBDD6\uBDD7\uBDD9\uBDDA\uBDDB\uBDDD", 11, "\uBDEA", 5, "\uBDF1"], + ["9561", "\uBDF2\uBDF3\uBDF5\uBDF6\uBDF7\uBDF9", 6, "\uBE01\uBE02\uBE04\uBE06", 5, "\uBE0E\uBE0F\uBE11\uBE12\uBE13"], + ["9581", "\uBE15", 6, "\uBE1E\uBE20", 35, "\uBE46\uBE47\uBE49\uBE4A\uBE4B\uBE4D\uBE4F", 4, "\uBE56\uBE58\uBE5C\uBE5D\uBE5E\uBE5F\uBE62\uBE63\uBE65\uBE66\uBE67\uBE69\uBE6B", 4, "\uBE72\uBE76", 4, "\uBE7E\uBE7F\uBE81\uBE82\uBE83\uBE85", 6, "\uBE8E\uBE92", 5, "\uBE9A", 13, "\uBEA9", 14], + ["9641", "\uBEB8", 23, "\uBED2\uBED3"], + ["9661", "\uBED5\uBED6\uBED9", 6, "\uBEE1\uBEE2\uBEE6", 5, "\uBEED", 8], + ["9681", "\uBEF6", 10, "\uBF02", 5, "\uBF0A", 13, "\uBF1A\uBF1E", 33, "\uBF42\uBF43\uBF45\uBF46\uBF47\uBF49", 6, "\uBF52\uBF53\uBF54\uBF56", 44], + ["9741", "\uBF83", 16, "\uBF95", 8], + ["9761", "\uBF9E", 17, "\uBFB1", 7], + ["9781", "\uBFB9", 11, "\uBFC6", 5, "\uBFCE\uBFCF\uBFD1\uBFD2\uBFD3\uBFD5", 6, "\uBFDD\uBFDE\uBFE0\uBFE2", 89, "\uC03D\uC03E\uC03F"], + ["9841", "\uC040", 16, "\uC052", 5, "\uC059\uC05A\uC05B"], + ["9861", "\uC05D\uC05E\uC05F\uC061", 6, "\uC06A", 15], + ["9881", "\uC07A", 21, "\uC092\uC093\uC095\uC096\uC097\uC099", 6, "\uC0A2\uC0A4\uC0A6", 5, "\uC0AE\uC0B1\uC0B2\uC0B7", 4, "\uC0BE\uC0C2\uC0C3\uC0C4\uC0C6\uC0C7\uC0CA\uC0CB\uC0CD\uC0CE\uC0CF\uC0D1", 6, "\uC0DA\uC0DE", 5, "\uC0E6\uC0E7\uC0E9\uC0EA\uC0EB\uC0ED", 6, "\uC0F6\uC0F8\uC0FA", 5, "\uC101\uC102\uC103\uC105\uC106\uC107\uC109", 6, "\uC111\uC112\uC113\uC114\uC116", 5, "\uC121\uC122\uC125\uC128\uC129\uC12A\uC12B\uC12E"], + ["9941", "\uC132\uC133\uC134\uC135\uC137\uC13A\uC13B\uC13D\uC13E\uC13F\uC141", 6, "\uC14A\uC14E", 5, "\uC156\uC157"], + ["9961", "\uC159\uC15A\uC15B\uC15D", 6, "\uC166\uC16A", 5, "\uC171\uC172\uC173\uC175\uC176\uC177\uC179\uC17A\uC17B"], + ["9981", "\uC17C", 8, "\uC186", 5, "\uC18F\uC191\uC192\uC193\uC195\uC197", 4, "\uC19E\uC1A0\uC1A2\uC1A3\uC1A4\uC1A6\uC1A7\uC1AA\uC1AB\uC1AD\uC1AE\uC1AF\uC1B1", 11, "\uC1BE", 5, "\uC1C5\uC1C6\uC1C7\uC1C9\uC1CA\uC1CB\uC1CD", 6, "\uC1D5\uC1D6\uC1D9", 6, "\uC1E1\uC1E2\uC1E3\uC1E5\uC1E6\uC1E7\uC1E9", 6, "\uC1F2\uC1F4", 7, "\uC1FE\uC1FF\uC201\uC202\uC203\uC205", 6, "\uC20E\uC210\uC212", 5, "\uC21A\uC21B\uC21D\uC21E\uC221\uC222\uC223"], + ["9a41", "\uC224\uC225\uC226\uC227\uC22A\uC22C\uC22E\uC230\uC233\uC235", 16], + ["9a61", "\uC246\uC247\uC249", 6, "\uC252\uC253\uC255\uC256\uC257\uC259", 6, "\uC261\uC262\uC263\uC264\uC266"], + ["9a81", "\uC267", 4, "\uC26E\uC26F\uC271\uC272\uC273\uC275", 6, "\uC27E\uC280\uC282", 5, "\uC28A", 5, "\uC291", 6, "\uC299\uC29A\uC29C\uC29E", 5, "\uC2A6\uC2A7\uC2A9\uC2AA\uC2AB\uC2AE", 5, "\uC2B6\uC2B8\uC2BA", 33, "\uC2DE\uC2DF\uC2E1\uC2E2\uC2E5", 5, "\uC2EE\uC2F0\uC2F2\uC2F3\uC2F4\uC2F5\uC2F7\uC2FA\uC2FD\uC2FE\uC2FF\uC301", 6, "\uC30A\uC30B\uC30E\uC30F"], + ["9b41", "\uC310\uC311\uC312\uC316\uC317\uC319\uC31A\uC31B\uC31D", 6, "\uC326\uC327\uC32A", 8], + ["9b61", "\uC333", 17, "\uC346", 7], + ["9b81", "\uC34E", 25, "\uC36A\uC36B\uC36D\uC36E\uC36F\uC371\uC373", 4, "\uC37A\uC37B\uC37E", 5, "\uC385\uC386\uC387\uC389\uC38A\uC38B\uC38D", 50, "\uC3C1", 22, "\uC3DA"], + ["9c41", "\uC3DB\uC3DD\uC3DE\uC3E1\uC3E3", 4, "\uC3EA\uC3EB\uC3EC\uC3EE", 5, "\uC3F6\uC3F7\uC3F9", 5], + ["9c61", "\uC3FF", 8, "\uC409", 6, "\uC411", 9], + ["9c81", "\uC41B", 8, "\uC425", 6, "\uC42D\uC42E\uC42F\uC431\uC432\uC433\uC435", 6, "\uC43E", 9, "\uC449", 26, "\uC466\uC467\uC469\uC46A\uC46B\uC46D", 6, "\uC476\uC477\uC478\uC47A", 5, "\uC481", 18, "\uC495", 6, "\uC49D", 12], + ["9d41", "\uC4AA", 13, "\uC4B9\uC4BA\uC4BB\uC4BD", 8], + ["9d61", "\uC4C6", 25], + ["9d81", "\uC4E0", 8, "\uC4EA", 5, "\uC4F2\uC4F3\uC4F5\uC4F6\uC4F7\uC4F9\uC4FB\uC4FC\uC4FD\uC4FE\uC502", 9, "\uC50D\uC50E\uC50F\uC511\uC512\uC513\uC515", 6, "\uC51D", 10, "\uC52A\uC52B\uC52D\uC52E\uC52F\uC531", 6, "\uC53A\uC53C\uC53E", 5, "\uC546\uC547\uC54B\uC54F\uC550\uC551\uC552\uC556\uC55A\uC55B\uC55C\uC55F\uC562\uC563\uC565\uC566\uC567\uC569", 6, "\uC572\uC576", 5, "\uC57E\uC57F\uC581\uC582\uC583\uC585\uC586\uC588\uC589\uC58A\uC58B\uC58E\uC590\uC592\uC593\uC594"], + ["9e41", "\uC596\uC599\uC59A\uC59B\uC59D\uC59E\uC59F\uC5A1", 7, "\uC5AA", 9, "\uC5B6"], + ["9e61", "\uC5B7\uC5BA\uC5BF", 4, "\uC5CB\uC5CD\uC5CF\uC5D2\uC5D3\uC5D5\uC5D6\uC5D7\uC5D9", 6, "\uC5E2\uC5E4\uC5E6\uC5E7"], + ["9e81", "\uC5E8\uC5E9\uC5EA\uC5EB\uC5EF\uC5F1\uC5F2\uC5F3\uC5F5\uC5F8\uC5F9\uC5FA\uC5FB\uC602\uC603\uC604\uC609\uC60A\uC60B\uC60D\uC60E\uC60F\uC611", 6, "\uC61A\uC61D", 6, "\uC626\uC627\uC629\uC62A\uC62B\uC62F\uC631\uC632\uC636\uC638\uC63A\uC63C\uC63D\uC63E\uC63F\uC642\uC643\uC645\uC646\uC647\uC649", 6, "\uC652\uC656", 5, "\uC65E\uC65F\uC661", 10, "\uC66D\uC66E\uC670\uC672", 5, "\uC67A\uC67B\uC67D\uC67E\uC67F\uC681", 6, "\uC68A\uC68C\uC68E", 5, "\uC696\uC697\uC699\uC69A\uC69B\uC69D", 6, "\uC6A6"], + ["9f41", "\uC6A8\uC6AA", 5, "\uC6B2\uC6B3\uC6B5\uC6B6\uC6B7\uC6BB", 4, "\uC6C2\uC6C4\uC6C6", 5, "\uC6CE"], + ["9f61", "\uC6CF\uC6D1\uC6D2\uC6D3\uC6D5", 6, "\uC6DE\uC6DF\uC6E2", 5, "\uC6EA\uC6EB\uC6ED\uC6EE\uC6EF\uC6F1\uC6F2"], + ["9f81", "\uC6F3", 4, "\uC6FA\uC6FB\uC6FC\uC6FE", 5, "\uC706\uC707\uC709\uC70A\uC70B\uC70D", 6, "\uC716\uC718\uC71A", 5, "\uC722\uC723\uC725\uC726\uC727\uC729", 6, "\uC732\uC734\uC736\uC738\uC739\uC73A\uC73B\uC73E\uC73F\uC741\uC742\uC743\uC745", 4, "\uC74B\uC74E\uC750\uC759\uC75A\uC75B\uC75D\uC75E\uC75F\uC761", 6, "\uC769\uC76A\uC76C", 7, "\uC776\uC777\uC779\uC77A\uC77B\uC77F\uC780\uC781\uC782\uC786\uC78B\uC78C\uC78D\uC78F\uC792\uC793\uC795\uC799\uC79B", 4, "\uC7A2\uC7A7", 4, "\uC7AE\uC7AF\uC7B1\uC7B2\uC7B3\uC7B5\uC7B6\uC7B7"], + ["a041", "\uC7B8\uC7B9\uC7BA\uC7BB\uC7BE\uC7C2", 5, "\uC7CA\uC7CB\uC7CD\uC7CF\uC7D1", 6, "\uC7D9\uC7DA\uC7DB\uC7DC"], + ["a061", "\uC7DE", 5, "\uC7E5\uC7E6\uC7E7\uC7E9\uC7EA\uC7EB\uC7ED", 13], + ["a081", "\uC7FB", 4, "\uC802\uC803\uC805\uC806\uC807\uC809\uC80B", 4, "\uC812\uC814\uC817", 4, "\uC81E\uC81F\uC821\uC822\uC823\uC825", 6, "\uC82E\uC830\uC832", 5, "\uC839\uC83A\uC83B\uC83D\uC83E\uC83F\uC841", 6, "\uC84A\uC84B\uC84E", 5, "\uC855", 26, "\uC872\uC873\uC875\uC876\uC877\uC879\uC87B", 4, "\uC882\uC884\uC888\uC889\uC88A\uC88E", 5, "\uC895", 7, "\uC89E\uC8A0\uC8A2\uC8A3\uC8A4"], + ["a141", "\uC8A5\uC8A6\uC8A7\uC8A9", 18, "\uC8BE\uC8BF\uC8C0\uC8C1"], + ["a161", "\uC8C2\uC8C3\uC8C5\uC8C6\uC8C7\uC8C9\uC8CA\uC8CB\uC8CD", 6, "\uC8D6\uC8D8\uC8DA", 5, "\uC8E2\uC8E3\uC8E5"], + ["a181", "\uC8E6", 14, "\uC8F6", 5, "\uC8FE\uC8FF\uC901\uC902\uC903\uC907", 4, "\uC90E\u3000\u3001\u3002\xB7\u2025\u2026\xA8\u3003\xAD\u2015\u2225\uFF3C\u223C\u2018\u2019\u201C\u201D\u3014\u3015\u3008", 9, "\xB1\xD7\xF7\u2260\u2264\u2265\u221E\u2234\xB0\u2032\u2033\u2103\u212B\uFFE0\uFFE1\uFFE5\u2642\u2640\u2220\u22A5\u2312\u2202\u2207\u2261\u2252\xA7\u203B\u2606\u2605\u25CB\u25CF\u25CE\u25C7\u25C6\u25A1\u25A0\u25B3\u25B2\u25BD\u25BC\u2192\u2190\u2191\u2193\u2194\u3013\u226A\u226B\u221A\u223D\u221D\u2235\u222B\u222C\u2208\u220B\u2286\u2287\u2282\u2283\u222A\u2229\u2227\u2228\uFFE2"], + ["a241", "\uC910\uC912", 5, "\uC919", 18], + ["a261", "\uC92D", 6, "\uC935", 18], + ["a281", "\uC948", 7, "\uC952\uC953\uC955\uC956\uC957\uC959", 6, "\uC962\uC964", 7, "\uC96D\uC96E\uC96F\u21D2\u21D4\u2200\u2203\xB4\uFF5E\u02C7\u02D8\u02DD\u02DA\u02D9\xB8\u02DB\xA1\xBF\u02D0\u222E\u2211\u220F\xA4\u2109\u2030\u25C1\u25C0\u25B7\u25B6\u2664\u2660\u2661\u2665\u2667\u2663\u2299\u25C8\u25A3\u25D0\u25D1\u2592\u25A4\u25A5\u25A8\u25A7\u25A6\u25A9\u2668\u260F\u260E\u261C\u261E\xB6\u2020\u2021\u2195\u2197\u2199\u2196\u2198\u266D\u2669\u266A\u266C\u327F\u321C\u2116\u33C7\u2122\u33C2\u33D8\u2121\u20AC\xAE"], + ["a341", "\uC971\uC972\uC973\uC975", 6, "\uC97D", 10, "\uC98A\uC98B\uC98D\uC98E\uC98F"], + ["a361", "\uC991", 6, "\uC99A\uC99C\uC99E", 16], + ["a381", "\uC9AF", 16, "\uC9C2\uC9C3\uC9C5\uC9C6\uC9C9\uC9CB", 4, "\uC9D2\uC9D4\uC9D7\uC9D8\uC9DB\uFF01", 58, "\uFFE6\uFF3D", 32, "\uFFE3"], + ["a441", "\uC9DE\uC9DF\uC9E1\uC9E3\uC9E5\uC9E6\uC9E8\uC9E9\uC9EA\uC9EB\uC9EE\uC9F2", 5, "\uC9FA\uC9FB\uC9FD\uC9FE\uC9FF\uCA01\uCA02\uCA03\uCA04"], + ["a461", "\uCA05\uCA06\uCA07\uCA0A\uCA0E", 5, "\uCA15\uCA16\uCA17\uCA19", 12], + ["a481", "\uCA26\uCA27\uCA28\uCA2A", 28, "\u3131", 93], + ["a541", "\uCA47", 4, "\uCA4E\uCA4F\uCA51\uCA52\uCA53\uCA55", 6, "\uCA5E\uCA62", 5, "\uCA69\uCA6A"], + ["a561", "\uCA6B", 17, "\uCA7E", 5, "\uCA85\uCA86"], + ["a581", "\uCA87", 16, "\uCA99", 14, "\u2170", 9], + ["a5b0", "\u2160", 9], + ["a5c1", "\u0391", 16, "\u03A3", 6], + ["a5e1", "\u03B1", 16, "\u03C3", 6], + ["a641", "\uCAA8", 19, "\uCABE\uCABF\uCAC1\uCAC2\uCAC3\uCAC5"], + ["a661", "\uCAC6", 5, "\uCACE\uCAD0\uCAD2\uCAD4\uCAD5\uCAD6\uCAD7\uCADA", 5, "\uCAE1", 6], + ["a681", "\uCAE8\uCAE9\uCAEA\uCAEB\uCAED", 6, "\uCAF5", 18, "\uCB09\uCB0A\u2500\u2502\u250C\u2510\u2518\u2514\u251C\u252C\u2524\u2534\u253C\u2501\u2503\u250F\u2513\u251B\u2517\u2523\u2533\u252B\u253B\u254B\u2520\u252F\u2528\u2537\u253F\u251D\u2530\u2525\u2538\u2542\u2512\u2511\u251A\u2519\u2516\u2515\u250E\u250D\u251E\u251F\u2521\u2522\u2526\u2527\u2529\u252A\u252D\u252E\u2531\u2532\u2535\u2536\u2539\u253A\u253D\u253E\u2540\u2541\u2543", 7], + ["a741", "\uCB0B", 4, "\uCB11\uCB12\uCB13\uCB15\uCB16\uCB17\uCB19", 6, "\uCB22", 7], + ["a761", "\uCB2A", 22, "\uCB42\uCB43\uCB44"], + ["a781", "\uCB45\uCB46\uCB47\uCB4A\uCB4B\uCB4D\uCB4E\uCB4F\uCB51", 6, "\uCB5A\uCB5B\uCB5C\uCB5E", 5, "\uCB65", 7, "\u3395\u3396\u3397\u2113\u3398\u33C4\u33A3\u33A4\u33A5\u33A6\u3399", 9, "\u33CA\u338D\u338E\u338F\u33CF\u3388\u3389\u33C8\u33A7\u33A8\u33B0", 9, "\u3380", 4, "\u33BA", 5, "\u3390", 4, "\u2126\u33C0\u33C1\u338A\u338B\u338C\u33D6\u33C5\u33AD\u33AE\u33AF\u33DB\u33A9\u33AA\u33AB\u33AC\u33DD\u33D0\u33D3\u33C3\u33C9\u33DC\u33C6"], + ["a841", "\uCB6D", 10, "\uCB7A", 14], + ["a861", "\uCB89", 18, "\uCB9D", 6], + ["a881", "\uCBA4", 19, "\uCBB9", 11, "\xC6\xD0\xAA\u0126"], + ["a8a6", "\u0132"], + ["a8a8", "\u013F\u0141\xD8\u0152\xBA\xDE\u0166\u014A"], + ["a8b1", "\u3260", 27, "\u24D0", 25, "\u2460", 14, "\xBD\u2153\u2154\xBC\xBE\u215B\u215C\u215D\u215E"], + ["a941", "\uCBC5", 14, "\uCBD5", 10], + ["a961", "\uCBE0\uCBE1\uCBE2\uCBE3\uCBE5\uCBE6\uCBE8\uCBEA", 18], + ["a981", "\uCBFD", 14, "\uCC0E\uCC0F\uCC11\uCC12\uCC13\uCC15", 6, "\uCC1E\uCC1F\uCC20\uCC23\uCC24\xE6\u0111\xF0\u0127\u0131\u0133\u0138\u0140\u0142\xF8\u0153\xDF\xFE\u0167\u014B\u0149\u3200", 27, "\u249C", 25, "\u2474", 14, "\xB9\xB2\xB3\u2074\u207F\u2081\u2082\u2083\u2084"], + ["aa41", "\uCC25\uCC26\uCC2A\uCC2B\uCC2D\uCC2F\uCC31", 6, "\uCC3A\uCC3F", 4, "\uCC46\uCC47\uCC49\uCC4A\uCC4B\uCC4D\uCC4E"], + ["aa61", "\uCC4F", 4, "\uCC56\uCC5A", 5, "\uCC61\uCC62\uCC63\uCC65\uCC67\uCC69", 6, "\uCC71\uCC72"], + ["aa81", "\uCC73\uCC74\uCC76", 29, "\u3041", 82], + ["ab41", "\uCC94\uCC95\uCC96\uCC97\uCC9A\uCC9B\uCC9D\uCC9E\uCC9F\uCCA1", 6, "\uCCAA\uCCAE", 5, "\uCCB6\uCCB7\uCCB9"], + ["ab61", "\uCCBA\uCCBB\uCCBD", 6, "\uCCC6\uCCC8\uCCCA", 5, "\uCCD1\uCCD2\uCCD3\uCCD5", 5], + ["ab81", "\uCCDB", 8, "\uCCE5", 6, "\uCCED\uCCEE\uCCEF\uCCF1", 12, "\u30A1", 85], + ["ac41", "\uCCFE\uCCFF\uCD00\uCD02", 5, "\uCD0A\uCD0B\uCD0D\uCD0E\uCD0F\uCD11", 6, "\uCD1A\uCD1C\uCD1E\uCD1F\uCD20"], + ["ac61", "\uCD21\uCD22\uCD23\uCD25\uCD26\uCD27\uCD29\uCD2A\uCD2B\uCD2D", 11, "\uCD3A", 4], + ["ac81", "\uCD3F", 28, "\uCD5D\uCD5E\uCD5F\u0410", 5, "\u0401\u0416", 25], + ["acd1", "\u0430", 5, "\u0451\u0436", 25], + ["ad41", "\uCD61\uCD62\uCD63\uCD65", 6, "\uCD6E\uCD70\uCD72", 5, "\uCD79", 7], + ["ad61", "\uCD81", 6, "\uCD89", 10, "\uCD96\uCD97\uCD99\uCD9A\uCD9B\uCD9D\uCD9E\uCD9F"], + ["ad81", "\uCDA0\uCDA1\uCDA2\uCDA3\uCDA6\uCDA8\uCDAA", 5, "\uCDB1", 18, "\uCDC5"], + ["ae41", "\uCDC6", 5, "\uCDCD\uCDCE\uCDCF\uCDD1", 16], + ["ae61", "\uCDE2", 5, "\uCDE9\uCDEA\uCDEB\uCDED\uCDEE\uCDEF\uCDF1", 6, "\uCDFA\uCDFC\uCDFE", 4], + ["ae81", "\uCE03\uCE05\uCE06\uCE07\uCE09\uCE0A\uCE0B\uCE0D", 6, "\uCE15\uCE16\uCE17\uCE18\uCE1A", 5, "\uCE22\uCE23\uCE25\uCE26\uCE27\uCE29\uCE2A\uCE2B"], + ["af41", "\uCE2C\uCE2D\uCE2E\uCE2F\uCE32\uCE34\uCE36", 19], + ["af61", "\uCE4A", 13, "\uCE5A\uCE5B\uCE5D\uCE5E\uCE62", 5, "\uCE6A\uCE6C"], + ["af81", "\uCE6E", 5, "\uCE76\uCE77\uCE79\uCE7A\uCE7B\uCE7D", 6, "\uCE86\uCE88\uCE8A", 5, "\uCE92\uCE93\uCE95\uCE96\uCE97\uCE99"], + ["b041", "\uCE9A", 5, "\uCEA2\uCEA6", 5, "\uCEAE", 12], + ["b061", "\uCEBB", 5, "\uCEC2", 19], + ["b081", "\uCED6", 13, "\uCEE6\uCEE7\uCEE9\uCEEA\uCEED", 6, "\uCEF6\uCEFA", 5, "\uAC00\uAC01\uAC04\uAC07\uAC08\uAC09\uAC0A\uAC10", 7, "\uAC19", 4, "\uAC20\uAC24\uAC2C\uAC2D\uAC2F\uAC30\uAC31\uAC38\uAC39\uAC3C\uAC40\uAC4B\uAC4D\uAC54\uAC58\uAC5C\uAC70\uAC71\uAC74\uAC77\uAC78\uAC7A\uAC80\uAC81\uAC83\uAC84\uAC85\uAC86\uAC89\uAC8A\uAC8B\uAC8C\uAC90\uAC94\uAC9C\uAC9D\uAC9F\uACA0\uACA1\uACA8\uACA9\uACAA\uACAC\uACAF\uACB0\uACB8\uACB9\uACBB\uACBC\uACBD\uACC1\uACC4\uACC8\uACCC\uACD5\uACD7\uACE0\uACE1\uACE4\uACE7\uACE8\uACEA\uACEC\uACEF\uACF0\uACF1\uACF3\uACF5\uACF6\uACFC\uACFD\uAD00\uAD04\uAD06"], + ["b141", "\uCF02\uCF03\uCF05\uCF06\uCF07\uCF09", 6, "\uCF12\uCF14\uCF16", 5, "\uCF1D\uCF1E\uCF1F\uCF21\uCF22\uCF23"], + ["b161", "\uCF25", 6, "\uCF2E\uCF32", 5, "\uCF39", 11], + ["b181", "\uCF45", 14, "\uCF56\uCF57\uCF59\uCF5A\uCF5B\uCF5D", 6, "\uCF66\uCF68\uCF6A\uCF6B\uCF6C\uAD0C\uAD0D\uAD0F\uAD11\uAD18\uAD1C\uAD20\uAD29\uAD2C\uAD2D\uAD34\uAD35\uAD38\uAD3C\uAD44\uAD45\uAD47\uAD49\uAD50\uAD54\uAD58\uAD61\uAD63\uAD6C\uAD6D\uAD70\uAD73\uAD74\uAD75\uAD76\uAD7B\uAD7C\uAD7D\uAD7F\uAD81\uAD82\uAD88\uAD89\uAD8C\uAD90\uAD9C\uAD9D\uADA4\uADB7\uADC0\uADC1\uADC4\uADC8\uADD0\uADD1\uADD3\uADDC\uADE0\uADE4\uADF8\uADF9\uADFC\uADFF\uAE00\uAE01\uAE08\uAE09\uAE0B\uAE0D\uAE14\uAE30\uAE31\uAE34\uAE37\uAE38\uAE3A\uAE40\uAE41\uAE43\uAE45\uAE46\uAE4A\uAE4C\uAE4D\uAE4E\uAE50\uAE54\uAE56\uAE5C\uAE5D\uAE5F\uAE60\uAE61\uAE65\uAE68\uAE69\uAE6C\uAE70\uAE78"], + ["b241", "\uCF6D\uCF6E\uCF6F\uCF72\uCF73\uCF75\uCF76\uCF77\uCF79", 6, "\uCF81\uCF82\uCF83\uCF84\uCF86", 5, "\uCF8D"], + ["b261", "\uCF8E", 18, "\uCFA2", 5, "\uCFA9"], + ["b281", "\uCFAA", 5, "\uCFB1", 18, "\uCFC5", 6, "\uAE79\uAE7B\uAE7C\uAE7D\uAE84\uAE85\uAE8C\uAEBC\uAEBD\uAEBE\uAEC0\uAEC4\uAECC\uAECD\uAECF\uAED0\uAED1\uAED8\uAED9\uAEDC\uAEE8\uAEEB\uAEED\uAEF4\uAEF8\uAEFC\uAF07\uAF08\uAF0D\uAF10\uAF2C\uAF2D\uAF30\uAF32\uAF34\uAF3C\uAF3D\uAF3F\uAF41\uAF42\uAF43\uAF48\uAF49\uAF50\uAF5C\uAF5D\uAF64\uAF65\uAF79\uAF80\uAF84\uAF88\uAF90\uAF91\uAF95\uAF9C\uAFB8\uAFB9\uAFBC\uAFC0\uAFC7\uAFC8\uAFC9\uAFCB\uAFCD\uAFCE\uAFD4\uAFDC\uAFE8\uAFE9\uAFF0\uAFF1\uAFF4\uAFF8\uB000\uB001\uB004\uB00C\uB010\uB014\uB01C\uB01D\uB028\uB044\uB045\uB048\uB04A\uB04C\uB04E\uB053\uB054\uB055\uB057\uB059"], + ["b341", "\uCFCC", 19, "\uCFE2\uCFE3\uCFE5\uCFE6\uCFE7\uCFE9"], + ["b361", "\uCFEA", 5, "\uCFF2\uCFF4\uCFF6", 5, "\uCFFD\uCFFE\uCFFF\uD001\uD002\uD003\uD005", 5], + ["b381", "\uD00B", 5, "\uD012", 5, "\uD019", 19, "\uB05D\uB07C\uB07D\uB080\uB084\uB08C\uB08D\uB08F\uB091\uB098\uB099\uB09A\uB09C\uB09F\uB0A0\uB0A1\uB0A2\uB0A8\uB0A9\uB0AB", 4, "\uB0B1\uB0B3\uB0B4\uB0B5\uB0B8\uB0BC\uB0C4\uB0C5\uB0C7\uB0C8\uB0C9\uB0D0\uB0D1\uB0D4\uB0D8\uB0E0\uB0E5\uB108\uB109\uB10B\uB10C\uB110\uB112\uB113\uB118\uB119\uB11B\uB11C\uB11D\uB123\uB124\uB125\uB128\uB12C\uB134\uB135\uB137\uB138\uB139\uB140\uB141\uB144\uB148\uB150\uB151\uB154\uB155\uB158\uB15C\uB160\uB178\uB179\uB17C\uB180\uB182\uB188\uB189\uB18B\uB18D\uB192\uB193\uB194\uB198\uB19C\uB1A8\uB1CC\uB1D0\uB1D4\uB1DC\uB1DD"], + ["b441", "\uD02E", 5, "\uD036\uD037\uD039\uD03A\uD03B\uD03D", 6, "\uD046\uD048\uD04A", 5], + ["b461", "\uD051\uD052\uD053\uD055\uD056\uD057\uD059", 6, "\uD061", 10, "\uD06E\uD06F"], + ["b481", "\uD071\uD072\uD073\uD075", 6, "\uD07E\uD07F\uD080\uD082", 18, "\uB1DF\uB1E8\uB1E9\uB1EC\uB1F0\uB1F9\uB1FB\uB1FD\uB204\uB205\uB208\uB20B\uB20C\uB214\uB215\uB217\uB219\uB220\uB234\uB23C\uB258\uB25C\uB260\uB268\uB269\uB274\uB275\uB27C\uB284\uB285\uB289\uB290\uB291\uB294\uB298\uB299\uB29A\uB2A0\uB2A1\uB2A3\uB2A5\uB2A6\uB2AA\uB2AC\uB2B0\uB2B4\uB2C8\uB2C9\uB2CC\uB2D0\uB2D2\uB2D8\uB2D9\uB2DB\uB2DD\uB2E2\uB2E4\uB2E5\uB2E6\uB2E8\uB2EB", 4, "\uB2F3\uB2F4\uB2F5\uB2F7", 4, "\uB2FF\uB300\uB301\uB304\uB308\uB310\uB311\uB313\uB314\uB315\uB31C\uB354\uB355\uB356\uB358\uB35B\uB35C\uB35E\uB35F\uB364\uB365"], + ["b541", "\uD095", 14, "\uD0A6\uD0A7\uD0A9\uD0AA\uD0AB\uD0AD", 5], + ["b561", "\uD0B3\uD0B6\uD0B8\uD0BA", 5, "\uD0C2\uD0C3\uD0C5\uD0C6\uD0C7\uD0CA", 5, "\uD0D2\uD0D6", 4], + ["b581", "\uD0DB\uD0DE\uD0DF\uD0E1\uD0E2\uD0E3\uD0E5", 6, "\uD0EE\uD0F2", 5, "\uD0F9", 11, "\uB367\uB369\uB36B\uB36E\uB370\uB371\uB374\uB378\uB380\uB381\uB383\uB384\uB385\uB38C\uB390\uB394\uB3A0\uB3A1\uB3A8\uB3AC\uB3C4\uB3C5\uB3C8\uB3CB\uB3CC\uB3CE\uB3D0\uB3D4\uB3D5\uB3D7\uB3D9\uB3DB\uB3DD\uB3E0\uB3E4\uB3E8\uB3FC\uB410\uB418\uB41C\uB420\uB428\uB429\uB42B\uB434\uB450\uB451\uB454\uB458\uB460\uB461\uB463\uB465\uB46C\uB480\uB488\uB49D\uB4A4\uB4A8\uB4AC\uB4B5\uB4B7\uB4B9\uB4C0\uB4C4\uB4C8\uB4D0\uB4D5\uB4DC\uB4DD\uB4E0\uB4E3\uB4E4\uB4E6\uB4EC\uB4ED\uB4EF\uB4F1\uB4F8\uB514\uB515\uB518\uB51B\uB51C\uB524\uB525\uB527\uB528\uB529\uB52A\uB530\uB531\uB534\uB538"], + ["b641", "\uD105", 7, "\uD10E", 17], + ["b661", "\uD120", 15, "\uD132\uD133\uD135\uD136\uD137\uD139\uD13B\uD13C\uD13D\uD13E"], + ["b681", "\uD13F\uD142\uD146", 5, "\uD14E\uD14F\uD151\uD152\uD153\uD155", 6, "\uD15E\uD160\uD162", 5, "\uD169\uD16A\uD16B\uD16D\uB540\uB541\uB543\uB544\uB545\uB54B\uB54C\uB54D\uB550\uB554\uB55C\uB55D\uB55F\uB560\uB561\uB5A0\uB5A1\uB5A4\uB5A8\uB5AA\uB5AB\uB5B0\uB5B1\uB5B3\uB5B4\uB5B5\uB5BB\uB5BC\uB5BD\uB5C0\uB5C4\uB5CC\uB5CD\uB5CF\uB5D0\uB5D1\uB5D8\uB5EC\uB610\uB611\uB614\uB618\uB625\uB62C\uB634\uB648\uB664\uB668\uB69C\uB69D\uB6A0\uB6A4\uB6AB\uB6AC\uB6B1\uB6D4\uB6F0\uB6F4\uB6F8\uB700\uB701\uB705\uB728\uB729\uB72C\uB72F\uB730\uB738\uB739\uB73B\uB744\uB748\uB74C\uB754\uB755\uB760\uB764\uB768\uB770\uB771\uB773\uB775\uB77C\uB77D\uB780\uB784\uB78C\uB78D\uB78F\uB790\uB791\uB792\uB796\uB797"], + ["b741", "\uD16E", 13, "\uD17D", 6, "\uD185\uD186\uD187\uD189\uD18A"], + ["b761", "\uD18B", 20, "\uD1A2\uD1A3\uD1A5\uD1A6\uD1A7"], + ["b781", "\uD1A9", 6, "\uD1B2\uD1B4\uD1B6\uD1B7\uD1B8\uD1B9\uD1BB\uD1BD\uD1BE\uD1BF\uD1C1", 14, "\uB798\uB799\uB79C\uB7A0\uB7A8\uB7A9\uB7AB\uB7AC\uB7AD\uB7B4\uB7B5\uB7B8\uB7C7\uB7C9\uB7EC\uB7ED\uB7F0\uB7F4\uB7FC\uB7FD\uB7FF\uB800\uB801\uB807\uB808\uB809\uB80C\uB810\uB818\uB819\uB81B\uB81D\uB824\uB825\uB828\uB82C\uB834\uB835\uB837\uB838\uB839\uB840\uB844\uB851\uB853\uB85C\uB85D\uB860\uB864\uB86C\uB86D\uB86F\uB871\uB878\uB87C\uB88D\uB8A8\uB8B0\uB8B4\uB8B8\uB8C0\uB8C1\uB8C3\uB8C5\uB8CC\uB8D0\uB8D4\uB8DD\uB8DF\uB8E1\uB8E8\uB8E9\uB8EC\uB8F0\uB8F8\uB8F9\uB8FB\uB8FD\uB904\uB918\uB920\uB93C\uB93D\uB940\uB944\uB94C\uB94F\uB951\uB958\uB959\uB95C\uB960\uB968\uB969"], + ["b841", "\uD1D0", 7, "\uD1D9", 17], + ["b861", "\uD1EB", 8, "\uD1F5\uD1F6\uD1F7\uD1F9", 13], + ["b881", "\uD208\uD20A", 5, "\uD211", 24, "\uB96B\uB96D\uB974\uB975\uB978\uB97C\uB984\uB985\uB987\uB989\uB98A\uB98D\uB98E\uB9AC\uB9AD\uB9B0\uB9B4\uB9BC\uB9BD\uB9BF\uB9C1\uB9C8\uB9C9\uB9CC\uB9CE", 4, "\uB9D8\uB9D9\uB9DB\uB9DD\uB9DE\uB9E1\uB9E3\uB9E4\uB9E5\uB9E8\uB9EC\uB9F4\uB9F5\uB9F7\uB9F8\uB9F9\uB9FA\uBA00\uBA01\uBA08\uBA15\uBA38\uBA39\uBA3C\uBA40\uBA42\uBA48\uBA49\uBA4B\uBA4D\uBA4E\uBA53\uBA54\uBA55\uBA58\uBA5C\uBA64\uBA65\uBA67\uBA68\uBA69\uBA70\uBA71\uBA74\uBA78\uBA83\uBA84\uBA85\uBA87\uBA8C\uBAA8\uBAA9\uBAAB\uBAAC\uBAB0\uBAB2\uBAB8\uBAB9\uBABB\uBABD\uBAC4\uBAC8\uBAD8\uBAD9\uBAFC"], + ["b941", "\uD22A\uD22B\uD22E\uD22F\uD231\uD232\uD233\uD235", 6, "\uD23E\uD240\uD242", 5, "\uD249\uD24A\uD24B\uD24C"], + ["b961", "\uD24D", 14, "\uD25D", 6, "\uD265\uD266\uD267\uD268"], + ["b981", "\uD269", 22, "\uD282\uD283\uD285\uD286\uD287\uD289\uD28A\uD28B\uD28C\uBB00\uBB04\uBB0D\uBB0F\uBB11\uBB18\uBB1C\uBB20\uBB29\uBB2B\uBB34\uBB35\uBB36\uBB38\uBB3B\uBB3C\uBB3D\uBB3E\uBB44\uBB45\uBB47\uBB49\uBB4D\uBB4F\uBB50\uBB54\uBB58\uBB61\uBB63\uBB6C\uBB88\uBB8C\uBB90\uBBA4\uBBA8\uBBAC\uBBB4\uBBB7\uBBC0\uBBC4\uBBC8\uBBD0\uBBD3\uBBF8\uBBF9\uBBFC\uBBFF\uBC00\uBC02\uBC08\uBC09\uBC0B\uBC0C\uBC0D\uBC0F\uBC11\uBC14", 4, "\uBC1B", 4, "\uBC24\uBC25\uBC27\uBC29\uBC2D\uBC30\uBC31\uBC34\uBC38\uBC40\uBC41\uBC43\uBC44\uBC45\uBC49\uBC4C\uBC4D\uBC50\uBC5D\uBC84\uBC85\uBC88\uBC8B\uBC8C\uBC8E\uBC94\uBC95\uBC97"], + ["ba41", "\uD28D\uD28E\uD28F\uD292\uD293\uD294\uD296", 5, "\uD29D\uD29E\uD29F\uD2A1\uD2A2\uD2A3\uD2A5", 6, "\uD2AD"], + ["ba61", "\uD2AE\uD2AF\uD2B0\uD2B2", 5, "\uD2BA\uD2BB\uD2BD\uD2BE\uD2C1\uD2C3", 4, "\uD2CA\uD2CC", 5], + ["ba81", "\uD2D2\uD2D3\uD2D5\uD2D6\uD2D7\uD2D9\uD2DA\uD2DB\uD2DD", 6, "\uD2E6", 9, "\uD2F2\uD2F3\uD2F5\uD2F6\uD2F7\uD2F9\uD2FA\uBC99\uBC9A\uBCA0\uBCA1\uBCA4\uBCA7\uBCA8\uBCB0\uBCB1\uBCB3\uBCB4\uBCB5\uBCBC\uBCBD\uBCC0\uBCC4\uBCCD\uBCCF\uBCD0\uBCD1\uBCD5\uBCD8\uBCDC\uBCF4\uBCF5\uBCF6\uBCF8\uBCFC\uBD04\uBD05\uBD07\uBD09\uBD10\uBD14\uBD24\uBD2C\uBD40\uBD48\uBD49\uBD4C\uBD50\uBD58\uBD59\uBD64\uBD68\uBD80\uBD81\uBD84\uBD87\uBD88\uBD89\uBD8A\uBD90\uBD91\uBD93\uBD95\uBD99\uBD9A\uBD9C\uBDA4\uBDB0\uBDB8\uBDD4\uBDD5\uBDD8\uBDDC\uBDE9\uBDF0\uBDF4\uBDF8\uBE00\uBE03\uBE05\uBE0C\uBE0D\uBE10\uBE14\uBE1C\uBE1D\uBE1F\uBE44\uBE45\uBE48\uBE4C\uBE4E\uBE54\uBE55\uBE57\uBE59\uBE5A\uBE5B\uBE60\uBE61\uBE64"], + ["bb41", "\uD2FB", 4, "\uD302\uD304\uD306", 5, "\uD30F\uD311\uD312\uD313\uD315\uD317", 4, "\uD31E\uD322\uD323"], + ["bb61", "\uD324\uD326\uD327\uD32A\uD32B\uD32D\uD32E\uD32F\uD331", 6, "\uD33A\uD33E", 5, "\uD346\uD347\uD348\uD349"], + ["bb81", "\uD34A", 31, "\uBE68\uBE6A\uBE70\uBE71\uBE73\uBE74\uBE75\uBE7B\uBE7C\uBE7D\uBE80\uBE84\uBE8C\uBE8D\uBE8F\uBE90\uBE91\uBE98\uBE99\uBEA8\uBED0\uBED1\uBED4\uBED7\uBED8\uBEE0\uBEE3\uBEE4\uBEE5\uBEEC\uBF01\uBF08\uBF09\uBF18\uBF19\uBF1B\uBF1C\uBF1D\uBF40\uBF41\uBF44\uBF48\uBF50\uBF51\uBF55\uBF94\uBFB0\uBFC5\uBFCC\uBFCD\uBFD0\uBFD4\uBFDC\uBFDF\uBFE1\uC03C\uC051\uC058\uC05C\uC060\uC068\uC069\uC090\uC091\uC094\uC098\uC0A0\uC0A1\uC0A3\uC0A5\uC0AC\uC0AD\uC0AF\uC0B0\uC0B3\uC0B4\uC0B5\uC0B6\uC0BC\uC0BD\uC0BF\uC0C0\uC0C1\uC0C5\uC0C8\uC0C9\uC0CC\uC0D0\uC0D8\uC0D9\uC0DB\uC0DC\uC0DD\uC0E4"], + ["bc41", "\uD36A", 17, "\uD37E\uD37F\uD381\uD382\uD383\uD385\uD386\uD387"], + ["bc61", "\uD388\uD389\uD38A\uD38B\uD38E\uD392", 5, "\uD39A\uD39B\uD39D\uD39E\uD39F\uD3A1", 6, "\uD3AA\uD3AC\uD3AE"], + ["bc81", "\uD3AF", 4, "\uD3B5\uD3B6\uD3B7\uD3B9\uD3BA\uD3BB\uD3BD", 6, "\uD3C6\uD3C7\uD3CA", 5, "\uD3D1", 5, "\uC0E5\uC0E8\uC0EC\uC0F4\uC0F5\uC0F7\uC0F9\uC100\uC104\uC108\uC110\uC115\uC11C", 4, "\uC123\uC124\uC126\uC127\uC12C\uC12D\uC12F\uC130\uC131\uC136\uC138\uC139\uC13C\uC140\uC148\uC149\uC14B\uC14C\uC14D\uC154\uC155\uC158\uC15C\uC164\uC165\uC167\uC168\uC169\uC170\uC174\uC178\uC185\uC18C\uC18D\uC18E\uC190\uC194\uC196\uC19C\uC19D\uC19F\uC1A1\uC1A5\uC1A8\uC1A9\uC1AC\uC1B0\uC1BD\uC1C4\uC1C8\uC1CC\uC1D4\uC1D7\uC1D8\uC1E0\uC1E4\uC1E8\uC1F0\uC1F1\uC1F3\uC1FC\uC1FD\uC200\uC204\uC20C\uC20D\uC20F\uC211\uC218\uC219\uC21C\uC21F\uC220\uC228\uC229\uC22B\uC22D"], + ["bd41", "\uD3D7\uD3D9", 7, "\uD3E2\uD3E4", 7, "\uD3EE\uD3EF\uD3F1\uD3F2\uD3F3\uD3F5\uD3F6\uD3F7"], + ["bd61", "\uD3F8\uD3F9\uD3FA\uD3FB\uD3FE\uD400\uD402", 5, "\uD409", 13], + ["bd81", "\uD417", 5, "\uD41E", 25, "\uC22F\uC231\uC232\uC234\uC248\uC250\uC251\uC254\uC258\uC260\uC265\uC26C\uC26D\uC270\uC274\uC27C\uC27D\uC27F\uC281\uC288\uC289\uC290\uC298\uC29B\uC29D\uC2A4\uC2A5\uC2A8\uC2AC\uC2AD\uC2B4\uC2B5\uC2B7\uC2B9\uC2DC\uC2DD\uC2E0\uC2E3\uC2E4\uC2EB\uC2EC\uC2ED\uC2EF\uC2F1\uC2F6\uC2F8\uC2F9\uC2FB\uC2FC\uC300\uC308\uC309\uC30C\uC30D\uC313\uC314\uC315\uC318\uC31C\uC324\uC325\uC328\uC329\uC345\uC368\uC369\uC36C\uC370\uC372\uC378\uC379\uC37C\uC37D\uC384\uC388\uC38C\uC3C0\uC3D8\uC3D9\uC3DC\uC3DF\uC3E0\uC3E2\uC3E8\uC3E9\uC3ED\uC3F4\uC3F5\uC3F8\uC408\uC410\uC424\uC42C\uC430"], + ["be41", "\uD438", 7, "\uD441\uD442\uD443\uD445", 14], + ["be61", "\uD454", 7, "\uD45D\uD45E\uD45F\uD461\uD462\uD463\uD465", 7, "\uD46E\uD470\uD471\uD472"], + ["be81", "\uD473", 4, "\uD47A\uD47B\uD47D\uD47E\uD481\uD483", 4, "\uD48A\uD48C\uD48E", 5, "\uD495", 8, "\uC434\uC43C\uC43D\uC448\uC464\uC465\uC468\uC46C\uC474\uC475\uC479\uC480\uC494\uC49C\uC4B8\uC4BC\uC4E9\uC4F0\uC4F1\uC4F4\uC4F8\uC4FA\uC4FF\uC500\uC501\uC50C\uC510\uC514\uC51C\uC528\uC529\uC52C\uC530\uC538\uC539\uC53B\uC53D\uC544\uC545\uC548\uC549\uC54A\uC54C\uC54D\uC54E\uC553\uC554\uC555\uC557\uC558\uC559\uC55D\uC55E\uC560\uC561\uC564\uC568\uC570\uC571\uC573\uC574\uC575\uC57C\uC57D\uC580\uC584\uC587\uC58C\uC58D\uC58F\uC591\uC595\uC597\uC598\uC59C\uC5A0\uC5A9\uC5B4\uC5B5\uC5B8\uC5B9\uC5BB\uC5BC\uC5BD\uC5BE\uC5C4", 6, "\uC5CC\uC5CE"], + ["bf41", "\uD49E", 10, "\uD4AA", 14], + ["bf61", "\uD4B9", 18, "\uD4CD\uD4CE\uD4CF\uD4D1\uD4D2\uD4D3\uD4D5"], + ["bf81", "\uD4D6", 5, "\uD4DD\uD4DE\uD4E0", 7, "\uD4E9\uD4EA\uD4EB\uD4ED\uD4EE\uD4EF\uD4F1", 6, "\uD4F9\uD4FA\uD4FC\uC5D0\uC5D1\uC5D4\uC5D8\uC5E0\uC5E1\uC5E3\uC5E5\uC5EC\uC5ED\uC5EE\uC5F0\uC5F4\uC5F6\uC5F7\uC5FC", 5, "\uC605\uC606\uC607\uC608\uC60C\uC610\uC618\uC619\uC61B\uC61C\uC624\uC625\uC628\uC62C\uC62D\uC62E\uC630\uC633\uC634\uC635\uC637\uC639\uC63B\uC640\uC641\uC644\uC648\uC650\uC651\uC653\uC654\uC655\uC65C\uC65D\uC660\uC66C\uC66F\uC671\uC678\uC679\uC67C\uC680\uC688\uC689\uC68B\uC68D\uC694\uC695\uC698\uC69C\uC6A4\uC6A5\uC6A7\uC6A9\uC6B0\uC6B1\uC6B4\uC6B8\uC6B9\uC6BA\uC6C0\uC6C1\uC6C3\uC6C5\uC6CC\uC6CD\uC6D0\uC6D4\uC6DC\uC6DD\uC6E0\uC6E1\uC6E8"], + ["c041", "\uD4FE", 5, "\uD505\uD506\uD507\uD509\uD50A\uD50B\uD50D", 6, "\uD516\uD518", 5], + ["c061", "\uD51E", 25], + ["c081", "\uD538\uD539\uD53A\uD53B\uD53E\uD53F\uD541\uD542\uD543\uD545", 6, "\uD54E\uD550\uD552", 5, "\uD55A\uD55B\uD55D\uD55E\uD55F\uD561\uD562\uD563\uC6E9\uC6EC\uC6F0\uC6F8\uC6F9\uC6FD\uC704\uC705\uC708\uC70C\uC714\uC715\uC717\uC719\uC720\uC721\uC724\uC728\uC730\uC731\uC733\uC735\uC737\uC73C\uC73D\uC740\uC744\uC74A\uC74C\uC74D\uC74F\uC751", 7, "\uC75C\uC760\uC768\uC76B\uC774\uC775\uC778\uC77C\uC77D\uC77E\uC783\uC784\uC785\uC787\uC788\uC789\uC78A\uC78E\uC790\uC791\uC794\uC796\uC797\uC798\uC79A\uC7A0\uC7A1\uC7A3\uC7A4\uC7A5\uC7A6\uC7AC\uC7AD\uC7B0\uC7B4\uC7BC\uC7BD\uC7BF\uC7C0\uC7C1\uC7C8\uC7C9\uC7CC\uC7CE\uC7D0\uC7D8\uC7DD\uC7E4\uC7E8\uC7EC\uC800\uC801\uC804\uC808\uC80A"], + ["c141", "\uD564\uD566\uD567\uD56A\uD56C\uD56E", 5, "\uD576\uD577\uD579\uD57A\uD57B\uD57D", 6, "\uD586\uD58A\uD58B"], + ["c161", "\uD58C\uD58D\uD58E\uD58F\uD591", 19, "\uD5A6\uD5A7"], + ["c181", "\uD5A8", 31, "\uC810\uC811\uC813\uC815\uC816\uC81C\uC81D\uC820\uC824\uC82C\uC82D\uC82F\uC831\uC838\uC83C\uC840\uC848\uC849\uC84C\uC84D\uC854\uC870\uC871\uC874\uC878\uC87A\uC880\uC881\uC883\uC885\uC886\uC887\uC88B\uC88C\uC88D\uC894\uC89D\uC89F\uC8A1\uC8A8\uC8BC\uC8BD\uC8C4\uC8C8\uC8CC\uC8D4\uC8D5\uC8D7\uC8D9\uC8E0\uC8E1\uC8E4\uC8F5\uC8FC\uC8FD\uC900\uC904\uC905\uC906\uC90C\uC90D\uC90F\uC911\uC918\uC92C\uC934\uC950\uC951\uC954\uC958\uC960\uC961\uC963\uC96C\uC970\uC974\uC97C\uC988\uC989\uC98C\uC990\uC998\uC999\uC99B\uC99D\uC9C0\uC9C1\uC9C4\uC9C7\uC9C8\uC9CA\uC9D0\uC9D1\uC9D3"], + ["c241", "\uD5CA\uD5CB\uD5CD\uD5CE\uD5CF\uD5D1\uD5D3", 4, "\uD5DA\uD5DC\uD5DE", 5, "\uD5E6\uD5E7\uD5E9\uD5EA\uD5EB\uD5ED\uD5EE"], + ["c261", "\uD5EF", 4, "\uD5F6\uD5F8\uD5FA", 5, "\uD602\uD603\uD605\uD606\uD607\uD609", 6, "\uD612"], + ["c281", "\uD616", 5, "\uD61D\uD61E\uD61F\uD621\uD622\uD623\uD625", 7, "\uD62E", 9, "\uD63A\uD63B\uC9D5\uC9D6\uC9D9\uC9DA\uC9DC\uC9DD\uC9E0\uC9E2\uC9E4\uC9E7\uC9EC\uC9ED\uC9EF\uC9F0\uC9F1\uC9F8\uC9F9\uC9FC\uCA00\uCA08\uCA09\uCA0B\uCA0C\uCA0D\uCA14\uCA18\uCA29\uCA4C\uCA4D\uCA50\uCA54\uCA5C\uCA5D\uCA5F\uCA60\uCA61\uCA68\uCA7D\uCA84\uCA98\uCABC\uCABD\uCAC0\uCAC4\uCACC\uCACD\uCACF\uCAD1\uCAD3\uCAD8\uCAD9\uCAE0\uCAEC\uCAF4\uCB08\uCB10\uCB14\uCB18\uCB20\uCB21\uCB41\uCB48\uCB49\uCB4C\uCB50\uCB58\uCB59\uCB5D\uCB64\uCB78\uCB79\uCB9C\uCBB8\uCBD4\uCBE4\uCBE7\uCBE9\uCC0C\uCC0D\uCC10\uCC14\uCC1C\uCC1D\uCC21\uCC22\uCC27\uCC28\uCC29\uCC2C\uCC2E\uCC30\uCC38\uCC39\uCC3B"], + ["c341", "\uD63D\uD63E\uD63F\uD641\uD642\uD643\uD644\uD646\uD647\uD64A\uD64C\uD64E\uD64F\uD650\uD652\uD653\uD656\uD657\uD659\uD65A\uD65B\uD65D", 4], + ["c361", "\uD662", 4, "\uD668\uD66A", 5, "\uD672\uD673\uD675", 11], + ["c381", "\uD681\uD682\uD684\uD686", 5, "\uD68E\uD68F\uD691\uD692\uD693\uD695", 7, "\uD69E\uD6A0\uD6A2", 5, "\uD6A9\uD6AA\uCC3C\uCC3D\uCC3E\uCC44\uCC45\uCC48\uCC4C\uCC54\uCC55\uCC57\uCC58\uCC59\uCC60\uCC64\uCC66\uCC68\uCC70\uCC75\uCC98\uCC99\uCC9C\uCCA0\uCCA8\uCCA9\uCCAB\uCCAC\uCCAD\uCCB4\uCCB5\uCCB8\uCCBC\uCCC4\uCCC5\uCCC7\uCCC9\uCCD0\uCCD4\uCCE4\uCCEC\uCCF0\uCD01\uCD08\uCD09\uCD0C\uCD10\uCD18\uCD19\uCD1B\uCD1D\uCD24\uCD28\uCD2C\uCD39\uCD5C\uCD60\uCD64\uCD6C\uCD6D\uCD6F\uCD71\uCD78\uCD88\uCD94\uCD95\uCD98\uCD9C\uCDA4\uCDA5\uCDA7\uCDA9\uCDB0\uCDC4\uCDCC\uCDD0\uCDE8\uCDEC\uCDF0\uCDF8\uCDF9\uCDFB\uCDFD\uCE04\uCE08\uCE0C\uCE14\uCE19\uCE20\uCE21\uCE24\uCE28\uCE30\uCE31\uCE33\uCE35"], + ["c441", "\uD6AB\uD6AD\uD6AE\uD6AF\uD6B1", 7, "\uD6BA\uD6BC", 7, "\uD6C6\uD6C7\uD6C9\uD6CA\uD6CB"], + ["c461", "\uD6CD\uD6CE\uD6CF\uD6D0\uD6D2\uD6D3\uD6D5\uD6D6\uD6D8\uD6DA", 5, "\uD6E1\uD6E2\uD6E3\uD6E5\uD6E6\uD6E7\uD6E9", 4], + ["c481", "\uD6EE\uD6EF\uD6F1\uD6F2\uD6F3\uD6F4\uD6F6", 5, "\uD6FE\uD6FF\uD701\uD702\uD703\uD705", 11, "\uD712\uD713\uD714\uCE58\uCE59\uCE5C\uCE5F\uCE60\uCE61\uCE68\uCE69\uCE6B\uCE6D\uCE74\uCE75\uCE78\uCE7C\uCE84\uCE85\uCE87\uCE89\uCE90\uCE91\uCE94\uCE98\uCEA0\uCEA1\uCEA3\uCEA4\uCEA5\uCEAC\uCEAD\uCEC1\uCEE4\uCEE5\uCEE8\uCEEB\uCEEC\uCEF4\uCEF5\uCEF7\uCEF8\uCEF9\uCF00\uCF01\uCF04\uCF08\uCF10\uCF11\uCF13\uCF15\uCF1C\uCF20\uCF24\uCF2C\uCF2D\uCF2F\uCF30\uCF31\uCF38\uCF54\uCF55\uCF58\uCF5C\uCF64\uCF65\uCF67\uCF69\uCF70\uCF71\uCF74\uCF78\uCF80\uCF85\uCF8C\uCFA1\uCFA8\uCFB0\uCFC4\uCFE0\uCFE1\uCFE4\uCFE8\uCFF0\uCFF1\uCFF3\uCFF5\uCFFC\uD000\uD004\uD011\uD018\uD02D\uD034\uD035\uD038\uD03C"], + ["c541", "\uD715\uD716\uD717\uD71A\uD71B\uD71D\uD71E\uD71F\uD721", 6, "\uD72A\uD72C\uD72E", 5, "\uD736\uD737\uD739"], + ["c561", "\uD73A\uD73B\uD73D", 6, "\uD745\uD746\uD748\uD74A", 5, "\uD752\uD753\uD755\uD75A", 4], + ["c581", "\uD75F\uD762\uD764\uD766\uD767\uD768\uD76A\uD76B\uD76D\uD76E\uD76F\uD771\uD772\uD773\uD775", 6, "\uD77E\uD77F\uD780\uD782", 5, "\uD78A\uD78B\uD044\uD045\uD047\uD049\uD050\uD054\uD058\uD060\uD06C\uD06D\uD070\uD074\uD07C\uD07D\uD081\uD0A4\uD0A5\uD0A8\uD0AC\uD0B4\uD0B5\uD0B7\uD0B9\uD0C0\uD0C1\uD0C4\uD0C8\uD0C9\uD0D0\uD0D1\uD0D3\uD0D4\uD0D5\uD0DC\uD0DD\uD0E0\uD0E4\uD0EC\uD0ED\uD0EF\uD0F0\uD0F1\uD0F8\uD10D\uD130\uD131\uD134\uD138\uD13A\uD140\uD141\uD143\uD144\uD145\uD14C\uD14D\uD150\uD154\uD15C\uD15D\uD15F\uD161\uD168\uD16C\uD17C\uD184\uD188\uD1A0\uD1A1\uD1A4\uD1A8\uD1B0\uD1B1\uD1B3\uD1B5\uD1BA\uD1BC\uD1C0\uD1D8\uD1F4\uD1F8\uD207\uD209\uD210\uD22C\uD22D\uD230\uD234\uD23C\uD23D\uD23F\uD241\uD248\uD25C"], + ["c641", "\uD78D\uD78E\uD78F\uD791", 6, "\uD79A\uD79C\uD79E", 5], + ["c6a1", "\uD264\uD280\uD281\uD284\uD288\uD290\uD291\uD295\uD29C\uD2A0\uD2A4\uD2AC\uD2B1\uD2B8\uD2B9\uD2BC\uD2BF\uD2C0\uD2C2\uD2C8\uD2C9\uD2CB\uD2D4\uD2D8\uD2DC\uD2E4\uD2E5\uD2F0\uD2F1\uD2F4\uD2F8\uD300\uD301\uD303\uD305\uD30C\uD30D\uD30E\uD310\uD314\uD316\uD31C\uD31D\uD31F\uD320\uD321\uD325\uD328\uD329\uD32C\uD330\uD338\uD339\uD33B\uD33C\uD33D\uD344\uD345\uD37C\uD37D\uD380\uD384\uD38C\uD38D\uD38F\uD390\uD391\uD398\uD399\uD39C\uD3A0\uD3A8\uD3A9\uD3AB\uD3AD\uD3B4\uD3B8\uD3BC\uD3C4\uD3C5\uD3C8\uD3C9\uD3D0\uD3D8\uD3E1\uD3E3\uD3EC\uD3ED\uD3F0\uD3F4\uD3FC\uD3FD\uD3FF\uD401"], + ["c7a1", "\uD408\uD41D\uD440\uD444\uD45C\uD460\uD464\uD46D\uD46F\uD478\uD479\uD47C\uD47F\uD480\uD482\uD488\uD489\uD48B\uD48D\uD494\uD4A9\uD4CC\uD4D0\uD4D4\uD4DC\uD4DF\uD4E8\uD4EC\uD4F0\uD4F8\uD4FB\uD4FD\uD504\uD508\uD50C\uD514\uD515\uD517\uD53C\uD53D\uD540\uD544\uD54C\uD54D\uD54F\uD551\uD558\uD559\uD55C\uD560\uD565\uD568\uD569\uD56B\uD56D\uD574\uD575\uD578\uD57C\uD584\uD585\uD587\uD588\uD589\uD590\uD5A5\uD5C8\uD5C9\uD5CC\uD5D0\uD5D2\uD5D8\uD5D9\uD5DB\uD5DD\uD5E4\uD5E5\uD5E8\uD5EC\uD5F4\uD5F5\uD5F7\uD5F9\uD600\uD601\uD604\uD608\uD610\uD611\uD613\uD614\uD615\uD61C\uD620"], + ["c8a1", "\uD624\uD62D\uD638\uD639\uD63C\uD640\uD645\uD648\uD649\uD64B\uD64D\uD651\uD654\uD655\uD658\uD65C\uD667\uD669\uD670\uD671\uD674\uD683\uD685\uD68C\uD68D\uD690\uD694\uD69D\uD69F\uD6A1\uD6A8\uD6AC\uD6B0\uD6B9\uD6BB\uD6C4\uD6C5\uD6C8\uD6CC\uD6D1\uD6D4\uD6D7\uD6D9\uD6E0\uD6E4\uD6E8\uD6F0\uD6F5\uD6FC\uD6FD\uD700\uD704\uD711\uD718\uD719\uD71C\uD720\uD728\uD729\uD72B\uD72D\uD734\uD735\uD738\uD73C\uD744\uD747\uD749\uD750\uD751\uD754\uD756\uD757\uD758\uD759\uD760\uD761\uD763\uD765\uD769\uD76C\uD770\uD774\uD77C\uD77D\uD781\uD788\uD789\uD78C\uD790\uD798\uD799\uD79B\uD79D"], + ["caa1", "\u4F3D\u4F73\u5047\u50F9\u52A0\u53EF\u5475\u54E5\u5609\u5AC1\u5BB6\u6687\u67B6\u67B7\u67EF\u6B4C\u73C2\u75C2\u7A3C\u82DB\u8304\u8857\u8888\u8A36\u8CC8\u8DCF\u8EFB\u8FE6\u99D5\u523B\u5374\u5404\u606A\u6164\u6BBC\u73CF\u811A\u89BA\u89D2\u95A3\u4F83\u520A\u58BE\u5978\u59E6\u5E72\u5E79\u61C7\u63C0\u6746\u67EC\u687F\u6F97\u764E\u770B\u78F5\u7A08\u7AFF\u7C21\u809D\u826E\u8271\u8AEB\u9593\u4E6B\u559D\u66F7\u6E34\u78A3\u7AED\u845B\u8910\u874E\u97A8\u52D8\u574E\u582A\u5D4C\u611F\u61BE\u6221\u6562\u67D1\u6A44\u6E1B\u7518\u75B3\u76E3\u77B0\u7D3A\u90AF\u9451\u9452\u9F95"], + ["cba1", "\u5323\u5CAC\u7532\u80DB\u9240\u9598\u525B\u5808\u59DC\u5CA1\u5D17\u5EB7\u5F3A\u5F4A\u6177\u6C5F\u757A\u7586\u7CE0\u7D73\u7DB1\u7F8C\u8154\u8221\u8591\u8941\u8B1B\u92FC\u964D\u9C47\u4ECB\u4EF7\u500B\u51F1\u584F\u6137\u613E\u6168\u6539\u69EA\u6F11\u75A5\u7686\u76D6\u7B87\u82A5\u84CB\uF900\u93A7\u958B\u5580\u5BA2\u5751\uF901\u7CB3\u7FB9\u91B5\u5028\u53BB\u5C45\u5DE8\u62D2\u636E\u64DA\u64E7\u6E20\u70AC\u795B\u8DDD\u8E1E\uF902\u907D\u9245\u92F8\u4E7E\u4EF6\u5065\u5DFE\u5EFA\u6106\u6957\u8171\u8654\u8E47\u9375\u9A2B\u4E5E\u5091\u6770\u6840\u5109\u528D\u5292\u6AA2"], + ["cca1", "\u77BC\u9210\u9ED4\u52AB\u602F\u8FF2\u5048\u61A9\u63ED\u64CA\u683C\u6A84\u6FC0\u8188\u89A1\u9694\u5805\u727D\u72AC\u7504\u7D79\u7E6D\u80A9\u898B\u8B74\u9063\u9D51\u6289\u6C7A\u6F54\u7D50\u7F3A\u8A23\u517C\u614A\u7B9D\u8B19\u9257\u938C\u4EAC\u4FD3\u501E\u50BE\u5106\u52C1\u52CD\u537F\u5770\u5883\u5E9A\u5F91\u6176\u61AC\u64CE\u656C\u666F\u66BB\u66F4\u6897\u6D87\u7085\u70F1\u749F\u74A5\u74CA\u75D9\u786C\u78EC\u7ADF\u7AF6\u7D45\u7D93\u8015\u803F\u811B\u8396\u8B66\u8F15\u9015\u93E1\u9803\u9838\u9A5A\u9BE8\u4FC2\u5553\u583A\u5951\u5B63\u5C46\u60B8\u6212\u6842\u68B0"], + ["cda1", "\u68E8\u6EAA\u754C\u7678\u78CE\u7A3D\u7CFB\u7E6B\u7E7C\u8A08\u8AA1\u8C3F\u968E\u9DC4\u53E4\u53E9\u544A\u5471\u56FA\u59D1\u5B64\u5C3B\u5EAB\u62F7\u6537\u6545\u6572\u66A0\u67AF\u69C1\u6CBD\u75FC\u7690\u777E\u7A3F\u7F94\u8003\u80A1\u818F\u82E6\u82FD\u83F0\u85C1\u8831\u88B4\u8AA5\uF903\u8F9C\u932E\u96C7\u9867\u9AD8\u9F13\u54ED\u659B\u66F2\u688F\u7A40\u8C37\u9D60\u56F0\u5764\u5D11\u6606\u68B1\u68CD\u6EFE\u7428\u889E\u9BE4\u6C68\uF904\u9AA8\u4F9B\u516C\u5171\u529F\u5B54\u5DE5\u6050\u606D\u62F1\u63A7\u653B\u73D9\u7A7A\u86A3\u8CA2\u978F\u4E32\u5BE1\u6208\u679C\u74DC"], + ["cea1", "\u79D1\u83D3\u8A87\u8AB2\u8DE8\u904E\u934B\u9846\u5ED3\u69E8\u85FF\u90ED\uF905\u51A0\u5B98\u5BEC\u6163\u68FA\u6B3E\u704C\u742F\u74D8\u7BA1\u7F50\u83C5\u89C0\u8CAB\u95DC\u9928\u522E\u605D\u62EC\u9002\u4F8A\u5149\u5321\u58D9\u5EE3\u66E0\u6D38\u709A\u72C2\u73D6\u7B50\u80F1\u945B\u5366\u639B\u7F6B\u4E56\u5080\u584A\u58DE\u602A\u6127\u62D0\u69D0\u9B41\u5B8F\u7D18\u80B1\u8F5F\u4EA4\u50D1\u54AC\u55AC\u5B0C\u5DA0\u5DE7\u652A\u654E\u6821\u6A4B\u72E1\u768E\u77EF\u7D5E\u7FF9\u81A0\u854E\u86DF\u8F03\u8F4E\u90CA\u9903\u9A55\u9BAB\u4E18\u4E45\u4E5D\u4EC7\u4FF1\u5177\u52FE"], + ["cfa1", "\u5340\u53E3\u53E5\u548E\u5614\u5775\u57A2\u5BC7\u5D87\u5ED0\u61FC\u62D8\u6551\u67B8\u67E9\u69CB\u6B50\u6BC6\u6BEC\u6C42\u6E9D\u7078\u72D7\u7396\u7403\u77BF\u77E9\u7A76\u7D7F\u8009\u81FC\u8205\u820A\u82DF\u8862\u8B33\u8CFC\u8EC0\u9011\u90B1\u9264\u92B6\u99D2\u9A45\u9CE9\u9DD7\u9F9C\u570B\u5C40\u83CA\u97A0\u97AB\u9EB4\u541B\u7A98\u7FA4\u88D9\u8ECD\u90E1\u5800\u5C48\u6398\u7A9F\u5BAE\u5F13\u7A79\u7AAE\u828E\u8EAC\u5026\u5238\u52F8\u5377\u5708\u62F3\u6372\u6B0A\u6DC3\u7737\u53A5\u7357\u8568\u8E76\u95D5\u673A\u6AC3\u6F70\u8A6D\u8ECC\u994B\uF906\u6677\u6B78\u8CB4"], + ["d0a1", "\u9B3C\uF907\u53EB\u572D\u594E\u63C6\u69FB\u73EA\u7845\u7ABA\u7AC5\u7CFE\u8475\u898F\u8D73\u9035\u95A8\u52FB\u5747\u7547\u7B60\u83CC\u921E\uF908\u6A58\u514B\u524B\u5287\u621F\u68D8\u6975\u9699\u50C5\u52A4\u52E4\u61C3\u65A4\u6839\u69FF\u747E\u7B4B\u82B9\u83EB\u89B2\u8B39\u8FD1\u9949\uF909\u4ECA\u5997\u64D2\u6611\u6A8E\u7434\u7981\u79BD\u82A9\u887E\u887F\u895F\uF90A\u9326\u4F0B\u53CA\u6025\u6271\u6C72\u7D1A\u7D66\u4E98\u5162\u77DC\u80AF\u4F01\u4F0E\u5176\u5180\u55DC\u5668\u573B\u57FA\u57FC\u5914\u5947\u5993\u5BC4\u5C90\u5D0E\u5DF1\u5E7E\u5FCC\u6280\u65D7\u65E3"], + ["d1a1", "\u671E\u671F\u675E\u68CB\u68C4\u6A5F\u6B3A\u6C23\u6C7D\u6C82\u6DC7\u7398\u7426\u742A\u7482\u74A3\u7578\u757F\u7881\u78EF\u7941\u7947\u7948\u797A\u7B95\u7D00\u7DBA\u7F88\u8006\u802D\u808C\u8A18\u8B4F\u8C48\u8D77\u9321\u9324\u98E2\u9951\u9A0E\u9A0F\u9A65\u9E92\u7DCA\u4F76\u5409\u62EE\u6854\u91D1\u55AB\u513A\uF90B\uF90C\u5A1C\u61E6\uF90D\u62CF\u62FF\uF90E", 5, "\u90A3\uF914", 4, "\u8AFE\uF919\uF91A\uF91B\uF91C\u6696\uF91D\u7156\uF91E\uF91F\u96E3\uF920\u634F\u637A\u5357\uF921\u678F\u6960\u6E73\uF922\u7537\uF923\uF924\uF925"], + ["d2a1", "\u7D0D\uF926\uF927\u8872\u56CA\u5A18\uF928", 4, "\u4E43\uF92D\u5167\u5948\u67F0\u8010\uF92E\u5973\u5E74\u649A\u79CA\u5FF5\u606C\u62C8\u637B\u5BE7\u5BD7\u52AA\uF92F\u5974\u5F29\u6012\uF930\uF931\uF932\u7459\uF933", 5, "\u99D1\uF939", 10, "\u6FC3\uF944\uF945\u81BF\u8FB2\u60F1\uF946\uF947\u8166\uF948\uF949\u5C3F\uF94A", 7, "\u5AE9\u8A25\u677B\u7D10\uF952", 5, "\u80FD\uF958\uF959\u5C3C\u6CE5\u533F\u6EBA\u591A\u8336"], + ["d3a1", "\u4E39\u4EB6\u4F46\u55AE\u5718\u58C7\u5F56\u65B7\u65E6\u6A80\u6BB5\u6E4D\u77ED\u7AEF\u7C1E\u7DDE\u86CB\u8892\u9132\u935B\u64BB\u6FBE\u737A\u75B8\u9054\u5556\u574D\u61BA\u64D4\u66C7\u6DE1\u6E5B\u6F6D\u6FB9\u75F0\u8043\u81BD\u8541\u8983\u8AC7\u8B5A\u931F\u6C93\u7553\u7B54\u8E0F\u905D\u5510\u5802\u5858\u5E62\u6207\u649E\u68E0\u7576\u7CD6\u87B3\u9EE8\u4EE3\u5788\u576E\u5927\u5C0D\u5CB1\u5E36\u5F85\u6234\u64E1\u73B3\u81FA\u888B\u8CB8\u968A\u9EDB\u5B85\u5FB7\u60B3\u5012\u5200\u5230\u5716\u5835\u5857\u5C0E\u5C60\u5CF6\u5D8B\u5EA6\u5F92\u60BC\u6311\u6389\u6417\u6843"], + ["d4a1", "\u68F9\u6AC2\u6DD8\u6E21\u6ED4\u6FE4\u71FE\u76DC\u7779\u79B1\u7A3B\u8404\u89A9\u8CED\u8DF3\u8E48\u9003\u9014\u9053\u90FD\u934D\u9676\u97DC\u6BD2\u7006\u7258\u72A2\u7368\u7763\u79BF\u7BE4\u7E9B\u8B80\u58A9\u60C7\u6566\u65FD\u66BE\u6C8C\u711E\u71C9\u8C5A\u9813\u4E6D\u7A81\u4EDD\u51AC\u51CD\u52D5\u540C\u61A7\u6771\u6850\u68DF\u6D1E\u6F7C\u75BC\u77B3\u7AE5\u80F4\u8463\u9285\u515C\u6597\u675C\u6793\u75D8\u7AC7\u8373\uF95A\u8C46\u9017\u982D\u5C6F\u81C0\u829A\u9041\u906F\u920D\u5F97\u5D9D\u6A59\u71C8\u767B\u7B49\u85E4\u8B04\u9127\u9A30\u5587\u61F6\uF95B\u7669\u7F85"], + ["d5a1", "\u863F\u87BA\u88F8\u908F\uF95C\u6D1B\u70D9\u73DE\u7D61\u843D\uF95D\u916A\u99F1\uF95E\u4E82\u5375\u6B04\u6B12\u703E\u721B\u862D\u9E1E\u524C\u8FA3\u5D50\u64E5\u652C\u6B16\u6FEB\u7C43\u7E9C\u85CD\u8964\u89BD\u62C9\u81D8\u881F\u5ECA\u6717\u6D6A\u72FC\u7405\u746F\u8782\u90DE\u4F86\u5D0D\u5FA0\u840A\u51B7\u63A0\u7565\u4EAE\u5006\u5169\u51C9\u6881\u6A11\u7CAE\u7CB1\u7CE7\u826F\u8AD2\u8F1B\u91CF\u4FB6\u5137\u52F5\u5442\u5EEC\u616E\u623E\u65C5\u6ADA\u6FFE\u792A\u85DC\u8823\u95AD\u9A62\u9A6A\u9E97\u9ECE\u529B\u66C6\u6B77\u701D\u792B\u8F62\u9742\u6190\u6200\u6523\u6F23"], + ["d6a1", "\u7149\u7489\u7DF4\u806F\u84EE\u8F26\u9023\u934A\u51BD\u5217\u52A3\u6D0C\u70C8\u88C2\u5EC9\u6582\u6BAE\u6FC2\u7C3E\u7375\u4EE4\u4F36\u56F9\uF95F\u5CBA\u5DBA\u601C\u73B2\u7B2D\u7F9A\u7FCE\u8046\u901E\u9234\u96F6\u9748\u9818\u9F61\u4F8B\u6FA7\u79AE\u91B4\u96B7\u52DE\uF960\u6488\u64C4\u6AD3\u6F5E\u7018\u7210\u76E7\u8001\u8606\u865C\u8DEF\u8F05\u9732\u9B6F\u9DFA\u9E75\u788C\u797F\u7DA0\u83C9\u9304\u9E7F\u9E93\u8AD6\u58DF\u5F04\u6727\u7027\u74CF\u7C60\u807E\u5121\u7028\u7262\u78CA\u8CC2\u8CDA\u8CF4\u96F7\u4E86\u50DA\u5BEE\u5ED6\u6599\u71CE\u7642\u77AD\u804A\u84FC"], + ["d7a1", "\u907C\u9B27\u9F8D\u58D8\u5A41\u5C62\u6A13\u6DDA\u6F0F\u763B\u7D2F\u7E37\u851E\u8938\u93E4\u964B\u5289\u65D2\u67F3\u69B4\u6D41\u6E9C\u700F\u7409\u7460\u7559\u7624\u786B\u8B2C\u985E\u516D\u622E\u9678\u4F96\u502B\u5D19\u6DEA\u7DB8\u8F2A\u5F8B\u6144\u6817\uF961\u9686\u52D2\u808B\u51DC\u51CC\u695E\u7A1C\u7DBE\u83F1\u9675\u4FDA\u5229\u5398\u540F\u550E\u5C65\u60A7\u674E\u68A8\u6D6C\u7281\u72F8\u7406\u7483\uF962\u75E2\u7C6C\u7F79\u7FB8\u8389\u88CF\u88E1\u91CC\u91D0\u96E2\u9BC9\u541D\u6F7E\u71D0\u7498\u85FA\u8EAA\u96A3\u9C57\u9E9F\u6797\u6DCB\u7433\u81E8\u9716\u782C"], + ["d8a1", "\u7ACB\u7B20\u7C92\u6469\u746A\u75F2\u78BC\u78E8\u99AC\u9B54\u9EBB\u5BDE\u5E55\u6F20\u819C\u83AB\u9088\u4E07\u534D\u5A29\u5DD2\u5F4E\u6162\u633D\u6669\u66FC\u6EFF\u6F2B\u7063\u779E\u842C\u8513\u883B\u8F13\u9945\u9C3B\u551C\u62B9\u672B\u6CAB\u8309\u896A\u977A\u4EA1\u5984\u5FD8\u5FD9\u671B\u7DB2\u7F54\u8292\u832B\u83BD\u8F1E\u9099\u57CB\u59B9\u5A92\u5BD0\u6627\u679A\u6885\u6BCF\u7164\u7F75\u8CB7\u8CE3\u9081\u9B45\u8108\u8C8A\u964C\u9A40\u9EA5\u5B5F\u6C13\u731B\u76F2\u76DF\u840C\u51AA\u8993\u514D\u5195\u52C9\u68C9\u6C94\u7704\u7720\u7DBF\u7DEC\u9762\u9EB5\u6EC5"], + ["d9a1", "\u8511\u51A5\u540D\u547D\u660E\u669D\u6927\u6E9F\u76BF\u7791\u8317\u84C2\u879F\u9169\u9298\u9CF4\u8882\u4FAE\u5192\u52DF\u59C6\u5E3D\u6155\u6478\u6479\u66AE\u67D0\u6A21\u6BCD\u6BDB\u725F\u7261\u7441\u7738\u77DB\u8017\u82BC\u8305\u8B00\u8B28\u8C8C\u6728\u6C90\u7267\u76EE\u7766\u7A46\u9DA9\u6B7F\u6C92\u5922\u6726\u8499\u536F\u5893\u5999\u5EDF\u63CF\u6634\u6773\u6E3A\u732B\u7AD7\u82D7\u9328\u52D9\u5DEB\u61AE\u61CB\u620A\u62C7\u64AB\u65E0\u6959\u6B66\u6BCB\u7121\u73F7\u755D\u7E46\u821E\u8302\u856A\u8AA3\u8CBF\u9727\u9D61\u58A8\u9ED8\u5011\u520E\u543B\u554F\u6587"], + ["daa1", "\u6C76\u7D0A\u7D0B\u805E\u868A\u9580\u96EF\u52FF\u6C95\u7269\u5473\u5A9A\u5C3E\u5D4B\u5F4C\u5FAE\u672A\u68B6\u6963\u6E3C\u6E44\u7709\u7C73\u7F8E\u8587\u8B0E\u8FF7\u9761\u9EF4\u5CB7\u60B6\u610D\u61AB\u654F\u65FB\u65FC\u6C11\u6CEF\u739F\u73C9\u7DE1\u9594\u5BC6\u871C\u8B10\u525D\u535A\u62CD\u640F\u64B2\u6734\u6A38\u6CCA\u73C0\u749E\u7B94\u7C95\u7E1B\u818A\u8236\u8584\u8FEB\u96F9\u99C1\u4F34\u534A\u53CD\u53DB\u62CC\u642C\u6500\u6591\u69C3\u6CEE\u6F58\u73ED\u7554\u7622\u76E4\u76FC\u78D0\u78FB\u792C\u7D46\u822C\u87E0\u8FD4\u9812\u98EF\u52C3\u62D4\u64A5\u6E24\u6F51"], + ["dba1", "\u767C\u8DCB\u91B1\u9262\u9AEE\u9B43\u5023\u508D\u574A\u59A8\u5C28\u5E47\u5F77\u623F\u653E\u65B9\u65C1\u6609\u678B\u699C\u6EC2\u78C5\u7D21\u80AA\u8180\u822B\u82B3\u84A1\u868C\u8A2A\u8B17\u90A6\u9632\u9F90\u500D\u4FF3\uF963\u57F9\u5F98\u62DC\u6392\u676F\u6E43\u7119\u76C3\u80CC\u80DA\u88F4\u88F5\u8919\u8CE0\u8F29\u914D\u966A\u4F2F\u4F70\u5E1B\u67CF\u6822\u767D\u767E\u9B44\u5E61\u6A0A\u7169\u71D4\u756A\uF964\u7E41\u8543\u85E9\u98DC\u4F10\u7B4F\u7F70\u95A5\u51E1\u5E06\u68B5\u6C3E\u6C4E\u6CDB\u72AF\u7BC4\u8303\u6CD5\u743A\u50FB\u5288\u58C1\u64D8\u6A97\u74A7\u7656"], + ["dca1", "\u78A7\u8617\u95E2\u9739\uF965\u535E\u5F01\u8B8A\u8FA8\u8FAF\u908A\u5225\u77A5\u9C49\u9F08\u4E19\u5002\u5175\u5C5B\u5E77\u661E\u663A\u67C4\u68C5\u70B3\u7501\u75C5\u79C9\u7ADD\u8F27\u9920\u9A08\u4FDD\u5821\u5831\u5BF6\u666E\u6B65\u6D11\u6E7A\u6F7D\u73E4\u752B\u83E9\u88DC\u8913\u8B5C\u8F14\u4F0F\u50D5\u5310\u535C\u5B93\u5FA9\u670D\u798F\u8179\u832F\u8514\u8907\u8986\u8F39\u8F3B\u99A5\u9C12\u672C\u4E76\u4FF8\u5949\u5C01\u5CEF\u5CF0\u6367\u68D2\u70FD\u71A2\u742B\u7E2B\u84EC\u8702\u9022\u92D2\u9CF3\u4E0D\u4ED8\u4FEF\u5085\u5256\u526F\u5426\u5490\u57E0\u592B\u5A66"], + ["dda1", "\u5B5A\u5B75\u5BCC\u5E9C\uF966\u6276\u6577\u65A7\u6D6E\u6EA5\u7236\u7B26\u7C3F\u7F36\u8150\u8151\u819A\u8240\u8299\u83A9\u8A03\u8CA0\u8CE6\u8CFB\u8D74\u8DBA\u90E8\u91DC\u961C\u9644\u99D9\u9CE7\u5317\u5206\u5429\u5674\u58B3\u5954\u596E\u5FFF\u61A4\u626E\u6610\u6C7E\u711A\u76C6\u7C89\u7CDE\u7D1B\u82AC\u8CC1\u96F0\uF967\u4F5B\u5F17\u5F7F\u62C2\u5D29\u670B\u68DA\u787C\u7E43\u9D6C\u4E15\u5099\u5315\u532A\u5351\u5983\u5A62\u5E87\u60B2\u618A\u6249\u6279\u6590\u6787\u69A7\u6BD4\u6BD6\u6BD7\u6BD8\u6CB8\uF968\u7435\u75FA\u7812\u7891\u79D5\u79D8\u7C83\u7DCB\u7FE1\u80A5"], + ["dea1", "\u813E\u81C2\u83F2\u871A\u88E8\u8AB9\u8B6C\u8CBB\u9119\u975E\u98DB\u9F3B\u56AC\u5B2A\u5F6C\u658C\u6AB3\u6BAF\u6D5C\u6FF1\u7015\u725D\u73AD\u8CA7\u8CD3\u983B\u6191\u6C37\u8058\u9A01\u4E4D\u4E8B\u4E9B\u4ED5\u4F3A\u4F3C\u4F7F\u4FDF\u50FF\u53F2\u53F8\u5506\u55E3\u56DB\u58EB\u5962\u5A11\u5BEB\u5BFA\u5C04\u5DF3\u5E2B\u5F99\u601D\u6368\u659C\u65AF\u67F6\u67FB\u68AD\u6B7B\u6C99\u6CD7\u6E23\u7009\u7345\u7802\u793E\u7940\u7960\u79C1\u7BE9\u7D17\u7D72\u8086\u820D\u838E\u84D1\u86C7\u88DF\u8A50\u8A5E\u8B1D\u8CDC\u8D66\u8FAD\u90AA\u98FC\u99DF\u9E9D\u524A\uF969\u6714\uF96A"], + ["dfa1", "\u5098\u522A\u5C71\u6563\u6C55\u73CA\u7523\u759D\u7B97\u849C\u9178\u9730\u4E77\u6492\u6BBA\u715E\u85A9\u4E09\uF96B\u6749\u68EE\u6E17\u829F\u8518\u886B\u63F7\u6F81\u9212\u98AF\u4E0A\u50B7\u50CF\u511F\u5546\u55AA\u5617\u5B40\u5C19\u5CE0\u5E38\u5E8A\u5EA0\u5EC2\u60F3\u6851\u6A61\u6E58\u723D\u7240\u72C0\u76F8\u7965\u7BB1\u7FD4\u88F3\u89F4\u8A73\u8C61\u8CDE\u971C\u585E\u74BD\u8CFD\u55C7\uF96C\u7A61\u7D22\u8272\u7272\u751F\u7525\uF96D\u7B19\u5885\u58FB\u5DBC\u5E8F\u5EB6\u5F90\u6055\u6292\u637F\u654D\u6691\u66D9\u66F8\u6816\u68F2\u7280\u745E\u7B6E\u7D6E\u7DD6\u7F72"], + ["e0a1", "\u80E5\u8212\u85AF\u897F\u8A93\u901D\u92E4\u9ECD\u9F20\u5915\u596D\u5E2D\u60DC\u6614\u6673\u6790\u6C50\u6DC5\u6F5F\u77F3\u78A9\u84C6\u91CB\u932B\u4ED9\u50CA\u5148\u5584\u5B0B\u5BA3\u6247\u657E\u65CB\u6E32\u717D\u7401\u7444\u7487\u74BF\u766C\u79AA\u7DDA\u7E55\u7FA8\u817A\u81B3\u8239\u861A\u87EC\u8A75\u8DE3\u9078\u9291\u9425\u994D\u9BAE\u5368\u5C51\u6954\u6CC4\u6D29\u6E2B\u820C\u859B\u893B\u8A2D\u8AAA\u96EA\u9F67\u5261\u66B9\u6BB2\u7E96\u87FE\u8D0D\u9583\u965D\u651D\u6D89\u71EE\uF96E\u57CE\u59D3\u5BAC\u6027\u60FA\u6210\u661F\u665F\u7329\u73F9\u76DB\u7701\u7B6C"], + ["e1a1", "\u8056\u8072\u8165\u8AA0\u9192\u4E16\u52E2\u6B72\u6D17\u7A05\u7B39\u7D30\uF96F\u8CB0\u53EC\u562F\u5851\u5BB5\u5C0F\u5C11\u5DE2\u6240\u6383\u6414\u662D\u68B3\u6CBC\u6D88\u6EAF\u701F\u70A4\u71D2\u7526\u758F\u758E\u7619\u7B11\u7BE0\u7C2B\u7D20\u7D39\u852C\u856D\u8607\u8A34\u900D\u9061\u90B5\u92B7\u97F6\u9A37\u4FD7\u5C6C\u675F\u6D91\u7C9F\u7E8C\u8B16\u8D16\u901F\u5B6B\u5DFD\u640D\u84C0\u905C\u98E1\u7387\u5B8B\u609A\u677E\u6DDE\u8A1F\u8AA6\u9001\u980C\u5237\uF970\u7051\u788E\u9396\u8870\u91D7\u4FEE\u53D7\u55FD\u56DA\u5782\u58FD\u5AC2\u5B88\u5CAB\u5CC0\u5E25\u6101"], + ["e2a1", "\u620D\u624B\u6388\u641C\u6536\u6578\u6A39\u6B8A\u6C34\u6D19\u6F31\u71E7\u72E9\u7378\u7407\u74B2\u7626\u7761\u79C0\u7A57\u7AEA\u7CB9\u7D8F\u7DAC\u7E61\u7F9E\u8129\u8331\u8490\u84DA\u85EA\u8896\u8AB0\u8B90\u8F38\u9042\u9083\u916C\u9296\u92B9\u968B\u96A7\u96A8\u96D6\u9700\u9808\u9996\u9AD3\u9B1A\u53D4\u587E\u5919\u5B70\u5BBF\u6DD1\u6F5A\u719F\u7421\u74B9\u8085\u83FD\u5DE1\u5F87\u5FAA\u6042\u65EC\u6812\u696F\u6A53\u6B89\u6D35\u6DF3\u73E3\u76FE\u77AC\u7B4D\u7D14\u8123\u821C\u8340\u84F4\u8563\u8A62\u8AC4\u9187\u931E\u9806\u99B4\u620C\u8853\u8FF0\u9265\u5D07\u5D27"], + ["e3a1", "\u5D69\u745F\u819D\u8768\u6FD5\u62FE\u7FD2\u8936\u8972\u4E1E\u4E58\u50E7\u52DD\u5347\u627F\u6607\u7E69\u8805\u965E\u4F8D\u5319\u5636\u59CB\u5AA4\u5C38\u5C4E\u5C4D\u5E02\u5F11\u6043\u65BD\u662F\u6642\u67BE\u67F4\u731C\u77E2\u793A\u7FC5\u8494\u84CD\u8996\u8A66\u8A69\u8AE1\u8C55\u8C7A\u57F4\u5BD4\u5F0F\u606F\u62ED\u690D\u6B96\u6E5C\u7184\u7BD2\u8755\u8B58\u8EFE\u98DF\u98FE\u4F38\u4F81\u4FE1\u547B\u5A20\u5BB8\u613C\u65B0\u6668\u71FC\u7533\u795E\u7D33\u814E\u81E3\u8398\u85AA\u85CE\u8703\u8A0A\u8EAB\u8F9B\uF971\u8FC5\u5931\u5BA4\u5BE6\u6089\u5BE9\u5C0B\u5FC3\u6C81"], + ["e4a1", "\uF972\u6DF1\u700B\u751A\u82AF\u8AF6\u4EC0\u5341\uF973\u96D9\u6C0F\u4E9E\u4FC4\u5152\u555E\u5A25\u5CE8\u6211\u7259\u82BD\u83AA\u86FE\u8859\u8A1D\u963F\u96C5\u9913\u9D09\u9D5D\u580A\u5CB3\u5DBD\u5E44\u60E1\u6115\u63E1\u6A02\u6E25\u9102\u9354\u984E\u9C10\u9F77\u5B89\u5CB8\u6309\u664F\u6848\u773C\u96C1\u978D\u9854\u9B9F\u65A1\u8B01\u8ECB\u95BC\u5535\u5CA9\u5DD6\u5EB5\u6697\u764C\u83F4\u95C7\u58D3\u62BC\u72CE\u9D28\u4EF0\u592E\u600F\u663B\u6B83\u79E7\u9D26\u5393\u54C0\u57C3\u5D16\u611B\u66D6\u6DAF\u788D\u827E\u9698\u9744\u5384\u627C\u6396\u6DB2\u7E0A\u814B\u984D"], + ["e5a1", "\u6AFB\u7F4C\u9DAF\u9E1A\u4E5F\u503B\u51B6\u591C\u60F9\u63F6\u6930\u723A\u8036\uF974\u91CE\u5F31\uF975\uF976\u7D04\u82E5\u846F\u84BB\u85E5\u8E8D\uF977\u4F6F\uF978\uF979\u58E4\u5B43\u6059\u63DA\u6518\u656D\u6698\uF97A\u694A\u6A23\u6D0B\u7001\u716C\u75D2\u760D\u79B3\u7A70\uF97B\u7F8A\uF97C\u8944\uF97D\u8B93\u91C0\u967D\uF97E\u990A\u5704\u5FA1\u65BC\u6F01\u7600\u79A6\u8A9E\u99AD\u9B5A\u9F6C\u5104\u61B6\u6291\u6A8D\u81C6\u5043\u5830\u5F66\u7109\u8A00\u8AFA\u5B7C\u8616\u4FFA\u513C\u56B4\u5944\u63A9\u6DF9\u5DAA\u696D\u5186\u4E88\u4F59\uF97F\uF980\uF981\u5982\uF982"], + ["e6a1", "\uF983\u6B5F\u6C5D\uF984\u74B5\u7916\uF985\u8207\u8245\u8339\u8F3F\u8F5D\uF986\u9918\uF987\uF988\uF989\u4EA6\uF98A\u57DF\u5F79\u6613\uF98B\uF98C\u75AB\u7E79\u8B6F\uF98D\u9006\u9A5B\u56A5\u5827\u59F8\u5A1F\u5BB4\uF98E\u5EF6\uF98F\uF990\u6350\u633B\uF991\u693D\u6C87\u6CBF\u6D8E\u6D93\u6DF5\u6F14\uF992\u70DF\u7136\u7159\uF993\u71C3\u71D5\uF994\u784F\u786F\uF995\u7B75\u7DE3\uF996\u7E2F\uF997\u884D\u8EDF\uF998\uF999\uF99A\u925B\uF99B\u9CF6\uF99C\uF99D\uF99E\u6085\u6D85\uF99F\u71B1\uF9A0\uF9A1\u95B1\u53AD\uF9A2\uF9A3\uF9A4\u67D3\uF9A5\u708E\u7130\u7430\u8276\u82D2"], + ["e7a1", "\uF9A6\u95BB\u9AE5\u9E7D\u66C4\uF9A7\u71C1\u8449\uF9A8\uF9A9\u584B\uF9AA\uF9AB\u5DB8\u5F71\uF9AC\u6620\u668E\u6979\u69AE\u6C38\u6CF3\u6E36\u6F41\u6FDA\u701B\u702F\u7150\u71DF\u7370\uF9AD\u745B\uF9AE\u74D4\u76C8\u7A4E\u7E93\uF9AF\uF9B0\u82F1\u8A60\u8FCE\uF9B1\u9348\uF9B2\u9719\uF9B3\uF9B4\u4E42\u502A\uF9B5\u5208\u53E1\u66F3\u6C6D\u6FCA\u730A\u777F\u7A62\u82AE\u85DD\u8602\uF9B6\u88D4\u8A63\u8B7D\u8C6B\uF9B7\u92B3\uF9B8\u9713\u9810\u4E94\u4F0D\u4FC9\u50B2\u5348\u543E\u5433\u55DA\u5862\u58BA\u5967\u5A1B\u5BE4\u609F\uF9B9\u61CA\u6556\u65FF\u6664\u68A7\u6C5A\u6FB3"], + ["e8a1", "\u70CF\u71AC\u7352\u7B7D\u8708\u8AA4\u9C32\u9F07\u5C4B\u6C83\u7344\u7389\u923A\u6EAB\u7465\u761F\u7A69\u7E15\u860A\u5140\u58C5\u64C1\u74EE\u7515\u7670\u7FC1\u9095\u96CD\u9954\u6E26\u74E6\u7AA9\u7AAA\u81E5\u86D9\u8778\u8A1B\u5A49\u5B8C\u5B9B\u68A1\u6900\u6D63\u73A9\u7413\u742C\u7897\u7DE9\u7FEB\u8118\u8155\u839E\u8C4C\u962E\u9811\u66F0\u5F80\u65FA\u6789\u6C6A\u738B\u502D\u5A03\u6B6A\u77EE\u5916\u5D6C\u5DCD\u7325\u754F\uF9BA\uF9BB\u50E5\u51F9\u582F\u592D\u5996\u59DA\u5BE5\uF9BC\uF9BD\u5DA2\u62D7\u6416\u6493\u64FE\uF9BE\u66DC\uF9BF\u6A48\uF9C0\u71FF\u7464\uF9C1"], + ["e9a1", "\u7A88\u7AAF\u7E47\u7E5E\u8000\u8170\uF9C2\u87EF\u8981\u8B20\u9059\uF9C3\u9080\u9952\u617E\u6B32\u6D74\u7E1F\u8925\u8FB1\u4FD1\u50AD\u5197\u52C7\u57C7\u5889\u5BB9\u5EB8\u6142\u6995\u6D8C\u6E67\u6EB6\u7194\u7462\u7528\u752C\u8073\u8338\u84C9\u8E0A\u9394\u93DE\uF9C4\u4E8E\u4F51\u5076\u512A\u53C8\u53CB\u53F3\u5B87\u5BD3\u5C24\u611A\u6182\u65F4\u725B\u7397\u7440\u76C2\u7950\u7991\u79B9\u7D06\u7FBD\u828B\u85D5\u865E\u8FC2\u9047\u90F5\u91EA\u9685\u96E8\u96E9\u52D6\u5F67\u65ED\u6631\u682F\u715C\u7A36\u90C1\u980A\u4E91\uF9C5\u6A52\u6B9E\u6F90\u7189\u8018\u82B8\u8553"], + ["eaa1", "\u904B\u9695\u96F2\u97FB\u851A\u9B31\u4E90\u718A\u96C4\u5143\u539F\u54E1\u5713\u5712\u57A3\u5A9B\u5AC4\u5BC3\u6028\u613F\u63F4\u6C85\u6D39\u6E72\u6E90\u7230\u733F\u7457\u82D1\u8881\u8F45\u9060\uF9C6\u9662\u9858\u9D1B\u6708\u8D8A\u925E\u4F4D\u5049\u50DE\u5371\u570D\u59D4\u5A01\u5C09\u6170\u6690\u6E2D\u7232\u744B\u7DEF\u80C3\u840E\u8466\u853F\u875F\u885B\u8918\u8B02\u9055\u97CB\u9B4F\u4E73\u4F91\u5112\u516A\uF9C7\u552F\u55A9\u5B7A\u5BA5\u5E7C\u5E7D\u5EBE\u60A0\u60DF\u6108\u6109\u63C4\u6538\u6709\uF9C8\u67D4\u67DA\uF9C9\u6961\u6962\u6CB9\u6D27\uF9CA\u6E38\uF9CB"], + ["eba1", "\u6FE1\u7336\u7337\uF9CC\u745C\u7531\uF9CD\u7652\uF9CE\uF9CF\u7DAD\u81FE\u8438\u88D5\u8A98\u8ADB\u8AED\u8E30\u8E42\u904A\u903E\u907A\u9149\u91C9\u936E\uF9D0\uF9D1\u5809\uF9D2\u6BD3\u8089\u80B2\uF9D3\uF9D4\u5141\u596B\u5C39\uF9D5\uF9D6\u6F64\u73A7\u80E4\u8D07\uF9D7\u9217\u958F\uF9D8\uF9D9\uF9DA\uF9DB\u807F\u620E\u701C\u7D68\u878D\uF9DC\u57A0\u6069\u6147\u6BB7\u8ABE\u9280\u96B1\u4E59\u541F\u6DEB\u852D\u9670\u97F3\u98EE\u63D6\u6CE3\u9091\u51DD\u61C9\u81BA\u9DF9\u4F9D\u501A\u5100\u5B9C\u610F\u61FF\u64EC\u6905\u6BC5\u7591\u77E3\u7FA9\u8264\u858F\u87FB\u8863\u8ABC"], + ["eca1", "\u8B70\u91AB\u4E8C\u4EE5\u4F0A\uF9DD\uF9DE\u5937\u59E8\uF9DF\u5DF2\u5F1B\u5F5B\u6021\uF9E0\uF9E1\uF9E2\uF9E3\u723E\u73E5\uF9E4\u7570\u75CD\uF9E5\u79FB\uF9E6\u800C\u8033\u8084\u82E1\u8351\uF9E7\uF9E8\u8CBD\u8CB3\u9087\uF9E9\uF9EA\u98F4\u990C\uF9EB\uF9EC\u7037\u76CA\u7FCA\u7FCC\u7FFC\u8B1A\u4EBA\u4EC1\u5203\u5370\uF9ED\u54BD\u56E0\u59FB\u5BC5\u5F15\u5FCD\u6E6E\uF9EE\uF9EF\u7D6A\u8335\uF9F0\u8693\u8A8D\uF9F1\u976D\u9777\uF9F2\uF9F3\u4E00\u4F5A\u4F7E\u58F9\u65E5\u6EA2\u9038\u93B0\u99B9\u4EFB\u58EC\u598A\u59D9\u6041\uF9F4\uF9F5\u7A14\uF9F6\u834F\u8CC3\u5165\u5344"], + ["eda1", "\uF9F7\uF9F8\uF9F9\u4ECD\u5269\u5B55\u82BF\u4ED4\u523A\u54A8\u59C9\u59FF\u5B50\u5B57\u5B5C\u6063\u6148\u6ECB\u7099\u716E\u7386\u74F7\u75B5\u78C1\u7D2B\u8005\u81EA\u8328\u8517\u85C9\u8AEE\u8CC7\u96CC\u4F5C\u52FA\u56BC\u65AB\u6628\u707C\u70B8\u7235\u7DBD\u828D\u914C\u96C0\u9D72\u5B71\u68E7\u6B98\u6F7A\u76DE\u5C91\u66AB\u6F5B\u7BB4\u7C2A\u8836\u96DC\u4E08\u4ED7\u5320\u5834\u58BB\u58EF\u596C\u5C07\u5E33\u5E84\u5F35\u638C\u66B2\u6756\u6A1F\u6AA3\u6B0C\u6F3F\u7246\uF9FA\u7350\u748B\u7AE0\u7CA7\u8178\u81DF\u81E7\u838A\u846C\u8523\u8594\u85CF\u88DD\u8D13\u91AC\u9577"], + ["eea1", "\u969C\u518D\u54C9\u5728\u5BB0\u624D\u6750\u683D\u6893\u6E3D\u6ED3\u707D\u7E21\u88C1\u8CA1\u8F09\u9F4B\u9F4E\u722D\u7B8F\u8ACD\u931A\u4F47\u4F4E\u5132\u5480\u59D0\u5E95\u62B5\u6775\u696E\u6A17\u6CAE\u6E1A\u72D9\u732A\u75BD\u7BB8\u7D35\u82E7\u83F9\u8457\u85F7\u8A5B\u8CAF\u8E87\u9019\u90B8\u96CE\u9F5F\u52E3\u540A\u5AE1\u5BC2\u6458\u6575\u6EF4\u72C4\uF9FB\u7684\u7A4D\u7B1B\u7C4D\u7E3E\u7FDF\u837B\u8B2B\u8CCA\u8D64\u8DE1\u8E5F\u8FEA\u8FF9\u9069\u93D1\u4F43\u4F7A\u50B3\u5168\u5178\u524D\u526A\u5861\u587C\u5960\u5C08\u5C55\u5EDB\u609B\u6230\u6813\u6BBF\u6C08\u6FB1"], + ["efa1", "\u714E\u7420\u7530\u7538\u7551\u7672\u7B4C\u7B8B\u7BAD\u7BC6\u7E8F\u8A6E\u8F3E\u8F49\u923F\u9293\u9322\u942B\u96FB\u985A\u986B\u991E\u5207\u622A\u6298\u6D59\u7664\u7ACA\u7BC0\u7D76\u5360\u5CBE\u5E97\u6F38\u70B9\u7C98\u9711\u9B8E\u9EDE\u63A5\u647A\u8776\u4E01\u4E95\u4EAD\u505C\u5075\u5448\u59C3\u5B9A\u5E40\u5EAD\u5EF7\u5F81\u60C5\u633A\u653F\u6574\u65CC\u6676\u6678\u67FE\u6968\u6A89\u6B63\u6C40\u6DC0\u6DE8\u6E1F\u6E5E\u701E\u70A1\u738E\u73FD\u753A\u775B\u7887\u798E\u7A0B\u7A7D\u7CBE\u7D8E\u8247\u8A02\u8AEA\u8C9E\u912D\u914A\u91D8\u9266\u92CC\u9320\u9706\u9756"], + ["f0a1", "\u975C\u9802\u9F0E\u5236\u5291\u557C\u5824\u5E1D\u5F1F\u608C\u63D0\u68AF\u6FDF\u796D\u7B2C\u81CD\u85BA\u88FD\u8AF8\u8E44\u918D\u9664\u969B\u973D\u984C\u9F4A\u4FCE\u5146\u51CB\u52A9\u5632\u5F14\u5F6B\u63AA\u64CD\u65E9\u6641\u66FA\u66F9\u671D\u689D\u68D7\u69FD\u6F15\u6F6E\u7167\u71E5\u722A\u74AA\u773A\u7956\u795A\u79DF\u7A20\u7A95\u7C97\u7CDF\u7D44\u7E70\u8087\u85FB\u86A4\u8A54\u8ABF\u8D99\u8E81\u9020\u906D\u91E3\u963B\u96D5\u9CE5\u65CF\u7C07\u8DB3\u93C3\u5B58\u5C0A\u5352\u62D9\u731D\u5027\u5B97\u5F9E\u60B0\u616B\u68D5\u6DD9\u742E\u7A2E\u7D42\u7D9C\u7E31\u816B"], + ["f1a1", "\u8E2A\u8E35\u937E\u9418\u4F50\u5750\u5DE6\u5EA7\u632B\u7F6A\u4E3B\u4F4F\u4F8F\u505A\u59DD\u80C4\u546A\u5468\u55FE\u594F\u5B99\u5DDE\u5EDA\u665D\u6731\u67F1\u682A\u6CE8\u6D32\u6E4A\u6F8D\u70B7\u73E0\u7587\u7C4C\u7D02\u7D2C\u7DA2\u821F\u86DB\u8A3B\u8A85\u8D70\u8E8A\u8F33\u9031\u914E\u9152\u9444\u99D0\u7AF9\u7CA5\u4FCA\u5101\u51C6\u57C8\u5BEF\u5CFB\u6659\u6A3D\u6D5A\u6E96\u6FEC\u710C\u756F\u7AE3\u8822\u9021\u9075\u96CB\u99FF\u8301\u4E2D\u4EF2\u8846\u91CD\u537D\u6ADB\u696B\u6C41\u847A\u589E\u618E\u66FE\u62EF\u70DD\u7511\u75C7\u7E52\u84B8\u8B49\u8D08\u4E4B\u53EA"], + ["f2a1", "\u54AB\u5730\u5740\u5FD7\u6301\u6307\u646F\u652F\u65E8\u667A\u679D\u67B3\u6B62\u6C60\u6C9A\u6F2C\u77E5\u7825\u7949\u7957\u7D19\u80A2\u8102\u81F3\u829D\u82B7\u8718\u8A8C\uF9FC\u8D04\u8DBE\u9072\u76F4\u7A19\u7A37\u7E54\u8077\u5507\u55D4\u5875\u632F\u6422\u6649\u664B\u686D\u699B\u6B84\u6D25\u6EB1\u73CD\u7468\u74A1\u755B\u75B9\u76E1\u771E\u778B\u79E6\u7E09\u7E1D\u81FB\u852F\u8897\u8A3A\u8CD1\u8EEB\u8FB0\u9032\u93AD\u9663\u9673\u9707\u4F84\u53F1\u59EA\u5AC9\u5E19\u684E\u74C6\u75BE\u79E9\u7A92\u81A3\u86ED\u8CEA\u8DCC\u8FED\u659F\u6715\uF9FD\u57F7\u6F57\u7DDD\u8F2F"], + ["f3a1", "\u93F6\u96C6\u5FB5\u61F2\u6F84\u4E14\u4F98\u501F\u53C9\u55DF\u5D6F\u5DEE\u6B21\u6B64\u78CB\u7B9A\uF9FE\u8E49\u8ECA\u906E\u6349\u643E\u7740\u7A84\u932F\u947F\u9F6A\u64B0\u6FAF\u71E6\u74A8\u74DA\u7AC4\u7C12\u7E82\u7CB2\u7E98\u8B9A\u8D0A\u947D\u9910\u994C\u5239\u5BDF\u64E6\u672D\u7D2E\u50ED\u53C3\u5879\u6158\u6159\u61FA\u65AC\u7AD9\u8B92\u8B96\u5009\u5021\u5275\u5531\u5A3C\u5EE0\u5F70\u6134\u655E\u660C\u6636\u66A2\u69CD\u6EC4\u6F32\u7316\u7621\u7A93\u8139\u8259\u83D6\u84BC\u50B5\u57F0\u5BC0\u5BE8\u5F69\u63A1\u7826\u7DB5\u83DC\u8521\u91C7\u91F5\u518A\u67F5\u7B56"], + ["f4a1", "\u8CAC\u51C4\u59BB\u60BD\u8655\u501C\uF9FF\u5254\u5C3A\u617D\u621A\u62D3\u64F2\u65A5\u6ECC\u7620\u810A\u8E60\u965F\u96BB\u4EDF\u5343\u5598\u5929\u5DDD\u64C5\u6CC9\u6DFA\u7394\u7A7F\u821B\u85A6\u8CE4\u8E10\u9077\u91E7\u95E1\u9621\u97C6\u51F8\u54F2\u5586\u5FB9\u64A4\u6F88\u7DB4\u8F1F\u8F4D\u9435\u50C9\u5C16\u6CBE\u6DFB\u751B\u77BB\u7C3D\u7C64\u8A79\u8AC2\u581E\u59BE\u5E16\u6377\u7252\u758A\u776B\u8ADC\u8CBC\u8F12\u5EF3\u6674\u6DF8\u807D\u83C1\u8ACB\u9751\u9BD6\uFA00\u5243\u66FF\u6D95\u6EEF\u7DE0\u8AE6\u902E\u905E\u9AD4\u521D\u527F\u54E8\u6194\u6284\u62DB\u68A2"], + ["f5a1", "\u6912\u695A\u6A35\u7092\u7126\u785D\u7901\u790E\u79D2\u7A0D\u8096\u8278\u82D5\u8349\u8549\u8C82\u8D85\u9162\u918B\u91AE\u4FC3\u56D1\u71ED\u77D7\u8700\u89F8\u5BF8\u5FD6\u6751\u90A8\u53E2\u585A\u5BF5\u60A4\u6181\u6460\u7E3D\u8070\u8525\u9283\u64AE\u50AC\u5D14\u6700\u589C\u62BD\u63A8\u690E\u6978\u6A1E\u6E6B\u76BA\u79CB\u82BB\u8429\u8ACF\u8DA8\u8FFD\u9112\u914B\u919C\u9310\u9318\u939A\u96DB\u9A36\u9C0D\u4E11\u755C\u795D\u7AFA\u7B51\u7BC9\u7E2E\u84C4\u8E59\u8E74\u8EF8\u9010\u6625\u693F\u7443\u51FA\u672E\u9EDC\u5145\u5FE0\u6C96\u87F2\u885D\u8877\u60B4\u81B5\u8403"], + ["f6a1", "\u8D05\u53D6\u5439\u5634\u5A36\u5C31\u708A\u7FE0\u805A\u8106\u81ED\u8DA3\u9189\u9A5F\u9DF2\u5074\u4EC4\u53A0\u60FB\u6E2C\u5C64\u4F88\u5024\u55E4\u5CD9\u5E5F\u6065\u6894\u6CBB\u6DC4\u71BE\u75D4\u75F4\u7661\u7A1A\u7A49\u7DC7\u7DFB\u7F6E\u81F4\u86A9\u8F1C\u96C9\u99B3\u9F52\u5247\u52C5\u98ED\u89AA\u4E03\u67D2\u6F06\u4FB5\u5BE2\u6795\u6C88\u6D78\u741B\u7827\u91DD\u937C\u87C4\u79E4\u7A31\u5FEB\u4ED6\u54A4\u553E\u58AE\u59A5\u60F0\u6253\u62D6\u6736\u6955\u8235\u9640\u99B1\u99DD\u502C\u5353\u5544\u577C\uFA01\u6258\uFA02\u64E2\u666B\u67DD\u6FC1\u6FEF\u7422\u7438\u8A17"], + ["f7a1", "\u9438\u5451\u5606\u5766\u5F48\u619A\u6B4E\u7058\u70AD\u7DBB\u8A95\u596A\u812B\u63A2\u7708\u803D\u8CAA\u5854\u642D\u69BB\u5B95\u5E11\u6E6F\uFA03\u8569\u514C\u53F0\u592A\u6020\u614B\u6B86\u6C70\u6CF0\u7B1E\u80CE\u82D4\u8DC6\u90B0\u98B1\uFA04\u64C7\u6FA4\u6491\u6504\u514E\u5410\u571F\u8A0E\u615F\u6876\uFA05\u75DB\u7B52\u7D71\u901A\u5806\u69CC\u817F\u892A\u9000\u9839\u5078\u5957\u59AC\u6295\u900F\u9B2A\u615D\u7279\u95D6\u5761\u5A46\u5DF4\u628A\u64AD\u64FA\u6777\u6CE2\u6D3E\u722C\u7436\u7834\u7F77\u82AD\u8DDB\u9817\u5224\u5742\u677F\u7248\u74E3\u8CA9\u8FA6\u9211"], + ["f8a1", "\u962A\u516B\u53ED\u634C\u4F69\u5504\u6096\u6557\u6C9B\u6D7F\u724C\u72FD\u7A17\u8987\u8C9D\u5F6D\u6F8E\u70F9\u81A8\u610E\u4FBF\u504F\u6241\u7247\u7BC7\u7DE8\u7FE9\u904D\u97AD\u9A19\u8CB6\u576A\u5E73\u67B0\u840D\u8A55\u5420\u5B16\u5E63\u5EE2\u5F0A\u6583\u80BA\u853D\u9589\u965B\u4F48\u5305\u530D\u530F\u5486\u54FA\u5703\u5E03\u6016\u629B\u62B1\u6355\uFA06\u6CE1\u6D66\u75B1\u7832\u80DE\u812F\u82DE\u8461\u84B2\u888D\u8912\u900B\u92EA\u98FD\u9B91\u5E45\u66B4\u66DD\u7011\u7206\uFA07\u4FF5\u527D\u5F6A\u6153\u6753\u6A19\u6F02\u74E2\u7968\u8868\u8C79\u98C7\u98C4\u9A43"], + ["f9a1", "\u54C1\u7A1F\u6953\u8AF7\u8C4A\u98A8\u99AE\u5F7C\u62AB\u75B2\u76AE\u88AB\u907F\u9642\u5339\u5F3C\u5FC5\u6CCC\u73CC\u7562\u758B\u7B46\u82FE\u999D\u4E4F\u903C\u4E0B\u4F55\u53A6\u590F\u5EC8\u6630\u6CB3\u7455\u8377\u8766\u8CC0\u9050\u971E\u9C15\u58D1\u5B78\u8650\u8B14\u9DB4\u5BD2\u6068\u608D\u65F1\u6C57\u6F22\u6FA3\u701A\u7F55\u7FF0\u9591\u9592\u9650\u97D3\u5272\u8F44\u51FD\u542B\u54B8\u5563\u558A\u6ABB\u6DB5\u7DD8\u8266\u929C\u9677\u9E79\u5408\u54C8\u76D2\u86E4\u95A4\u95D4\u965C\u4EA2\u4F09\u59EE\u5AE6\u5DF7\u6052\u6297\u676D\u6841\u6C86\u6E2F\u7F38\u809B\u822A"], + ["faa1", "\uFA08\uFA09\u9805\u4EA5\u5055\u54B3\u5793\u595A\u5B69\u5BB3\u61C8\u6977\u6D77\u7023\u87F9\u89E3\u8A72\u8AE7\u9082\u99ED\u9AB8\u52BE\u6838\u5016\u5E78\u674F\u8347\u884C\u4EAB\u5411\u56AE\u73E6\u9115\u97FF\u9909\u9957\u9999\u5653\u589F\u865B\u8A31\u61B2\u6AF6\u737B\u8ED2\u6B47\u96AA\u9A57\u5955\u7200\u8D6B\u9769\u4FD4\u5CF4\u5F26\u61F8\u665B\u6CEB\u70AB\u7384\u73B9\u73FE\u7729\u774D\u7D43\u7D62\u7E23\u8237\u8852\uFA0A\u8CE2\u9249\u986F\u5B51\u7A74\u8840\u9801\u5ACC\u4FE0\u5354\u593E\u5CFD\u633E\u6D79\u72F9\u8105\u8107\u83A2\u92CF\u9830\u4EA8\u5144\u5211\u578B"], + ["fba1", "\u5F62\u6CC2\u6ECE\u7005\u7050\u70AF\u7192\u73E9\u7469\u834A\u87A2\u8861\u9008\u90A2\u93A3\u99A8\u516E\u5F57\u60E0\u6167\u66B3\u8559\u8E4A\u91AF\u978B\u4E4E\u4E92\u547C\u58D5\u58FA\u597D\u5CB5\u5F27\u6236\u6248\u660A\u6667\u6BEB\u6D69\u6DCF\u6E56\u6EF8\u6F94\u6FE0\u6FE9\u705D\u72D0\u7425\u745A\u74E0\u7693\u795C\u7CCA\u7E1E\u80E1\u82A6\u846B\u84BF\u864E\u865F\u8774\u8B77\u8C6A\u93AC\u9800\u9865\u60D1\u6216\u9177\u5A5A\u660F\u6DF7\u6E3E\u743F\u9B42\u5FFD\u60DA\u7B0F\u54C4\u5F18\u6C5E\u6CD3\u6D2A\u70D8\u7D05\u8679\u8A0C\u9D3B\u5316\u548C\u5B05\u6A3A\u706B\u7575"], + ["fca1", "\u798D\u79BE\u82B1\u83EF\u8A71\u8B41\u8CA8\u9774\uFA0B\u64F4\u652B\u78BA\u78BB\u7A6B\u4E38\u559A\u5950\u5BA6\u5E7B\u60A3\u63DB\u6B61\u6665\u6853\u6E19\u7165\u74B0\u7D08\u9084\u9A69\u9C25\u6D3B\u6ED1\u733E\u8C41\u95CA\u51F0\u5E4C\u5FA8\u604D\u60F6\u6130\u614C\u6643\u6644\u69A5\u6CC1\u6E5F\u6EC9\u6F62\u714C\u749C\u7687\u7BC1\u7C27\u8352\u8757\u9051\u968D\u9EC3\u532F\u56DE\u5EFB\u5F8A\u6062\u6094\u61F7\u6666\u6703\u6A9C\u6DEE\u6FAE\u7070\u736A\u7E6A\u81BE\u8334\u86D4\u8AA8\u8CC4\u5283\u7372\u5B96\u6A6B\u9404\u54EE\u5686\u5B5D\u6548\u6585\u66C9\u689F\u6D8D\u6DC6"], + ["fda1", "\u723B\u80B4\u9175\u9A4D\u4FAF\u5019\u539A\u540E\u543C\u5589\u55C5\u5E3F\u5F8C\u673D\u7166\u73DD\u9005\u52DB\u52F3\u5864\u58CE\u7104\u718F\u71FB\u85B0\u8A13\u6688\u85A8\u55A7\u6684\u714A\u8431\u5349\u5599\u6BC1\u5F59\u5FBD\u63EE\u6689\u7147\u8AF1\u8F1D\u9EBE\u4F11\u643A\u70CB\u7566\u8667\u6064\u8B4E\u9DF8\u5147\u51F6\u5308\u6D36\u80F8\u9ED1\u6615\u6B23\u7098\u75D5\u5403\u5C79\u7D07\u8A16\u6B20\u6B3D\u6B46\u5438\u6070\u6D3D\u7FD5\u8208\u50D6\u51DE\u559C\u566B\u56CD\u59EC\u5B09\u5E0C\u6199\u6198\u6231\u665E\u66E6\u7199\u71B9\u71BA\u72A7\u79A7\u7A00\u7FB2\u8A70"] + ]; + } +}); + +// node_modules/iconv-lite/encodings/tables/cp950.json +var require_cp950 = __commonJS({ + "node_modules/iconv-lite/encodings/tables/cp950.json"(exports2, module2) { + module2.exports = [ + ["0", "\0", 127], + ["a140", "\u3000\uFF0C\u3001\u3002\uFF0E\u2027\uFF1B\uFF1A\uFF1F\uFF01\uFE30\u2026\u2025\uFE50\uFE51\uFE52\xB7\uFE54\uFE55\uFE56\uFE57\uFF5C\u2013\uFE31\u2014\uFE33\u2574\uFE34\uFE4F\uFF08\uFF09\uFE35\uFE36\uFF5B\uFF5D\uFE37\uFE38\u3014\u3015\uFE39\uFE3A\u3010\u3011\uFE3B\uFE3C\u300A\u300B\uFE3D\uFE3E\u3008\u3009\uFE3F\uFE40\u300C\u300D\uFE41\uFE42\u300E\u300F\uFE43\uFE44\uFE59\uFE5A"], + ["a1a1", "\uFE5B\uFE5C\uFE5D\uFE5E\u2018\u2019\u201C\u201D\u301D\u301E\u2035\u2032\uFF03\uFF06\uFF0A\u203B\xA7\u3003\u25CB\u25CF\u25B3\u25B2\u25CE\u2606\u2605\u25C7\u25C6\u25A1\u25A0\u25BD\u25BC\u32A3\u2105\xAF\uFFE3\uFF3F\u02CD\uFE49\uFE4A\uFE4D\uFE4E\uFE4B\uFE4C\uFE5F\uFE60\uFE61\uFF0B\uFF0D\xD7\xF7\xB1\u221A\uFF1C\uFF1E\uFF1D\u2266\u2267\u2260\u221E\u2252\u2261\uFE62", 4, "\uFF5E\u2229\u222A\u22A5\u2220\u221F\u22BF\u33D2\u33D1\u222B\u222E\u2235\u2234\u2640\u2642\u2295\u2299\u2191\u2193\u2190\u2192\u2196\u2197\u2199\u2198\u2225\u2223\uFF0F"], + ["a240", "\uFF3C\u2215\uFE68\uFF04\uFFE5\u3012\uFFE0\uFFE1\uFF05\uFF20\u2103\u2109\uFE69\uFE6A\uFE6B\u33D5\u339C\u339D\u339E\u33CE\u33A1\u338E\u338F\u33C4\xB0\u5159\u515B\u515E\u515D\u5161\u5163\u55E7\u74E9\u7CCE\u2581", 7, "\u258F\u258E\u258D\u258C\u258B\u258A\u2589\u253C\u2534\u252C\u2524\u251C\u2594\u2500\u2502\u2595\u250C\u2510\u2514\u2518\u256D"], + ["a2a1", "\u256E\u2570\u256F\u2550\u255E\u256A\u2561\u25E2\u25E3\u25E5\u25E4\u2571\u2572\u2573\uFF10", 9, "\u2160", 9, "\u3021", 8, "\u5341\u5344\u5345\uFF21", 25, "\uFF41", 21], + ["a340", "\uFF57\uFF58\uFF59\uFF5A\u0391", 16, "\u03A3", 6, "\u03B1", 16, "\u03C3", 6, "\u3105", 10], + ["a3a1", "\u3110", 25, "\u02D9\u02C9\u02CA\u02C7\u02CB"], + ["a3e1", "\u20AC"], + ["a440", "\u4E00\u4E59\u4E01\u4E03\u4E43\u4E5D\u4E86\u4E8C\u4EBA\u513F\u5165\u516B\u51E0\u5200\u5201\u529B\u5315\u5341\u535C\u53C8\u4E09\u4E0B\u4E08\u4E0A\u4E2B\u4E38\u51E1\u4E45\u4E48\u4E5F\u4E5E\u4E8E\u4EA1\u5140\u5203\u52FA\u5343\u53C9\u53E3\u571F\u58EB\u5915\u5927\u5973\u5B50\u5B51\u5B53\u5BF8\u5C0F\u5C22\u5C38\u5C71\u5DDD\u5DE5\u5DF1\u5DF2\u5DF3\u5DFE\u5E72\u5EFE\u5F0B\u5F13\u624D"], + ["a4a1", "\u4E11\u4E10\u4E0D\u4E2D\u4E30\u4E39\u4E4B\u5C39\u4E88\u4E91\u4E95\u4E92\u4E94\u4EA2\u4EC1\u4EC0\u4EC3\u4EC6\u4EC7\u4ECD\u4ECA\u4ECB\u4EC4\u5143\u5141\u5167\u516D\u516E\u516C\u5197\u51F6\u5206\u5207\u5208\u52FB\u52FE\u52FF\u5316\u5339\u5348\u5347\u5345\u535E\u5384\u53CB\u53CA\u53CD\u58EC\u5929\u592B\u592A\u592D\u5B54\u5C11\u5C24\u5C3A\u5C6F\u5DF4\u5E7B\u5EFF\u5F14\u5F15\u5FC3\u6208\u6236\u624B\u624E\u652F\u6587\u6597\u65A4\u65B9\u65E5\u66F0\u6708\u6728\u6B20\u6B62\u6B79\u6BCB\u6BD4\u6BDB\u6C0F\u6C34\u706B\u722A\u7236\u723B\u7247\u7259\u725B\u72AC\u738B\u4E19"], + ["a540", "\u4E16\u4E15\u4E14\u4E18\u4E3B\u4E4D\u4E4F\u4E4E\u4EE5\u4ED8\u4ED4\u4ED5\u4ED6\u4ED7\u4EE3\u4EE4\u4ED9\u4EDE\u5145\u5144\u5189\u518A\u51AC\u51F9\u51FA\u51F8\u520A\u52A0\u529F\u5305\u5306\u5317\u531D\u4EDF\u534A\u5349\u5361\u5360\u536F\u536E\u53BB\u53EF\u53E4\u53F3\u53EC\u53EE\u53E9\u53E8\u53FC\u53F8\u53F5\u53EB\u53E6\u53EA\u53F2\u53F1\u53F0\u53E5\u53ED\u53FB\u56DB\u56DA\u5916"], + ["a5a1", "\u592E\u5931\u5974\u5976\u5B55\u5B83\u5C3C\u5DE8\u5DE7\u5DE6\u5E02\u5E03\u5E73\u5E7C\u5F01\u5F18\u5F17\u5FC5\u620A\u6253\u6254\u6252\u6251\u65A5\u65E6\u672E\u672C\u672A\u672B\u672D\u6B63\u6BCD\u6C11\u6C10\u6C38\u6C41\u6C40\u6C3E\u72AF\u7384\u7389\u74DC\u74E6\u7518\u751F\u7528\u7529\u7530\u7531\u7532\u7533\u758B\u767D\u76AE\u76BF\u76EE\u77DB\u77E2\u77F3\u793A\u79BE\u7A74\u7ACB\u4E1E\u4E1F\u4E52\u4E53\u4E69\u4E99\u4EA4\u4EA6\u4EA5\u4EFF\u4F09\u4F19\u4F0A\u4F15\u4F0D\u4F10\u4F11\u4F0F\u4EF2\u4EF6\u4EFB\u4EF0\u4EF3\u4EFD\u4F01\u4F0B\u5149\u5147\u5146\u5148\u5168"], + ["a640", "\u5171\u518D\u51B0\u5217\u5211\u5212\u520E\u5216\u52A3\u5308\u5321\u5320\u5370\u5371\u5409\u540F\u540C\u540A\u5410\u5401\u540B\u5404\u5411\u540D\u5408\u5403\u540E\u5406\u5412\u56E0\u56DE\u56DD\u5733\u5730\u5728\u572D\u572C\u572F\u5729\u5919\u591A\u5937\u5938\u5984\u5978\u5983\u597D\u5979\u5982\u5981\u5B57\u5B58\u5B87\u5B88\u5B85\u5B89\u5BFA\u5C16\u5C79\u5DDE\u5E06\u5E76\u5E74"], + ["a6a1", "\u5F0F\u5F1B\u5FD9\u5FD6\u620E\u620C\u620D\u6210\u6263\u625B\u6258\u6536\u65E9\u65E8\u65EC\u65ED\u66F2\u66F3\u6709\u673D\u6734\u6731\u6735\u6B21\u6B64\u6B7B\u6C16\u6C5D\u6C57\u6C59\u6C5F\u6C60\u6C50\u6C55\u6C61\u6C5B\u6C4D\u6C4E\u7070\u725F\u725D\u767E\u7AF9\u7C73\u7CF8\u7F36\u7F8A\u7FBD\u8001\u8003\u800C\u8012\u8033\u807F\u8089\u808B\u808C\u81E3\u81EA\u81F3\u81FC\u820C\u821B\u821F\u826E\u8272\u827E\u866B\u8840\u884C\u8863\u897F\u9621\u4E32\u4EA8\u4F4D\u4F4F\u4F47\u4F57\u4F5E\u4F34\u4F5B\u4F55\u4F30\u4F50\u4F51\u4F3D\u4F3A\u4F38\u4F43\u4F54\u4F3C\u4F46\u4F63"], + ["a740", "\u4F5C\u4F60\u4F2F\u4F4E\u4F36\u4F59\u4F5D\u4F48\u4F5A\u514C\u514B\u514D\u5175\u51B6\u51B7\u5225\u5224\u5229\u522A\u5228\u52AB\u52A9\u52AA\u52AC\u5323\u5373\u5375\u541D\u542D\u541E\u543E\u5426\u544E\u5427\u5446\u5443\u5433\u5448\u5442\u541B\u5429\u544A\u5439\u543B\u5438\u542E\u5435\u5436\u5420\u543C\u5440\u5431\u542B\u541F\u542C\u56EA\u56F0\u56E4\u56EB\u574A\u5751\u5740\u574D"], + ["a7a1", "\u5747\u574E\u573E\u5750\u574F\u573B\u58EF\u593E\u599D\u5992\u59A8\u599E\u59A3\u5999\u5996\u598D\u59A4\u5993\u598A\u59A5\u5B5D\u5B5C\u5B5A\u5B5B\u5B8C\u5B8B\u5B8F\u5C2C\u5C40\u5C41\u5C3F\u5C3E\u5C90\u5C91\u5C94\u5C8C\u5DEB\u5E0C\u5E8F\u5E87\u5E8A\u5EF7\u5F04\u5F1F\u5F64\u5F62\u5F77\u5F79\u5FD8\u5FCC\u5FD7\u5FCD\u5FF1\u5FEB\u5FF8\u5FEA\u6212\u6211\u6284\u6297\u6296\u6280\u6276\u6289\u626D\u628A\u627C\u627E\u6279\u6273\u6292\u626F\u6298\u626E\u6295\u6293\u6291\u6286\u6539\u653B\u6538\u65F1\u66F4\u675F\u674E\u674F\u6750\u6751\u675C\u6756\u675E\u6749\u6746\u6760"], + ["a840", "\u6753\u6757\u6B65\u6BCF\u6C42\u6C5E\u6C99\u6C81\u6C88\u6C89\u6C85\u6C9B\u6C6A\u6C7A\u6C90\u6C70\u6C8C\u6C68\u6C96\u6C92\u6C7D\u6C83\u6C72\u6C7E\u6C74\u6C86\u6C76\u6C8D\u6C94\u6C98\u6C82\u7076\u707C\u707D\u7078\u7262\u7261\u7260\u72C4\u72C2\u7396\u752C\u752B\u7537\u7538\u7682\u76EF\u77E3\u79C1\u79C0\u79BF\u7A76\u7CFB\u7F55\u8096\u8093\u809D\u8098\u809B\u809A\u80B2\u826F\u8292"], + ["a8a1", "\u828B\u828D\u898B\u89D2\u8A00\u8C37\u8C46\u8C55\u8C9D\u8D64\u8D70\u8DB3\u8EAB\u8ECA\u8F9B\u8FB0\u8FC2\u8FC6\u8FC5\u8FC4\u5DE1\u9091\u90A2\u90AA\u90A6\u90A3\u9149\u91C6\u91CC\u9632\u962E\u9631\u962A\u962C\u4E26\u4E56\u4E73\u4E8B\u4E9B\u4E9E\u4EAB\u4EAC\u4F6F\u4F9D\u4F8D\u4F73\u4F7F\u4F6C\u4F9B\u4F8B\u4F86\u4F83\u4F70\u4F75\u4F88\u4F69\u4F7B\u4F96\u4F7E\u4F8F\u4F91\u4F7A\u5154\u5152\u5155\u5169\u5177\u5176\u5178\u51BD\u51FD\u523B\u5238\u5237\u523A\u5230\u522E\u5236\u5241\u52BE\u52BB\u5352\u5354\u5353\u5351\u5366\u5377\u5378\u5379\u53D6\u53D4\u53D7\u5473\u5475"], + ["a940", "\u5496\u5478\u5495\u5480\u547B\u5477\u5484\u5492\u5486\u547C\u5490\u5471\u5476\u548C\u549A\u5462\u5468\u548B\u547D\u548E\u56FA\u5783\u5777\u576A\u5769\u5761\u5766\u5764\u577C\u591C\u5949\u5947\u5948\u5944\u5954\u59BE\u59BB\u59D4\u59B9\u59AE\u59D1\u59C6\u59D0\u59CD\u59CB\u59D3\u59CA\u59AF\u59B3\u59D2\u59C5\u5B5F\u5B64\u5B63\u5B97\u5B9A\u5B98\u5B9C\u5B99\u5B9B\u5C1A\u5C48\u5C45"], + ["a9a1", "\u5C46\u5CB7\u5CA1\u5CB8\u5CA9\u5CAB\u5CB1\u5CB3\u5E18\u5E1A\u5E16\u5E15\u5E1B\u5E11\u5E78\u5E9A\u5E97\u5E9C\u5E95\u5E96\u5EF6\u5F26\u5F27\u5F29\u5F80\u5F81\u5F7F\u5F7C\u5FDD\u5FE0\u5FFD\u5FF5\u5FFF\u600F\u6014\u602F\u6035\u6016\u602A\u6015\u6021\u6027\u6029\u602B\u601B\u6216\u6215\u623F\u623E\u6240\u627F\u62C9\u62CC\u62C4\u62BF\u62C2\u62B9\u62D2\u62DB\u62AB\u62D3\u62D4\u62CB\u62C8\u62A8\u62BD\u62BC\u62D0\u62D9\u62C7\u62CD\u62B5\u62DA\u62B1\u62D8\u62D6\u62D7\u62C6\u62AC\u62CE\u653E\u65A7\u65BC\u65FA\u6614\u6613\u660C\u6606\u6602\u660E\u6600\u660F\u6615\u660A"], + ["aa40", "\u6607\u670D\u670B\u676D\u678B\u6795\u6771\u679C\u6773\u6777\u6787\u679D\u6797\u676F\u6770\u677F\u6789\u677E\u6790\u6775\u679A\u6793\u677C\u676A\u6772\u6B23\u6B66\u6B67\u6B7F\u6C13\u6C1B\u6CE3\u6CE8\u6CF3\u6CB1\u6CCC\u6CE5\u6CB3\u6CBD\u6CBE\u6CBC\u6CE2\u6CAB\u6CD5\u6CD3\u6CB8\u6CC4\u6CB9\u6CC1\u6CAE\u6CD7\u6CC5\u6CF1\u6CBF\u6CBB\u6CE1\u6CDB\u6CCA\u6CAC\u6CEF\u6CDC\u6CD6\u6CE0"], + ["aaa1", "\u7095\u708E\u7092\u708A\u7099\u722C\u722D\u7238\u7248\u7267\u7269\u72C0\u72CE\u72D9\u72D7\u72D0\u73A9\u73A8\u739F\u73AB\u73A5\u753D\u759D\u7599\u759A\u7684\u76C2\u76F2\u76F4\u77E5\u77FD\u793E\u7940\u7941\u79C9\u79C8\u7A7A\u7A79\u7AFA\u7CFE\u7F54\u7F8C\u7F8B\u8005\u80BA\u80A5\u80A2\u80B1\u80A1\u80AB\u80A9\u80B4\u80AA\u80AF\u81E5\u81FE\u820D\u82B3\u829D\u8299\u82AD\u82BD\u829F\u82B9\u82B1\u82AC\u82A5\u82AF\u82B8\u82A3\u82B0\u82BE\u82B7\u864E\u8671\u521D\u8868\u8ECB\u8FCE\u8FD4\u8FD1\u90B5\u90B8\u90B1\u90B6\u91C7\u91D1\u9577\u9580\u961C\u9640\u963F\u963B\u9644"], + ["ab40", "\u9642\u96B9\u96E8\u9752\u975E\u4E9F\u4EAD\u4EAE\u4FE1\u4FB5\u4FAF\u4FBF\u4FE0\u4FD1\u4FCF\u4FDD\u4FC3\u4FB6\u4FD8\u4FDF\u4FCA\u4FD7\u4FAE\u4FD0\u4FC4\u4FC2\u4FDA\u4FCE\u4FDE\u4FB7\u5157\u5192\u5191\u51A0\u524E\u5243\u524A\u524D\u524C\u524B\u5247\u52C7\u52C9\u52C3\u52C1\u530D\u5357\u537B\u539A\u53DB\u54AC\u54C0\u54A8\u54CE\u54C9\u54B8\u54A6\u54B3\u54C7\u54C2\u54BD\u54AA\u54C1"], + ["aba1", "\u54C4\u54C8\u54AF\u54AB\u54B1\u54BB\u54A9\u54A7\u54BF\u56FF\u5782\u578B\u57A0\u57A3\u57A2\u57CE\u57AE\u5793\u5955\u5951\u594F\u594E\u5950\u59DC\u59D8\u59FF\u59E3\u59E8\u5A03\u59E5\u59EA\u59DA\u59E6\u5A01\u59FB\u5B69\u5BA3\u5BA6\u5BA4\u5BA2\u5BA5\u5C01\u5C4E\u5C4F\u5C4D\u5C4B\u5CD9\u5CD2\u5DF7\u5E1D\u5E25\u5E1F\u5E7D\u5EA0\u5EA6\u5EFA\u5F08\u5F2D\u5F65\u5F88\u5F85\u5F8A\u5F8B\u5F87\u5F8C\u5F89\u6012\u601D\u6020\u6025\u600E\u6028\u604D\u6070\u6068\u6062\u6046\u6043\u606C\u606B\u606A\u6064\u6241\u62DC\u6316\u6309\u62FC\u62ED\u6301\u62EE\u62FD\u6307\u62F1\u62F7"], + ["ac40", "\u62EF\u62EC\u62FE\u62F4\u6311\u6302\u653F\u6545\u65AB\u65BD\u65E2\u6625\u662D\u6620\u6627\u662F\u661F\u6628\u6631\u6624\u66F7\u67FF\u67D3\u67F1\u67D4\u67D0\u67EC\u67B6\u67AF\u67F5\u67E9\u67EF\u67C4\u67D1\u67B4\u67DA\u67E5\u67B8\u67CF\u67DE\u67F3\u67B0\u67D9\u67E2\u67DD\u67D2\u6B6A\u6B83\u6B86\u6BB5\u6BD2\u6BD7\u6C1F\u6CC9\u6D0B\u6D32\u6D2A\u6D41\u6D25\u6D0C\u6D31\u6D1E\u6D17"], + ["aca1", "\u6D3B\u6D3D\u6D3E\u6D36\u6D1B\u6CF5\u6D39\u6D27\u6D38\u6D29\u6D2E\u6D35\u6D0E\u6D2B\u70AB\u70BA\u70B3\u70AC\u70AF\u70AD\u70B8\u70AE\u70A4\u7230\u7272\u726F\u7274\u72E9\u72E0\u72E1\u73B7\u73CA\u73BB\u73B2\u73CD\u73C0\u73B3\u751A\u752D\u754F\u754C\u754E\u754B\u75AB\u75A4\u75A5\u75A2\u75A3\u7678\u7686\u7687\u7688\u76C8\u76C6\u76C3\u76C5\u7701\u76F9\u76F8\u7709\u770B\u76FE\u76FC\u7707\u77DC\u7802\u7814\u780C\u780D\u7946\u7949\u7948\u7947\u79B9\u79BA\u79D1\u79D2\u79CB\u7A7F\u7A81\u7AFF\u7AFD\u7C7D\u7D02\u7D05\u7D00\u7D09\u7D07\u7D04\u7D06\u7F38\u7F8E\u7FBF\u8004"], + ["ad40", "\u8010\u800D\u8011\u8036\u80D6\u80E5\u80DA\u80C3\u80C4\u80CC\u80E1\u80DB\u80CE\u80DE\u80E4\u80DD\u81F4\u8222\u82E7\u8303\u8305\u82E3\u82DB\u82E6\u8304\u82E5\u8302\u8309\u82D2\u82D7\u82F1\u8301\u82DC\u82D4\u82D1\u82DE\u82D3\u82DF\u82EF\u8306\u8650\u8679\u867B\u867A\u884D\u886B\u8981\u89D4\u8A08\u8A02\u8A03\u8C9E\u8CA0\u8D74\u8D73\u8DB4\u8ECD\u8ECC\u8FF0\u8FE6\u8FE2\u8FEA\u8FE5"], + ["ada1", "\u8FED\u8FEB\u8FE4\u8FE8\u90CA\u90CE\u90C1\u90C3\u914B\u914A\u91CD\u9582\u9650\u964B\u964C\u964D\u9762\u9769\u97CB\u97ED\u97F3\u9801\u98A8\u98DB\u98DF\u9996\u9999\u4E58\u4EB3\u500C\u500D\u5023\u4FEF\u5026\u5025\u4FF8\u5029\u5016\u5006\u503C\u501F\u501A\u5012\u5011\u4FFA\u5000\u5014\u5028\u4FF1\u5021\u500B\u5019\u5018\u4FF3\u4FEE\u502D\u502A\u4FFE\u502B\u5009\u517C\u51A4\u51A5\u51A2\u51CD\u51CC\u51C6\u51CB\u5256\u525C\u5254\u525B\u525D\u532A\u537F\u539F\u539D\u53DF\u54E8\u5510\u5501\u5537\u54FC\u54E5\u54F2\u5506\u54FA\u5514\u54E9\u54ED\u54E1\u5509\u54EE\u54EA"], + ["ae40", "\u54E6\u5527\u5507\u54FD\u550F\u5703\u5704\u57C2\u57D4\u57CB\u57C3\u5809\u590F\u5957\u5958\u595A\u5A11\u5A18\u5A1C\u5A1F\u5A1B\u5A13\u59EC\u5A20\u5A23\u5A29\u5A25\u5A0C\u5A09\u5B6B\u5C58\u5BB0\u5BB3\u5BB6\u5BB4\u5BAE\u5BB5\u5BB9\u5BB8\u5C04\u5C51\u5C55\u5C50\u5CED\u5CFD\u5CFB\u5CEA\u5CE8\u5CF0\u5CF6\u5D01\u5CF4\u5DEE\u5E2D\u5E2B\u5EAB\u5EAD\u5EA7\u5F31\u5F92\u5F91\u5F90\u6059"], + ["aea1", "\u6063\u6065\u6050\u6055\u606D\u6069\u606F\u6084\u609F\u609A\u608D\u6094\u608C\u6085\u6096\u6247\u62F3\u6308\u62FF\u634E\u633E\u632F\u6355\u6342\u6346\u634F\u6349\u633A\u6350\u633D\u632A\u632B\u6328\u634D\u634C\u6548\u6549\u6599\u65C1\u65C5\u6642\u6649\u664F\u6643\u6652\u664C\u6645\u6641\u66F8\u6714\u6715\u6717\u6821\u6838\u6848\u6846\u6853\u6839\u6842\u6854\u6829\u68B3\u6817\u684C\u6851\u683D\u67F4\u6850\u6840\u683C\u6843\u682A\u6845\u6813\u6818\u6841\u6B8A\u6B89\u6BB7\u6C23\u6C27\u6C28\u6C26\u6C24\u6CF0\u6D6A\u6D95\u6D88\u6D87\u6D66\u6D78\u6D77\u6D59\u6D93"], + ["af40", "\u6D6C\u6D89\u6D6E\u6D5A\u6D74\u6D69\u6D8C\u6D8A\u6D79\u6D85\u6D65\u6D94\u70CA\u70D8\u70E4\u70D9\u70C8\u70CF\u7239\u7279\u72FC\u72F9\u72FD\u72F8\u72F7\u7386\u73ED\u7409\u73EE\u73E0\u73EA\u73DE\u7554\u755D\u755C\u755A\u7559\u75BE\u75C5\u75C7\u75B2\u75B3\u75BD\u75BC\u75B9\u75C2\u75B8\u768B\u76B0\u76CA\u76CD\u76CE\u7729\u771F\u7720\u7728\u77E9\u7830\u7827\u7838\u781D\u7834\u7837"], + ["afa1", "\u7825\u782D\u7820\u781F\u7832\u7955\u7950\u7960\u795F\u7956\u795E\u795D\u7957\u795A\u79E4\u79E3\u79E7\u79DF\u79E6\u79E9\u79D8\u7A84\u7A88\u7AD9\u7B06\u7B11\u7C89\u7D21\u7D17\u7D0B\u7D0A\u7D20\u7D22\u7D14\u7D10\u7D15\u7D1A\u7D1C\u7D0D\u7D19\u7D1B\u7F3A\u7F5F\u7F94\u7FC5\u7FC1\u8006\u8018\u8015\u8019\u8017\u803D\u803F\u80F1\u8102\u80F0\u8105\u80ED\u80F4\u8106\u80F8\u80F3\u8108\u80FD\u810A\u80FC\u80EF\u81ED\u81EC\u8200\u8210\u822A\u822B\u8228\u822C\u82BB\u832B\u8352\u8354\u834A\u8338\u8350\u8349\u8335\u8334\u834F\u8332\u8339\u8336\u8317\u8340\u8331\u8328\u8343"], + ["b040", "\u8654\u868A\u86AA\u8693\u86A4\u86A9\u868C\u86A3\u869C\u8870\u8877\u8881\u8882\u887D\u8879\u8A18\u8A10\u8A0E\u8A0C\u8A15\u8A0A\u8A17\u8A13\u8A16\u8A0F\u8A11\u8C48\u8C7A\u8C79\u8CA1\u8CA2\u8D77\u8EAC\u8ED2\u8ED4\u8ECF\u8FB1\u9001\u9006\u8FF7\u9000\u8FFA\u8FF4\u9003\u8FFD\u9005\u8FF8\u9095\u90E1\u90DD\u90E2\u9152\u914D\u914C\u91D8\u91DD\u91D7\u91DC\u91D9\u9583\u9662\u9663\u9661"], + ["b0a1", "\u965B\u965D\u9664\u9658\u965E\u96BB\u98E2\u99AC\u9AA8\u9AD8\u9B25\u9B32\u9B3C\u4E7E\u507A\u507D\u505C\u5047\u5043\u504C\u505A\u5049\u5065\u5076\u504E\u5055\u5075\u5074\u5077\u504F\u500F\u506F\u506D\u515C\u5195\u51F0\u526A\u526F\u52D2\u52D9\u52D8\u52D5\u5310\u530F\u5319\u533F\u5340\u533E\u53C3\u66FC\u5546\u556A\u5566\u5544\u555E\u5561\u5543\u554A\u5531\u5556\u554F\u5555\u552F\u5564\u5538\u552E\u555C\u552C\u5563\u5533\u5541\u5557\u5708\u570B\u5709\u57DF\u5805\u580A\u5806\u57E0\u57E4\u57FA\u5802\u5835\u57F7\u57F9\u5920\u5962\u5A36\u5A41\u5A49\u5A66\u5A6A\u5A40"], + ["b140", "\u5A3C\u5A62\u5A5A\u5A46\u5A4A\u5B70\u5BC7\u5BC5\u5BC4\u5BC2\u5BBF\u5BC6\u5C09\u5C08\u5C07\u5C60\u5C5C\u5C5D\u5D07\u5D06\u5D0E\u5D1B\u5D16\u5D22\u5D11\u5D29\u5D14\u5D19\u5D24\u5D27\u5D17\u5DE2\u5E38\u5E36\u5E33\u5E37\u5EB7\u5EB8\u5EB6\u5EB5\u5EBE\u5F35\u5F37\u5F57\u5F6C\u5F69\u5F6B\u5F97\u5F99\u5F9E\u5F98\u5FA1\u5FA0\u5F9C\u607F\u60A3\u6089\u60A0\u60A8\u60CB\u60B4\u60E6\u60BD"], + ["b1a1", "\u60C5\u60BB\u60B5\u60DC\u60BC\u60D8\u60D5\u60C6\u60DF\u60B8\u60DA\u60C7\u621A\u621B\u6248\u63A0\u63A7\u6372\u6396\u63A2\u63A5\u6377\u6367\u6398\u63AA\u6371\u63A9\u6389\u6383\u639B\u636B\u63A8\u6384\u6388\u6399\u63A1\u63AC\u6392\u638F\u6380\u637B\u6369\u6368\u637A\u655D\u6556\u6551\u6559\u6557\u555F\u654F\u6558\u6555\u6554\u659C\u659B\u65AC\u65CF\u65CB\u65CC\u65CE\u665D\u665A\u6664\u6668\u6666\u665E\u66F9\u52D7\u671B\u6881\u68AF\u68A2\u6893\u68B5\u687F\u6876\u68B1\u68A7\u6897\u68B0\u6883\u68C4\u68AD\u6886\u6885\u6894\u689D\u68A8\u689F\u68A1\u6882\u6B32\u6BBA"], + ["b240", "\u6BEB\u6BEC\u6C2B\u6D8E\u6DBC\u6DF3\u6DD9\u6DB2\u6DE1\u6DCC\u6DE4\u6DFB\u6DFA\u6E05\u6DC7\u6DCB\u6DAF\u6DD1\u6DAE\u6DDE\u6DF9\u6DB8\u6DF7\u6DF5\u6DC5\u6DD2\u6E1A\u6DB5\u6DDA\u6DEB\u6DD8\u6DEA\u6DF1\u6DEE\u6DE8\u6DC6\u6DC4\u6DAA\u6DEC\u6DBF\u6DE6\u70F9\u7109\u710A\u70FD\u70EF\u723D\u727D\u7281\u731C\u731B\u7316\u7313\u7319\u7387\u7405\u740A\u7403\u7406\u73FE\u740D\u74E0\u74F6"], + ["b2a1", "\u74F7\u751C\u7522\u7565\u7566\u7562\u7570\u758F\u75D4\u75D5\u75B5\u75CA\u75CD\u768E\u76D4\u76D2\u76DB\u7737\u773E\u773C\u7736\u7738\u773A\u786B\u7843\u784E\u7965\u7968\u796D\u79FB\u7A92\u7A95\u7B20\u7B28\u7B1B\u7B2C\u7B26\u7B19\u7B1E\u7B2E\u7C92\u7C97\u7C95\u7D46\u7D43\u7D71\u7D2E\u7D39\u7D3C\u7D40\u7D30\u7D33\u7D44\u7D2F\u7D42\u7D32\u7D31\u7F3D\u7F9E\u7F9A\u7FCC\u7FCE\u7FD2\u801C\u804A\u8046\u812F\u8116\u8123\u812B\u8129\u8130\u8124\u8202\u8235\u8237\u8236\u8239\u838E\u839E\u8398\u8378\u83A2\u8396\u83BD\u83AB\u8392\u838A\u8393\u8389\u83A0\u8377\u837B\u837C"], + ["b340", "\u8386\u83A7\u8655\u5F6A\u86C7\u86C0\u86B6\u86C4\u86B5\u86C6\u86CB\u86B1\u86AF\u86C9\u8853\u889E\u8888\u88AB\u8892\u8896\u888D\u888B\u8993\u898F\u8A2A\u8A1D\u8A23\u8A25\u8A31\u8A2D\u8A1F\u8A1B\u8A22\u8C49\u8C5A\u8CA9\u8CAC\u8CAB\u8CA8\u8CAA\u8CA7\u8D67\u8D66\u8DBE\u8DBA\u8EDB\u8EDF\u9019\u900D\u901A\u9017\u9023\u901F\u901D\u9010\u9015\u901E\u9020\u900F\u9022\u9016\u901B\u9014"], + ["b3a1", "\u90E8\u90ED\u90FD\u9157\u91CE\u91F5\u91E6\u91E3\u91E7\u91ED\u91E9\u9589\u966A\u9675\u9673\u9678\u9670\u9674\u9676\u9677\u966C\u96C0\u96EA\u96E9\u7AE0\u7ADF\u9802\u9803\u9B5A\u9CE5\u9E75\u9E7F\u9EA5\u9EBB\u50A2\u508D\u5085\u5099\u5091\u5080\u5096\u5098\u509A\u6700\u51F1\u5272\u5274\u5275\u5269\u52DE\u52DD\u52DB\u535A\u53A5\u557B\u5580\u55A7\u557C\u558A\u559D\u5598\u5582\u559C\u55AA\u5594\u5587\u558B\u5583\u55B3\u55AE\u559F\u553E\u55B2\u559A\u55BB\u55AC\u55B1\u557E\u5589\u55AB\u5599\u570D\u582F\u582A\u5834\u5824\u5830\u5831\u5821\u581D\u5820\u58F9\u58FA\u5960"], + ["b440", "\u5A77\u5A9A\u5A7F\u5A92\u5A9B\u5AA7\u5B73\u5B71\u5BD2\u5BCC\u5BD3\u5BD0\u5C0A\u5C0B\u5C31\u5D4C\u5D50\u5D34\u5D47\u5DFD\u5E45\u5E3D\u5E40\u5E43\u5E7E\u5ECA\u5EC1\u5EC2\u5EC4\u5F3C\u5F6D\u5FA9\u5FAA\u5FA8\u60D1\u60E1\u60B2\u60B6\u60E0\u611C\u6123\u60FA\u6115\u60F0\u60FB\u60F4\u6168\u60F1\u610E\u60F6\u6109\u6100\u6112\u621F\u6249\u63A3\u638C\u63CF\u63C0\u63E9\u63C9\u63C6\u63CD"], + ["b4a1", "\u63D2\u63E3\u63D0\u63E1\u63D6\u63ED\u63EE\u6376\u63F4\u63EA\u63DB\u6452\u63DA\u63F9\u655E\u6566\u6562\u6563\u6591\u6590\u65AF\u666E\u6670\u6674\u6676\u666F\u6691\u667A\u667E\u6677\u66FE\u66FF\u671F\u671D\u68FA\u68D5\u68E0\u68D8\u68D7\u6905\u68DF\u68F5\u68EE\u68E7\u68F9\u68D2\u68F2\u68E3\u68CB\u68CD\u690D\u6912\u690E\u68C9\u68DA\u696E\u68FB\u6B3E\u6B3A\u6B3D\u6B98\u6B96\u6BBC\u6BEF\u6C2E\u6C2F\u6C2C\u6E2F\u6E38\u6E54\u6E21\u6E32\u6E67\u6E4A\u6E20\u6E25\u6E23\u6E1B\u6E5B\u6E58\u6E24\u6E56\u6E6E\u6E2D\u6E26\u6E6F\u6E34\u6E4D\u6E3A\u6E2C\u6E43\u6E1D\u6E3E\u6ECB"], + ["b540", "\u6E89\u6E19\u6E4E\u6E63\u6E44\u6E72\u6E69\u6E5F\u7119\u711A\u7126\u7130\u7121\u7136\u716E\u711C\u724C\u7284\u7280\u7336\u7325\u7334\u7329\u743A\u742A\u7433\u7422\u7425\u7435\u7436\u7434\u742F\u741B\u7426\u7428\u7525\u7526\u756B\u756A\u75E2\u75DB\u75E3\u75D9\u75D8\u75DE\u75E0\u767B\u767C\u7696\u7693\u76B4\u76DC\u774F\u77ED\u785D\u786C\u786F\u7A0D\u7A08\u7A0B\u7A05\u7A00\u7A98"], + ["b5a1", "\u7A97\u7A96\u7AE5\u7AE3\u7B49\u7B56\u7B46\u7B50\u7B52\u7B54\u7B4D\u7B4B\u7B4F\u7B51\u7C9F\u7CA5\u7D5E\u7D50\u7D68\u7D55\u7D2B\u7D6E\u7D72\u7D61\u7D66\u7D62\u7D70\u7D73\u5584\u7FD4\u7FD5\u800B\u8052\u8085\u8155\u8154\u814B\u8151\u814E\u8139\u8146\u813E\u814C\u8153\u8174\u8212\u821C\u83E9\u8403\u83F8\u840D\u83E0\u83C5\u840B\u83C1\u83EF\u83F1\u83F4\u8457\u840A\u83F0\u840C\u83CC\u83FD\u83F2\u83CA\u8438\u840E\u8404\u83DC\u8407\u83D4\u83DF\u865B\u86DF\u86D9\u86ED\u86D4\u86DB\u86E4\u86D0\u86DE\u8857\u88C1\u88C2\u88B1\u8983\u8996\u8A3B\u8A60\u8A55\u8A5E\u8A3C\u8A41"], + ["b640", "\u8A54\u8A5B\u8A50\u8A46\u8A34\u8A3A\u8A36\u8A56\u8C61\u8C82\u8CAF\u8CBC\u8CB3\u8CBD\u8CC1\u8CBB\u8CC0\u8CB4\u8CB7\u8CB6\u8CBF\u8CB8\u8D8A\u8D85\u8D81\u8DCE\u8DDD\u8DCB\u8DDA\u8DD1\u8DCC\u8DDB\u8DC6\u8EFB\u8EF8\u8EFC\u8F9C\u902E\u9035\u9031\u9038\u9032\u9036\u9102\u90F5\u9109\u90FE\u9163\u9165\u91CF\u9214\u9215\u9223\u9209\u921E\u920D\u9210\u9207\u9211\u9594\u958F\u958B\u9591"], + ["b6a1", "\u9593\u9592\u958E\u968A\u968E\u968B\u967D\u9685\u9686\u968D\u9672\u9684\u96C1\u96C5\u96C4\u96C6\u96C7\u96EF\u96F2\u97CC\u9805\u9806\u9808\u98E7\u98EA\u98EF\u98E9\u98F2\u98ED\u99AE\u99AD\u9EC3\u9ECD\u9ED1\u4E82\u50AD\u50B5\u50B2\u50B3\u50C5\u50BE\u50AC\u50B7\u50BB\u50AF\u50C7\u527F\u5277\u527D\u52DF\u52E6\u52E4\u52E2\u52E3\u532F\u55DF\u55E8\u55D3\u55E6\u55CE\u55DC\u55C7\u55D1\u55E3\u55E4\u55EF\u55DA\u55E1\u55C5\u55C6\u55E5\u55C9\u5712\u5713\u585E\u5851\u5858\u5857\u585A\u5854\u586B\u584C\u586D\u584A\u5862\u5852\u584B\u5967\u5AC1\u5AC9\u5ACC\u5ABE\u5ABD\u5ABC"], + ["b740", "\u5AB3\u5AC2\u5AB2\u5D69\u5D6F\u5E4C\u5E79\u5EC9\u5EC8\u5F12\u5F59\u5FAC\u5FAE\u611A\u610F\u6148\u611F\u60F3\u611B\u60F9\u6101\u6108\u614E\u614C\u6144\u614D\u613E\u6134\u6127\u610D\u6106\u6137\u6221\u6222\u6413\u643E\u641E\u642A\u642D\u643D\u642C\u640F\u641C\u6414\u640D\u6436\u6416\u6417\u6406\u656C\u659F\u65B0\u6697\u6689\u6687\u6688\u6696\u6684\u6698\u668D\u6703\u6994\u696D"], + ["b7a1", "\u695A\u6977\u6960\u6954\u6975\u6930\u6982\u694A\u6968\u696B\u695E\u6953\u6979\u6986\u695D\u6963\u695B\u6B47\u6B72\u6BC0\u6BBF\u6BD3\u6BFD\u6EA2\u6EAF\u6ED3\u6EB6\u6EC2\u6E90\u6E9D\u6EC7\u6EC5\u6EA5\u6E98\u6EBC\u6EBA\u6EAB\u6ED1\u6E96\u6E9C\u6EC4\u6ED4\u6EAA\u6EA7\u6EB4\u714E\u7159\u7169\u7164\u7149\u7167\u715C\u716C\u7166\u714C\u7165\u715E\u7146\u7168\u7156\u723A\u7252\u7337\u7345\u733F\u733E\u746F\u745A\u7455\u745F\u745E\u7441\u743F\u7459\u745B\u745C\u7576\u7578\u7600\u75F0\u7601\u75F2\u75F1\u75FA\u75FF\u75F4\u75F3\u76DE\u76DF\u775B\u776B\u7766\u775E\u7763"], + ["b840", "\u7779\u776A\u776C\u775C\u7765\u7768\u7762\u77EE\u788E\u78B0\u7897\u7898\u788C\u7889\u787C\u7891\u7893\u787F\u797A\u797F\u7981\u842C\u79BD\u7A1C\u7A1A\u7A20\u7A14\u7A1F\u7A1E\u7A9F\u7AA0\u7B77\u7BC0\u7B60\u7B6E\u7B67\u7CB1\u7CB3\u7CB5\u7D93\u7D79\u7D91\u7D81\u7D8F\u7D5B\u7F6E\u7F69\u7F6A\u7F72\u7FA9\u7FA8\u7FA4\u8056\u8058\u8086\u8084\u8171\u8170\u8178\u8165\u816E\u8173\u816B"], + ["b8a1", "\u8179\u817A\u8166\u8205\u8247\u8482\u8477\u843D\u8431\u8475\u8466\u846B\u8449\u846C\u845B\u843C\u8435\u8461\u8463\u8469\u846D\u8446\u865E\u865C\u865F\u86F9\u8713\u8708\u8707\u8700\u86FE\u86FB\u8702\u8703\u8706\u870A\u8859\u88DF\u88D4\u88D9\u88DC\u88D8\u88DD\u88E1\u88CA\u88D5\u88D2\u899C\u89E3\u8A6B\u8A72\u8A73\u8A66\u8A69\u8A70\u8A87\u8A7C\u8A63\u8AA0\u8A71\u8A85\u8A6D\u8A62\u8A6E\u8A6C\u8A79\u8A7B\u8A3E\u8A68\u8C62\u8C8A\u8C89\u8CCA\u8CC7\u8CC8\u8CC4\u8CB2\u8CC3\u8CC2\u8CC5\u8DE1\u8DDF\u8DE8\u8DEF\u8DF3\u8DFA\u8DEA\u8DE4\u8DE6\u8EB2\u8F03\u8F09\u8EFE\u8F0A"], + ["b940", "\u8F9F\u8FB2\u904B\u904A\u9053\u9042\u9054\u903C\u9055\u9050\u9047\u904F\u904E\u904D\u9051\u903E\u9041\u9112\u9117\u916C\u916A\u9169\u91C9\u9237\u9257\u9238\u923D\u9240\u923E\u925B\u924B\u9264\u9251\u9234\u9249\u924D\u9245\u9239\u923F\u925A\u9598\u9698\u9694\u9695\u96CD\u96CB\u96C9\u96CA\u96F7\u96FB\u96F9\u96F6\u9756\u9774\u9776\u9810\u9811\u9813\u980A\u9812\u980C\u98FC\u98F4"], + ["b9a1", "\u98FD\u98FE\u99B3\u99B1\u99B4\u9AE1\u9CE9\u9E82\u9F0E\u9F13\u9F20\u50E7\u50EE\u50E5\u50D6\u50ED\u50DA\u50D5\u50CF\u50D1\u50F1\u50CE\u50E9\u5162\u51F3\u5283\u5282\u5331\u53AD\u55FE\u5600\u561B\u5617\u55FD\u5614\u5606\u5609\u560D\u560E\u55F7\u5616\u561F\u5608\u5610\u55F6\u5718\u5716\u5875\u587E\u5883\u5893\u588A\u5879\u5885\u587D\u58FD\u5925\u5922\u5924\u596A\u5969\u5AE1\u5AE6\u5AE9\u5AD7\u5AD6\u5AD8\u5AE3\u5B75\u5BDE\u5BE7\u5BE1\u5BE5\u5BE6\u5BE8\u5BE2\u5BE4\u5BDF\u5C0D\u5C62\u5D84\u5D87\u5E5B\u5E63\u5E55\u5E57\u5E54\u5ED3\u5ED6\u5F0A\u5F46\u5F70\u5FB9\u6147"], + ["ba40", "\u613F\u614B\u6177\u6162\u6163\u615F\u615A\u6158\u6175\u622A\u6487\u6458\u6454\u64A4\u6478\u645F\u647A\u6451\u6467\u6434\u646D\u647B\u6572\u65A1\u65D7\u65D6\u66A2\u66A8\u669D\u699C\u69A8\u6995\u69C1\u69AE\u69D3\u69CB\u699B\u69B7\u69BB\u69AB\u69B4\u69D0\u69CD\u69AD\u69CC\u69A6\u69C3\u69A3\u6B49\u6B4C\u6C33\u6F33\u6F14\u6EFE\u6F13\u6EF4\u6F29\u6F3E\u6F20\u6F2C\u6F0F\u6F02\u6F22"], + ["baa1", "\u6EFF\u6EEF\u6F06\u6F31\u6F38\u6F32\u6F23\u6F15\u6F2B\u6F2F\u6F88\u6F2A\u6EEC\u6F01\u6EF2\u6ECC\u6EF7\u7194\u7199\u717D\u718A\u7184\u7192\u723E\u7292\u7296\u7344\u7350\u7464\u7463\u746A\u7470\u746D\u7504\u7591\u7627\u760D\u760B\u7609\u7613\u76E1\u76E3\u7784\u777D\u777F\u7761\u78C1\u789F\u78A7\u78B3\u78A9\u78A3\u798E\u798F\u798D\u7A2E\u7A31\u7AAA\u7AA9\u7AED\u7AEF\u7BA1\u7B95\u7B8B\u7B75\u7B97\u7B9D\u7B94\u7B8F\u7BB8\u7B87\u7B84\u7CB9\u7CBD\u7CBE\u7DBB\u7DB0\u7D9C\u7DBD\u7DBE\u7DA0\u7DCA\u7DB4\u7DB2\u7DB1\u7DBA\u7DA2\u7DBF\u7DB5\u7DB8\u7DAD\u7DD2\u7DC7\u7DAC"], + ["bb40", "\u7F70\u7FE0\u7FE1\u7FDF\u805E\u805A\u8087\u8150\u8180\u818F\u8188\u818A\u817F\u8182\u81E7\u81FA\u8207\u8214\u821E\u824B\u84C9\u84BF\u84C6\u84C4\u8499\u849E\u84B2\u849C\u84CB\u84B8\u84C0\u84D3\u8490\u84BC\u84D1\u84CA\u873F\u871C\u873B\u8722\u8725\u8734\u8718\u8755\u8737\u8729\u88F3\u8902\u88F4\u88F9\u88F8\u88FD\u88E8\u891A\u88EF\u8AA6\u8A8C\u8A9E\u8AA3\u8A8D\u8AA1\u8A93\u8AA4"], + ["bba1", "\u8AAA\u8AA5\u8AA8\u8A98\u8A91\u8A9A\u8AA7\u8C6A\u8C8D\u8C8C\u8CD3\u8CD1\u8CD2\u8D6B\u8D99\u8D95\u8DFC\u8F14\u8F12\u8F15\u8F13\u8FA3\u9060\u9058\u905C\u9063\u9059\u905E\u9062\u905D\u905B\u9119\u9118\u911E\u9175\u9178\u9177\u9174\u9278\u9280\u9285\u9298\u9296\u927B\u9293\u929C\u92A8\u927C\u9291\u95A1\u95A8\u95A9\u95A3\u95A5\u95A4\u9699\u969C\u969B\u96CC\u96D2\u9700\u977C\u9785\u97F6\u9817\u9818\u98AF\u98B1\u9903\u9905\u990C\u9909\u99C1\u9AAF\u9AB0\u9AE6\u9B41\u9B42\u9CF4\u9CF6\u9CF3\u9EBC\u9F3B\u9F4A\u5104\u5100\u50FB\u50F5\u50F9\u5102\u5108\u5109\u5105\u51DC"], + ["bc40", "\u5287\u5288\u5289\u528D\u528A\u52F0\u53B2\u562E\u563B\u5639\u5632\u563F\u5634\u5629\u5653\u564E\u5657\u5674\u5636\u562F\u5630\u5880\u589F\u589E\u58B3\u589C\u58AE\u58A9\u58A6\u596D\u5B09\u5AFB\u5B0B\u5AF5\u5B0C\u5B08\u5BEE\u5BEC\u5BE9\u5BEB\u5C64\u5C65\u5D9D\u5D94\u5E62\u5E5F\u5E61\u5EE2\u5EDA\u5EDF\u5EDD\u5EE3\u5EE0\u5F48\u5F71\u5FB7\u5FB5\u6176\u6167\u616E\u615D\u6155\u6182"], + ["bca1", "\u617C\u6170\u616B\u617E\u61A7\u6190\u61AB\u618E\u61AC\u619A\u61A4\u6194\u61AE\u622E\u6469\u646F\u6479\u649E\u64B2\u6488\u6490\u64B0\u64A5\u6493\u6495\u64A9\u6492\u64AE\u64AD\u64AB\u649A\u64AC\u6499\u64A2\u64B3\u6575\u6577\u6578\u66AE\u66AB\u66B4\u66B1\u6A23\u6A1F\u69E8\u6A01\u6A1E\u6A19\u69FD\u6A21\u6A13\u6A0A\u69F3\u6A02\u6A05\u69ED\u6A11\u6B50\u6B4E\u6BA4\u6BC5\u6BC6\u6F3F\u6F7C\u6F84\u6F51\u6F66\u6F54\u6F86\u6F6D\u6F5B\u6F78\u6F6E\u6F8E\u6F7A\u6F70\u6F64\u6F97\u6F58\u6ED5\u6F6F\u6F60\u6F5F\u719F\u71AC\u71B1\u71A8\u7256\u729B\u734E\u7357\u7469\u748B\u7483"], + ["bd40", "\u747E\u7480\u757F\u7620\u7629\u761F\u7624\u7626\u7621\u7622\u769A\u76BA\u76E4\u778E\u7787\u778C\u7791\u778B\u78CB\u78C5\u78BA\u78CA\u78BE\u78D5\u78BC\u78D0\u7A3F\u7A3C\u7A40\u7A3D\u7A37\u7A3B\u7AAF\u7AAE\u7BAD\u7BB1\u7BC4\u7BB4\u7BC6\u7BC7\u7BC1\u7BA0\u7BCC\u7CCA\u7DE0\u7DF4\u7DEF\u7DFB\u7DD8\u7DEC\u7DDD\u7DE8\u7DE3\u7DDA\u7DDE\u7DE9\u7D9E\u7DD9\u7DF2\u7DF9\u7F75\u7F77\u7FAF"], + ["bda1", "\u7FE9\u8026\u819B\u819C\u819D\u81A0\u819A\u8198\u8517\u853D\u851A\u84EE\u852C\u852D\u8513\u8511\u8523\u8521\u8514\u84EC\u8525\u84FF\u8506\u8782\u8774\u8776\u8760\u8766\u8778\u8768\u8759\u8757\u874C\u8753\u885B\u885D\u8910\u8907\u8912\u8913\u8915\u890A\u8ABC\u8AD2\u8AC7\u8AC4\u8A95\u8ACB\u8AF8\u8AB2\u8AC9\u8AC2\u8ABF\u8AB0\u8AD6\u8ACD\u8AB6\u8AB9\u8ADB\u8C4C\u8C4E\u8C6C\u8CE0\u8CDE\u8CE6\u8CE4\u8CEC\u8CED\u8CE2\u8CE3\u8CDC\u8CEA\u8CE1\u8D6D\u8D9F\u8DA3\u8E2B\u8E10\u8E1D\u8E22\u8E0F\u8E29\u8E1F\u8E21\u8E1E\u8EBA\u8F1D\u8F1B\u8F1F\u8F29\u8F26\u8F2A\u8F1C\u8F1E"], + ["be40", "\u8F25\u9069\u906E\u9068\u906D\u9077\u9130\u912D\u9127\u9131\u9187\u9189\u918B\u9183\u92C5\u92BB\u92B7\u92EA\u92AC\u92E4\u92C1\u92B3\u92BC\u92D2\u92C7\u92F0\u92B2\u95AD\u95B1\u9704\u9706\u9707\u9709\u9760\u978D\u978B\u978F\u9821\u982B\u981C\u98B3\u990A\u9913\u9912\u9918\u99DD\u99D0\u99DF\u99DB\u99D1\u99D5\u99D2\u99D9\u9AB7\u9AEE\u9AEF\u9B27\u9B45\u9B44\u9B77\u9B6F\u9D06\u9D09"], + ["bea1", "\u9D03\u9EA9\u9EBE\u9ECE\u58A8\u9F52\u5112\u5118\u5114\u5110\u5115\u5180\u51AA\u51DD\u5291\u5293\u52F3\u5659\u566B\u5679\u5669\u5664\u5678\u566A\u5668\u5665\u5671\u566F\u566C\u5662\u5676\u58C1\u58BE\u58C7\u58C5\u596E\u5B1D\u5B34\u5B78\u5BF0\u5C0E\u5F4A\u61B2\u6191\u61A9\u618A\u61CD\u61B6\u61BE\u61CA\u61C8\u6230\u64C5\u64C1\u64CB\u64BB\u64BC\u64DA\u64C4\u64C7\u64C2\u64CD\u64BF\u64D2\u64D4\u64BE\u6574\u66C6\u66C9\u66B9\u66C4\u66C7\u66B8\u6A3D\u6A38\u6A3A\u6A59\u6A6B\u6A58\u6A39\u6A44\u6A62\u6A61\u6A4B\u6A47\u6A35\u6A5F\u6A48\u6B59\u6B77\u6C05\u6FC2\u6FB1\u6FA1"], + ["bf40", "\u6FC3\u6FA4\u6FC1\u6FA7\u6FB3\u6FC0\u6FB9\u6FB6\u6FA6\u6FA0\u6FB4\u71BE\u71C9\u71D0\u71D2\u71C8\u71D5\u71B9\u71CE\u71D9\u71DC\u71C3\u71C4\u7368\u749C\u74A3\u7498\u749F\u749E\u74E2\u750C\u750D\u7634\u7638\u763A\u76E7\u76E5\u77A0\u779E\u779F\u77A5\u78E8\u78DA\u78EC\u78E7\u79A6\u7A4D\u7A4E\u7A46\u7A4C\u7A4B\u7ABA\u7BD9\u7C11\u7BC9\u7BE4\u7BDB\u7BE1\u7BE9\u7BE6\u7CD5\u7CD6\u7E0A"], + ["bfa1", "\u7E11\u7E08\u7E1B\u7E23\u7E1E\u7E1D\u7E09\u7E10\u7F79\u7FB2\u7FF0\u7FF1\u7FEE\u8028\u81B3\u81A9\u81A8\u81FB\u8208\u8258\u8259\u854A\u8559\u8548\u8568\u8569\u8543\u8549\u856D\u856A\u855E\u8783\u879F\u879E\u87A2\u878D\u8861\u892A\u8932\u8925\u892B\u8921\u89AA\u89A6\u8AE6\u8AFA\u8AEB\u8AF1\u8B00\u8ADC\u8AE7\u8AEE\u8AFE\u8B01\u8B02\u8AF7\u8AED\u8AF3\u8AF6\u8AFC\u8C6B\u8C6D\u8C93\u8CF4\u8E44\u8E31\u8E34\u8E42\u8E39\u8E35\u8F3B\u8F2F\u8F38\u8F33\u8FA8\u8FA6\u9075\u9074\u9078\u9072\u907C\u907A\u9134\u9192\u9320\u9336\u92F8\u9333\u932F\u9322\u92FC\u932B\u9304\u931A"], + ["c040", "\u9310\u9326\u9321\u9315\u932E\u9319\u95BB\u96A7\u96A8\u96AA\u96D5\u970E\u9711\u9716\u970D\u9713\u970F\u975B\u975C\u9766\u9798\u9830\u9838\u983B\u9837\u982D\u9839\u9824\u9910\u9928\u991E\u991B\u9921\u991A\u99ED\u99E2\u99F1\u9AB8\u9ABC\u9AFB\u9AED\u9B28\u9B91\u9D15\u9D23\u9D26\u9D28\u9D12\u9D1B\u9ED8\u9ED4\u9F8D\u9F9C\u512A\u511F\u5121\u5132\u52F5\u568E\u5680\u5690\u5685\u5687"], + ["c0a1", "\u568F\u58D5\u58D3\u58D1\u58CE\u5B30\u5B2A\u5B24\u5B7A\u5C37\u5C68\u5DBC\u5DBA\u5DBD\u5DB8\u5E6B\u5F4C\u5FBD\u61C9\u61C2\u61C7\u61E6\u61CB\u6232\u6234\u64CE\u64CA\u64D8\u64E0\u64F0\u64E6\u64EC\u64F1\u64E2\u64ED\u6582\u6583\u66D9\u66D6\u6A80\u6A94\u6A84\u6AA2\u6A9C\u6ADB\u6AA3\u6A7E\u6A97\u6A90\u6AA0\u6B5C\u6BAE\u6BDA\u6C08\u6FD8\u6FF1\u6FDF\u6FE0\u6FDB\u6FE4\u6FEB\u6FEF\u6F80\u6FEC\u6FE1\u6FE9\u6FD5\u6FEE\u6FF0\u71E7\u71DF\u71EE\u71E6\u71E5\u71ED\u71EC\u71F4\u71E0\u7235\u7246\u7370\u7372\u74A9\u74B0\u74A6\u74A8\u7646\u7642\u764C\u76EA\u77B3\u77AA\u77B0\u77AC"], + ["c140", "\u77A7\u77AD\u77EF\u78F7\u78FA\u78F4\u78EF\u7901\u79A7\u79AA\u7A57\u7ABF\u7C07\u7C0D\u7BFE\u7BF7\u7C0C\u7BE0\u7CE0\u7CDC\u7CDE\u7CE2\u7CDF\u7CD9\u7CDD\u7E2E\u7E3E\u7E46\u7E37\u7E32\u7E43\u7E2B\u7E3D\u7E31\u7E45\u7E41\u7E34\u7E39\u7E48\u7E35\u7E3F\u7E2F\u7F44\u7FF3\u7FFC\u8071\u8072\u8070\u806F\u8073\u81C6\u81C3\u81BA\u81C2\u81C0\u81BF\u81BD\u81C9\u81BE\u81E8\u8209\u8271\u85AA"], + ["c1a1", "\u8584\u857E\u859C\u8591\u8594\u85AF\u859B\u8587\u85A8\u858A\u8667\u87C0\u87D1\u87B3\u87D2\u87C6\u87AB\u87BB\u87BA\u87C8\u87CB\u893B\u8936\u8944\u8938\u893D\u89AC\u8B0E\u8B17\u8B19\u8B1B\u8B0A\u8B20\u8B1D\u8B04\u8B10\u8C41\u8C3F\u8C73\u8CFA\u8CFD\u8CFC\u8CF8\u8CFB\u8DA8\u8E49\u8E4B\u8E48\u8E4A\u8F44\u8F3E\u8F42\u8F45\u8F3F\u907F\u907D\u9084\u9081\u9082\u9080\u9139\u91A3\u919E\u919C\u934D\u9382\u9328\u9375\u934A\u9365\u934B\u9318\u937E\u936C\u935B\u9370\u935A\u9354\u95CA\u95CB\u95CC\u95C8\u95C6\u96B1\u96B8\u96D6\u971C\u971E\u97A0\u97D3\u9846\u98B6\u9935\u9A01"], + ["c240", "\u99FF\u9BAE\u9BAB\u9BAA\u9BAD\u9D3B\u9D3F\u9E8B\u9ECF\u9EDE\u9EDC\u9EDD\u9EDB\u9F3E\u9F4B\u53E2\u5695\u56AE\u58D9\u58D8\u5B38\u5F5D\u61E3\u6233\u64F4\u64F2\u64FE\u6506\u64FA\u64FB\u64F7\u65B7\u66DC\u6726\u6AB3\u6AAC\u6AC3\u6ABB\u6AB8\u6AC2\u6AAE\u6AAF\u6B5F\u6B78\u6BAF\u7009\u700B\u6FFE\u7006\u6FFA\u7011\u700F\u71FB\u71FC\u71FE\u71F8\u7377\u7375\u74A7\u74BF\u7515\u7656\u7658"], + ["c2a1", "\u7652\u77BD\u77BF\u77BB\u77BC\u790E\u79AE\u7A61\u7A62\u7A60\u7AC4\u7AC5\u7C2B\u7C27\u7C2A\u7C1E\u7C23\u7C21\u7CE7\u7E54\u7E55\u7E5E\u7E5A\u7E61\u7E52\u7E59\u7F48\u7FF9\u7FFB\u8077\u8076\u81CD\u81CF\u820A\u85CF\u85A9\u85CD\u85D0\u85C9\u85B0\u85BA\u85B9\u85A6\u87EF\u87EC\u87F2\u87E0\u8986\u89B2\u89F4\u8B28\u8B39\u8B2C\u8B2B\u8C50\u8D05\u8E59\u8E63\u8E66\u8E64\u8E5F\u8E55\u8EC0\u8F49\u8F4D\u9087\u9083\u9088\u91AB\u91AC\u91D0\u9394\u938A\u9396\u93A2\u93B3\u93AE\u93AC\u93B0\u9398\u939A\u9397\u95D4\u95D6\u95D0\u95D5\u96E2\u96DC\u96D9\u96DB\u96DE\u9724\u97A3\u97A6"], + ["c340", "\u97AD\u97F9\u984D\u984F\u984C\u984E\u9853\u98BA\u993E\u993F\u993D\u992E\u99A5\u9A0E\u9AC1\u9B03\u9B06\u9B4F\u9B4E\u9B4D\u9BCA\u9BC9\u9BFD\u9BC8\u9BC0\u9D51\u9D5D\u9D60\u9EE0\u9F15\u9F2C\u5133\u56A5\u58DE\u58DF\u58E2\u5BF5\u9F90\u5EEC\u61F2\u61F7\u61F6\u61F5\u6500\u650F\u66E0\u66DD\u6AE5\u6ADD\u6ADA\u6AD3\u701B\u701F\u7028\u701A\u701D\u7015\u7018\u7206\u720D\u7258\u72A2\u7378"], + ["c3a1", "\u737A\u74BD\u74CA\u74E3\u7587\u7586\u765F\u7661\u77C7\u7919\u79B1\u7A6B\u7A69\u7C3E\u7C3F\u7C38\u7C3D\u7C37\u7C40\u7E6B\u7E6D\u7E79\u7E69\u7E6A\u7F85\u7E73\u7FB6\u7FB9\u7FB8\u81D8\u85E9\u85DD\u85EA\u85D5\u85E4\u85E5\u85F7\u87FB\u8805\u880D\u87F9\u87FE\u8960\u895F\u8956\u895E\u8B41\u8B5C\u8B58\u8B49\u8B5A\u8B4E\u8B4F\u8B46\u8B59\u8D08\u8D0A\u8E7C\u8E72\u8E87\u8E76\u8E6C\u8E7A\u8E74\u8F54\u8F4E\u8FAD\u908A\u908B\u91B1\u91AE\u93E1\u93D1\u93DF\u93C3\u93C8\u93DC\u93DD\u93D6\u93E2\u93CD\u93D8\u93E4\u93D7\u93E8\u95DC\u96B4\u96E3\u972A\u9727\u9761\u97DC\u97FB\u985E"], + ["c440", "\u9858\u985B\u98BC\u9945\u9949\u9A16\u9A19\u9B0D\u9BE8\u9BE7\u9BD6\u9BDB\u9D89\u9D61\u9D72\u9D6A\u9D6C\u9E92\u9E97\u9E93\u9EB4\u52F8\u56A8\u56B7\u56B6\u56B4\u56BC\u58E4\u5B40\u5B43\u5B7D\u5BF6\u5DC9\u61F8\u61FA\u6518\u6514\u6519\u66E6\u6727\u6AEC\u703E\u7030\u7032\u7210\u737B\u74CF\u7662\u7665\u7926\u792A\u792C\u792B\u7AC7\u7AF6\u7C4C\u7C43\u7C4D\u7CEF\u7CF0\u8FAE\u7E7D\u7E7C"], + ["c4a1", "\u7E82\u7F4C\u8000\u81DA\u8266\u85FB\u85F9\u8611\u85FA\u8606\u860B\u8607\u860A\u8814\u8815\u8964\u89BA\u89F8\u8B70\u8B6C\u8B66\u8B6F\u8B5F\u8B6B\u8D0F\u8D0D\u8E89\u8E81\u8E85\u8E82\u91B4\u91CB\u9418\u9403\u93FD\u95E1\u9730\u98C4\u9952\u9951\u99A8\u9A2B\u9A30\u9A37\u9A35\u9C13\u9C0D\u9E79\u9EB5\u9EE8\u9F2F\u9F5F\u9F63\u9F61\u5137\u5138\u56C1\u56C0\u56C2\u5914\u5C6C\u5DCD\u61FC\u61FE\u651D\u651C\u6595\u66E9\u6AFB\u6B04\u6AFA\u6BB2\u704C\u721B\u72A7\u74D6\u74D4\u7669\u77D3\u7C50\u7E8F\u7E8C\u7FBC\u8617\u862D\u861A\u8823\u8822\u8821\u881F\u896A\u896C\u89BD\u8B74"], + ["c540", "\u8B77\u8B7D\u8D13\u8E8A\u8E8D\u8E8B\u8F5F\u8FAF\u91BA\u942E\u9433\u9435\u943A\u9438\u9432\u942B\u95E2\u9738\u9739\u9732\u97FF\u9867\u9865\u9957\u9A45\u9A43\u9A40\u9A3E\u9ACF\u9B54\u9B51\u9C2D\u9C25\u9DAF\u9DB4\u9DC2\u9DB8\u9E9D\u9EEF\u9F19\u9F5C\u9F66\u9F67\u513C\u513B\u56C8\u56CA\u56C9\u5B7F\u5DD4\u5DD2\u5F4E\u61FF\u6524\u6B0A\u6B61\u7051\u7058\u7380\u74E4\u758A\u766E\u766C"], + ["c5a1", "\u79B3\u7C60\u7C5F\u807E\u807D\u81DF\u8972\u896F\u89FC\u8B80\u8D16\u8D17\u8E91\u8E93\u8F61\u9148\u9444\u9451\u9452\u973D\u973E\u97C3\u97C1\u986B\u9955\u9A55\u9A4D\u9AD2\u9B1A\u9C49\u9C31\u9C3E\u9C3B\u9DD3\u9DD7\u9F34\u9F6C\u9F6A\u9F94\u56CC\u5DD6\u6200\u6523\u652B\u652A\u66EC\u6B10\u74DA\u7ACA\u7C64\u7C63\u7C65\u7E93\u7E96\u7E94\u81E2\u8638\u863F\u8831\u8B8A\u9090\u908F\u9463\u9460\u9464\u9768\u986F\u995C\u9A5A\u9A5B\u9A57\u9AD3\u9AD4\u9AD1\u9C54\u9C57\u9C56\u9DE5\u9E9F\u9EF4\u56D1\u58E9\u652C\u705E\u7671\u7672\u77D7\u7F50\u7F88\u8836\u8839\u8862\u8B93\u8B92"], + ["c640", "\u8B96\u8277\u8D1B\u91C0\u946A\u9742\u9748\u9744\u97C6\u9870\u9A5F\u9B22\u9B58\u9C5F\u9DF9\u9DFA\u9E7C\u9E7D\u9F07\u9F77\u9F72\u5EF3\u6B16\u7063\u7C6C\u7C6E\u883B\u89C0\u8EA1\u91C1\u9472\u9470\u9871\u995E\u9AD6\u9B23\u9ECC\u7064\u77DA\u8B9A\u9477\u97C9\u9A62\u9A65\u7E9C\u8B9C\u8EAA\u91C5\u947D\u947E\u947C\u9C77\u9C78\u9EF7\u8C54\u947F\u9E1A\u7228\u9A6A\u9B31\u9E1B\u9E1E\u7C72"], + ["c940", "\u4E42\u4E5C\u51F5\u531A\u5382\u4E07\u4E0C\u4E47\u4E8D\u56D7\uFA0C\u5C6E\u5F73\u4E0F\u5187\u4E0E\u4E2E\u4E93\u4EC2\u4EC9\u4EC8\u5198\u52FC\u536C\u53B9\u5720\u5903\u592C\u5C10\u5DFF\u65E1\u6BB3\u6BCC\u6C14\u723F\u4E31\u4E3C\u4EE8\u4EDC\u4EE9\u4EE1\u4EDD\u4EDA\u520C\u531C\u534C\u5722\u5723\u5917\u592F\u5B81\u5B84\u5C12\u5C3B\u5C74\u5C73\u5E04\u5E80\u5E82\u5FC9\u6209\u6250\u6C15"], + ["c9a1", "\u6C36\u6C43\u6C3F\u6C3B\u72AE\u72B0\u738A\u79B8\u808A\u961E\u4F0E\u4F18\u4F2C\u4EF5\u4F14\u4EF1\u4F00\u4EF7\u4F08\u4F1D\u4F02\u4F05\u4F22\u4F13\u4F04\u4EF4\u4F12\u51B1\u5213\u5209\u5210\u52A6\u5322\u531F\u534D\u538A\u5407\u56E1\u56DF\u572E\u572A\u5734\u593C\u5980\u597C\u5985\u597B\u597E\u5977\u597F\u5B56\u5C15\u5C25\u5C7C\u5C7A\u5C7B\u5C7E\u5DDF\u5E75\u5E84\u5F02\u5F1A\u5F74\u5FD5\u5FD4\u5FCF\u625C\u625E\u6264\u6261\u6266\u6262\u6259\u6260\u625A\u6265\u65EF\u65EE\u673E\u6739\u6738\u673B\u673A\u673F\u673C\u6733\u6C18\u6C46\u6C52\u6C5C\u6C4F\u6C4A\u6C54\u6C4B"], + ["ca40", "\u6C4C\u7071\u725E\u72B4\u72B5\u738E\u752A\u767F\u7A75\u7F51\u8278\u827C\u8280\u827D\u827F\u864D\u897E\u9099\u9097\u9098\u909B\u9094\u9622\u9624\u9620\u9623\u4F56\u4F3B\u4F62\u4F49\u4F53\u4F64\u4F3E\u4F67\u4F52\u4F5F\u4F41\u4F58\u4F2D\u4F33\u4F3F\u4F61\u518F\u51B9\u521C\u521E\u5221\u52AD\u52AE\u5309\u5363\u5372\u538E\u538F\u5430\u5437\u542A\u5454\u5445\u5419\u541C\u5425\u5418"], + ["caa1", "\u543D\u544F\u5441\u5428\u5424\u5447\u56EE\u56E7\u56E5\u5741\u5745\u574C\u5749\u574B\u5752\u5906\u5940\u59A6\u5998\u59A0\u5997\u598E\u59A2\u5990\u598F\u59A7\u59A1\u5B8E\u5B92\u5C28\u5C2A\u5C8D\u5C8F\u5C88\u5C8B\u5C89\u5C92\u5C8A\u5C86\u5C93\u5C95\u5DE0\u5E0A\u5E0E\u5E8B\u5E89\u5E8C\u5E88\u5E8D\u5F05\u5F1D\u5F78\u5F76\u5FD2\u5FD1\u5FD0\u5FED\u5FE8\u5FEE\u5FF3\u5FE1\u5FE4\u5FE3\u5FFA\u5FEF\u5FF7\u5FFB\u6000\u5FF4\u623A\u6283\u628C\u628E\u628F\u6294\u6287\u6271\u627B\u627A\u6270\u6281\u6288\u6277\u627D\u6272\u6274\u6537\u65F0\u65F4\u65F3\u65F2\u65F5\u6745\u6747"], + ["cb40", "\u6759\u6755\u674C\u6748\u675D\u674D\u675A\u674B\u6BD0\u6C19\u6C1A\u6C78\u6C67\u6C6B\u6C84\u6C8B\u6C8F\u6C71\u6C6F\u6C69\u6C9A\u6C6D\u6C87\u6C95\u6C9C\u6C66\u6C73\u6C65\u6C7B\u6C8E\u7074\u707A\u7263\u72BF\u72BD\u72C3\u72C6\u72C1\u72BA\u72C5\u7395\u7397\u7393\u7394\u7392\u753A\u7539\u7594\u7595\u7681\u793D\u8034\u8095\u8099\u8090\u8092\u809C\u8290\u828F\u8285\u828E\u8291\u8293"], + ["cba1", "\u828A\u8283\u8284\u8C78\u8FC9\u8FBF\u909F\u90A1\u90A5\u909E\u90A7\u90A0\u9630\u9628\u962F\u962D\u4E33\u4F98\u4F7C\u4F85\u4F7D\u4F80\u4F87\u4F76\u4F74\u4F89\u4F84\u4F77\u4F4C\u4F97\u4F6A\u4F9A\u4F79\u4F81\u4F78\u4F90\u4F9C\u4F94\u4F9E\u4F92\u4F82\u4F95\u4F6B\u4F6E\u519E\u51BC\u51BE\u5235\u5232\u5233\u5246\u5231\u52BC\u530A\u530B\u533C\u5392\u5394\u5487\u547F\u5481\u5491\u5482\u5488\u546B\u547A\u547E\u5465\u546C\u5474\u5466\u548D\u546F\u5461\u5460\u5498\u5463\u5467\u5464\u56F7\u56F9\u576F\u5772\u576D\u576B\u5771\u5770\u5776\u5780\u5775\u577B\u5773\u5774\u5762"], + ["cc40", "\u5768\u577D\u590C\u5945\u59B5\u59BA\u59CF\u59CE\u59B2\u59CC\u59C1\u59B6\u59BC\u59C3\u59D6\u59B1\u59BD\u59C0\u59C8\u59B4\u59C7\u5B62\u5B65\u5B93\u5B95\u5C44\u5C47\u5CAE\u5CA4\u5CA0\u5CB5\u5CAF\u5CA8\u5CAC\u5C9F\u5CA3\u5CAD\u5CA2\u5CAA\u5CA7\u5C9D\u5CA5\u5CB6\u5CB0\u5CA6\u5E17\u5E14\u5E19\u5F28\u5F22\u5F23\u5F24\u5F54\u5F82\u5F7E\u5F7D\u5FDE\u5FE5\u602D\u6026\u6019\u6032\u600B"], + ["cca1", "\u6034\u600A\u6017\u6033\u601A\u601E\u602C\u6022\u600D\u6010\u602E\u6013\u6011\u600C\u6009\u601C\u6214\u623D\u62AD\u62B4\u62D1\u62BE\u62AA\u62B6\u62CA\u62AE\u62B3\u62AF\u62BB\u62A9\u62B0\u62B8\u653D\u65A8\u65BB\u6609\u65FC\u6604\u6612\u6608\u65FB\u6603\u660B\u660D\u6605\u65FD\u6611\u6610\u66F6\u670A\u6785\u676C\u678E\u6792\u6776\u677B\u6798\u6786\u6784\u6774\u678D\u678C\u677A\u679F\u6791\u6799\u6783\u677D\u6781\u6778\u6779\u6794\u6B25\u6B80\u6B7E\u6BDE\u6C1D\u6C93\u6CEC\u6CEB\u6CEE\u6CD9\u6CB6\u6CD4\u6CAD\u6CE7\u6CB7\u6CD0\u6CC2\u6CBA\u6CC3\u6CC6\u6CED\u6CF2"], + ["cd40", "\u6CD2\u6CDD\u6CB4\u6C8A\u6C9D\u6C80\u6CDE\u6CC0\u6D30\u6CCD\u6CC7\u6CB0\u6CF9\u6CCF\u6CE9\u6CD1\u7094\u7098\u7085\u7093\u7086\u7084\u7091\u7096\u7082\u709A\u7083\u726A\u72D6\u72CB\u72D8\u72C9\u72DC\u72D2\u72D4\u72DA\u72CC\u72D1\u73A4\u73A1\u73AD\u73A6\u73A2\u73A0\u73AC\u739D\u74DD\u74E8\u753F\u7540\u753E\u758C\u7598\u76AF\u76F3\u76F1\u76F0\u76F5\u77F8\u77FC\u77F9\u77FB\u77FA"], + ["cda1", "\u77F7\u7942\u793F\u79C5\u7A78\u7A7B\u7AFB\u7C75\u7CFD\u8035\u808F\u80AE\u80A3\u80B8\u80B5\u80AD\u8220\u82A0\u82C0\u82AB\u829A\u8298\u829B\u82B5\u82A7\u82AE\u82BC\u829E\u82BA\u82B4\u82A8\u82A1\u82A9\u82C2\u82A4\u82C3\u82B6\u82A2\u8670\u866F\u866D\u866E\u8C56\u8FD2\u8FCB\u8FD3\u8FCD\u8FD6\u8FD5\u8FD7\u90B2\u90B4\u90AF\u90B3\u90B0\u9639\u963D\u963C\u963A\u9643\u4FCD\u4FC5\u4FD3\u4FB2\u4FC9\u4FCB\u4FC1\u4FD4\u4FDC\u4FD9\u4FBB\u4FB3\u4FDB\u4FC7\u4FD6\u4FBA\u4FC0\u4FB9\u4FEC\u5244\u5249\u52C0\u52C2\u533D\u537C\u5397\u5396\u5399\u5398\u54BA\u54A1\u54AD\u54A5\u54CF"], + ["ce40", "\u54C3\u830D\u54B7\u54AE\u54D6\u54B6\u54C5\u54C6\u54A0\u5470\u54BC\u54A2\u54BE\u5472\u54DE\u54B0\u57B5\u579E\u579F\u57A4\u578C\u5797\u579D\u579B\u5794\u5798\u578F\u5799\u57A5\u579A\u5795\u58F4\u590D\u5953\u59E1\u59DE\u59EE\u5A00\u59F1\u59DD\u59FA\u59FD\u59FC\u59F6\u59E4\u59F2\u59F7\u59DB\u59E9\u59F3\u59F5\u59E0\u59FE\u59F4\u59ED\u5BA8\u5C4C\u5CD0\u5CD8\u5CCC\u5CD7\u5CCB\u5CDB"], + ["cea1", "\u5CDE\u5CDA\u5CC9\u5CC7\u5CCA\u5CD6\u5CD3\u5CD4\u5CCF\u5CC8\u5CC6\u5CCE\u5CDF\u5CF8\u5DF9\u5E21\u5E22\u5E23\u5E20\u5E24\u5EB0\u5EA4\u5EA2\u5E9B\u5EA3\u5EA5\u5F07\u5F2E\u5F56\u5F86\u6037\u6039\u6054\u6072\u605E\u6045\u6053\u6047\u6049\u605B\u604C\u6040\u6042\u605F\u6024\u6044\u6058\u6066\u606E\u6242\u6243\u62CF\u630D\u630B\u62F5\u630E\u6303\u62EB\u62F9\u630F\u630C\u62F8\u62F6\u6300\u6313\u6314\u62FA\u6315\u62FB\u62F0\u6541\u6543\u65AA\u65BF\u6636\u6621\u6632\u6635\u661C\u6626\u6622\u6633\u662B\u663A\u661D\u6634\u6639\u662E\u670F\u6710\u67C1\u67F2\u67C8\u67BA"], + ["cf40", "\u67DC\u67BB\u67F8\u67D8\u67C0\u67B7\u67C5\u67EB\u67E4\u67DF\u67B5\u67CD\u67B3\u67F7\u67F6\u67EE\u67E3\u67C2\u67B9\u67CE\u67E7\u67F0\u67B2\u67FC\u67C6\u67ED\u67CC\u67AE\u67E6\u67DB\u67FA\u67C9\u67CA\u67C3\u67EA\u67CB\u6B28\u6B82\u6B84\u6BB6\u6BD6\u6BD8\u6BE0\u6C20\u6C21\u6D28\u6D34\u6D2D\u6D1F\u6D3C\u6D3F\u6D12\u6D0A\u6CDA\u6D33\u6D04\u6D19\u6D3A\u6D1A\u6D11\u6D00\u6D1D\u6D42"], + ["cfa1", "\u6D01\u6D18\u6D37\u6D03\u6D0F\u6D40\u6D07\u6D20\u6D2C\u6D08\u6D22\u6D09\u6D10\u70B7\u709F\u70BE\u70B1\u70B0\u70A1\u70B4\u70B5\u70A9\u7241\u7249\u724A\u726C\u7270\u7273\u726E\u72CA\u72E4\u72E8\u72EB\u72DF\u72EA\u72E6\u72E3\u7385\u73CC\u73C2\u73C8\u73C5\u73B9\u73B6\u73B5\u73B4\u73EB\u73BF\u73C7\u73BE\u73C3\u73C6\u73B8\u73CB\u74EC\u74EE\u752E\u7547\u7548\u75A7\u75AA\u7679\u76C4\u7708\u7703\u7704\u7705\u770A\u76F7\u76FB\u76FA\u77E7\u77E8\u7806\u7811\u7812\u7805\u7810\u780F\u780E\u7809\u7803\u7813\u794A\u794C\u794B\u7945\u7944\u79D5\u79CD\u79CF\u79D6\u79CE\u7A80"], + ["d040", "\u7A7E\u7AD1\u7B00\u7B01\u7C7A\u7C78\u7C79\u7C7F\u7C80\u7C81\u7D03\u7D08\u7D01\u7F58\u7F91\u7F8D\u7FBE\u8007\u800E\u800F\u8014\u8037\u80D8\u80C7\u80E0\u80D1\u80C8\u80C2\u80D0\u80C5\u80E3\u80D9\u80DC\u80CA\u80D5\u80C9\u80CF\u80D7\u80E6\u80CD\u81FF\u8221\u8294\u82D9\u82FE\u82F9\u8307\u82E8\u8300\u82D5\u833A\u82EB\u82D6\u82F4\u82EC\u82E1\u82F2\u82F5\u830C\u82FB\u82F6\u82F0\u82EA"], + ["d0a1", "\u82E4\u82E0\u82FA\u82F3\u82ED\u8677\u8674\u867C\u8673\u8841\u884E\u8867\u886A\u8869\u89D3\u8A04\u8A07\u8D72\u8FE3\u8FE1\u8FEE\u8FE0\u90F1\u90BD\u90BF\u90D5\u90C5\u90BE\u90C7\u90CB\u90C8\u91D4\u91D3\u9654\u964F\u9651\u9653\u964A\u964E\u501E\u5005\u5007\u5013\u5022\u5030\u501B\u4FF5\u4FF4\u5033\u5037\u502C\u4FF6\u4FF7\u5017\u501C\u5020\u5027\u5035\u502F\u5031\u500E\u515A\u5194\u5193\u51CA\u51C4\u51C5\u51C8\u51CE\u5261\u525A\u5252\u525E\u525F\u5255\u5262\u52CD\u530E\u539E\u5526\u54E2\u5517\u5512\u54E7\u54F3\u54E4\u551A\u54FF\u5504\u5508\u54EB\u5511\u5505\u54F1"], + ["d140", "\u550A\u54FB\u54F7\u54F8\u54E0\u550E\u5503\u550B\u5701\u5702\u57CC\u5832\u57D5\u57D2\u57BA\u57C6\u57BD\u57BC\u57B8\u57B6\u57BF\u57C7\u57D0\u57B9\u57C1\u590E\u594A\u5A19\u5A16\u5A2D\u5A2E\u5A15\u5A0F\u5A17\u5A0A\u5A1E\u5A33\u5B6C\u5BA7\u5BAD\u5BAC\u5C03\u5C56\u5C54\u5CEC\u5CFF\u5CEE\u5CF1\u5CF7\u5D00\u5CF9\u5E29\u5E28\u5EA8\u5EAE\u5EAA\u5EAC\u5F33\u5F30\u5F67\u605D\u605A\u6067"], + ["d1a1", "\u6041\u60A2\u6088\u6080\u6092\u6081\u609D\u6083\u6095\u609B\u6097\u6087\u609C\u608E\u6219\u6246\u62F2\u6310\u6356\u632C\u6344\u6345\u6336\u6343\u63E4\u6339\u634B\u634A\u633C\u6329\u6341\u6334\u6358\u6354\u6359\u632D\u6347\u6333\u635A\u6351\u6338\u6357\u6340\u6348\u654A\u6546\u65C6\u65C3\u65C4\u65C2\u664A\u665F\u6647\u6651\u6712\u6713\u681F\u681A\u6849\u6832\u6833\u683B\u684B\u684F\u6816\u6831\u681C\u6835\u682B\u682D\u682F\u684E\u6844\u6834\u681D\u6812\u6814\u6826\u6828\u682E\u684D\u683A\u6825\u6820\u6B2C\u6B2F\u6B2D\u6B31\u6B34\u6B6D\u8082\u6B88\u6BE6\u6BE4"], + ["d240", "\u6BE8\u6BE3\u6BE2\u6BE7\u6C25\u6D7A\u6D63\u6D64\u6D76\u6D0D\u6D61\u6D92\u6D58\u6D62\u6D6D\u6D6F\u6D91\u6D8D\u6DEF\u6D7F\u6D86\u6D5E\u6D67\u6D60\u6D97\u6D70\u6D7C\u6D5F\u6D82\u6D98\u6D2F\u6D68\u6D8B\u6D7E\u6D80\u6D84\u6D16\u6D83\u6D7B\u6D7D\u6D75\u6D90\u70DC\u70D3\u70D1\u70DD\u70CB\u7F39\u70E2\u70D7\u70D2\u70DE\u70E0\u70D4\u70CD\u70C5\u70C6\u70C7\u70DA\u70CE\u70E1\u7242\u7278"], + ["d2a1", "\u7277\u7276\u7300\u72FA\u72F4\u72FE\u72F6\u72F3\u72FB\u7301\u73D3\u73D9\u73E5\u73D6\u73BC\u73E7\u73E3\u73E9\u73DC\u73D2\u73DB\u73D4\u73DD\u73DA\u73D7\u73D8\u73E8\u74DE\u74DF\u74F4\u74F5\u7521\u755B\u755F\u75B0\u75C1\u75BB\u75C4\u75C0\u75BF\u75B6\u75BA\u768A\u76C9\u771D\u771B\u7710\u7713\u7712\u7723\u7711\u7715\u7719\u771A\u7722\u7727\u7823\u782C\u7822\u7835\u782F\u7828\u782E\u782B\u7821\u7829\u7833\u782A\u7831\u7954\u795B\u794F\u795C\u7953\u7952\u7951\u79EB\u79EC\u79E0\u79EE\u79ED\u79EA\u79DC\u79DE\u79DD\u7A86\u7A89\u7A85\u7A8B\u7A8C\u7A8A\u7A87\u7AD8\u7B10"], + ["d340", "\u7B04\u7B13\u7B05\u7B0F\u7B08\u7B0A\u7B0E\u7B09\u7B12\u7C84\u7C91\u7C8A\u7C8C\u7C88\u7C8D\u7C85\u7D1E\u7D1D\u7D11\u7D0E\u7D18\u7D16\u7D13\u7D1F\u7D12\u7D0F\u7D0C\u7F5C\u7F61\u7F5E\u7F60\u7F5D\u7F5B\u7F96\u7F92\u7FC3\u7FC2\u7FC0\u8016\u803E\u8039\u80FA\u80F2\u80F9\u80F5\u8101\u80FB\u8100\u8201\u822F\u8225\u8333\u832D\u8344\u8319\u8351\u8325\u8356\u833F\u8341\u8326\u831C\u8322"], + ["d3a1", "\u8342\u834E\u831B\u832A\u8308\u833C\u834D\u8316\u8324\u8320\u8337\u832F\u8329\u8347\u8345\u834C\u8353\u831E\u832C\u834B\u8327\u8348\u8653\u8652\u86A2\u86A8\u8696\u868D\u8691\u869E\u8687\u8697\u8686\u868B\u869A\u8685\u86A5\u8699\u86A1\u86A7\u8695\u8698\u868E\u869D\u8690\u8694\u8843\u8844\u886D\u8875\u8876\u8872\u8880\u8871\u887F\u886F\u8883\u887E\u8874\u887C\u8A12\u8C47\u8C57\u8C7B\u8CA4\u8CA3\u8D76\u8D78\u8DB5\u8DB7\u8DB6\u8ED1\u8ED3\u8FFE\u8FF5\u9002\u8FFF\u8FFB\u9004\u8FFC\u8FF6\u90D6\u90E0\u90D9\u90DA\u90E3\u90DF\u90E5\u90D8\u90DB\u90D7\u90DC\u90E4\u9150"], + ["d440", "\u914E\u914F\u91D5\u91E2\u91DA\u965C\u965F\u96BC\u98E3\u9ADF\u9B2F\u4E7F\u5070\u506A\u5061\u505E\u5060\u5053\u504B\u505D\u5072\u5048\u504D\u5041\u505B\u504A\u5062\u5015\u5045\u505F\u5069\u506B\u5063\u5064\u5046\u5040\u506E\u5073\u5057\u5051\u51D0\u526B\u526D\u526C\u526E\u52D6\u52D3\u532D\u539C\u5575\u5576\u553C\u554D\u5550\u5534\u552A\u5551\u5562\u5536\u5535\u5530\u5552\u5545"], + ["d4a1", "\u550C\u5532\u5565\u554E\u5539\u5548\u552D\u553B\u5540\u554B\u570A\u5707\u57FB\u5814\u57E2\u57F6\u57DC\u57F4\u5800\u57ED\u57FD\u5808\u57F8\u580B\u57F3\u57CF\u5807\u57EE\u57E3\u57F2\u57E5\u57EC\u57E1\u580E\u57FC\u5810\u57E7\u5801\u580C\u57F1\u57E9\u57F0\u580D\u5804\u595C\u5A60\u5A58\u5A55\u5A67\u5A5E\u5A38\u5A35\u5A6D\u5A50\u5A5F\u5A65\u5A6C\u5A53\u5A64\u5A57\u5A43\u5A5D\u5A52\u5A44\u5A5B\u5A48\u5A8E\u5A3E\u5A4D\u5A39\u5A4C\u5A70\u5A69\u5A47\u5A51\u5A56\u5A42\u5A5C\u5B72\u5B6E\u5BC1\u5BC0\u5C59\u5D1E\u5D0B\u5D1D\u5D1A\u5D20\u5D0C\u5D28\u5D0D\u5D26\u5D25\u5D0F"], + ["d540", "\u5D30\u5D12\u5D23\u5D1F\u5D2E\u5E3E\u5E34\u5EB1\u5EB4\u5EB9\u5EB2\u5EB3\u5F36\u5F38\u5F9B\u5F96\u5F9F\u608A\u6090\u6086\u60BE\u60B0\u60BA\u60D3\u60D4\u60CF\u60E4\u60D9\u60DD\u60C8\u60B1\u60DB\u60B7\u60CA\u60BF\u60C3\u60CD\u60C0\u6332\u6365\u638A\u6382\u637D\u63BD\u639E\u63AD\u639D\u6397\u63AB\u638E\u636F\u6387\u6390\u636E\u63AF\u6375\u639C\u636D\u63AE\u637C\u63A4\u633B\u639F"], + ["d5a1", "\u6378\u6385\u6381\u6391\u638D\u6370\u6553\u65CD\u6665\u6661\u665B\u6659\u665C\u6662\u6718\u6879\u6887\u6890\u689C\u686D\u686E\u68AE\u68AB\u6956\u686F\u68A3\u68AC\u68A9\u6875\u6874\u68B2\u688F\u6877\u6892\u687C\u686B\u6872\u68AA\u6880\u6871\u687E\u689B\u6896\u688B\u68A0\u6889\u68A4\u6878\u687B\u6891\u688C\u688A\u687D\u6B36\u6B33\u6B37\u6B38\u6B91\u6B8F\u6B8D\u6B8E\u6B8C\u6C2A\u6DC0\u6DAB\u6DB4\u6DB3\u6E74\u6DAC\u6DE9\u6DE2\u6DB7\u6DF6\u6DD4\u6E00\u6DC8\u6DE0\u6DDF\u6DD6\u6DBE\u6DE5\u6DDC\u6DDD\u6DDB\u6DF4\u6DCA\u6DBD\u6DED\u6DF0\u6DBA\u6DD5\u6DC2\u6DCF\u6DC9"], + ["d640", "\u6DD0\u6DF2\u6DD3\u6DFD\u6DD7\u6DCD\u6DE3\u6DBB\u70FA\u710D\u70F7\u7117\u70F4\u710C\u70F0\u7104\u70F3\u7110\u70FC\u70FF\u7106\u7113\u7100\u70F8\u70F6\u710B\u7102\u710E\u727E\u727B\u727C\u727F\u731D\u7317\u7307\u7311\u7318\u730A\u7308\u72FF\u730F\u731E\u7388\u73F6\u73F8\u73F5\u7404\u7401\u73FD\u7407\u7400\u73FA\u73FC\u73FF\u740C\u740B\u73F4\u7408\u7564\u7563\u75CE\u75D2\u75CF"], + ["d6a1", "\u75CB\u75CC\u75D1\u75D0\u768F\u7689\u76D3\u7739\u772F\u772D\u7731\u7732\u7734\u7733\u773D\u7725\u773B\u7735\u7848\u7852\u7849\u784D\u784A\u784C\u7826\u7845\u7850\u7964\u7967\u7969\u796A\u7963\u796B\u7961\u79BB\u79FA\u79F8\u79F6\u79F7\u7A8F\u7A94\u7A90\u7B35\u7B47\u7B34\u7B25\u7B30\u7B22\u7B24\u7B33\u7B18\u7B2A\u7B1D\u7B31\u7B2B\u7B2D\u7B2F\u7B32\u7B38\u7B1A\u7B23\u7C94\u7C98\u7C96\u7CA3\u7D35\u7D3D\u7D38\u7D36\u7D3A\u7D45\u7D2C\u7D29\u7D41\u7D47\u7D3E\u7D3F\u7D4A\u7D3B\u7D28\u7F63\u7F95\u7F9C\u7F9D\u7F9B\u7FCA\u7FCB\u7FCD\u7FD0\u7FD1\u7FC7\u7FCF\u7FC9\u801F"], + ["d740", "\u801E\u801B\u8047\u8043\u8048\u8118\u8125\u8119\u811B\u812D\u811F\u812C\u811E\u8121\u8115\u8127\u811D\u8122\u8211\u8238\u8233\u823A\u8234\u8232\u8274\u8390\u83A3\u83A8\u838D\u837A\u8373\u83A4\u8374\u838F\u8381\u8395\u8399\u8375\u8394\u83A9\u837D\u8383\u838C\u839D\u839B\u83AA\u838B\u837E\u83A5\u83AF\u8388\u8397\u83B0\u837F\u83A6\u8387\u83AE\u8376\u839A\u8659\u8656\u86BF\u86B7"], + ["d7a1", "\u86C2\u86C1\u86C5\u86BA\u86B0\u86C8\u86B9\u86B3\u86B8\u86CC\u86B4\u86BB\u86BC\u86C3\u86BD\u86BE\u8852\u8889\u8895\u88A8\u88A2\u88AA\u889A\u8891\u88A1\u889F\u8898\u88A7\u8899\u889B\u8897\u88A4\u88AC\u888C\u8893\u888E\u8982\u89D6\u89D9\u89D5\u8A30\u8A27\u8A2C\u8A1E\u8C39\u8C3B\u8C5C\u8C5D\u8C7D\u8CA5\u8D7D\u8D7B\u8D79\u8DBC\u8DC2\u8DB9\u8DBF\u8DC1\u8ED8\u8EDE\u8EDD\u8EDC\u8ED7\u8EE0\u8EE1\u9024\u900B\u9011\u901C\u900C\u9021\u90EF\u90EA\u90F0\u90F4\u90F2\u90F3\u90D4\u90EB\u90EC\u90E9\u9156\u9158\u915A\u9153\u9155\u91EC\u91F4\u91F1\u91F3\u91F8\u91E4\u91F9\u91EA"], + ["d840", "\u91EB\u91F7\u91E8\u91EE\u957A\u9586\u9588\u967C\u966D\u966B\u9671\u966F\u96BF\u976A\u9804\u98E5\u9997\u509B\u5095\u5094\u509E\u508B\u50A3\u5083\u508C\u508E\u509D\u5068\u509C\u5092\u5082\u5087\u515F\u51D4\u5312\u5311\u53A4\u53A7\u5591\u55A8\u55A5\u55AD\u5577\u5645\u55A2\u5593\u5588\u558F\u55B5\u5581\u55A3\u5592\u55A4\u557D\u558C\u55A6\u557F\u5595\u55A1\u558E\u570C\u5829\u5837"], + ["d8a1", "\u5819\u581E\u5827\u5823\u5828\u57F5\u5848\u5825\u581C\u581B\u5833\u583F\u5836\u582E\u5839\u5838\u582D\u582C\u583B\u5961\u5AAF\u5A94\u5A9F\u5A7A\u5AA2\u5A9E\u5A78\u5AA6\u5A7C\u5AA5\u5AAC\u5A95\u5AAE\u5A37\u5A84\u5A8A\u5A97\u5A83\u5A8B\u5AA9\u5A7B\u5A7D\u5A8C\u5A9C\u5A8F\u5A93\u5A9D\u5BEA\u5BCD\u5BCB\u5BD4\u5BD1\u5BCA\u5BCE\u5C0C\u5C30\u5D37\u5D43\u5D6B\u5D41\u5D4B\u5D3F\u5D35\u5D51\u5D4E\u5D55\u5D33\u5D3A\u5D52\u5D3D\u5D31\u5D59\u5D42\u5D39\u5D49\u5D38\u5D3C\u5D32\u5D36\u5D40\u5D45\u5E44\u5E41\u5F58\u5FA6\u5FA5\u5FAB\u60C9\u60B9\u60CC\u60E2\u60CE\u60C4\u6114"], + ["d940", "\u60F2\u610A\u6116\u6105\u60F5\u6113\u60F8\u60FC\u60FE\u60C1\u6103\u6118\u611D\u6110\u60FF\u6104\u610B\u624A\u6394\u63B1\u63B0\u63CE\u63E5\u63E8\u63EF\u63C3\u649D\u63F3\u63CA\u63E0\u63F6\u63D5\u63F2\u63F5\u6461\u63DF\u63BE\u63DD\u63DC\u63C4\u63D8\u63D3\u63C2\u63C7\u63CC\u63CB\u63C8\u63F0\u63D7\u63D9\u6532\u6567\u656A\u6564\u655C\u6568\u6565\u658C\u659D\u659E\u65AE\u65D0\u65D2"], + ["d9a1", "\u667C\u666C\u667B\u6680\u6671\u6679\u666A\u6672\u6701\u690C\u68D3\u6904\u68DC\u692A\u68EC\u68EA\u68F1\u690F\u68D6\u68F7\u68EB\u68E4\u68F6\u6913\u6910\u68F3\u68E1\u6907\u68CC\u6908\u6970\u68B4\u6911\u68EF\u68C6\u6914\u68F8\u68D0\u68FD\u68FC\u68E8\u690B\u690A\u6917\u68CE\u68C8\u68DD\u68DE\u68E6\u68F4\u68D1\u6906\u68D4\u68E9\u6915\u6925\u68C7\u6B39\u6B3B\u6B3F\u6B3C\u6B94\u6B97\u6B99\u6B95\u6BBD\u6BF0\u6BF2\u6BF3\u6C30\u6DFC\u6E46\u6E47\u6E1F\u6E49\u6E88\u6E3C\u6E3D\u6E45\u6E62\u6E2B\u6E3F\u6E41\u6E5D\u6E73\u6E1C\u6E33\u6E4B\u6E40\u6E51\u6E3B\u6E03\u6E2E\u6E5E"], + ["da40", "\u6E68\u6E5C\u6E61\u6E31\u6E28\u6E60\u6E71\u6E6B\u6E39\u6E22\u6E30\u6E53\u6E65\u6E27\u6E78\u6E64\u6E77\u6E55\u6E79\u6E52\u6E66\u6E35\u6E36\u6E5A\u7120\u711E\u712F\u70FB\u712E\u7131\u7123\u7125\u7122\u7132\u711F\u7128\u713A\u711B\u724B\u725A\u7288\u7289\u7286\u7285\u728B\u7312\u730B\u7330\u7322\u7331\u7333\u7327\u7332\u732D\u7326\u7323\u7335\u730C\u742E\u742C\u7430\u742B\u7416"], + ["daa1", "\u741A\u7421\u742D\u7431\u7424\u7423\u741D\u7429\u7420\u7432\u74FB\u752F\u756F\u756C\u75E7\u75DA\u75E1\u75E6\u75DD\u75DF\u75E4\u75D7\u7695\u7692\u76DA\u7746\u7747\u7744\u774D\u7745\u774A\u774E\u774B\u774C\u77DE\u77EC\u7860\u7864\u7865\u785C\u786D\u7871\u786A\u786E\u7870\u7869\u7868\u785E\u7862\u7974\u7973\u7972\u7970\u7A02\u7A0A\u7A03\u7A0C\u7A04\u7A99\u7AE6\u7AE4\u7B4A\u7B3B\u7B44\u7B48\u7B4C\u7B4E\u7B40\u7B58\u7B45\u7CA2\u7C9E\u7CA8\u7CA1\u7D58\u7D6F\u7D63\u7D53\u7D56\u7D67\u7D6A\u7D4F\u7D6D\u7D5C\u7D6B\u7D52\u7D54\u7D69\u7D51\u7D5F\u7D4E\u7F3E\u7F3F\u7F65"], + ["db40", "\u7F66\u7FA2\u7FA0\u7FA1\u7FD7\u8051\u804F\u8050\u80FE\u80D4\u8143\u814A\u8152\u814F\u8147\u813D\u814D\u813A\u81E6\u81EE\u81F7\u81F8\u81F9\u8204\u823C\u823D\u823F\u8275\u833B\u83CF\u83F9\u8423\u83C0\u83E8\u8412\u83E7\u83E4\u83FC\u83F6\u8410\u83C6\u83C8\u83EB\u83E3\u83BF\u8401\u83DD\u83E5\u83D8\u83FF\u83E1\u83CB\u83CE\u83D6\u83F5\u83C9\u8409\u840F\u83DE\u8411\u8406\u83C2\u83F3"], + ["dba1", "\u83D5\u83FA\u83C7\u83D1\u83EA\u8413\u83C3\u83EC\u83EE\u83C4\u83FB\u83D7\u83E2\u841B\u83DB\u83FE\u86D8\u86E2\u86E6\u86D3\u86E3\u86DA\u86EA\u86DD\u86EB\u86DC\u86EC\u86E9\u86D7\u86E8\u86D1\u8848\u8856\u8855\u88BA\u88D7\u88B9\u88B8\u88C0\u88BE\u88B6\u88BC\u88B7\u88BD\u88B2\u8901\u88C9\u8995\u8998\u8997\u89DD\u89DA\u89DB\u8A4E\u8A4D\u8A39\u8A59\u8A40\u8A57\u8A58\u8A44\u8A45\u8A52\u8A48\u8A51\u8A4A\u8A4C\u8A4F\u8C5F\u8C81\u8C80\u8CBA\u8CBE\u8CB0\u8CB9\u8CB5\u8D84\u8D80\u8D89\u8DD8\u8DD3\u8DCD\u8DC7\u8DD6\u8DDC\u8DCF\u8DD5\u8DD9\u8DC8\u8DD7\u8DC5\u8EEF\u8EF7\u8EFA"], + ["dc40", "\u8EF9\u8EE6\u8EEE\u8EE5\u8EF5\u8EE7\u8EE8\u8EF6\u8EEB\u8EF1\u8EEC\u8EF4\u8EE9\u902D\u9034\u902F\u9106\u912C\u9104\u90FF\u90FC\u9108\u90F9\u90FB\u9101\u9100\u9107\u9105\u9103\u9161\u9164\u915F\u9162\u9160\u9201\u920A\u9225\u9203\u921A\u9226\u920F\u920C\u9200\u9212\u91FF\u91FD\u9206\u9204\u9227\u9202\u921C\u9224\u9219\u9217\u9205\u9216\u957B\u958D\u958C\u9590\u9687\u967E\u9688"], + ["dca1", "\u9689\u9683\u9680\u96C2\u96C8\u96C3\u96F1\u96F0\u976C\u9770\u976E\u9807\u98A9\u98EB\u9CE6\u9EF9\u4E83\u4E84\u4EB6\u50BD\u50BF\u50C6\u50AE\u50C4\u50CA\u50B4\u50C8\u50C2\u50B0\u50C1\u50BA\u50B1\u50CB\u50C9\u50B6\u50B8\u51D7\u527A\u5278\u527B\u527C\u55C3\u55DB\u55CC\u55D0\u55CB\u55CA\u55DD\u55C0\u55D4\u55C4\u55E9\u55BF\u55D2\u558D\u55CF\u55D5\u55E2\u55D6\u55C8\u55F2\u55CD\u55D9\u55C2\u5714\u5853\u5868\u5864\u584F\u584D\u5849\u586F\u5855\u584E\u585D\u5859\u5865\u585B\u583D\u5863\u5871\u58FC\u5AC7\u5AC4\u5ACB\u5ABA\u5AB8\u5AB1\u5AB5\u5AB0\u5ABF\u5AC8\u5ABB\u5AC6"], + ["dd40", "\u5AB7\u5AC0\u5ACA\u5AB4\u5AB6\u5ACD\u5AB9\u5A90\u5BD6\u5BD8\u5BD9\u5C1F\u5C33\u5D71\u5D63\u5D4A\u5D65\u5D72\u5D6C\u5D5E\u5D68\u5D67\u5D62\u5DF0\u5E4F\u5E4E\u5E4A\u5E4D\u5E4B\u5EC5\u5ECC\u5EC6\u5ECB\u5EC7\u5F40\u5FAF\u5FAD\u60F7\u6149\u614A\u612B\u6145\u6136\u6132\u612E\u6146\u612F\u614F\u6129\u6140\u6220\u9168\u6223\u6225\u6224\u63C5\u63F1\u63EB\u6410\u6412\u6409\u6420\u6424"], + ["dda1", "\u6433\u6443\u641F\u6415\u6418\u6439\u6437\u6422\u6423\u640C\u6426\u6430\u6428\u6441\u6435\u642F\u640A\u641A\u6440\u6425\u6427\u640B\u63E7\u641B\u642E\u6421\u640E\u656F\u6592\u65D3\u6686\u668C\u6695\u6690\u668B\u668A\u6699\u6694\u6678\u6720\u6966\u695F\u6938\u694E\u6962\u6971\u693F\u6945\u696A\u6939\u6942\u6957\u6959\u697A\u6948\u6949\u6935\u696C\u6933\u693D\u6965\u68F0\u6978\u6934\u6969\u6940\u696F\u6944\u6976\u6958\u6941\u6974\u694C\u693B\u694B\u6937\u695C\u694F\u6951\u6932\u6952\u692F\u697B\u693C\u6B46\u6B45\u6B43\u6B42\u6B48\u6B41\u6B9B\uFA0D\u6BFB\u6BFC"], + ["de40", "\u6BF9\u6BF7\u6BF8\u6E9B\u6ED6\u6EC8\u6E8F\u6EC0\u6E9F\u6E93\u6E94\u6EA0\u6EB1\u6EB9\u6EC6\u6ED2\u6EBD\u6EC1\u6E9E\u6EC9\u6EB7\u6EB0\u6ECD\u6EA6\u6ECF\u6EB2\u6EBE\u6EC3\u6EDC\u6ED8\u6E99\u6E92\u6E8E\u6E8D\u6EA4\u6EA1\u6EBF\u6EB3\u6ED0\u6ECA\u6E97\u6EAE\u6EA3\u7147\u7154\u7152\u7163\u7160\u7141\u715D\u7162\u7172\u7178\u716A\u7161\u7142\u7158\u7143\u714B\u7170\u715F\u7150\u7153"], + ["dea1", "\u7144\u714D\u715A\u724F\u728D\u728C\u7291\u7290\u728E\u733C\u7342\u733B\u733A\u7340\u734A\u7349\u7444\u744A\u744B\u7452\u7451\u7457\u7440\u744F\u7450\u744E\u7442\u7446\u744D\u7454\u74E1\u74FF\u74FE\u74FD\u751D\u7579\u7577\u6983\u75EF\u760F\u7603\u75F7\u75FE\u75FC\u75F9\u75F8\u7610\u75FB\u75F6\u75ED\u75F5\u75FD\u7699\u76B5\u76DD\u7755\u775F\u7760\u7752\u7756\u775A\u7769\u7767\u7754\u7759\u776D\u77E0\u7887\u789A\u7894\u788F\u7884\u7895\u7885\u7886\u78A1\u7883\u7879\u7899\u7880\u7896\u787B\u797C\u7982\u797D\u7979\u7A11\u7A18\u7A19\u7A12\u7A17\u7A15\u7A22\u7A13"], + ["df40", "\u7A1B\u7A10\u7AA3\u7AA2\u7A9E\u7AEB\u7B66\u7B64\u7B6D\u7B74\u7B69\u7B72\u7B65\u7B73\u7B71\u7B70\u7B61\u7B78\u7B76\u7B63\u7CB2\u7CB4\u7CAF\u7D88\u7D86\u7D80\u7D8D\u7D7F\u7D85\u7D7A\u7D8E\u7D7B\u7D83\u7D7C\u7D8C\u7D94\u7D84\u7D7D\u7D92\u7F6D\u7F6B\u7F67\u7F68\u7F6C\u7FA6\u7FA5\u7FA7\u7FDB\u7FDC\u8021\u8164\u8160\u8177\u815C\u8169\u815B\u8162\u8172\u6721\u815E\u8176\u8167\u816F"], + ["dfa1", "\u8144\u8161\u821D\u8249\u8244\u8240\u8242\u8245\u84F1\u843F\u8456\u8476\u8479\u848F\u848D\u8465\u8451\u8440\u8486\u8467\u8430\u844D\u847D\u845A\u8459\u8474\u8473\u845D\u8507\u845E\u8437\u843A\u8434\u847A\u8443\u8478\u8432\u8445\u8429\u83D9\u844B\u842F\u8442\u842D\u845F\u8470\u8439\u844E\u844C\u8452\u846F\u84C5\u848E\u843B\u8447\u8436\u8433\u8468\u847E\u8444\u842B\u8460\u8454\u846E\u8450\u870B\u8704\u86F7\u870C\u86FA\u86D6\u86F5\u874D\u86F8\u870E\u8709\u8701\u86F6\u870D\u8705\u88D6\u88CB\u88CD\u88CE\u88DE\u88DB\u88DA\u88CC\u88D0\u8985\u899B\u89DF\u89E5\u89E4"], + ["e040", "\u89E1\u89E0\u89E2\u89DC\u89E6\u8A76\u8A86\u8A7F\u8A61\u8A3F\u8A77\u8A82\u8A84\u8A75\u8A83\u8A81\u8A74\u8A7A\u8C3C\u8C4B\u8C4A\u8C65\u8C64\u8C66\u8C86\u8C84\u8C85\u8CCC\u8D68\u8D69\u8D91\u8D8C\u8D8E\u8D8F\u8D8D\u8D93\u8D94\u8D90\u8D92\u8DF0\u8DE0\u8DEC\u8DF1\u8DEE\u8DD0\u8DE9\u8DE3\u8DE2\u8DE7\u8DF2\u8DEB\u8DF4\u8F06\u8EFF\u8F01\u8F00\u8F05\u8F07\u8F08\u8F02\u8F0B\u9052\u903F"], + ["e0a1", "\u9044\u9049\u903D\u9110\u910D\u910F\u9111\u9116\u9114\u910B\u910E\u916E\u916F\u9248\u9252\u9230\u923A\u9266\u9233\u9265\u925E\u9283\u922E\u924A\u9246\u926D\u926C\u924F\u9260\u9267\u926F\u9236\u9261\u9270\u9231\u9254\u9263\u9250\u9272\u924E\u9253\u924C\u9256\u9232\u959F\u959C\u959E\u959B\u9692\u9693\u9691\u9697\u96CE\u96FA\u96FD\u96F8\u96F5\u9773\u9777\u9778\u9772\u980F\u980D\u980E\u98AC\u98F6\u98F9\u99AF\u99B2\u99B0\u99B5\u9AAD\u9AAB\u9B5B\u9CEA\u9CED\u9CE7\u9E80\u9EFD\u50E6\u50D4\u50D7\u50E8\u50F3\u50DB\u50EA\u50DD\u50E4\u50D3\u50EC\u50F0\u50EF\u50E3\u50E0"], + ["e140", "\u51D8\u5280\u5281\u52E9\u52EB\u5330\u53AC\u5627\u5615\u560C\u5612\u55FC\u560F\u561C\u5601\u5613\u5602\u55FA\u561D\u5604\u55FF\u55F9\u5889\u587C\u5890\u5898\u5886\u5881\u587F\u5874\u588B\u587A\u5887\u5891\u588E\u5876\u5882\u5888\u587B\u5894\u588F\u58FE\u596B\u5ADC\u5AEE\u5AE5\u5AD5\u5AEA\u5ADA\u5AED\u5AEB\u5AF3\u5AE2\u5AE0\u5ADB\u5AEC\u5ADE\u5ADD\u5AD9\u5AE8\u5ADF\u5B77\u5BE0"], + ["e1a1", "\u5BE3\u5C63\u5D82\u5D80\u5D7D\u5D86\u5D7A\u5D81\u5D77\u5D8A\u5D89\u5D88\u5D7E\u5D7C\u5D8D\u5D79\u5D7F\u5E58\u5E59\u5E53\u5ED8\u5ED1\u5ED7\u5ECE\u5EDC\u5ED5\u5ED9\u5ED2\u5ED4\u5F44\u5F43\u5F6F\u5FB6\u612C\u6128\u6141\u615E\u6171\u6173\u6152\u6153\u6172\u616C\u6180\u6174\u6154\u617A\u615B\u6165\u613B\u616A\u6161\u6156\u6229\u6227\u622B\u642B\u644D\u645B\u645D\u6474\u6476\u6472\u6473\u647D\u6475\u6466\u64A6\u644E\u6482\u645E\u645C\u644B\u6453\u6460\u6450\u647F\u643F\u646C\u646B\u6459\u6465\u6477\u6573\u65A0\u66A1\u66A0\u669F\u6705\u6704\u6722\u69B1\u69B6\u69C9"], + ["e240", "\u69A0\u69CE\u6996\u69B0\u69AC\u69BC\u6991\u6999\u698E\u69A7\u698D\u69A9\u69BE\u69AF\u69BF\u69C4\u69BD\u69A4\u69D4\u69B9\u69CA\u699A\u69CF\u69B3\u6993\u69AA\u69A1\u699E\u69D9\u6997\u6990\u69C2\u69B5\u69A5\u69C6\u6B4A\u6B4D\u6B4B\u6B9E\u6B9F\u6BA0\u6BC3\u6BC4\u6BFE\u6ECE\u6EF5\u6EF1\u6F03\u6F25\u6EF8\u6F37\u6EFB\u6F2E\u6F09\u6F4E\u6F19\u6F1A\u6F27\u6F18\u6F3B\u6F12\u6EED\u6F0A"], + ["e2a1", "\u6F36\u6F73\u6EF9\u6EEE\u6F2D\u6F40\u6F30\u6F3C\u6F35\u6EEB\u6F07\u6F0E\u6F43\u6F05\u6EFD\u6EF6\u6F39\u6F1C\u6EFC\u6F3A\u6F1F\u6F0D\u6F1E\u6F08\u6F21\u7187\u7190\u7189\u7180\u7185\u7182\u718F\u717B\u7186\u7181\u7197\u7244\u7253\u7297\u7295\u7293\u7343\u734D\u7351\u734C\u7462\u7473\u7471\u7475\u7472\u7467\u746E\u7500\u7502\u7503\u757D\u7590\u7616\u7608\u760C\u7615\u7611\u760A\u7614\u76B8\u7781\u777C\u7785\u7782\u776E\u7780\u776F\u777E\u7783\u78B2\u78AA\u78B4\u78AD\u78A8\u787E\u78AB\u789E\u78A5\u78A0\u78AC\u78A2\u78A4\u7998\u798A\u798B\u7996\u7995\u7994\u7993"], + ["e340", "\u7997\u7988\u7992\u7990\u7A2B\u7A4A\u7A30\u7A2F\u7A28\u7A26\u7AA8\u7AAB\u7AAC\u7AEE\u7B88\u7B9C\u7B8A\u7B91\u7B90\u7B96\u7B8D\u7B8C\u7B9B\u7B8E\u7B85\u7B98\u5284\u7B99\u7BA4\u7B82\u7CBB\u7CBF\u7CBC\u7CBA\u7DA7\u7DB7\u7DC2\u7DA3\u7DAA\u7DC1\u7DC0\u7DC5\u7D9D\u7DCE\u7DC4\u7DC6\u7DCB\u7DCC\u7DAF\u7DB9\u7D96\u7DBC\u7D9F\u7DA6\u7DAE\u7DA9\u7DA1\u7DC9\u7F73\u7FE2\u7FE3\u7FE5\u7FDE"], + ["e3a1", "\u8024\u805D\u805C\u8189\u8186\u8183\u8187\u818D\u818C\u818B\u8215\u8497\u84A4\u84A1\u849F\u84BA\u84CE\u84C2\u84AC\u84AE\u84AB\u84B9\u84B4\u84C1\u84CD\u84AA\u849A\u84B1\u84D0\u849D\u84A7\u84BB\u84A2\u8494\u84C7\u84CC\u849B\u84A9\u84AF\u84A8\u84D6\u8498\u84B6\u84CF\u84A0\u84D7\u84D4\u84D2\u84DB\u84B0\u8491\u8661\u8733\u8723\u8728\u876B\u8740\u872E\u871E\u8721\u8719\u871B\u8743\u872C\u8741\u873E\u8746\u8720\u8732\u872A\u872D\u873C\u8712\u873A\u8731\u8735\u8742\u8726\u8727\u8738\u8724\u871A\u8730\u8711\u88F7\u88E7\u88F1\u88F2\u88FA\u88FE\u88EE\u88FC\u88F6\u88FB"], + ["e440", "\u88F0\u88EC\u88EB\u899D\u89A1\u899F\u899E\u89E9\u89EB\u89E8\u8AAB\u8A99\u8A8B\u8A92\u8A8F\u8A96\u8C3D\u8C68\u8C69\u8CD5\u8CCF\u8CD7\u8D96\u8E09\u8E02\u8DFF\u8E0D\u8DFD\u8E0A\u8E03\u8E07\u8E06\u8E05\u8DFE\u8E00\u8E04\u8F10\u8F11\u8F0E\u8F0D\u9123\u911C\u9120\u9122\u911F\u911D\u911A\u9124\u9121\u911B\u917A\u9172\u9179\u9173\u92A5\u92A4\u9276\u929B\u927A\u92A0\u9294\u92AA\u928D"], + ["e4a1", "\u92A6\u929A\u92AB\u9279\u9297\u927F\u92A3\u92EE\u928E\u9282\u9295\u92A2\u927D\u9288\u92A1\u928A\u9286\u928C\u9299\u92A7\u927E\u9287\u92A9\u929D\u928B\u922D\u969E\u96A1\u96FF\u9758\u977D\u977A\u977E\u9783\u9780\u9782\u977B\u9784\u9781\u977F\u97CE\u97CD\u9816\u98AD\u98AE\u9902\u9900\u9907\u999D\u999C\u99C3\u99B9\u99BB\u99BA\u99C2\u99BD\u99C7\u9AB1\u9AE3\u9AE7\u9B3E\u9B3F\u9B60\u9B61\u9B5F\u9CF1\u9CF2\u9CF5\u9EA7\u50FF\u5103\u5130\u50F8\u5106\u5107\u50F6\u50FE\u510B\u510C\u50FD\u510A\u528B\u528C\u52F1\u52EF\u5648\u5642\u564C\u5635\u5641\u564A\u5649\u5646\u5658"], + ["e540", "\u565A\u5640\u5633\u563D\u562C\u563E\u5638\u562A\u563A\u571A\u58AB\u589D\u58B1\u58A0\u58A3\u58AF\u58AC\u58A5\u58A1\u58FF\u5AFF\u5AF4\u5AFD\u5AF7\u5AF6\u5B03\u5AF8\u5B02\u5AF9\u5B01\u5B07\u5B05\u5B0F\u5C67\u5D99\u5D97\u5D9F\u5D92\u5DA2\u5D93\u5D95\u5DA0\u5D9C\u5DA1\u5D9A\u5D9E\u5E69\u5E5D\u5E60\u5E5C\u7DF3\u5EDB\u5EDE\u5EE1\u5F49\u5FB2\u618B\u6183\u6179\u61B1\u61B0\u61A2\u6189"], + ["e5a1", "\u619B\u6193\u61AF\u61AD\u619F\u6192\u61AA\u61A1\u618D\u6166\u61B3\u622D\u646E\u6470\u6496\u64A0\u6485\u6497\u649C\u648F\u648B\u648A\u648C\u64A3\u649F\u6468\u64B1\u6498\u6576\u657A\u6579\u657B\u65B2\u65B3\u66B5\u66B0\u66A9\u66B2\u66B7\u66AA\u66AF\u6A00\u6A06\u6A17\u69E5\u69F8\u6A15\u69F1\u69E4\u6A20\u69FF\u69EC\u69E2\u6A1B\u6A1D\u69FE\u6A27\u69F2\u69EE\u6A14\u69F7\u69E7\u6A40\u6A08\u69E6\u69FB\u6A0D\u69FC\u69EB\u6A09\u6A04\u6A18\u6A25\u6A0F\u69F6\u6A26\u6A07\u69F4\u6A16\u6B51\u6BA5\u6BA3\u6BA2\u6BA6\u6C01\u6C00\u6BFF\u6C02\u6F41\u6F26\u6F7E\u6F87\u6FC6\u6F92"], + ["e640", "\u6F8D\u6F89\u6F8C\u6F62\u6F4F\u6F85\u6F5A\u6F96\u6F76\u6F6C\u6F82\u6F55\u6F72\u6F52\u6F50\u6F57\u6F94\u6F93\u6F5D\u6F00\u6F61\u6F6B\u6F7D\u6F67\u6F90\u6F53\u6F8B\u6F69\u6F7F\u6F95\u6F63\u6F77\u6F6A\u6F7B\u71B2\u71AF\u719B\u71B0\u71A0\u719A\u71A9\u71B5\u719D\u71A5\u719E\u71A4\u71A1\u71AA\u719C\u71A7\u71B3\u7298\u729A\u7358\u7352\u735E\u735F\u7360\u735D\u735B\u7361\u735A\u7359"], + ["e6a1", "\u7362\u7487\u7489\u748A\u7486\u7481\u747D\u7485\u7488\u747C\u7479\u7508\u7507\u757E\u7625\u761E\u7619\u761D\u761C\u7623\u761A\u7628\u761B\u769C\u769D\u769E\u769B\u778D\u778F\u7789\u7788\u78CD\u78BB\u78CF\u78CC\u78D1\u78CE\u78D4\u78C8\u78C3\u78C4\u78C9\u799A\u79A1\u79A0\u799C\u79A2\u799B\u6B76\u7A39\u7AB2\u7AB4\u7AB3\u7BB7\u7BCB\u7BBE\u7BAC\u7BCE\u7BAF\u7BB9\u7BCA\u7BB5\u7CC5\u7CC8\u7CCC\u7CCB\u7DF7\u7DDB\u7DEA\u7DE7\u7DD7\u7DE1\u7E03\u7DFA\u7DE6\u7DF6\u7DF1\u7DF0\u7DEE\u7DDF\u7F76\u7FAC\u7FB0\u7FAD\u7FED\u7FEB\u7FEA\u7FEC\u7FE6\u7FE8\u8064\u8067\u81A3\u819F"], + ["e740", "\u819E\u8195\u81A2\u8199\u8197\u8216\u824F\u8253\u8252\u8250\u824E\u8251\u8524\u853B\u850F\u8500\u8529\u850E\u8509\u850D\u851F\u850A\u8527\u851C\u84FB\u852B\u84FA\u8508\u850C\u84F4\u852A\u84F2\u8515\u84F7\u84EB\u84F3\u84FC\u8512\u84EA\u84E9\u8516\u84FE\u8528\u851D\u852E\u8502\u84FD\u851E\u84F6\u8531\u8526\u84E7\u84E8\u84F0\u84EF\u84F9\u8518\u8520\u8530\u850B\u8519\u852F\u8662"], + ["e7a1", "\u8756\u8763\u8764\u8777\u87E1\u8773\u8758\u8754\u875B\u8752\u8761\u875A\u8751\u875E\u876D\u876A\u8750\u874E\u875F\u875D\u876F\u876C\u877A\u876E\u875C\u8765\u874F\u877B\u8775\u8762\u8767\u8769\u885A\u8905\u890C\u8914\u890B\u8917\u8918\u8919\u8906\u8916\u8911\u890E\u8909\u89A2\u89A4\u89A3\u89ED\u89F0\u89EC\u8ACF\u8AC6\u8AB8\u8AD3\u8AD1\u8AD4\u8AD5\u8ABB\u8AD7\u8ABE\u8AC0\u8AC5\u8AD8\u8AC3\u8ABA\u8ABD\u8AD9\u8C3E\u8C4D\u8C8F\u8CE5\u8CDF\u8CD9\u8CE8\u8CDA\u8CDD\u8CE7\u8DA0\u8D9C\u8DA1\u8D9B\u8E20\u8E23\u8E25\u8E24\u8E2E\u8E15\u8E1B\u8E16\u8E11\u8E19\u8E26\u8E27"], + ["e840", "\u8E14\u8E12\u8E18\u8E13\u8E1C\u8E17\u8E1A\u8F2C\u8F24\u8F18\u8F1A\u8F20\u8F23\u8F16\u8F17\u9073\u9070\u906F\u9067\u906B\u912F\u912B\u9129\u912A\u9132\u9126\u912E\u9185\u9186\u918A\u9181\u9182\u9184\u9180\u92D0\u92C3\u92C4\u92C0\u92D9\u92B6\u92CF\u92F1\u92DF\u92D8\u92E9\u92D7\u92DD\u92CC\u92EF\u92C2\u92E8\u92CA\u92C8\u92CE\u92E6\u92CD\u92D5\u92C9\u92E0\u92DE\u92E7\u92D1\u92D3"], + ["e8a1", "\u92B5\u92E1\u92C6\u92B4\u957C\u95AC\u95AB\u95AE\u95B0\u96A4\u96A2\u96D3\u9705\u9708\u9702\u975A\u978A\u978E\u9788\u97D0\u97CF\u981E\u981D\u9826\u9829\u9828\u9820\u981B\u9827\u98B2\u9908\u98FA\u9911\u9914\u9916\u9917\u9915\u99DC\u99CD\u99CF\u99D3\u99D4\u99CE\u99C9\u99D6\u99D8\u99CB\u99D7\u99CC\u9AB3\u9AEC\u9AEB\u9AF3\u9AF2\u9AF1\u9B46\u9B43\u9B67\u9B74\u9B71\u9B66\u9B76\u9B75\u9B70\u9B68\u9B64\u9B6C\u9CFC\u9CFA\u9CFD\u9CFF\u9CF7\u9D07\u9D00\u9CF9\u9CFB\u9D08\u9D05\u9D04\u9E83\u9ED3\u9F0F\u9F10\u511C\u5113\u5117\u511A\u5111\u51DE\u5334\u53E1\u5670\u5660\u566E"], + ["e940", "\u5673\u5666\u5663\u566D\u5672\u565E\u5677\u571C\u571B\u58C8\u58BD\u58C9\u58BF\u58BA\u58C2\u58BC\u58C6\u5B17\u5B19\u5B1B\u5B21\u5B14\u5B13\u5B10\u5B16\u5B28\u5B1A\u5B20\u5B1E\u5BEF\u5DAC\u5DB1\u5DA9\u5DA7\u5DB5\u5DB0\u5DAE\u5DAA\u5DA8\u5DB2\u5DAD\u5DAF\u5DB4\u5E67\u5E68\u5E66\u5E6F\u5EE9\u5EE7\u5EE6\u5EE8\u5EE5\u5F4B\u5FBC\u619D\u61A8\u6196\u61C5\u61B4\u61C6\u61C1\u61CC\u61BA"], + ["e9a1", "\u61BF\u61B8\u618C\u64D7\u64D6\u64D0\u64CF\u64C9\u64BD\u6489\u64C3\u64DB\u64F3\u64D9\u6533\u657F\u657C\u65A2\u66C8\u66BE\u66C0\u66CA\u66CB\u66CF\u66BD\u66BB\u66BA\u66CC\u6723\u6A34\u6A66\u6A49\u6A67\u6A32\u6A68\u6A3E\u6A5D\u6A6D\u6A76\u6A5B\u6A51\u6A28\u6A5A\u6A3B\u6A3F\u6A41\u6A6A\u6A64\u6A50\u6A4F\u6A54\u6A6F\u6A69\u6A60\u6A3C\u6A5E\u6A56\u6A55\u6A4D\u6A4E\u6A46\u6B55\u6B54\u6B56\u6BA7\u6BAA\u6BAB\u6BC8\u6BC7\u6C04\u6C03\u6C06\u6FAD\u6FCB\u6FA3\u6FC7\u6FBC\u6FCE\u6FC8\u6F5E\u6FC4\u6FBD\u6F9E\u6FCA\u6FA8\u7004\u6FA5\u6FAE\u6FBA\u6FAC\u6FAA\u6FCF\u6FBF\u6FB8"], + ["ea40", "\u6FA2\u6FC9\u6FAB\u6FCD\u6FAF\u6FB2\u6FB0\u71C5\u71C2\u71BF\u71B8\u71D6\u71C0\u71C1\u71CB\u71D4\u71CA\u71C7\u71CF\u71BD\u71D8\u71BC\u71C6\u71DA\u71DB\u729D\u729E\u7369\u7366\u7367\u736C\u7365\u736B\u736A\u747F\u749A\u74A0\u7494\u7492\u7495\u74A1\u750B\u7580\u762F\u762D\u7631\u763D\u7633\u763C\u7635\u7632\u7630\u76BB\u76E6\u779A\u779D\u77A1\u779C\u779B\u77A2\u77A3\u7795\u7799"], + ["eaa1", "\u7797\u78DD\u78E9\u78E5\u78EA\u78DE\u78E3\u78DB\u78E1\u78E2\u78ED\u78DF\u78E0\u79A4\u7A44\u7A48\u7A47\u7AB6\u7AB8\u7AB5\u7AB1\u7AB7\u7BDE\u7BE3\u7BE7\u7BDD\u7BD5\u7BE5\u7BDA\u7BE8\u7BF9\u7BD4\u7BEA\u7BE2\u7BDC\u7BEB\u7BD8\u7BDF\u7CD2\u7CD4\u7CD7\u7CD0\u7CD1\u7E12\u7E21\u7E17\u7E0C\u7E1F\u7E20\u7E13\u7E0E\u7E1C\u7E15\u7E1A\u7E22\u7E0B\u7E0F\u7E16\u7E0D\u7E14\u7E25\u7E24\u7F43\u7F7B\u7F7C\u7F7A\u7FB1\u7FEF\u802A\u8029\u806C\u81B1\u81A6\u81AE\u81B9\u81B5\u81AB\u81B0\u81AC\u81B4\u81B2\u81B7\u81A7\u81F2\u8255\u8256\u8257\u8556\u8545\u856B\u854D\u8553\u8561\u8558"], + ["eb40", "\u8540\u8546\u8564\u8541\u8562\u8544\u8551\u8547\u8563\u853E\u855B\u8571\u854E\u856E\u8575\u8555\u8567\u8560\u858C\u8566\u855D\u8554\u8565\u856C\u8663\u8665\u8664\u879B\u878F\u8797\u8793\u8792\u8788\u8781\u8796\u8798\u8779\u8787\u87A3\u8785\u8790\u8791\u879D\u8784\u8794\u879C\u879A\u8789\u891E\u8926\u8930\u892D\u892E\u8927\u8931\u8922\u8929\u8923\u892F\u892C\u891F\u89F1\u8AE0"], + ["eba1", "\u8AE2\u8AF2\u8AF4\u8AF5\u8ADD\u8B14\u8AE4\u8ADF\u8AF0\u8AC8\u8ADE\u8AE1\u8AE8\u8AFF\u8AEF\u8AFB\u8C91\u8C92\u8C90\u8CF5\u8CEE\u8CF1\u8CF0\u8CF3\u8D6C\u8D6E\u8DA5\u8DA7\u8E33\u8E3E\u8E38\u8E40\u8E45\u8E36\u8E3C\u8E3D\u8E41\u8E30\u8E3F\u8EBD\u8F36\u8F2E\u8F35\u8F32\u8F39\u8F37\u8F34\u9076\u9079\u907B\u9086\u90FA\u9133\u9135\u9136\u9193\u9190\u9191\u918D\u918F\u9327\u931E\u9308\u931F\u9306\u930F\u937A\u9338\u933C\u931B\u9323\u9312\u9301\u9346\u932D\u930E\u930D\u92CB\u931D\u92FA\u9325\u9313\u92F9\u92F7\u9334\u9302\u9324\u92FF\u9329\u9339\u9335\u932A\u9314\u930C"], + ["ec40", "\u930B\u92FE\u9309\u9300\u92FB\u9316\u95BC\u95CD\u95BE\u95B9\u95BA\u95B6\u95BF\u95B5\u95BD\u96A9\u96D4\u970B\u9712\u9710\u9799\u9797\u9794\u97F0\u97F8\u9835\u982F\u9832\u9924\u991F\u9927\u9929\u999E\u99EE\u99EC\u99E5\u99E4\u99F0\u99E3\u99EA\u99E9\u99E7\u9AB9\u9ABF\u9AB4\u9ABB\u9AF6\u9AFA\u9AF9\u9AF7\u9B33\u9B80\u9B85\u9B87\u9B7C\u9B7E\u9B7B\u9B82\u9B93\u9B92\u9B90\u9B7A\u9B95"], + ["eca1", "\u9B7D\u9B88\u9D25\u9D17\u9D20\u9D1E\u9D14\u9D29\u9D1D\u9D18\u9D22\u9D10\u9D19\u9D1F\u9E88\u9E86\u9E87\u9EAE\u9EAD\u9ED5\u9ED6\u9EFA\u9F12\u9F3D\u5126\u5125\u5122\u5124\u5120\u5129\u52F4\u5693\u568C\u568D\u5686\u5684\u5683\u567E\u5682\u567F\u5681\u58D6\u58D4\u58CF\u58D2\u5B2D\u5B25\u5B32\u5B23\u5B2C\u5B27\u5B26\u5B2F\u5B2E\u5B7B\u5BF1\u5BF2\u5DB7\u5E6C\u5E6A\u5FBE\u5FBB\u61C3\u61B5\u61BC\u61E7\u61E0\u61E5\u61E4\u61E8\u61DE\u64EF\u64E9\u64E3\u64EB\u64E4\u64E8\u6581\u6580\u65B6\u65DA\u66D2\u6A8D\u6A96\u6A81\u6AA5\u6A89\u6A9F\u6A9B\u6AA1\u6A9E\u6A87\u6A93\u6A8E"], + ["ed40", "\u6A95\u6A83\u6AA8\u6AA4\u6A91\u6A7F\u6AA6\u6A9A\u6A85\u6A8C\u6A92\u6B5B\u6BAD\u6C09\u6FCC\u6FA9\u6FF4\u6FD4\u6FE3\u6FDC\u6FED\u6FE7\u6FE6\u6FDE\u6FF2\u6FDD\u6FE2\u6FE8\u71E1\u71F1\u71E8\u71F2\u71E4\u71F0\u71E2\u7373\u736E\u736F\u7497\u74B2\u74AB\u7490\u74AA\u74AD\u74B1\u74A5\u74AF\u7510\u7511\u7512\u750F\u7584\u7643\u7648\u7649\u7647\u76A4\u76E9\u77B5\u77AB\u77B2\u77B7\u77B6"], + ["eda1", "\u77B4\u77B1\u77A8\u77F0\u78F3\u78FD\u7902\u78FB\u78FC\u78F2\u7905\u78F9\u78FE\u7904\u79AB\u79A8\u7A5C\u7A5B\u7A56\u7A58\u7A54\u7A5A\u7ABE\u7AC0\u7AC1\u7C05\u7C0F\u7BF2\u7C00\u7BFF\u7BFB\u7C0E\u7BF4\u7C0B\u7BF3\u7C02\u7C09\u7C03\u7C01\u7BF8\u7BFD\u7C06\u7BF0\u7BF1\u7C10\u7C0A\u7CE8\u7E2D\u7E3C\u7E42\u7E33\u9848\u7E38\u7E2A\u7E49\u7E40\u7E47\u7E29\u7E4C\u7E30\u7E3B\u7E36\u7E44\u7E3A\u7F45\u7F7F\u7F7E\u7F7D\u7FF4\u7FF2\u802C\u81BB\u81C4\u81CC\u81CA\u81C5\u81C7\u81BC\u81E9\u825B\u825A\u825C\u8583\u8580\u858F\u85A7\u8595\u85A0\u858B\u85A3\u857B\u85A4\u859A\u859E"], + ["ee40", "\u8577\u857C\u8589\u85A1\u857A\u8578\u8557\u858E\u8596\u8586\u858D\u8599\u859D\u8581\u85A2\u8582\u8588\u8585\u8579\u8576\u8598\u8590\u859F\u8668\u87BE\u87AA\u87AD\u87C5\u87B0\u87AC\u87B9\u87B5\u87BC\u87AE\u87C9\u87C3\u87C2\u87CC\u87B7\u87AF\u87C4\u87CA\u87B4\u87B6\u87BF\u87B8\u87BD\u87DE\u87B2\u8935\u8933\u893C\u893E\u8941\u8952\u8937\u8942\u89AD\u89AF\u89AE\u89F2\u89F3\u8B1E"], + ["eea1", "\u8B18\u8B16\u8B11\u8B05\u8B0B\u8B22\u8B0F\u8B12\u8B15\u8B07\u8B0D\u8B08\u8B06\u8B1C\u8B13\u8B1A\u8C4F\u8C70\u8C72\u8C71\u8C6F\u8C95\u8C94\u8CF9\u8D6F\u8E4E\u8E4D\u8E53\u8E50\u8E4C\u8E47\u8F43\u8F40\u9085\u907E\u9138\u919A\u91A2\u919B\u9199\u919F\u91A1\u919D\u91A0\u93A1\u9383\u93AF\u9364\u9356\u9347\u937C\u9358\u935C\u9376\u9349\u9350\u9351\u9360\u936D\u938F\u934C\u936A\u9379\u9357\u9355\u9352\u934F\u9371\u9377\u937B\u9361\u935E\u9363\u9367\u9380\u934E\u9359\u95C7\u95C0\u95C9\u95C3\u95C5\u95B7\u96AE\u96B0\u96AC\u9720\u971F\u9718\u971D\u9719\u979A\u97A1\u979C"], + ["ef40", "\u979E\u979D\u97D5\u97D4\u97F1\u9841\u9844\u984A\u9849\u9845\u9843\u9925\u992B\u992C\u992A\u9933\u9932\u992F\u992D\u9931\u9930\u9998\u99A3\u99A1\u9A02\u99FA\u99F4\u99F7\u99F9\u99F8\u99F6\u99FB\u99FD\u99FE\u99FC\u9A03\u9ABE\u9AFE\u9AFD\u9B01\u9AFC\u9B48\u9B9A\u9BA8\u9B9E\u9B9B\u9BA6\u9BA1\u9BA5\u9BA4\u9B86\u9BA2\u9BA0\u9BAF\u9D33\u9D41\u9D67\u9D36\u9D2E\u9D2F\u9D31\u9D38\u9D30"], + ["efa1", "\u9D45\u9D42\u9D43\u9D3E\u9D37\u9D40\u9D3D\u7FF5\u9D2D\u9E8A\u9E89\u9E8D\u9EB0\u9EC8\u9EDA\u9EFB\u9EFF\u9F24\u9F23\u9F22\u9F54\u9FA0\u5131\u512D\u512E\u5698\u569C\u5697\u569A\u569D\u5699\u5970\u5B3C\u5C69\u5C6A\u5DC0\u5E6D\u5E6E\u61D8\u61DF\u61ED\u61EE\u61F1\u61EA\u61F0\u61EB\u61D6\u61E9\u64FF\u6504\u64FD\u64F8\u6501\u6503\u64FC\u6594\u65DB\u66DA\u66DB\u66D8\u6AC5\u6AB9\u6ABD\u6AE1\u6AC6\u6ABA\u6AB6\u6AB7\u6AC7\u6AB4\u6AAD\u6B5E\u6BC9\u6C0B\u7007\u700C\u700D\u7001\u7005\u7014\u700E\u6FFF\u7000\u6FFB\u7026\u6FFC\u6FF7\u700A\u7201\u71FF\u71F9\u7203\u71FD\u7376"], + ["f040", "\u74B8\u74C0\u74B5\u74C1\u74BE\u74B6\u74BB\u74C2\u7514\u7513\u765C\u7664\u7659\u7650\u7653\u7657\u765A\u76A6\u76BD\u76EC\u77C2\u77BA\u78FF\u790C\u7913\u7914\u7909\u7910\u7912\u7911\u79AD\u79AC\u7A5F\u7C1C\u7C29\u7C19\u7C20\u7C1F\u7C2D\u7C1D\u7C26\u7C28\u7C22\u7C25\u7C30\u7E5C\u7E50\u7E56\u7E63\u7E58\u7E62\u7E5F\u7E51\u7E60\u7E57\u7E53\u7FB5\u7FB3\u7FF7\u7FF8\u8075\u81D1\u81D2"], + ["f0a1", "\u81D0\u825F\u825E\u85B4\u85C6\u85C0\u85C3\u85C2\u85B3\u85B5\u85BD\u85C7\u85C4\u85BF\u85CB\u85CE\u85C8\u85C5\u85B1\u85B6\u85D2\u8624\u85B8\u85B7\u85BE\u8669\u87E7\u87E6\u87E2\u87DB\u87EB\u87EA\u87E5\u87DF\u87F3\u87E4\u87D4\u87DC\u87D3\u87ED\u87D8\u87E3\u87A4\u87D7\u87D9\u8801\u87F4\u87E8\u87DD\u8953\u894B\u894F\u894C\u8946\u8950\u8951\u8949\u8B2A\u8B27\u8B23\u8B33\u8B30\u8B35\u8B47\u8B2F\u8B3C\u8B3E\u8B31\u8B25\u8B37\u8B26\u8B36\u8B2E\u8B24\u8B3B\u8B3D\u8B3A\u8C42\u8C75\u8C99\u8C98\u8C97\u8CFE\u8D04\u8D02\u8D00\u8E5C\u8E62\u8E60\u8E57\u8E56\u8E5E\u8E65\u8E67"], + ["f140", "\u8E5B\u8E5A\u8E61\u8E5D\u8E69\u8E54\u8F46\u8F47\u8F48\u8F4B\u9128\u913A\u913B\u913E\u91A8\u91A5\u91A7\u91AF\u91AA\u93B5\u938C\u9392\u93B7\u939B\u939D\u9389\u93A7\u938E\u93AA\u939E\u93A6\u9395\u9388\u9399\u939F\u938D\u93B1\u9391\u93B2\u93A4\u93A8\u93B4\u93A3\u93A5\u95D2\u95D3\u95D1\u96B3\u96D7\u96DA\u5DC2\u96DF\u96D8\u96DD\u9723\u9722\u9725\u97AC\u97AE\u97A8\u97AB\u97A4\u97AA"], + ["f1a1", "\u97A2\u97A5\u97D7\u97D9\u97D6\u97D8\u97FA\u9850\u9851\u9852\u98B8\u9941\u993C\u993A\u9A0F\u9A0B\u9A09\u9A0D\u9A04\u9A11\u9A0A\u9A05\u9A07\u9A06\u9AC0\u9ADC\u9B08\u9B04\u9B05\u9B29\u9B35\u9B4A\u9B4C\u9B4B\u9BC7\u9BC6\u9BC3\u9BBF\u9BC1\u9BB5\u9BB8\u9BD3\u9BB6\u9BC4\u9BB9\u9BBD\u9D5C\u9D53\u9D4F\u9D4A\u9D5B\u9D4B\u9D59\u9D56\u9D4C\u9D57\u9D52\u9D54\u9D5F\u9D58\u9D5A\u9E8E\u9E8C\u9EDF\u9F01\u9F00\u9F16\u9F25\u9F2B\u9F2A\u9F29\u9F28\u9F4C\u9F55\u5134\u5135\u5296\u52F7\u53B4\u56AB\u56AD\u56A6\u56A7\u56AA\u56AC\u58DA\u58DD\u58DB\u5912\u5B3D\u5B3E\u5B3F\u5DC3\u5E70"], + ["f240", "\u5FBF\u61FB\u6507\u6510\u650D\u6509\u650C\u650E\u6584\u65DE\u65DD\u66DE\u6AE7\u6AE0\u6ACC\u6AD1\u6AD9\u6ACB\u6ADF\u6ADC\u6AD0\u6AEB\u6ACF\u6ACD\u6ADE\u6B60\u6BB0\u6C0C\u7019\u7027\u7020\u7016\u702B\u7021\u7022\u7023\u7029\u7017\u7024\u701C\u702A\u720C\u720A\u7207\u7202\u7205\u72A5\u72A6\u72A4\u72A3\u72A1\u74CB\u74C5\u74B7\u74C3\u7516\u7660\u77C9\u77CA\u77C4\u77F1\u791D\u791B"], + ["f2a1", "\u7921\u791C\u7917\u791E\u79B0\u7A67\u7A68\u7C33\u7C3C\u7C39\u7C2C\u7C3B\u7CEC\u7CEA\u7E76\u7E75\u7E78\u7E70\u7E77\u7E6F\u7E7A\u7E72\u7E74\u7E68\u7F4B\u7F4A\u7F83\u7F86\u7FB7\u7FFD\u7FFE\u8078\u81D7\u81D5\u8264\u8261\u8263\u85EB\u85F1\u85ED\u85D9\u85E1\u85E8\u85DA\u85D7\u85EC\u85F2\u85F8\u85D8\u85DF\u85E3\u85DC\u85D1\u85F0\u85E6\u85EF\u85DE\u85E2\u8800\u87FA\u8803\u87F6\u87F7\u8809\u880C\u880B\u8806\u87FC\u8808\u87FF\u880A\u8802\u8962\u895A\u895B\u8957\u8961\u895C\u8958\u895D\u8959\u8988\u89B7\u89B6\u89F6\u8B50\u8B48\u8B4A\u8B40\u8B53\u8B56\u8B54\u8B4B\u8B55"], + ["f340", "\u8B51\u8B42\u8B52\u8B57\u8C43\u8C77\u8C76\u8C9A\u8D06\u8D07\u8D09\u8DAC\u8DAA\u8DAD\u8DAB\u8E6D\u8E78\u8E73\u8E6A\u8E6F\u8E7B\u8EC2\u8F52\u8F51\u8F4F\u8F50\u8F53\u8FB4\u9140\u913F\u91B0\u91AD\u93DE\u93C7\u93CF\u93C2\u93DA\u93D0\u93F9\u93EC\u93CC\u93D9\u93A9\u93E6\u93CA\u93D4\u93EE\u93E3\u93D5\u93C4\u93CE\u93C0\u93D2\u93E7\u957D\u95DA\u95DB\u96E1\u9729\u972B\u972C\u9728\u9726"], + ["f3a1", "\u97B3\u97B7\u97B6\u97DD\u97DE\u97DF\u985C\u9859\u985D\u9857\u98BF\u98BD\u98BB\u98BE\u9948\u9947\u9943\u99A6\u99A7\u9A1A\u9A15\u9A25\u9A1D\u9A24\u9A1B\u9A22\u9A20\u9A27\u9A23\u9A1E\u9A1C\u9A14\u9AC2\u9B0B\u9B0A\u9B0E\u9B0C\u9B37\u9BEA\u9BEB\u9BE0\u9BDE\u9BE4\u9BE6\u9BE2\u9BF0\u9BD4\u9BD7\u9BEC\u9BDC\u9BD9\u9BE5\u9BD5\u9BE1\u9BDA\u9D77\u9D81\u9D8A\u9D84\u9D88\u9D71\u9D80\u9D78\u9D86\u9D8B\u9D8C\u9D7D\u9D6B\u9D74\u9D75\u9D70\u9D69\u9D85\u9D73\u9D7B\u9D82\u9D6F\u9D79\u9D7F\u9D87\u9D68\u9E94\u9E91\u9EC0\u9EFC\u9F2D\u9F40\u9F41\u9F4D\u9F56\u9F57\u9F58\u5337\u56B2"], + ["f440", "\u56B5\u56B3\u58E3\u5B45\u5DC6\u5DC7\u5EEE\u5EEF\u5FC0\u5FC1\u61F9\u6517\u6516\u6515\u6513\u65DF\u66E8\u66E3\u66E4\u6AF3\u6AF0\u6AEA\u6AE8\u6AF9\u6AF1\u6AEE\u6AEF\u703C\u7035\u702F\u7037\u7034\u7031\u7042\u7038\u703F\u703A\u7039\u7040\u703B\u7033\u7041\u7213\u7214\u72A8\u737D\u737C\u74BA\u76AB\u76AA\u76BE\u76ED\u77CC\u77CE\u77CF\u77CD\u77F2\u7925\u7923\u7927\u7928\u7924\u7929"], + ["f4a1", "\u79B2\u7A6E\u7A6C\u7A6D\u7AF7\u7C49\u7C48\u7C4A\u7C47\u7C45\u7CEE\u7E7B\u7E7E\u7E81\u7E80\u7FBA\u7FFF\u8079\u81DB\u81D9\u820B\u8268\u8269\u8622\u85FF\u8601\u85FE\u861B\u8600\u85F6\u8604\u8609\u8605\u860C\u85FD\u8819\u8810\u8811\u8817\u8813\u8816\u8963\u8966\u89B9\u89F7\u8B60\u8B6A\u8B5D\u8B68\u8B63\u8B65\u8B67\u8B6D\u8DAE\u8E86\u8E88\u8E84\u8F59\u8F56\u8F57\u8F55\u8F58\u8F5A\u908D\u9143\u9141\u91B7\u91B5\u91B2\u91B3\u940B\u9413\u93FB\u9420\u940F\u9414\u93FE\u9415\u9410\u9428\u9419\u940D\u93F5\u9400\u93F7\u9407\u940E\u9416\u9412\u93FA\u9409\u93F8\u940A\u93FF"], + ["f540", "\u93FC\u940C\u93F6\u9411\u9406\u95DE\u95E0\u95DF\u972E\u972F\u97B9\u97BB\u97FD\u97FE\u9860\u9862\u9863\u985F\u98C1\u98C2\u9950\u994E\u9959\u994C\u994B\u9953\u9A32\u9A34\u9A31\u9A2C\u9A2A\u9A36\u9A29\u9A2E\u9A38\u9A2D\u9AC7\u9ACA\u9AC6\u9B10\u9B12\u9B11\u9C0B\u9C08\u9BF7\u9C05\u9C12\u9BF8\u9C40\u9C07\u9C0E\u9C06\u9C17\u9C14\u9C09\u9D9F\u9D99\u9DA4\u9D9D\u9D92\u9D98\u9D90\u9D9B"], + ["f5a1", "\u9DA0\u9D94\u9D9C\u9DAA\u9D97\u9DA1\u9D9A\u9DA2\u9DA8\u9D9E\u9DA3\u9DBF\u9DA9\u9D96\u9DA6\u9DA7\u9E99\u9E9B\u9E9A\u9EE5\u9EE4\u9EE7\u9EE6\u9F30\u9F2E\u9F5B\u9F60\u9F5E\u9F5D\u9F59\u9F91\u513A\u5139\u5298\u5297\u56C3\u56BD\u56BE\u5B48\u5B47\u5DCB\u5DCF\u5EF1\u61FD\u651B\u6B02\u6AFC\u6B03\u6AF8\u6B00\u7043\u7044\u704A\u7048\u7049\u7045\u7046\u721D\u721A\u7219\u737E\u7517\u766A\u77D0\u792D\u7931\u792F\u7C54\u7C53\u7CF2\u7E8A\u7E87\u7E88\u7E8B\u7E86\u7E8D\u7F4D\u7FBB\u8030\u81DD\u8618\u862A\u8626\u861F\u8623\u861C\u8619\u8627\u862E\u8621\u8620\u8629\u861E\u8625"], + ["f640", "\u8829\u881D\u881B\u8820\u8824\u881C\u882B\u884A\u896D\u8969\u896E\u896B\u89FA\u8B79\u8B78\u8B45\u8B7A\u8B7B\u8D10\u8D14\u8DAF\u8E8E\u8E8C\u8F5E\u8F5B\u8F5D\u9146\u9144\u9145\u91B9\u943F\u943B\u9436\u9429\u943D\u943C\u9430\u9439\u942A\u9437\u942C\u9440\u9431\u95E5\u95E4\u95E3\u9735\u973A\u97BF\u97E1\u9864\u98C9\u98C6\u98C0\u9958\u9956\u9A39\u9A3D\u9A46\u9A44\u9A42\u9A41\u9A3A"], + ["f6a1", "\u9A3F\u9ACD\u9B15\u9B17\u9B18\u9B16\u9B3A\u9B52\u9C2B\u9C1D\u9C1C\u9C2C\u9C23\u9C28\u9C29\u9C24\u9C21\u9DB7\u9DB6\u9DBC\u9DC1\u9DC7\u9DCA\u9DCF\u9DBE\u9DC5\u9DC3\u9DBB\u9DB5\u9DCE\u9DB9\u9DBA\u9DAC\u9DC8\u9DB1\u9DAD\u9DCC\u9DB3\u9DCD\u9DB2\u9E7A\u9E9C\u9EEB\u9EEE\u9EED\u9F1B\u9F18\u9F1A\u9F31\u9F4E\u9F65\u9F64\u9F92\u4EB9\u56C6\u56C5\u56CB\u5971\u5B4B\u5B4C\u5DD5\u5DD1\u5EF2\u6521\u6520\u6526\u6522\u6B0B\u6B08\u6B09\u6C0D\u7055\u7056\u7057\u7052\u721E\u721F\u72A9\u737F\u74D8\u74D5\u74D9\u74D7\u766D\u76AD\u7935\u79B4\u7A70\u7A71\u7C57\u7C5C\u7C59\u7C5B\u7C5A"], + ["f740", "\u7CF4\u7CF1\u7E91\u7F4F\u7F87\u81DE\u826B\u8634\u8635\u8633\u862C\u8632\u8636\u882C\u8828\u8826\u882A\u8825\u8971\u89BF\u89BE\u89FB\u8B7E\u8B84\u8B82\u8B86\u8B85\u8B7F\u8D15\u8E95\u8E94\u8E9A\u8E92\u8E90\u8E96\u8E97\u8F60\u8F62\u9147\u944C\u9450\u944A\u944B\u944F\u9447\u9445\u9448\u9449\u9446\u973F\u97E3\u986A\u9869\u98CB\u9954\u995B\u9A4E\u9A53\u9A54\u9A4C\u9A4F\u9A48\u9A4A"], + ["f7a1", "\u9A49\u9A52\u9A50\u9AD0\u9B19\u9B2B\u9B3B\u9B56\u9B55\u9C46\u9C48\u9C3F\u9C44\u9C39\u9C33\u9C41\u9C3C\u9C37\u9C34\u9C32\u9C3D\u9C36\u9DDB\u9DD2\u9DDE\u9DDA\u9DCB\u9DD0\u9DDC\u9DD1\u9DDF\u9DE9\u9DD9\u9DD8\u9DD6\u9DF5\u9DD5\u9DDD\u9EB6\u9EF0\u9F35\u9F33\u9F32\u9F42\u9F6B\u9F95\u9FA2\u513D\u5299\u58E8\u58E7\u5972\u5B4D\u5DD8\u882F\u5F4F\u6201\u6203\u6204\u6529\u6525\u6596\u66EB\u6B11\u6B12\u6B0F\u6BCA\u705B\u705A\u7222\u7382\u7381\u7383\u7670\u77D4\u7C67\u7C66\u7E95\u826C\u863A\u8640\u8639\u863C\u8631\u863B\u863E\u8830\u8832\u882E\u8833\u8976\u8974\u8973\u89FE"], + ["f840", "\u8B8C\u8B8E\u8B8B\u8B88\u8C45\u8D19\u8E98\u8F64\u8F63\u91BC\u9462\u9455\u945D\u9457\u945E\u97C4\u97C5\u9800\u9A56\u9A59\u9B1E\u9B1F\u9B20\u9C52\u9C58\u9C50\u9C4A\u9C4D\u9C4B\u9C55\u9C59\u9C4C\u9C4E\u9DFB\u9DF7\u9DEF\u9DE3\u9DEB\u9DF8\u9DE4\u9DF6\u9DE1\u9DEE\u9DE6\u9DF2\u9DF0\u9DE2\u9DEC\u9DF4\u9DF3\u9DE8\u9DED\u9EC2\u9ED0\u9EF2\u9EF3\u9F06\u9F1C\u9F38\u9F37\u9F36\u9F43\u9F4F"], + ["f8a1", "\u9F71\u9F70\u9F6E\u9F6F\u56D3\u56CD\u5B4E\u5C6D\u652D\u66ED\u66EE\u6B13\u705F\u7061\u705D\u7060\u7223\u74DB\u74E5\u77D5\u7938\u79B7\u79B6\u7C6A\u7E97\u7F89\u826D\u8643\u8838\u8837\u8835\u884B\u8B94\u8B95\u8E9E\u8E9F\u8EA0\u8E9D\u91BE\u91BD\u91C2\u946B\u9468\u9469\u96E5\u9746\u9743\u9747\u97C7\u97E5\u9A5E\u9AD5\u9B59\u9C63\u9C67\u9C66\u9C62\u9C5E\u9C60\u9E02\u9DFE\u9E07\u9E03\u9E06\u9E05\u9E00\u9E01\u9E09\u9DFF\u9DFD\u9E04\u9EA0\u9F1E\u9F46\u9F74\u9F75\u9F76\u56D4\u652E\u65B8\u6B18\u6B19\u6B17\u6B1A\u7062\u7226\u72AA\u77D8\u77D9\u7939\u7C69\u7C6B\u7CF6\u7E9A"], + ["f940", "\u7E98\u7E9B\u7E99\u81E0\u81E1\u8646\u8647\u8648\u8979\u897A\u897C\u897B\u89FF\u8B98\u8B99\u8EA5\u8EA4\u8EA3\u946E\u946D\u946F\u9471\u9473\u9749\u9872\u995F\u9C68\u9C6E\u9C6D\u9E0B\u9E0D\u9E10\u9E0F\u9E12\u9E11\u9EA1\u9EF5\u9F09\u9F47\u9F78\u9F7B\u9F7A\u9F79\u571E\u7066\u7C6F\u883C\u8DB2\u8EA6\u91C3\u9474\u9478\u9476\u9475\u9A60\u9C74\u9C73\u9C71\u9C75\u9E14\u9E13\u9EF6\u9F0A"], + ["f9a1", "\u9FA4\u7068\u7065\u7CF7\u866A\u883E\u883D\u883F\u8B9E\u8C9C\u8EA9\u8EC9\u974B\u9873\u9874\u98CC\u9961\u99AB\u9A64\u9A66\u9A67\u9B24\u9E15\u9E17\u9F48\u6207\u6B1E\u7227\u864C\u8EA8\u9482\u9480\u9481\u9A69\u9A68\u9B2E\u9E19\u7229\u864B\u8B9F\u9483\u9C79\u9EB7\u7675\u9A6B\u9C7A\u9E1D\u7069\u706A\u9EA4\u9F7E\u9F49\u9F98\u7881\u92B9\u88CF\u58BB\u6052\u7CA7\u5AFA\u2554\u2566\u2557\u2560\u256C\u2563\u255A\u2569\u255D\u2552\u2564\u2555\u255E\u256A\u2561\u2558\u2567\u255B\u2553\u2565\u2556\u255F\u256B\u2562\u2559\u2568\u255C\u2551\u2550\u256D\u256E\u2570\u256F\u2593"] + ]; + } +}); + +// node_modules/iconv-lite/encodings/tables/big5-added.json +var require_big5_added = __commonJS({ + "node_modules/iconv-lite/encodings/tables/big5-added.json"(exports2, module2) { + module2.exports = [ + ["8740", "\u43F0\u4C32\u4603\u45A6\u4578\u{27267}\u4D77\u45B3\u{27CB1}\u4CE2\u{27CC5}\u3B95\u4736\u4744\u4C47\u4C40\u{242BF}\u{23617}\u{27352}\u{26E8B}\u{270D2}\u4C57\u{2A351}\u474F\u45DA\u4C85\u{27C6C}\u4D07\u4AA4\u46A1\u{26B23}\u7225\u{25A54}\u{21A63}\u{23E06}\u{23F61}\u664D\u56FB"], + ["8767", "\u7D95\u591D\u{28BB9}\u3DF4\u9734\u{27BEF}\u5BDB\u{21D5E}\u5AA4\u3625\u{29EB0}\u5AD1\u5BB7\u5CFC\u676E\u8593\u{29945}\u7461\u749D\u3875\u{21D53}\u{2369E}\u{26021}\u3EEC"], + ["87a1", "\u{258DE}\u3AF5\u7AFC\u9F97\u{24161}\u{2890D}\u{231EA}\u{20A8A}\u{2325E}\u430A\u8484\u9F96\u942F\u4930\u8613\u5896\u974A\u9218\u79D0\u7A32\u6660\u6A29\u889D\u744C\u7BC5\u6782\u7A2C\u524F\u9046\u34E6\u73C4\u{25DB9}\u74C6\u9FC7\u57B3\u492F\u544C\u4131\u{2368E}\u5818\u7A72\u{27B65}\u8B8F\u46AE\u{26E88}\u4181\u{25D99}\u7BAE\u{224BC}\u9FC8\u{224C1}\u{224C9}\u{224CC}\u9FC9\u8504\u{235BB}\u40B4\u9FCA\u44E1\u{2ADFF}\u62C1\u706E\u9FCB"], + ["8840", "\u31C0", 4, "\u{2010C}\u31C5\u{200D1}\u{200CD}\u31C6\u31C7\u{200CB}\u{21FE8}\u31C8\u{200CA}\u31C9\u31CA\u31CB\u31CC\u{2010E}\u31CD\u31CE\u0100\xC1\u01CD\xC0\u0112\xC9\u011A\xC8\u014C\xD3\u01D1\xD2\u0FFF\xCA\u0304\u1EBE\u0FFF\xCA\u030C\u1EC0\xCA\u0101\xE1\u01CE\xE0\u0251\u0113\xE9\u011B\xE8\u012B\xED\u01D0\xEC\u014D\xF3\u01D2\xF2\u016B\xFA\u01D4\xF9\u01D6\u01D8\u01DA"], + ["88a1", "\u01DC\xFC\u0FFF\xEA\u0304\u1EBF\u0FFF\xEA\u030C\u1EC1\xEA\u0261\u23DA\u23DB"], + ["8940", "\u{2A3A9}\u{21145}"], + ["8943", "\u650A"], + ["8946", "\u4E3D\u6EDD\u9D4E\u91DF"], + ["894c", "\u{27735}\u6491\u4F1A\u4F28\u4FA8\u5156\u5174\u519C\u51E4\u52A1\u52A8\u533B\u534E\u53D1\u53D8\u56E2\u58F0\u5904\u5907\u5932\u5934\u5B66\u5B9E\u5B9F\u5C9A\u5E86\u603B\u6589\u67FE\u6804\u6865\u6D4E\u70BC\u7535\u7EA4\u7EAC\u7EBA\u7EC7\u7ECF\u7EDF\u7F06\u7F37\u827A\u82CF\u836F\u89C6\u8BBE\u8BE2\u8F66\u8F67\u8F6E"], + ["89a1", "\u7411\u7CFC\u7DCD\u6946\u7AC9\u5227"], + ["89ab", "\u918C\u78B8\u915E\u80BC"], + ["89b0", "\u8D0B\u80F6\u{209E7}"], + ["89b5", "\u809F\u9EC7\u4CCD\u9DC9\u9E0C\u4C3E\u{29DF6}\u{2700E}\u9E0A\u{2A133}\u35C1"], + ["89c1", "\u6E9A\u823E\u7519"], + ["89c5", "\u4911\u9A6C\u9A8F\u9F99\u7987\u{2846C}\u{21DCA}\u{205D0}\u{22AE6}\u4E24\u4E81\u4E80\u4E87\u4EBF\u4EEB\u4F37\u344C\u4FBD\u3E48\u5003\u5088\u347D\u3493\u34A5\u5186\u5905\u51DB\u51FC\u5205\u4E89\u5279\u5290\u5327\u35C7\u53A9\u3551\u53B0\u3553\u53C2\u5423\u356D\u3572\u3681\u5493\u54A3\u54B4\u54B9\u54D0\u54EF\u5518\u5523\u5528\u3598\u553F\u35A5\u35BF\u55D7\u35C5"], + ["8a40", "\u{27D84}\u5525"], + ["8a43", "\u{20C42}\u{20D15}\u{2512B}\u5590\u{22CC6}\u39EC\u{20341}\u8E46\u{24DB8}\u{294E5}\u4053\u{280BE}\u777A\u{22C38}\u3A34\u47D5\u{2815D}\u{269F2}\u{24DEA}\u64DD\u{20D7C}\u{20FB4}\u{20CD5}\u{210F4}\u648D\u8E7E\u{20E96}\u{20C0B}\u{20F64}\u{22CA9}\u{28256}\u{244D3}"], + ["8a64", "\u{20D46}\u{29A4D}\u{280E9}\u47F4\u{24EA7}\u{22CC2}\u9AB2\u3A67\u{295F4}\u3FED\u3506\u{252C7}\u{297D4}\u{278C8}\u{22D44}\u9D6E\u9815"], + ["8a76", "\u43D9\u{260A5}\u64B4\u54E3\u{22D4C}\u{22BCA}\u{21077}\u39FB\u{2106F}"], + ["8aa1", "\u{266DA}\u{26716}\u{279A0}\u64EA\u{25052}\u{20C43}\u8E68\u{221A1}\u{28B4C}\u{20731}"], + ["8aac", "\u480B\u{201A9}\u3FFA\u5873\u{22D8D}"], + ["8ab2", "\u{245C8}\u{204FC}\u{26097}\u{20F4C}\u{20D96}\u5579\u40BB\u43BA"], + ["8abb", "\u4AB4\u{22A66}\u{2109D}\u81AA\u98F5\u{20D9C}\u6379\u39FE\u{22775}\u8DC0\u56A1\u647C\u3E43"], + ["8ac9", "\u{2A601}\u{20E09}\u{22ACF}\u{22CC9}"], + ["8ace", "\u{210C8}\u{239C2}\u3992\u3A06\u{2829B}\u3578\u{25E49}\u{220C7}\u5652\u{20F31}\u{22CB2}\u{29720}\u34BC\u6C3D\u{24E3B}"], + ["8adf", "\u{27574}\u{22E8B}\u{22208}\u{2A65B}\u{28CCD}\u{20E7A}\u{20C34}\u{2681C}\u7F93\u{210CF}\u{22803}\u{22939}\u35FB\u{251E3}\u{20E8C}\u{20F8D}\u{20EAA}\u3F93\u{20F30}\u{20D47}\u{2114F}\u{20E4C}"], + ["8af6", "\u{20EAB}\u{20BA9}\u{20D48}\u{210C0}\u{2113D}\u3FF9\u{22696}\u6432\u{20FAD}"], + ["8b40", "\u{233F4}\u{27639}\u{22BCE}\u{20D7E}\u{20D7F}\u{22C51}\u{22C55}\u3A18\u{20E98}\u{210C7}\u{20F2E}\u{2A632}\u{26B50}\u{28CD2}\u{28D99}\u{28CCA}\u95AA\u54CC\u82C4\u55B9"], + ["8b55", "\u{29EC3}\u9C26\u9AB6\u{2775E}\u{22DEE}\u7140\u816D\u80EC\u5C1C\u{26572}\u8134\u3797\u535F\u{280BD}\u91B6\u{20EFA}\u{20E0F}\u{20E77}\u{20EFB}\u35DD\u{24DEB}\u3609\u{20CD6}\u56AF\u{227B5}\u{210C9}\u{20E10}\u{20E78}\u{21078}\u{21148}\u{28207}\u{21455}\u{20E79}\u{24E50}\u{22DA4}\u5A54\u{2101D}\u{2101E}\u{210F5}\u{210F6}\u579C\u{20E11}"], + ["8ba1", "\u{27694}\u{282CD}\u{20FB5}\u{20E7B}\u{2517E}\u3703\u{20FB6}\u{21180}\u{252D8}\u{2A2BD}\u{249DA}\u{2183A}\u{24177}\u{2827C}\u5899\u5268\u361A\u{2573D}\u7BB2\u5B68\u4800\u4B2C\u9F27\u49E7\u9C1F\u9B8D\u{25B74}\u{2313D}\u55FB\u35F2\u5689\u4E28\u5902\u{21BC1}\u{2F878}\u9751\u{20086}\u4E5B\u4EBB\u353E\u5C23\u5F51\u5FC4\u38FA\u624C\u6535\u6B7A\u6C35\u6C3A\u706C\u722B\u4E2C\u72AD\u{248E9}\u7F52\u793B\u7CF9\u7F53\u{2626A}\u34C1"], + ["8bde", "\u{2634B}\u8002\u8080\u{26612}\u{26951}\u535D\u8864\u89C1\u{278B2}\u8BA0\u8D1D\u9485\u9578\u957F\u95E8\u{28E0F}\u97E6\u9875\u98CE\u98DE\u9963\u{29810}\u9C7C\u9E1F\u9EC4\u6B6F\uF907\u4E37\u{20087}\u961D\u6237\u94A2"], + ["8c40", "\u503B\u6DFE\u{29C73}\u9FA6\u3DC9\u888F\u{2414E}\u7077\u5CF5\u4B20\u{251CD}\u3559\u{25D30}\u6122\u{28A32}\u8FA7\u91F6\u7191\u6719\u73BA\u{23281}\u{2A107}\u3C8B\u{21980}\u4B10\u78E4\u7402\u51AE\u{2870F}\u4009\u6A63\u{2A2BA}\u4223\u860F\u{20A6F}\u7A2A\u{29947}\u{28AEA}\u9755\u704D\u5324\u{2207E}\u93F4\u76D9\u{289E3}\u9FA7\u77DD\u4EA3\u4FF0\u50BC\u4E2F\u4F17\u9FA8\u5434\u7D8B\u5892\u58D0\u{21DB6}\u5E92\u5E99\u5FC2\u{22712}\u658B"], + ["8ca1", "\u{233F9}\u6919\u6A43\u{23C63}\u6CFF"], + ["8ca7", "\u7200\u{24505}\u738C\u3EDB\u{24A13}\u5B15\u74B9\u8B83\u{25CA4}\u{25695}\u7A93\u7BEC\u7CC3\u7E6C\u82F8\u8597\u9FA9\u8890\u9FAA\u8EB9\u9FAB\u8FCF\u855F\u99E0\u9221\u9FAC\u{28DB9}\u{2143F}\u4071\u42A2\u5A1A"], + ["8cc9", "\u9868\u676B\u4276\u573D"], + ["8cce", "\u85D6\u{2497B}\u82BF\u{2710D}\u4C81\u{26D74}\u5D7B\u{26B15}\u{26FBE}\u9FAD\u9FAE\u5B96\u9FAF\u66E7\u7E5B\u6E57\u79CA\u3D88\u44C3\u{23256}\u{22796}\u439A\u4536"], + ["8ce6", "\u5CD5\u{23B1A}\u8AF9\u5C78\u3D12\u{23551}\u5D78\u9FB2\u7157\u4558\u{240EC}\u{21E23}\u4C77\u3978\u344A\u{201A4}\u{26C41}\u8ACC\u4FB4\u{20239}\u59BF\u816C\u9856\u{298FA}\u5F3B"], + ["8d40", "\u{20B9F}"], + ["8d42", "\u{221C1}\u{2896D}\u4102\u46BB\u{29079}\u3F07\u9FB3\u{2A1B5}\u40F8\u37D6\u46F7\u{26C46}\u417C\u{286B2}\u{273FF}\u456D\u38D4\u{2549A}\u4561\u451B\u4D89\u4C7B\u4D76\u45EA\u3FC8\u{24B0F}\u3661\u44DE\u44BD\u41ED\u5D3E\u5D48\u5D56\u3DFC\u380F\u5DA4\u5DB9\u3820\u3838\u5E42\u5EBD\u5F25\u5F83\u3908\u3914\u393F\u394D\u60D7\u613D\u5CE5\u3989\u61B7\u61B9\u61CF\u39B8\u622C\u6290\u62E5\u6318\u39F8\u56B1"], + ["8da1", "\u3A03\u63E2\u63FB\u6407\u645A\u3A4B\u64C0\u5D15\u5621\u9F9F\u3A97\u6586\u3ABD\u65FF\u6653\u3AF2\u6692\u3B22\u6716\u3B42\u67A4\u6800\u3B58\u684A\u6884\u3B72\u3B71\u3B7B\u6909\u6943\u725C\u6964\u699F\u6985\u3BBC\u69D6\u3BDD\u6A65\u6A74\u6A71\u6A82\u3BEC\u6A99\u3BF2\u6AAB\u6AB5\u6AD4\u6AF6\u6B81\u6BC1\u6BEA\u6C75\u6CAA\u3CCB\u6D02\u6D06\u6D26\u6D81\u3CEF\u6DA4\u6DB1\u6E15\u6E18\u6E29\u6E86\u{289C0}\u6EBB\u6EE2\u6EDA\u9F7F\u6EE8\u6EE9\u6F24\u6F34\u3D46\u{23F41}\u6F81\u6FBE\u3D6A\u3D75\u71B7\u5C99\u3D8A\u702C\u3D91\u7050\u7054\u706F\u707F\u7089\u{20325}\u43C1\u35F1\u{20ED8}"], + ["8e40", "\u{23ED7}\u57BE\u{26ED3}\u713E\u{257E0}\u364E\u69A2\u{28BE9}\u5B74\u7A49\u{258E1}\u{294D9}\u7A65\u7A7D\u{259AC}\u7ABB\u7AB0\u7AC2\u7AC3\u71D1\u{2648D}\u41CA\u7ADA\u7ADD\u7AEA\u41EF\u54B2\u{25C01}\u7B0B\u7B55\u7B29\u{2530E}\u{25CFE}\u7BA2\u7B6F\u839C\u{25BB4}\u{26C7F}\u7BD0\u8421\u7B92\u7BB8\u{25D20}\u3DAD\u{25C65}\u8492\u7BFA\u7C06\u7C35\u{25CC1}\u7C44\u7C83\u{24882}\u7CA6\u667D\u{24578}\u7CC9\u7CC7\u7CE6\u7C74\u7CF3\u7CF5\u7CCE"], + ["8ea1", "\u7E67\u451D\u{26E44}\u7D5D\u{26ED6}\u748D\u7D89\u7DAB\u7135\u7DB3\u7DD2\u{24057}\u{26029}\u7DE4\u3D13\u7DF5\u{217F9}\u7DE5\u{2836D}\u7E1D\u{26121}\u{2615A}\u7E6E\u7E92\u432B\u946C\u7E27\u7F40\u7F41\u7F47\u7936\u{262D0}\u99E1\u7F97\u{26351}\u7FA3\u{21661}\u{20068}\u455C\u{23766}\u4503\u{2833A}\u7FFA\u{26489}\u8005\u8008\u801D\u8028\u802F\u{2A087}\u{26CC3}\u803B\u803C\u8061\u{22714}\u4989\u{26626}\u{23DE3}\u{266E8}\u6725\u80A7\u{28A48}\u8107\u811A\u58B0\u{226F6}\u6C7F\u{26498}\u{24FB8}\u64E7\u{2148A}\u8218\u{2185E}\u6A53\u{24A65}\u{24A95}\u447A\u8229\u{20B0D}\u{26A52}\u{23D7E}\u4FF9\u{214FD}\u84E2\u8362\u{26B0A}\u{249A7}\u{23530}\u{21773}\u{23DF8}\u82AA\u691B\u{2F994}\u41DB"], + ["8f40", "\u854B\u82D0\u831A\u{20E16}\u{217B4}\u36C1\u{2317D}\u{2355A}\u827B\u82E2\u8318\u{23E8B}\u{26DA3}\u{26B05}\u{26B97}\u{235CE}\u3DBF\u831D\u55EC\u8385\u450B\u{26DA5}\u83AC\u83C1\u83D3\u347E\u{26ED4}\u6A57\u855A\u3496\u{26E42}\u{22EEF}\u8458\u{25BE4}\u8471\u3DD3\u44E4\u6AA7\u844A\u{23CB5}\u7958\u84A8\u{26B96}\u{26E77}\u{26E43}\u84DE\u840F\u8391\u44A0\u8493\u84E4\u{25C91}\u4240\u{25CC0}\u4543\u8534\u5AF2\u{26E99}\u4527\u8573\u4516\u67BF\u8616"], + ["8fa1", "\u{28625}\u{2863B}\u85C1\u{27088}\u8602\u{21582}\u{270CD}\u{2F9B2}\u456A\u8628\u3648\u{218A2}\u53F7\u{2739A}\u867E\u8771\u{2A0F8}\u87EE\u{22C27}\u87B1\u87DA\u880F\u5661\u866C\u6856\u460F\u8845\u8846\u{275E0}\u{23DB9}\u{275E4}\u885E\u889C\u465B\u88B4\u88B5\u63C1\u88C5\u7777\u{2770F}\u8987\u898A\u89A6\u89A9\u89A7\u89BC\u{28A25}\u89E7\u{27924}\u{27ABD}\u8A9C\u7793\u91FE\u8A90\u{27A59}\u7AE9\u{27B3A}\u{23F8F}\u4713\u{27B38}\u717C\u8B0C\u8B1F\u{25430}\u{25565}\u8B3F\u8B4C\u8B4D\u8AA9\u{24A7A}\u8B90\u8B9B\u8AAF\u{216DF}\u4615\u884F\u8C9B\u{27D54}\u{27D8F}\u{2F9D4}\u3725\u{27D53}\u8CD6\u{27D98}\u{27DBD}\u8D12\u8D03\u{21910}\u8CDB\u705C\u8D11\u{24CC9}\u3ED0\u8D77"], + ["9040", "\u8DA9\u{28002}\u{21014}\u{2498A}\u3B7C\u{281BC}\u{2710C}\u7AE7\u8EAD\u8EB6\u8EC3\u92D4\u8F19\u8F2D\u{28365}\u{28412}\u8FA5\u9303\u{2A29F}\u{20A50}\u8FB3\u492A\u{289DE}\u{2853D}\u{23DBB}\u5EF8\u{23262}\u8FF9\u{2A014}\u{286BC}\u{28501}\u{22325}\u3980\u{26ED7}\u9037\u{2853C}\u{27ABE}\u9061\u{2856C}\u{2860B}\u90A8\u{28713}\u90C4\u{286E6}\u90AE\u90FD\u9167\u3AF0\u91A9\u91C4\u7CAC\u{28933}\u{21E89}\u920E\u6C9F\u9241\u9262\u{255B9}\u92B9\u{28AC6}\u{23C9B}\u{28B0C}\u{255DB}"], + ["90a1", "\u{20D31}\u932C\u936B\u{28AE1}\u{28BEB}\u708F\u5AC3\u{28AE2}\u{28AE5}\u4965\u9244\u{28BEC}\u{28C39}\u{28BFF}\u9373\u945B\u8EBC\u9585\u95A6\u9426\u95A0\u6FF6\u42B9\u{2267A}\u{286D8}\u{2127C}\u{23E2E}\u49DF\u6C1C\u967B\u9696\u416C\u96A3\u{26ED5}\u61DA\u96B6\u78F5\u{28AE0}\u96BD\u53CC\u49A1\u{26CB8}\u{20274}\u{26410}\u{290AF}\u{290E5}\u{24AD1}\u{21915}\u{2330A}\u9731\u8642\u9736\u4A0F\u453D\u4585\u{24AE9}\u7075\u5B41\u971B\u975C\u{291D5}\u9757\u5B4A\u{291EB}\u975F\u9425\u50D0\u{230B7}\u{230BC}\u9789\u979F\u97B1\u97BE\u97C0\u97D2\u97E0\u{2546C}\u97EE\u741C\u{29433}\u97FF\u97F5\u{2941D}\u{2797A}\u4AD1\u9834\u9833\u984B\u9866\u3B0E\u{27175}\u3D51\u{20630}\u{2415C}"], + ["9140", "\u{25706}\u98CA\u98B7\u98C8\u98C7\u4AFF\u{26D27}\u{216D3}\u55B0\u98E1\u98E6\u98EC\u9378\u9939\u{24A29}\u4B72\u{29857}\u{29905}\u99F5\u9A0C\u9A3B\u9A10\u9A58\u{25725}\u36C4\u{290B1}\u{29BD5}\u9AE0\u9AE2\u{29B05}\u9AF4\u4C0E\u9B14\u9B2D\u{28600}\u5034\u9B34\u{269A8}\u38C3\u{2307D}\u9B50\u9B40\u{29D3E}\u5A45\u{21863}\u9B8E\u{2424B}\u9C02\u9BFF\u9C0C\u{29E68}\u9DD4\u{29FB7}\u{2A192}\u{2A1AB}\u{2A0E1}\u{2A123}\u{2A1DF}\u9D7E\u9D83\u{2A134}\u9E0E\u6888"], + ["91a1", "\u9DC4\u{2215B}\u{2A193}\u{2A220}\u{2193B}\u{2A233}\u9D39\u{2A0B9}\u{2A2B4}\u9E90\u9E95\u9E9E\u9EA2\u4D34\u9EAA\u9EAF\u{24364}\u9EC1\u3B60\u39E5\u3D1D\u4F32\u37BE\u{28C2B}\u9F02\u9F08\u4B96\u9424\u{26DA2}\u9F17\u9F16\u9F39\u569F\u568A\u9F45\u99B8\u{2908B}\u97F2\u847F\u9F62\u9F69\u7ADC\u9F8E\u7216\u4BBE\u{24975}\u{249BB}\u7177\u{249F8}\u{24348}\u{24A51}\u739E\u{28BDA}\u{218FA}\u799F\u{2897E}\u{28E36}\u9369\u93F3\u{28A44}\u92EC\u9381\u93CB\u{2896C}\u{244B9}\u7217\u3EEB\u7772\u7A43\u70D0\u{24473}\u{243F8}\u717E\u{217EF}\u70A3\u{218BE}\u{23599}\u3EC7\u{21885}\u{2542F}\u{217F8}\u3722\u{216FB}\u{21839}\u36E1\u{21774}\u{218D1}\u{25F4B}\u3723\u{216C0}\u575B\u{24A25}\u{213FE}\u{212A8}"], + ["9240", "\u{213C6}\u{214B6}\u8503\u{236A6}\u8503\u8455\u{24994}\u{27165}\u{23E31}\u{2555C}\u{23EFB}\u{27052}\u44F4\u{236EE}\u{2999D}\u{26F26}\u67F9\u3733\u3C15\u3DE7\u586C\u{21922}\u6810\u4057\u{2373F}\u{240E1}\u{2408B}\u{2410F}\u{26C21}\u54CB\u569E\u{266B1}\u5692\u{20FDF}\u{20BA8}\u{20E0D}\u93C6\u{28B13}\u939C\u4EF8\u512B\u3819\u{24436}\u4EBC\u{20465}\u{2037F}\u4F4B\u4F8A\u{25651}\u5A68\u{201AB}\u{203CB}\u3999\u{2030A}\u{20414}\u3435\u4F29\u{202C0}\u{28EB3}\u{20275}\u8ADA\u{2020C}\u4E98"], + ["92a1", "\u50CD\u510D\u4FA2\u4F03\u{24A0E}\u{23E8A}\u4F42\u502E\u506C\u5081\u4FCC\u4FE5\u5058\u50FC\u5159\u515B\u515D\u515E\u6E76\u{23595}\u{23E39}\u{23EBF}\u6D72\u{21884}\u{23E89}\u51A8\u51C3\u{205E0}\u44DD\u{204A3}\u{20492}\u{20491}\u8D7A\u{28A9C}\u{2070E}\u5259\u52A4\u{20873}\u52E1\u936E\u467A\u718C\u{2438C}\u{20C20}\u{249AC}\u{210E4}\u69D1\u{20E1D}\u7479\u3EDE\u7499\u7414\u7456\u7398\u4B8E\u{24ABC}\u{2408D}\u53D0\u3584\u720F\u{240C9}\u55B4\u{20345}\u54CD\u{20BC6}\u571D\u925D\u96F4\u9366\u57DD\u578D\u577F\u363E\u58CB\u5A99\u{28A46}\u{216FA}\u{2176F}\u{21710}\u5A2C\u59B8\u928F\u5A7E\u5ACF\u5A12\u{25946}\u{219F3}\u{21861}\u{24295}\u36F5\u6D05\u7443\u5A21\u{25E83}"], + ["9340", "\u5A81\u{28BD7}\u{20413}\u93E0\u748C\u{21303}\u7105\u4972\u9408\u{289FB}\u93BD\u37A0\u5C1E\u5C9E\u5E5E\u5E48\u{21996}\u{2197C}\u{23AEE}\u5ECD\u5B4F\u{21903}\u{21904}\u3701\u{218A0}\u36DD\u{216FE}\u36D3\u812A\u{28A47}\u{21DBA}\u{23472}\u{289A8}\u5F0C\u5F0E\u{21927}\u{217AB}\u5A6B\u{2173B}\u5B44\u8614\u{275FD}\u8860\u607E\u{22860}\u{2262B}\u5FDB\u3EB8\u{225AF}\u{225BE}\u{29088}\u{26F73}\u61C0\u{2003E}\u{20046}\u{2261B}\u6199\u6198\u6075\u{22C9B}\u{22D07}\u{246D4}\u{2914D}"], + ["93a1", "\u6471\u{24665}\u{22B6A}\u3A29\u{22B22}\u{23450}\u{298EA}\u{22E78}\u6337\u{2A45B}\u64B6\u6331\u63D1\u{249E3}\u{22D67}\u62A4\u{22CA1}\u643B\u656B\u6972\u3BF4\u{2308E}\u{232AD}\u{24989}\u{232AB}\u550D\u{232E0}\u{218D9}\u{2943F}\u66CE\u{23289}\u{231B3}\u3AE0\u4190\u{25584}\u{28B22}\u{2558F}\u{216FC}\u{2555B}\u{25425}\u78EE\u{23103}\u{2182A}\u{23234}\u3464\u{2320F}\u{23182}\u{242C9}\u668E\u{26D24}\u666B\u4B93\u6630\u{27870}\u{21DEB}\u6663\u{232D2}\u{232E1}\u661E\u{25872}\u38D1\u{2383A}\u{237BC}\u3B99\u{237A2}\u{233FE}\u74D0\u3B96\u678F\u{2462A}\u68B6\u681E\u3BC4\u6ABE\u3863\u{237D5}\u{24487}\u6A33\u6A52\u6AC9\u6B05\u{21912}\u6511\u6898\u6A4C\u3BD7\u6A7A\u6B57\u{23FC0}\u{23C9A}\u93A0\u92F2\u{28BEA}\u{28ACB}"], + ["9440", "\u9289\u{2801E}\u{289DC}\u9467\u6DA5\u6F0B\u{249EC}\u6D67\u{23F7F}\u3D8F\u6E04\u{2403C}\u5A3D\u6E0A\u5847\u6D24\u7842\u713B\u{2431A}\u{24276}\u70F1\u7250\u7287\u7294\u{2478F}\u{24725}\u5179\u{24AA4}\u{205EB}\u747A\u{23EF8}\u{2365F}\u{24A4A}\u{24917}\u{25FE1}\u3F06\u3EB1\u{24ADF}\u{28C23}\u{23F35}\u60A7\u3EF3\u74CC\u743C\u9387\u7437\u449F\u{26DEA}\u4551\u7583\u3F63\u{24CD9}\u{24D06}\u3F58\u7555\u7673\u{2A5C6}\u3B19\u7468\u{28ACC}\u{249AB}\u{2498E}\u3AFB"], + ["94a1", "\u3DCD\u{24A4E}\u3EFF\u{249C5}\u{248F3}\u91FA\u5732\u9342\u{28AE3}\u{21864}\u50DF\u{25221}\u{251E7}\u7778\u{23232}\u770E\u770F\u777B\u{24697}\u{23781}\u3A5E\u{248F0}\u7438\u749B\u3EBF\u{24ABA}\u{24AC7}\u40C8\u{24A96}\u{261AE}\u9307\u{25581}\u781E\u788D\u7888\u78D2\u73D0\u7959\u{27741}\u{256E3}\u410E\u799B\u8496\u79A5\u6A2D\u{23EFA}\u7A3A\u79F4\u416E\u{216E6}\u4132\u9235\u79F1\u{20D4C}\u{2498C}\u{20299}\u{23DBA}\u{2176E}\u3597\u556B\u3570\u36AA\u{201D4}\u{20C0D}\u7AE2\u5A59\u{226F5}\u{25AAF}\u{25A9C}\u5A0D\u{2025B}\u78F0\u5A2A\u{25BC6}\u7AFE\u41F9\u7C5D\u7C6D\u4211\u{25BB3}\u{25EBC}\u{25EA6}\u7CCD\u{249F9}\u{217B0}\u7C8E\u7C7C\u7CAE\u6AB2\u7DDC\u7E07\u7DD3\u7F4E\u{26261}"], + ["9540", "\u{2615C}\u{27B48}\u7D97\u{25E82}\u426A\u{26B75}\u{20916}\u67D6\u{2004E}\u{235CF}\u57C4\u{26412}\u{263F8}\u{24962}\u7FDD\u7B27\u{2082C}\u{25AE9}\u{25D43}\u7B0C\u{25E0E}\u99E6\u8645\u9A63\u6A1C\u{2343F}\u39E2\u{249F7}\u{265AD}\u9A1F\u{265A0}\u8480\u{27127}\u{26CD1}\u44EA\u8137\u4402\u80C6\u8109\u8142\u{267B4}\u98C3\u{26A42}\u8262\u8265\u{26A51}\u8453\u{26DA7}\u8610\u{2721B}\u5A86\u417F\u{21840}\u5B2B\u{218A1}\u5AE4\u{218D8}\u86A0\u{2F9BC}\u{23D8F}\u882D\u{27422}\u5A02"], + ["95a1", "\u886E\u4F45\u8887\u88BF\u88E6\u8965\u894D\u{25683}\u8954\u{27785}\u{27784}\u{28BF5}\u{28BD9}\u{28B9C}\u{289F9}\u3EAD\u84A3\u46F5\u46CF\u37F2\u8A3D\u8A1C\u{29448}\u5F4D\u922B\u{24284}\u65D4\u7129\u70C4\u{21845}\u9D6D\u8C9F\u8CE9\u{27DDC}\u599A\u77C3\u59F0\u436E\u36D4\u8E2A\u8EA7\u{24C09}\u8F30\u8F4A\u42F4\u6C58\u6FBB\u{22321}\u489B\u6F79\u6E8B\u{217DA}\u9BE9\u36B5\u{2492F}\u90BB\u9097\u5571\u4906\u91BB\u9404\u{28A4B}\u4062\u{28AFC}\u9427\u{28C1D}\u{28C3B}\u84E5\u8A2B\u9599\u95A7\u9597\u9596\u{28D34}\u7445\u3EC2\u{248FF}\u{24A42}\u{243EA}\u3EE7\u{23225}\u968F\u{28EE7}\u{28E66}\u{28E65}\u3ECC\u{249ED}\u{24A78}\u{23FEE}\u7412\u746B\u3EFC\u9741\u{290B0}"], + ["9640", "\u6847\u4A1D\u{29093}\u{257DF}\u975D\u9368\u{28989}\u{28C26}\u{28B2F}\u{263BE}\u92BA\u5B11\u8B69\u493C\u73F9\u{2421B}\u979B\u9771\u9938\u{20F26}\u5DC1\u{28BC5}\u{24AB2}\u981F\u{294DA}\u92F6\u{295D7}\u91E5\u44C0\u{28B50}\u{24A67}\u{28B64}\u98DC\u{28A45}\u3F00\u922A\u4925\u8414\u993B\u994D\u{27B06}\u3DFD\u999B\u4B6F\u99AA\u9A5C\u{28B65}\u{258C8}\u6A8F\u9A21\u5AFE\u9A2F\u{298F1}\u4B90\u{29948}\u99BC\u4BBD\u4B97\u937D\u5872\u{21302}\u5822\u{249B8}"], + ["96a1", "\u{214E8}\u7844\u{2271F}\u{23DB8}\u68C5\u3D7D\u9458\u3927\u6150\u{22781}\u{2296B}\u6107\u9C4F\u9C53\u9C7B\u9C35\u9C10\u9B7F\u9BCF\u{29E2D}\u9B9F\u{2A1F5}\u{2A0FE}\u9D21\u4CAE\u{24104}\u9E18\u4CB0\u9D0C\u{2A1B4}\u{2A0ED}\u{2A0F3}\u{2992F}\u9DA5\u84BD\u{26E12}\u{26FDF}\u{26B82}\u85FC\u4533\u{26DA4}\u{26E84}\u{26DF0}\u8420\u85EE\u{26E00}\u{237D7}\u{26064}\u79E2\u{2359C}\u{23640}\u492D\u{249DE}\u3D62\u93DB\u92BE\u9348\u{202BF}\u78B9\u9277\u944D\u4FE4\u3440\u9064\u{2555D}\u783D\u7854\u78B6\u784B\u{21757}\u{231C9}\u{24941}\u369A\u4F72\u6FDA\u6FD9\u701E\u701E\u5414\u{241B5}\u57BB\u58F3\u578A\u9D16\u57D7\u7134\u34AF\u{241AC}\u71EB\u{26C40}\u{24F97}\u5B28\u{217B5}\u{28A49}"], + ["9740", "\u610C\u5ACE\u5A0B\u42BC\u{24488}\u372C\u4B7B\u{289FC}\u93BB\u93B8\u{218D6}\u{20F1D}\u8472\u{26CC0}\u{21413}\u{242FA}\u{22C26}\u{243C1}\u5994\u{23DB7}\u{26741}\u7DA8\u{2615B}\u{260A4}\u{249B9}\u{2498B}\u{289FA}\u92E5\u73E2\u3EE9\u74B4\u{28B63}\u{2189F}\u3EE1\u{24AB3}\u6AD8\u73F3\u73FB\u3ED6\u{24A3E}\u{24A94}\u{217D9}\u{24A66}\u{203A7}\u{21424}\u{249E5}\u7448\u{24916}\u70A5\u{24976}\u9284\u73E6\u935F\u{204FE}\u9331\u{28ACE}\u{28A16}\u9386\u{28BE7}\u{255D5}\u4935\u{28A82}\u716B"], + ["97a1", "\u{24943}\u{20CFF}\u56A4\u{2061A}\u{20BEB}\u{20CB8}\u5502\u79C4\u{217FA}\u7DFE\u{216C2}\u{24A50}\u{21852}\u452E\u9401\u370A\u{28AC0}\u{249AD}\u59B0\u{218BF}\u{21883}\u{27484}\u5AA1\u36E2\u{23D5B}\u36B0\u925F\u5A79\u{28A81}\u{21862}\u9374\u3CCD\u{20AB4}\u4A96\u398A\u50F4\u3D69\u3D4C\u{2139C}\u7175\u42FB\u{28218}\u6E0F\u{290E4}\u44EB\u6D57\u{27E4F}\u7067\u6CAF\u3CD6\u{23FED}\u{23E2D}\u6E02\u6F0C\u3D6F\u{203F5}\u7551\u36BC\u34C8\u4680\u3EDA\u4871\u59C4\u926E\u493E\u8F41\u{28C1C}\u{26BC0}\u5812\u57C8\u36D6\u{21452}\u70FE\u{24362}\u{24A71}\u{22FE3}\u{212B0}\u{223BD}\u68B9\u6967\u{21398}\u{234E5}\u{27BF4}\u{236DF}\u{28A83}\u{237D6}\u{233FA}\u{24C9F}\u6A1A\u{236AD}\u{26CB7}\u843E\u44DF\u44CE"], + ["9840", "\u{26D26}\u{26D51}\u{26C82}\u{26FDE}\u6F17\u{27109}\u833D\u{2173A}\u83ED\u{26C80}\u{27053}\u{217DB}\u5989\u5A82\u{217B3}\u5A61\u5A71\u{21905}\u{241FC}\u372D\u59EF\u{2173C}\u36C7\u718E\u9390\u669A\u{242A5}\u5A6E\u5A2B\u{24293}\u6A2B\u{23EF9}\u{27736}\u{2445B}\u{242CA}\u711D\u{24259}\u{289E1}\u4FB0\u{26D28}\u5CC2\u{244CE}\u{27E4D}\u{243BD}\u6A0C\u{24256}\u{21304}\u70A6\u7133\u{243E9}\u3DA5\u6CDF\u{2F825}\u{24A4F}\u7E65\u59EB\u5D2F\u3DF3\u5F5C\u{24A5D}\u{217DF}\u7DA4\u8426"], + ["98a1", "\u5485\u{23AFA}\u{23300}\u{20214}\u577E\u{208D5}\u{20619}\u3FE5\u{21F9E}\u{2A2B6}\u7003\u{2915B}\u5D70\u738F\u7CD3\u{28A59}\u{29420}\u4FC8\u7FE7\u72CD\u7310\u{27AF4}\u7338\u7339\u{256F6}\u7341\u7348\u3EA9\u{27B18}\u906C\u71F5\u{248F2}\u73E1\u81F6\u3ECA\u770C\u3ED1\u6CA2\u56FD\u7419\u741E\u741F\u3EE2\u3EF0\u3EF4\u3EFA\u74D3\u3F0E\u3F53\u7542\u756D\u7572\u758D\u3F7C\u75C8\u75DC\u3FC0\u764D\u3FD7\u7674\u3FDC\u767A\u{24F5C}\u7188\u5623\u8980\u5869\u401D\u7743\u4039\u6761\u4045\u35DB\u7798\u406A\u406F\u5C5E\u77BE\u77CB\u58F2\u7818\u70B9\u781C\u40A8\u7839\u7847\u7851\u7866\u8448\u{25535}\u7933\u6803\u7932\u4103"], + ["9940", "\u4109\u7991\u7999\u8FBB\u7A06\u8FBC\u4167\u7A91\u41B2\u7ABC\u8279\u41C4\u7ACF\u7ADB\u41CF\u4E21\u7B62\u7B6C\u7B7B\u7C12\u7C1B\u4260\u427A\u7C7B\u7C9C\u428C\u7CB8\u4294\u7CED\u8F93\u70C0\u{20CCF}\u7DCF\u7DD4\u7DD0\u7DFD\u7FAE\u7FB4\u729F\u4397\u8020\u8025\u7B39\u802E\u8031\u8054\u3DCC\u57B4\u70A0\u80B7\u80E9\u43ED\u810C\u732A\u810E\u8112\u7560\u8114\u4401\u3B39\u8156\u8159\u815A"], + ["99a1", "\u4413\u583A\u817C\u8184\u4425\u8193\u442D\u81A5\u57EF\u81C1\u81E4\u8254\u448F\u82A6\u8276\u82CA\u82D8\u82FF\u44B0\u8357\u9669\u698A\u8405\u70F5\u8464\u60E3\u8488\u4504\u84BE\u84E1\u84F8\u8510\u8538\u8552\u453B\u856F\u8570\u85E0\u4577\u8672\u8692\u86B2\u86EF\u9645\u878B\u4606\u4617\u88AE\u88FF\u8924\u8947\u8991\u{27967}\u8A29\u8A38\u8A94\u8AB4\u8C51\u8CD4\u8CF2\u8D1C\u4798\u585F\u8DC3\u47ED\u4EEE\u8E3A\u55D8\u5754\u8E71\u55F5\u8EB0\u4837\u8ECE\u8EE2\u8EE4\u8EED\u8EF2\u8FB7\u8FC1\u8FCA\u8FCC\u9033\u99C4\u48AD\u98E0\u9213\u491E\u9228\u9258\u926B\u92B1\u92AE\u92BF"], + ["9a40", "\u92E3\u92EB\u92F3\u92F4\u92FD\u9343\u9384\u93AD\u4945\u4951\u9EBF\u9417\u5301\u941D\u942D\u943E\u496A\u9454\u9479\u952D\u95A2\u49A7\u95F4\u9633\u49E5\u67A0\u4A24\u9740\u4A35\u97B2\u97C2\u5654\u4AE4\u60E8\u98B9\u4B19\u98F1\u5844\u990E\u9919\u51B4\u991C\u9937\u9942\u995D\u9962\u4B70\u99C5\u4B9D\u9A3C\u9B0F\u7A83\u9B69\u9B81\u9BDD\u9BF1\u9BF4\u4C6D\u9C20\u376F\u{21BC2}\u9D49\u9C3A"], + ["9aa1", "\u9EFE\u5650\u9D93\u9DBD\u9DC0\u9DFC\u94F6\u8FB6\u9E7B\u9EAC\u9EB1\u9EBD\u9EC6\u94DC\u9EE2\u9EF1\u9EF8\u7AC8\u9F44\u{20094}\u{202B7}\u{203A0}\u691A\u94C3\u59AC\u{204D7}\u5840\u94C1\u37B9\u{205D5}\u{20615}\u{20676}\u{216BA}\u5757\u7173\u{20AC2}\u{20ACD}\u{20BBF}\u546A\u{2F83B}\u{20BCB}\u549E\u{20BFB}\u{20C3B}\u{20C53}\u{20C65}\u{20C7C}\u60E7\u{20C8D}\u567A\u{20CB5}\u{20CDD}\u{20CED}\u{20D6F}\u{20DB2}\u{20DC8}\u6955\u9C2F\u87A5\u{20E04}\u{20E0E}\u{20ED7}\u{20F90}\u{20F2D}\u{20E73}\u5C20\u{20FBC}\u5E0B\u{2105C}\u{2104F}\u{21076}\u671E\u{2107B}\u{21088}\u{21096}\u3647\u{210BF}\u{210D3}\u{2112F}\u{2113B}\u5364\u84AD\u{212E3}\u{21375}\u{21336}\u8B81\u{21577}\u{21619}\u{217C3}\u{217C7}\u4E78\u70BB\u{2182D}\u{2196A}"], + ["9b40", "\u{21A2D}\u{21A45}\u{21C2A}\u{21C70}\u{21CAC}\u{21EC8}\u62C3\u{21ED5}\u{21F15}\u7198\u6855\u{22045}\u69E9\u36C8\u{2227C}\u{223D7}\u{223FA}\u{2272A}\u{22871}\u{2294F}\u82FD\u{22967}\u{22993}\u{22AD5}\u89A5\u{22AE8}\u8FA0\u{22B0E}\u97B8\u{22B3F}\u9847\u9ABD\u{22C4C}"], + ["9b62", "\u{22C88}\u{22CB7}\u{25BE8}\u{22D08}\u{22D12}\u{22DB7}\u{22D95}\u{22E42}\u{22F74}\u{22FCC}\u{23033}\u{23066}\u{2331F}\u{233DE}\u5FB1\u6648\u66BF\u{27A79}\u{23567}\u{235F3}\u7201\u{249BA}\u77D7\u{2361A}\u{23716}\u7E87\u{20346}\u58B5\u670E"], + ["9ba1", "\u6918\u{23AA7}\u{27657}\u{25FE2}\u{23E11}\u{23EB9}\u{275FE}\u{2209A}\u48D0\u4AB8\u{24119}\u{28A9A}\u{242EE}\u{2430D}\u{2403B}\u{24334}\u{24396}\u{24A45}\u{205CA}\u51D2\u{20611}\u599F\u{21EA8}\u3BBE\u{23CFF}\u{24404}\u{244D6}\u5788\u{24674}\u399B\u{2472F}\u{285E8}\u{299C9}\u3762\u{221C3}\u8B5E\u{28B4E}\u99D6\u{24812}\u{248FB}\u{24A15}\u7209\u{24AC0}\u{20C78}\u5965\u{24EA5}\u{24F86}\u{20779}\u8EDA\u{2502C}\u528F\u573F\u7171\u{25299}\u{25419}\u{23F4A}\u{24AA7}\u55BC\u{25446}\u{2546E}\u{26B52}\u91D4\u3473\u{2553F}\u{27632}\u{2555E}\u4718\u{25562}\u{25566}\u{257C7}\u{2493F}\u{2585D}\u5066\u34FB\u{233CC}\u60DE\u{25903}\u477C\u{28948}\u{25AAE}\u{25B89}\u{25C06}\u{21D90}\u57A1\u7151\u6FB6\u{26102}\u{27C12}\u9056\u{261B2}\u{24F9A}\u8B62\u{26402}\u{2644A}"], + ["9c40", "\u5D5B\u{26BF7}\u8F36\u{26484}\u{2191C}\u8AEA\u{249F6}\u{26488}\u{23FEF}\u{26512}\u4BC0\u{265BF}\u{266B5}\u{2271B}\u9465\u{257E1}\u6195\u5A27\u{2F8CD}\u4FBB\u56B9\u{24521}\u{266FC}\u4E6A\u{24934}\u9656\u6D8F\u{26CBD}\u3618\u8977\u{26799}\u{2686E}\u{26411}\u{2685E}\u71DF\u{268C7}\u7B42\u{290C0}\u{20A11}\u{26926}\u9104\u{26939}\u7A45\u9DF0\u{269FA}\u9A26\u{26A2D}\u365F\u{26469}\u{20021}\u7983\u{26A34}\u{26B5B}\u5D2C\u{23519}\u83CF\u{26B9D}\u46D0\u{26CA4}\u753B\u8865\u{26DAE}\u58B6"], + ["9ca1", "\u371C\u{2258D}\u{2704B}\u{271CD}\u3C54\u{27280}\u{27285}\u9281\u{2217A}\u{2728B}\u9330\u{272E6}\u{249D0}\u6C39\u949F\u{27450}\u{20EF8}\u8827\u88F5\u{22926}\u{28473}\u{217B1}\u6EB8\u{24A2A}\u{21820}\u39A4\u36B9\u5C10\u79E3\u453F\u66B6\u{29CAD}\u{298A4}\u8943\u{277CC}\u{27858}\u56D6\u40DF\u{2160A}\u39A1\u{2372F}\u{280E8}\u{213C5}\u71AD\u8366\u{279DD}\u{291A8}\u5A67\u4CB7\u{270AF}\u{289AB}\u{279FD}\u{27A0A}\u{27B0B}\u{27D66}\u{2417A}\u7B43\u797E\u{28009}\u6FB5\u{2A2DF}\u6A03\u{28318}\u53A2\u{26E07}\u93BF\u6836\u975D\u{2816F}\u{28023}\u{269B5}\u{213ED}\u{2322F}\u{28048}\u5D85\u{28C30}\u{28083}\u5715\u9823\u{28949}\u5DAB\u{24988}\u65BE\u69D5\u53D2\u{24AA5}\u{23F81}\u3C11\u6736\u{28090}\u{280F4}\u{2812E}\u{21FA1}\u{2814F}"], + ["9d40", "\u{28189}\u{281AF}\u{2821A}\u{28306}\u{2832F}\u{2838A}\u35CA\u{28468}\u{286AA}\u48FA\u63E6\u{28956}\u7808\u9255\u{289B8}\u43F2\u{289E7}\u43DF\u{289E8}\u{28B46}\u{28BD4}\u59F8\u{28C09}\u8F0B\u{28FC5}\u{290EC}\u7B51\u{29110}\u{2913C}\u3DF7\u{2915E}\u{24ACA}\u8FD0\u728F\u568B\u{294E7}\u{295E9}\u{295B0}\u{295B8}\u{29732}\u{298D1}\u{29949}\u{2996A}\u{299C3}\u{29A28}\u{29B0E}\u{29D5A}\u{29D9B}\u7E9F\u{29EF8}\u{29F23}\u4CA4\u9547\u{2A293}\u71A2\u{2A2FF}\u4D91\u9012\u{2A5CB}\u4D9C\u{20C9C}\u8FBE\u55C1"], + ["9da1", "\u8FBA\u{224B0}\u8FB9\u{24A93}\u4509\u7E7F\u6F56\u6AB1\u4EEA\u34E4\u{28B2C}\u{2789D}\u373A\u8E80\u{217F5}\u{28024}\u{28B6C}\u{28B99}\u{27A3E}\u{266AF}\u3DEB\u{27655}\u{23CB7}\u{25635}\u{25956}\u4E9A\u{25E81}\u{26258}\u56BF\u{20E6D}\u8E0E\u5B6D\u{23E88}\u{24C9E}\u63DE\u62D0\u{217F6}\u{2187B}\u6530\u562D\u{25C4A}\u541A\u{25311}\u3DC6\u{29D98}\u4C7D\u5622\u561E\u7F49\u{25ED8}\u5975\u{23D40}\u8770\u4E1C\u{20FEA}\u{20D49}\u{236BA}\u8117\u9D5E\u8D18\u763B\u9C45\u764E\u77B9\u9345\u5432\u8148\u82F7\u5625\u8132\u8418\u80BD\u55EA\u7962\u5643\u5416\u{20E9D}\u35CE\u5605\u55F1\u66F1\u{282E2}\u362D\u7534\u55F0\u55BA\u5497\u5572\u{20C41}\u{20C96}\u5ED0\u{25148}\u{20E76}\u{22C62}"], + ["9e40", "\u{20EA2}\u9EAB\u7D5A\u55DE\u{21075}\u629D\u976D\u5494\u8CCD\u71F6\u9176\u63FC\u63B9\u63FE\u5569\u{22B43}\u9C72\u{22EB3}\u519A\u34DF\u{20DA7}\u51A7\u544D\u551E\u5513\u7666\u8E2D\u{2688A}\u75B1\u80B6\u8804\u8786\u88C7\u81B6\u841C\u{210C1}\u44EC\u7304\u{24706}\u5B90\u830B\u{26893}\u567B\u{226F4}\u{27D2F}\u{241A3}\u{27D73}\u{26ED0}\u{272B6}\u9170\u{211D9}\u9208\u{23CFC}\u{2A6A9}\u{20EAC}\u{20EF9}\u7266\u{21CA2}\u474E\u{24FC2}\u{27FF9}\u{20FEB}\u40FA"], + ["9ea1", "\u9C5D\u651F\u{22DA0}\u48F3\u{247E0}\u{29D7C}\u{20FEC}\u{20E0A}\u6062\u{275A3}\u{20FED}"], + ["9ead", "\u{26048}\u{21187}\u71A3\u7E8E\u9D50\u4E1A\u4E04\u3577\u5B0D\u6CB2\u5367\u36AC\u39DC\u537D\u36A5\u{24618}\u589A\u{24B6E}\u822D\u544B\u57AA\u{25A95}\u{20979}"], + ["9ec5", "\u3A52\u{22465}\u7374\u{29EAC}\u4D09\u9BED\u{23CFE}\u{29F30}\u4C5B\u{24FA9}\u{2959E}\u{29FDE}\u845C\u{23DB6}\u{272B2}\u{267B3}\u{23720}\u632E\u7D25\u{23EF7}\u{23E2C}\u3A2A\u9008\u52CC\u3E74\u367A\u45E9\u{2048E}\u7640\u5AF0\u{20EB6}\u787A\u{27F2E}\u58A7\u40BF\u567C\u9B8B\u5D74\u7654\u{2A434}\u9E85\u4CE1\u75F9\u37FB\u6119\u{230DA}\u{243F2}"], + ["9ef5", "\u565D\u{212A9}\u57A7\u{24963}\u{29E06}\u5234\u{270AE}\u35AD\u6C4A\u9D7C"], + ["9f40", "\u7C56\u9B39\u57DE\u{2176C}\u5C53\u64D3\u{294D0}\u{26335}\u{27164}\u86AD\u{20D28}\u{26D22}\u{24AE2}\u{20D71}"], + ["9f4f", "\u51FE\u{21F0F}\u5D8E\u9703\u{21DD1}\u9E81\u904C\u7B1F\u9B02\u5CD1\u7BA3\u6268\u6335\u9AFF\u7BCF\u9B2A\u7C7E\u9B2E\u7C42\u7C86\u9C15\u7BFC\u9B09\u9F17\u9C1B\u{2493E}\u9F5A\u5573\u5BC3\u4FFD\u9E98\u4FF2\u5260\u3E06\u52D1\u5767\u5056\u59B7\u5E12\u97C8\u9DAB\u8F5C\u5469\u97B4\u9940\u97BA\u532C\u6130"], + ["9fa1", "\u692C\u53DA\u9C0A\u9D02\u4C3B\u9641\u6980\u50A6\u7546\u{2176D}\u99DA\u5273"], + ["9fae", "\u9159\u9681\u915C"], + ["9fb2", "\u9151\u{28E97}\u637F\u{26D23}\u6ACA\u5611\u918E\u757A\u6285\u{203FC}\u734F\u7C70\u{25C21}\u{23CFD}"], + ["9fc1", "\u{24919}\u76D6\u9B9D\u4E2A\u{20CD4}\u83BE\u8842"], + ["9fc9", "\u5C4A\u69C0\u50ED\u577A\u521F\u5DF5\u4ECE\u6C31\u{201F2}\u4F39\u549C\u54DA\u529A\u8D82\u35FE\u5F0C\u35F3"], + ["9fdb", "\u6B52\u917C\u9FA5\u9B97\u982E\u98B4\u9ABA\u9EA8\u9E84\u717A\u7B14"], + ["9fe7", "\u6BFA\u8818\u7F78"], + ["9feb", "\u5620\u{2A64A}\u8E77\u9F53"], + ["9ff0", "\u8DD4\u8E4F\u9E1C\u8E01\u6282\u{2837D}\u8E28\u8E75\u7AD3\u{24A77}\u7A3E\u78D8\u6CEA\u8A67\u7607"], + ["a040", "\u{28A5A}\u9F26\u6CCE\u87D6\u75C3\u{2A2B2}\u7853\u{2F840}\u8D0C\u72E2\u7371\u8B2D\u7302\u74F1\u8CEB\u{24ABB}\u862F\u5FBA\u88A0\u44B7"], + ["a055", "\u{2183B}\u{26E05}"], + ["a058", "\u8A7E\u{2251B}"], + ["a05b", "\u60FD\u7667\u9AD7\u9D44\u936E\u9B8F\u87F5"], + ["a063", "\u880F\u8CF7\u732C\u9721\u9BB0\u35D6\u72B2\u4C07\u7C51\u994A\u{26159}\u6159\u4C04\u9E96\u617D"], + ["a073", "\u575F\u616F\u62A6\u6239\u62CE\u3A5C\u61E2\u53AA\u{233F5}\u6364\u6802\u35D2"], + ["a0a1", "\u5D57\u{28BC2}\u8FDA\u{28E39}"], + ["a0a6", "\u50D9\u{21D46}\u7906\u5332\u9638\u{20F3B}\u4065"], + ["a0ae", "\u77FE"], + ["a0b0", "\u7CC2\u{25F1A}\u7CDA\u7A2D\u8066\u8063\u7D4D\u7505\u74F2\u8994\u821A\u670C\u8062\u{27486}\u805B\u74F0\u8103\u7724\u8989\u{267CC}\u7553\u{26ED1}\u87A9\u87CE\u81C8\u878C\u8A49\u8CAD\u8B43\u772B\u74F8\u84DA\u3635\u69B2\u8DA6"], + ["a0d4", "\u89A9\u7468\u6DB9\u87C1\u{24011}\u74E7\u3DDB\u7176\u60A4\u619C\u3CD1\u7162\u6077"], + ["a0e2", "\u7F71\u{28B2D}\u7250\u60E9\u4B7E\u5220\u3C18\u{23CC7}\u{25ED7}\u{27656}\u{25531}\u{21944}\u{212FE}\u{29903}\u{26DDC}\u{270AD}\u5CC1\u{261AD}\u{28A0F}\u{23677}\u{200EE}\u{26846}\u{24F0E}\u4562\u5B1F\u{2634C}\u9F50\u9EA6\u{2626B}"], + ["a3c0", "\u2400", 31, "\u2421"], + ["c6a1", "\u2460", 9, "\u2474", 9, "\u2170", 9, "\u4E36\u4E3F\u4E85\u4EA0\u5182\u5196\u51AB\u52F9\u5338\u5369\u53B6\u590A\u5B80\u5DDB\u2F33\u5E7F\u5EF4\u5F50\u5F61\u6534\u65E0\u7592\u7676\u8FB5\u96B6\xA8\u02C6\u30FD\u30FE\u309D\u309E\u3003\u4EDD\u3005\u3006\u3007\u30FC\uFF3B\uFF3D\u273D\u3041", 23], + ["c740", "\u3059", 58, "\u30A1\u30A2\u30A3\u30A4"], + ["c7a1", "\u30A5", 81, "\u0410", 5, "\u0401\u0416", 4], + ["c840", "\u041B", 26, "\u0451\u0436", 25, "\u21E7\u21B8\u21B9\u31CF\u{200CC}\u4E5A\u{2008A}\u5202\u4491"], + ["c8a1", "\u9FB0\u5188\u9FB1\u{27607}"], + ["c8cd", "\uFFE2\uFFE4\uFF07\uFF02\u3231\u2116\u2121\u309B\u309C\u2E80\u2E84\u2E86\u2E87\u2E88\u2E8A\u2E8C\u2E8D\u2E95\u2E9C\u2E9D\u2EA5\u2EA7\u2EAA\u2EAC\u2EAE\u2EB6\u2EBC\u2EBE\u2EC6\u2ECA\u2ECC\u2ECD\u2ECF\u2ED6\u2ED7\u2EDE\u2EE3"], + ["c8f5", "\u0283\u0250\u025B\u0254\u0275\u0153\xF8\u014B\u028A\u026A"], + ["f9fe", "\uFFED"], + ["fa40", "\u{20547}\u92DB\u{205DF}\u{23FC5}\u854C\u42B5\u73EF\u51B5\u3649\u{24942}\u{289E4}\u9344\u{219DB}\u82EE\u{23CC8}\u783C\u6744\u62DF\u{24933}\u{289AA}\u{202A0}\u{26BB3}\u{21305}\u4FAB\u{224ED}\u5008\u{26D29}\u{27A84}\u{23600}\u{24AB1}\u{22513}\u5029\u{2037E}\u5FA4\u{20380}\u{20347}\u6EDB\u{2041F}\u507D\u5101\u347A\u510E\u986C\u3743\u8416\u{249A4}\u{20487}\u5160\u{233B4}\u516A\u{20BFF}\u{220FC}\u{202E5}\u{22530}\u{2058E}\u{23233}\u{21983}\u5B82\u877D\u{205B3}\u{23C99}\u51B2\u51B8"], + ["faa1", "\u9D34\u51C9\u51CF\u51D1\u3CDC\u51D3\u{24AA6}\u51B3\u51E2\u5342\u51ED\u83CD\u693E\u{2372D}\u5F7B\u520B\u5226\u523C\u52B5\u5257\u5294\u52B9\u52C5\u7C15\u8542\u52E0\u860D\u{26B13}\u5305\u{28ADE}\u5549\u6ED9\u{23F80}\u{20954}\u{23FEC}\u5333\u5344\u{20BE2}\u6CCB\u{21726}\u681B\u73D5\u604A\u3EAA\u38CC\u{216E8}\u71DD\u44A2\u536D\u5374\u{286AB}\u537E\u537F\u{21596}\u{21613}\u77E6\u5393\u{28A9B}\u53A0\u53AB\u53AE\u73A7\u{25772}\u3F59\u739C\u53C1\u53C5\u6C49\u4E49\u57FE\u53D9\u3AAB\u{20B8F}\u53E0\u{23FEB}\u{22DA3}\u53F6\u{20C77}\u5413\u7079\u552B\u6657\u6D5B\u546D\u{26B53}\u{20D74}\u555D\u548F\u54A4\u47A6\u{2170D}\u{20EDD}\u3DB4\u{20D4D}"], + ["fb40", "\u{289BC}\u{22698}\u5547\u4CED\u542F\u7417\u5586\u55A9\u5605\u{218D7}\u{2403A}\u4552\u{24435}\u66B3\u{210B4}\u5637\u66CD\u{2328A}\u66A4\u66AD\u564D\u564F\u78F1\u56F1\u9787\u53FE\u5700\u56EF\u56ED\u{28B66}\u3623\u{2124F}\u5746\u{241A5}\u6C6E\u708B\u5742\u36B1\u{26C7E}\u57E6\u{21416}\u5803\u{21454}\u{24363}\u5826\u{24BF5}\u585C\u58AA\u3561\u58E0\u58DC\u{2123C}\u58FB\u5BFF\u5743\u{2A150}\u{24278}\u93D3\u35A1\u591F\u68A6\u36C3\u6E59"], + ["fba1", "\u{2163E}\u5A24\u5553\u{21692}\u8505\u59C9\u{20D4E}\u{26C81}\u{26D2A}\u{217DC}\u59D9\u{217FB}\u{217B2}\u{26DA6}\u6D71\u{21828}\u{216D5}\u59F9\u{26E45}\u5AAB\u5A63\u36E6\u{249A9}\u5A77\u3708\u5A96\u7465\u5AD3\u{26FA1}\u{22554}\u3D85\u{21911}\u3732\u{216B8}\u5E83\u52D0\u5B76\u6588\u5B7C\u{27A0E}\u4004\u485D\u{20204}\u5BD5\u6160\u{21A34}\u{259CC}\u{205A5}\u5BF3\u5B9D\u4D10\u5C05\u{21B44}\u5C13\u73CE\u5C14\u{21CA5}\u{26B28}\u5C49\u48DD\u5C85\u5CE9\u5CEF\u5D8B\u{21DF9}\u{21E37}\u5D10\u5D18\u5D46\u{21EA4}\u5CBA\u5DD7\u82FC\u382D\u{24901}\u{22049}\u{22173}\u8287\u3836\u3BC2\u5E2E\u6A8A\u5E75\u5E7A\u{244BC}\u{20CD3}\u53A6\u4EB7\u5ED0\u53A8\u{21771}\u5E09\u5EF4\u{28482}"], + ["fc40", "\u5EF9\u5EFB\u38A0\u5EFC\u683E\u941B\u5F0D\u{201C1}\u{2F894}\u3ADE\u48AE\u{2133A}\u5F3A\u{26888}\u{223D0}\u5F58\u{22471}\u5F63\u97BD\u{26E6E}\u5F72\u9340\u{28A36}\u5FA7\u5DB6\u3D5F\u{25250}\u{21F6A}\u{270F8}\u{22668}\u91D6\u{2029E}\u{28A29}\u6031\u6685\u{21877}\u3963\u3DC7\u3639\u5790\u{227B4}\u7971\u3E40\u609E\u60A4\u60B3\u{24982}\u{2498F}\u{27A53}\u74A4\u50E1\u5AA0\u6164\u8424\u6142\u{2F8A6}\u{26ED2}\u6181\u51F4\u{20656}\u6187\u5BAA\u{23FB7}"], + ["fca1", "\u{2285F}\u61D3\u{28B9D}\u{2995D}\u61D0\u3932\u{22980}\u{228C1}\u6023\u615C\u651E\u638B\u{20118}\u62C5\u{21770}\u62D5\u{22E0D}\u636C\u{249DF}\u3A17\u6438\u63F8\u{2138E}\u{217FC}\u6490\u6F8A\u{22E36}\u9814\u{2408C}\u{2571D}\u64E1\u64E5\u947B\u3A66\u643A\u3A57\u654D\u6F16\u{24A28}\u{24A23}\u6585\u656D\u655F\u{2307E}\u65B5\u{24940}\u4B37\u65D1\u40D8\u{21829}\u65E0\u65E3\u5FDF\u{23400}\u6618\u{231F7}\u{231F8}\u6644\u{231A4}\u{231A5}\u664B\u{20E75}\u6667\u{251E6}\u6673\u6674\u{21E3D}\u{23231}\u{285F4}\u{231C8}\u{25313}\u77C5\u{228F7}\u99A4\u6702\u{2439C}\u{24A21}\u3B2B\u69FA\u{237C2}\u675E\u6767\u6762\u{241CD}\u{290ED}\u67D7\u44E9\u6822\u6E50\u923C\u6801\u{233E6}\u{26DA0}\u685D"], + ["fd40", "\u{2346F}\u69E1\u6A0B\u{28ADF}\u6973\u68C3\u{235CD}\u6901\u6900\u3D32\u3A01\u{2363C}\u3B80\u67AC\u6961\u{28A4A}\u42FC\u6936\u6998\u3BA1\u{203C9}\u8363\u5090\u69F9\u{23659}\u{2212A}\u6A45\u{23703}\u6A9D\u3BF3\u67B1\u6AC8\u{2919C}\u3C0D\u6B1D\u{20923}\u60DE\u6B35\u6B74\u{227CD}\u6EB5\u{23ADB}\u{203B5}\u{21958}\u3740\u5421\u{23B5A}\u6BE1\u{23EFC}\u6BDC\u6C37\u{2248B}\u{248F1}\u{26B51}\u6C5A\u8226\u6C79\u{23DBC}\u44C5\u{23DBD}\u{241A4}\u{2490C}\u{24900}"], + ["fda1", "\u{23CC9}\u36E5\u3CEB\u{20D32}\u9B83\u{231F9}\u{22491}\u7F8F\u6837\u{26D25}\u{26DA1}\u{26DEB}\u6D96\u6D5C\u6E7C\u6F04\u{2497F}\u{24085}\u{26E72}\u8533\u{26F74}\u51C7\u6C9C\u6E1D\u842E\u{28B21}\u6E2F\u{23E2F}\u7453\u{23F82}\u79CC\u6E4F\u5A91\u{2304B}\u6FF8\u370D\u6F9D\u{23E30}\u6EFA\u{21497}\u{2403D}\u4555\u93F0\u6F44\u6F5C\u3D4E\u6F74\u{29170}\u3D3B\u6F9F\u{24144}\u6FD3\u{24091}\u{24155}\u{24039}\u{23FF0}\u{23FB4}\u{2413F}\u51DF\u{24156}\u{24157}\u{24140}\u{261DD}\u704B\u707E\u70A7\u7081\u70CC\u70D5\u70D6\u70DF\u4104\u3DE8\u71B4\u7196\u{24277}\u712B\u7145\u5A88\u714A\u716E\u5C9C\u{24365}\u714F\u9362\u{242C1}\u712C\u{2445A}\u{24A27}\u{24A22}\u71BA\u{28BE8}\u70BD\u720E"], + ["fe40", "\u9442\u7215\u5911\u9443\u7224\u9341\u{25605}\u722E\u7240\u{24974}\u68BD\u7255\u7257\u3E55\u{23044}\u680D\u6F3D\u7282\u732A\u732B\u{24823}\u{2882B}\u48ED\u{28804}\u7328\u732E\u73CF\u73AA\u{20C3A}\u{26A2E}\u73C9\u7449\u{241E2}\u{216E7}\u{24A24}\u6623\u36C5\u{249B7}\u{2498D}\u{249FB}\u73F7\u7415\u6903\u{24A26}\u7439\u{205C3}\u3ED7\u745C\u{228AD}\u7460\u{28EB2}\u7447\u73E4\u7476\u83B9\u746C\u3730\u7474\u93F1\u6A2C\u7482\u4953\u{24A8C}"], + ["fea1", "\u{2415F}\u{24A79}\u{28B8F}\u5B46\u{28C03}\u{2189E}\u74C8\u{21988}\u750E\u74E9\u751E\u{28ED9}\u{21A4B}\u5BD7\u{28EAC}\u9385\u754D\u754A\u7567\u756E\u{24F82}\u3F04\u{24D13}\u758E\u745D\u759E\u75B4\u7602\u762C\u7651\u764F\u766F\u7676\u{263F5}\u7690\u81EF\u37F8\u{26911}\u{2690E}\u76A1\u76A5\u76B7\u76CC\u{26F9F}\u8462\u{2509D}\u{2517D}\u{21E1C}\u771E\u7726\u7740\u64AF\u{25220}\u7758\u{232AC}\u77AF\u{28964}\u{28968}\u{216C1}\u77F4\u7809\u{21376}\u{24A12}\u68CA\u78AF\u78C7\u78D3\u96A5\u792E\u{255E0}\u78D7\u7934\u78B1\u{2760C}\u8FB8\u8884\u{28B2B}\u{26083}\u{2261C}\u7986\u8900\u6902\u7980\u{25857}\u799D\u{27B39}\u793C\u79A9\u6E2A\u{27126}\u3EA8\u79C6\u{2910D}\u79D4"] + ]; + } +}); + +// node_modules/iconv-lite/encodings/dbcs-data.js +var require_dbcs_data = __commonJS({ + "node_modules/iconv-lite/encodings/dbcs-data.js"(exports2, module2) { + "use strict"; + module2.exports = { + // == Japanese/ShiftJIS ==================================================== + // All japanese encodings are based on JIS X set of standards: + // JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF. + // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. + // Has several variations in 1978, 1983, 1990 and 1997. + // JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead. + // JIS X 0213 - Extension and modern replacement of 0208 and 0212. Total chars: 11233. + // 2 planes, first is superset of 0208, second - revised 0212. + // Introduced in 2000, revised 2004. Some characters are in Unicode Plane 2 (0x2xxxx) + // Byte encodings are: + // * Shift_JIS: Compatible with 0201, uses not defined chars in top half as lead bytes for double-byte + // encoding of 0208. Lead byte ranges: 0x81-0x9F, 0xE0-0xEF; Trail byte ranges: 0x40-0x7E, 0x80-0x9E, 0x9F-0xFC. + // Windows CP932 is a superset of Shift_JIS. Some companies added more chars, notably KDDI. + // * EUC-JP: Up to 3 bytes per character. Used mostly on *nixes. + // 0x00-0x7F - lower part of 0201 + // 0x8E, 0xA1-0xDF - upper part of 0201 + // (0xA1-0xFE)x2 - 0208 plane (94x94). + // 0x8F, (0xA1-0xFE)x2 - 0212 plane (94x94). + // * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon. + // Used as-is in ISO2022 family. + // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, + // 0201-1976 Roman, 0208-1978, 0208-1983. + // * ISO2022-JP-1: Adds esc seq for 0212-1990. + // * ISO2022-JP-2: Adds esc seq for GB2313-1980, KSX1001-1992, ISO8859-1, ISO8859-7. + // * ISO2022-JP-3: Adds esc seq for 0201-1976 Kana set, 0213-2000 Planes 1, 2. + // * ISO2022-JP-2004: Adds 0213-2004 Plane 1. + // + // After JIS X 0213 appeared, Shift_JIS-2004, EUC-JISX0213 and ISO2022-JP-2004 followed, with just changing the planes. + // + // Overall, it seems that it's a mess :( http://www8.plala.or.jp/tkubota1/unicode-symbols-map2.html + "shiftjis": { + type: "_dbcs", + table: function() { + return require_shiftjis(); + }, + encodeAdd: { "\xA5": 92, "\u203E": 126 }, + encodeSkipVals: [{ from: 60736, to: 63808 }] + }, + "csshiftjis": "shiftjis", + "mskanji": "shiftjis", + "sjis": "shiftjis", + "windows31j": "shiftjis", + "ms31j": "shiftjis", + "xsjis": "shiftjis", + "windows932": "shiftjis", + "ms932": "shiftjis", + "932": "shiftjis", + "cp932": "shiftjis", + "eucjp": { + type: "_dbcs", + table: function() { + return require_eucjp(); + }, + encodeAdd: { "\xA5": 92, "\u203E": 126 } + }, + // TODO: KDDI extension to Shift_JIS + // TODO: IBM CCSID 942 = CP932, but F0-F9 custom chars and other char changes. + // TODO: IBM CCSID 943 = Shift_JIS = CP932 with original Shift_JIS lower 128 chars. + // == Chinese/GBK ========================================================== + // http://en.wikipedia.org/wiki/GBK + // We mostly implement W3C recommendation: https://www.w3.org/TR/encoding/#gbk-encoder + // Oldest GB2312 (1981, ~7600 chars) is a subset of CP936 + "gb2312": "cp936", + "gb231280": "cp936", + "gb23121980": "cp936", + "csgb2312": "cp936", + "csiso58gb231280": "cp936", + "euccn": "cp936", + // Microsoft's CP936 is a subset and approximation of GBK. + "windows936": "cp936", + "ms936": "cp936", + "936": "cp936", + "cp936": { + type: "_dbcs", + table: function() { + return require_cp936(); + } + }, + // GBK (~22000 chars) is an extension of CP936 that added user-mapped chars and some other. + "gbk": { + type: "_dbcs", + table: function() { + return require_cp936().concat(require_gbk_added()); + } + }, + "xgbk": "gbk", + "isoir58": "gbk", + // GB18030 is an algorithmic extension of GBK. + // Main source: https://www.w3.org/TR/encoding/#gbk-encoder + // http://icu-project.org/docs/papers/gb18030.html + // http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml + // http://www.khngai.com/chinese/charmap/tblgbk.php?page=0 + "gb18030": { + type: "_dbcs", + table: function() { + return require_cp936().concat(require_gbk_added()); + }, + gb18030: function() { + return require_gb18030_ranges(); + }, + encodeSkipVals: [128], + encodeAdd: { "\u20AC": 41699 } + }, + "chinese": "gb18030", + // == Korean =============================================================== + // EUC-KR, KS_C_5601 and KS X 1001 are exactly the same. + "windows949": "cp949", + "ms949": "cp949", + "949": "cp949", + "cp949": { + type: "_dbcs", + table: function() { + return require_cp949(); + } + }, + "cseuckr": "cp949", + "csksc56011987": "cp949", + "euckr": "cp949", + "isoir149": "cp949", + "korean": "cp949", + "ksc56011987": "cp949", + "ksc56011989": "cp949", + "ksc5601": "cp949", + // == Big5/Taiwan/Hong Kong ================================================ + // There are lots of tables for Big5 and cp950. Please see the following links for history: + // http://moztw.org/docs/big5/ http://www.haible.de/bruno/charsets/conversion-tables/Big5.html + // Variations, in roughly number of defined chars: + // * Windows CP 950: Microsoft variant of Big5. Canonical: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT + // * Windows CP 951: Microsoft variant of Big5-HKSCS-2001. Seems to be never public. http://me.abelcheung.org/articles/research/what-is-cp951/ + // * Big5-2003 (Taiwan standard) almost superset of cp950. + // * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers. + // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. + // many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years. + // Plus, it has 4 combining sequences. + // Seems that Mozilla refused to support it for 10 yrs. https://bugzilla.mozilla.org/show_bug.cgi?id=162431 https://bugzilla.mozilla.org/show_bug.cgi?id=310299 + // because big5-hkscs is the only encoding to include astral characters in non-algorithmic way. + // Implementations are not consistent within browsers; sometimes labeled as just big5. + // MS Internet Explorer switches from big5 to big5-hkscs when a patch applied. + // Great discussion & recap of what's going on https://bugzilla.mozilla.org/show_bug.cgi?id=912470#c31 + // In the encoder, it might make sense to support encoding old PUA mappings to Big5 bytes seq-s. + // Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt + // http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt + // + // Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder + // Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong. + "windows950": "cp950", + "ms950": "cp950", + "950": "cp950", + "cp950": { + type: "_dbcs", + table: function() { + return require_cp950(); + } + }, + // Big5 has many variations and is an extension of cp950. We use Encoding Standard's as a consensus. + "big5": "big5hkscs", + "big5hkscs": { + type: "_dbcs", + table: function() { + return require_cp950().concat(require_big5_added()); + }, + encodeSkipVals: [41676] + }, + "cnbig5": "big5hkscs", + "csbig5": "big5hkscs", + "xxbig5": "big5hkscs" + }; + } +}); + +// node_modules/iconv-lite/encodings/index.js +var require_encodings = __commonJS({ + "node_modules/iconv-lite/encodings/index.js"(exports2, module2) { + "use strict"; + var modules = [ + require_internal(), + require_utf16(), + require_utf7(), + require_sbcs_codec(), + require_sbcs_data(), + require_sbcs_data_generated(), + require_dbcs_codec(), + require_dbcs_data() + ]; + for (i = 0; i < modules.length; i++) { + module2 = modules[i]; + for (enc in module2) + if (Object.prototype.hasOwnProperty.call(module2, enc)) + exports2[enc] = module2[enc]; + } + var module2; + var enc; + var i; + } +}); + +// node_modules/iconv-lite/lib/streams.js +var require_streams = __commonJS({ + "node_modules/iconv-lite/lib/streams.js"(exports2, module2) { + "use strict"; + var Buffer3 = require("buffer").Buffer; + var Transform = require("stream").Transform; + module2.exports = function(iconv) { + iconv.encodeStream = function encodeStream(encoding, options) { + return new IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options); + }; + iconv.decodeStream = function decodeStream(encoding, options) { + return new IconvLiteDecoderStream(iconv.getDecoder(encoding, options), options); + }; + iconv.supportsStreams = true; + iconv.IconvLiteEncoderStream = IconvLiteEncoderStream; + iconv.IconvLiteDecoderStream = IconvLiteDecoderStream; + iconv._collect = IconvLiteDecoderStream.prototype.collect; + }; + function IconvLiteEncoderStream(conv, options) { + this.conv = conv; + options = options || {}; + options.decodeStrings = false; + Transform.call(this, options); + } + IconvLiteEncoderStream.prototype = Object.create(Transform.prototype, { + constructor: { value: IconvLiteEncoderStream } + }); + IconvLiteEncoderStream.prototype._transform = function(chunk, encoding, done) { + if (typeof chunk != "string") + return done(new Error("Iconv encoding stream needs strings as its input.")); + try { + var res = this.conv.write(chunk); + if (res && res.length) this.push(res); + done(); + } catch (e) { + done(e); + } + }; + IconvLiteEncoderStream.prototype._flush = function(done) { + try { + var res = this.conv.end(); + if (res && res.length) this.push(res); + done(); + } catch (e) { + done(e); + } + }; + IconvLiteEncoderStream.prototype.collect = function(cb) { + var chunks = []; + this.on("error", cb); + this.on("data", function(chunk) { + chunks.push(chunk); + }); + this.on("end", function() { + cb(null, Buffer3.concat(chunks)); + }); + return this; + }; + function IconvLiteDecoderStream(conv, options) { + this.conv = conv; + options = options || {}; + options.encoding = this.encoding = "utf8"; + Transform.call(this, options); + } + IconvLiteDecoderStream.prototype = Object.create(Transform.prototype, { + constructor: { value: IconvLiteDecoderStream } + }); + IconvLiteDecoderStream.prototype._transform = function(chunk, encoding, done) { + if (!Buffer3.isBuffer(chunk)) + return done(new Error("Iconv decoding stream needs buffers as its input.")); + try { + var res = this.conv.write(chunk); + if (res && res.length) this.push(res, this.encoding); + done(); + } catch (e) { + done(e); + } + }; + IconvLiteDecoderStream.prototype._flush = function(done) { + try { + var res = this.conv.end(); + if (res && res.length) this.push(res, this.encoding); + done(); + } catch (e) { + done(e); + } + }; + IconvLiteDecoderStream.prototype.collect = function(cb) { + var res = ""; + this.on("error", cb); + this.on("data", function(chunk) { + res += chunk; + }); + this.on("end", function() { + cb(null, res); + }); + return this; + }; + } +}); + +// node_modules/iconv-lite/lib/extend-node.js +var require_extend_node = __commonJS({ + "node_modules/iconv-lite/lib/extend-node.js"(exports2, module2) { + "use strict"; + var Buffer3 = require("buffer").Buffer; + module2.exports = function(iconv) { + var original = void 0; + iconv.supportsNodeEncodingsExtension = !(Buffer3.from || new Buffer3(0) instanceof Uint8Array); + iconv.extendNodeEncodings = function extendNodeEncodings() { + if (original) return; + original = {}; + if (!iconv.supportsNodeEncodingsExtension) { + console.error("ACTION NEEDED: require('iconv-lite').extendNodeEncodings() is not supported in your version of Node"); + console.error("See more info at https://github.com/ashtuchkin/iconv-lite/wiki/Node-v4-compatibility"); + return; + } + var nodeNativeEncodings = { + "hex": true, + "utf8": true, + "utf-8": true, + "ascii": true, + "binary": true, + "base64": true, + "ucs2": true, + "ucs-2": true, + "utf16le": true, + "utf-16le": true + }; + Buffer3.isNativeEncoding = function(enc) { + return enc && nodeNativeEncodings[enc.toLowerCase()]; + }; + var SlowBuffer = require("buffer").SlowBuffer; + original.SlowBufferToString = SlowBuffer.prototype.toString; + SlowBuffer.prototype.toString = function(encoding, start, end) { + encoding = String(encoding || "utf8").toLowerCase(); + if (Buffer3.isNativeEncoding(encoding)) + return original.SlowBufferToString.call(this, encoding, start, end); + if (typeof start == "undefined") start = 0; + if (typeof end == "undefined") end = this.length; + return iconv.decode(this.slice(start, end), encoding); + }; + original.SlowBufferWrite = SlowBuffer.prototype.write; + SlowBuffer.prototype.write = function(string, offset, length, encoding) { + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = void 0; + } + } else { + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + encoding = String(encoding || "utf8").toLowerCase(); + if (Buffer3.isNativeEncoding(encoding)) + return original.SlowBufferWrite.call(this, string, offset, length, encoding); + if (string.length > 0 && (length < 0 || offset < 0)) + throw new RangeError("attempt to write beyond buffer bounds"); + var buf = iconv.encode(string, encoding); + if (buf.length < length) length = buf.length; + buf.copy(this, offset, 0, length); + return length; + }; + original.BufferIsEncoding = Buffer3.isEncoding; + Buffer3.isEncoding = function(encoding) { + return Buffer3.isNativeEncoding(encoding) || iconv.encodingExists(encoding); + }; + original.BufferByteLength = Buffer3.byteLength; + Buffer3.byteLength = SlowBuffer.byteLength = function(str, encoding) { + encoding = String(encoding || "utf8").toLowerCase(); + if (Buffer3.isNativeEncoding(encoding)) + return original.BufferByteLength.call(this, str, encoding); + return iconv.encode(str, encoding).length; + }; + original.BufferToString = Buffer3.prototype.toString; + Buffer3.prototype.toString = function(encoding, start, end) { + encoding = String(encoding || "utf8").toLowerCase(); + if (Buffer3.isNativeEncoding(encoding)) + return original.BufferToString.call(this, encoding, start, end); + if (typeof start == "undefined") start = 0; + if (typeof end == "undefined") end = this.length; + return iconv.decode(this.slice(start, end), encoding); + }; + original.BufferWrite = Buffer3.prototype.write; + Buffer3.prototype.write = function(string, offset, length, encoding) { + var _offset = offset, _length = length, _encoding = encoding; + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = void 0; + } + } else { + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } + encoding = String(encoding || "utf8").toLowerCase(); + if (Buffer3.isNativeEncoding(encoding)) + return original.BufferWrite.call(this, string, _offset, _length, _encoding); + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + if (string.length > 0 && (length < 0 || offset < 0)) + throw new RangeError("attempt to write beyond buffer bounds"); + var buf = iconv.encode(string, encoding); + if (buf.length < length) length = buf.length; + buf.copy(this, offset, 0, length); + return length; + }; + if (iconv.supportsStreams) { + var Readable = require("stream").Readable; + original.ReadableSetEncoding = Readable.prototype.setEncoding; + Readable.prototype.setEncoding = function setEncoding(enc, options) { + this._readableState.decoder = iconv.getDecoder(enc, options); + this._readableState.encoding = enc; + }; + Readable.prototype.collect = iconv._collect; + } + }; + iconv.undoExtendNodeEncodings = function undoExtendNodeEncodings() { + if (!iconv.supportsNodeEncodingsExtension) + return; + if (!original) + throw new Error("require('iconv-lite').undoExtendNodeEncodings(): Nothing to undo; extendNodeEncodings() is not called."); + delete Buffer3.isNativeEncoding; + var SlowBuffer = require("buffer").SlowBuffer; + SlowBuffer.prototype.toString = original.SlowBufferToString; + SlowBuffer.prototype.write = original.SlowBufferWrite; + Buffer3.isEncoding = original.BufferIsEncoding; + Buffer3.byteLength = original.BufferByteLength; + Buffer3.prototype.toString = original.BufferToString; + Buffer3.prototype.write = original.BufferWrite; + if (iconv.supportsStreams) { + var Readable = require("stream").Readable; + Readable.prototype.setEncoding = original.ReadableSetEncoding; + delete Readable.prototype.collect; + } + original = void 0; + }; + }; + } +}); + +// node_modules/iconv-lite/lib/index.js +var require_lib = __commonJS({ + "node_modules/iconv-lite/lib/index.js"(exports2, module2) { + "use strict"; + var Buffer3 = require_safer().Buffer; + var bomHandling = require_bom_handling(); + var iconv = module2.exports; + iconv.encodings = null; + iconv.defaultCharUnicode = "\uFFFD"; + iconv.defaultCharSingleByte = "?"; + iconv.encode = function encode(str, encoding, options) { + str = "" + (str || ""); + var encoder = iconv.getEncoder(encoding, options); + var res = encoder.write(str); + var trail = encoder.end(); + return trail && trail.length > 0 ? Buffer3.concat([res, trail]) : res; + }; + iconv.decode = function decode(buf, encoding, options) { + if (typeof buf === "string") { + if (!iconv.skipDecodeWarning) { + console.error("Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding"); + iconv.skipDecodeWarning = true; + } + buf = Buffer3.from("" + (buf || ""), "binary"); + } + var decoder = iconv.getDecoder(encoding, options); + var res = decoder.write(buf); + var trail = decoder.end(); + return trail ? res + trail : res; + }; + iconv.encodingExists = function encodingExists(enc) { + try { + iconv.getCodec(enc); + return true; + } catch (e) { + return false; + } + }; + iconv.toEncoding = iconv.encode; + iconv.fromEncoding = iconv.decode; + iconv._codecDataCache = {}; + iconv.getCodec = function getCodec(encoding) { + if (!iconv.encodings) + iconv.encodings = require_encodings(); + var enc = iconv._canonicalizeEncoding(encoding); + var codecOptions = {}; + while (true) { + var codec = iconv._codecDataCache[enc]; + if (codec) + return codec; + var codecDef = iconv.encodings[enc]; + switch (typeof codecDef) { + case "string": + enc = codecDef; + break; + case "object": + for (var key in codecDef) + codecOptions[key] = codecDef[key]; + if (!codecOptions.encodingName) + codecOptions.encodingName = enc; + enc = codecDef.type; + break; + case "function": + if (!codecOptions.encodingName) + codecOptions.encodingName = enc; + codec = new codecDef(codecOptions, iconv); + iconv._codecDataCache[codecOptions.encodingName] = codec; + return codec; + default: + throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '" + enc + "')"); + } + } + }; + iconv._canonicalizeEncoding = function(encoding) { + return ("" + encoding).toLowerCase().replace(/:\d{4}$|[^0-9a-z]/g, ""); + }; + iconv.getEncoder = function getEncoder(encoding, options) { + var codec = iconv.getCodec(encoding), encoder = new codec.encoder(options, codec); + if (codec.bomAware && options && options.addBOM) + encoder = new bomHandling.PrependBOM(encoder, options); + return encoder; + }; + iconv.getDecoder = function getDecoder(encoding, options) { + var codec = iconv.getCodec(encoding), decoder = new codec.decoder(options, codec); + if (codec.bomAware && !(options && options.stripBOM === false)) + decoder = new bomHandling.StripBOM(decoder, options); + return decoder; + }; + var nodeVer = typeof process !== "undefined" && process.versions && process.versions.node; + if (nodeVer) { + nodeVerArr = nodeVer.split(".").map(Number); + if (nodeVerArr[0] > 0 || nodeVerArr[1] >= 10) { + require_streams()(iconv); + } + require_extend_node()(iconv); + } + var nodeVerArr; + if (false) { + console.error("iconv-lite warning: javascript files use encoding different from utf-8. See https://github.com/ashtuchkin/iconv-lite/wiki/Javascript-source-file-encodings for more info."); + } + } +}); + +// node_modules/unpipe/index.js +var require_unpipe = __commonJS({ + "node_modules/unpipe/index.js"(exports2, module2) { + "use strict"; + module2.exports = unpipe; + function hasPipeDataListeners(stream) { + var listeners = stream.listeners("data"); + for (var i = 0; i < listeners.length; i++) { + if (listeners[i].name === "ondata") { + return true; + } + } + return false; + } + function unpipe(stream) { + if (!stream) { + throw new TypeError("argument stream is required"); + } + if (typeof stream.unpipe === "function") { + stream.unpipe(); + return; + } + if (!hasPipeDataListeners(stream)) { + return; + } + var listener; + var listeners = stream.listeners("close"); + for (var i = 0; i < listeners.length; i++) { + listener = listeners[i]; + if (listener.name !== "cleanup" && listener.name !== "onclose") { + continue; + } + listener.call(stream); + } + } + } +}); + +// node_modules/raw-body/index.js +var require_raw_body = __commonJS({ + "node_modules/raw-body/index.js"(exports2, module2) { + "use strict"; + var asyncHooks = tryRequireAsyncHooks(); + var bytes = require_bytes(); + var createError = require_http_errors(); + var iconv = require_lib(); + var unpipe = require_unpipe(); + module2.exports = getRawBody; + var ICONV_ENCODING_MESSAGE_REGEXP = /^Encoding not recognized: /; + function getDecoder(encoding) { + if (!encoding) return null; + try { + return iconv.getDecoder(encoding); + } catch (e) { + if (!ICONV_ENCODING_MESSAGE_REGEXP.test(e.message)) throw e; + throw createError(415, "specified encoding unsupported", { + encoding, + type: "encoding.unsupported" + }); + } + } + function getRawBody(stream, options, callback) { + var done = callback; + var opts = options || {}; + if (stream === void 0) { + throw new TypeError("argument stream is required"); + } else if (typeof stream !== "object" || stream === null || typeof stream.on !== "function") { + throw new TypeError("argument stream must be a stream"); + } + if (options === true || typeof options === "string") { + opts = { + encoding: options + }; + } + if (typeof options === "function") { + done = options; + opts = {}; + } + if (done !== void 0 && typeof done !== "function") { + throw new TypeError("argument callback must be a function"); + } + if (!done && !global.Promise) { + throw new TypeError("argument callback is required"); + } + var encoding = opts.encoding !== true ? opts.encoding : "utf-8"; + var limit = bytes.parse(opts.limit); + var length = opts.length != null && !isNaN(opts.length) ? parseInt(opts.length, 10) : null; + if (done) { + return readStream(stream, encoding, length, limit, wrap(done)); + } + return new Promise(function executor(resolve, reject) { + readStream(stream, encoding, length, limit, function onRead(err, buf) { + if (err) return reject(err); + resolve(buf); + }); + }); + } + function halt(stream) { + unpipe(stream); + if (typeof stream.pause === "function") { + stream.pause(); + } + } + function readStream(stream, encoding, length, limit, callback) { + var complete = false; + var sync = true; + if (limit !== null && length !== null && length > limit) { + return done(createError(413, "request entity too large", { + expected: length, + length, + limit, + type: "entity.too.large" + })); + } + var state = stream._readableState; + if (stream._decoder || state && (state.encoding || state.decoder)) { + return done(createError(500, "stream encoding should not be set", { + type: "stream.encoding.set" + })); + } + if (typeof stream.readable !== "undefined" && !stream.readable) { + return done(createError(500, "stream is not readable", { + type: "stream.not.readable" + })); + } + var received = 0; + var decoder; + try { + decoder = getDecoder(encoding); + } catch (err) { + return done(err); + } + var buffer = decoder ? "" : []; + stream.on("aborted", onAborted); + stream.on("close", cleanup); + stream.on("data", onData); + stream.on("end", onEnd); + stream.on("error", onEnd); + sync = false; + function done() { + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + complete = true; + if (sync) { + process.nextTick(invokeCallback); + } else { + invokeCallback(); + } + function invokeCallback() { + cleanup(); + if (args[0]) { + halt(stream); + } + callback.apply(null, args); + } + } + function onAborted() { + if (complete) return; + done(createError(400, "request aborted", { + code: "ECONNABORTED", + expected: length, + length, + received, + type: "request.aborted" + })); + } + function onData(chunk) { + if (complete) return; + received += chunk.length; + if (limit !== null && received > limit) { + done(createError(413, "request entity too large", { + limit, + received, + type: "entity.too.large" + })); + } else if (decoder) { + buffer += decoder.write(chunk); + } else { + buffer.push(chunk); + } + } + function onEnd(err) { + if (complete) return; + if (err) return done(err); + if (length !== null && received !== length) { + done(createError(400, "request size did not match content length", { + expected: length, + length, + received, + type: "request.size.invalid" + })); + } else { + var string = decoder ? buffer + (decoder.end() || "") : Buffer.concat(buffer); + done(null, string); + } + } + function cleanup() { + buffer = null; + stream.removeListener("aborted", onAborted); + stream.removeListener("data", onData); + stream.removeListener("end", onEnd); + stream.removeListener("error", onEnd); + stream.removeListener("close", cleanup); + } + } + function tryRequireAsyncHooks() { + try { + return require("async_hooks"); + } catch (e) { + return {}; + } + } + function wrap(fn) { + var res; + if (asyncHooks.AsyncResource) { + res = new asyncHooks.AsyncResource(fn.name || "bound-anonymous-fn"); + } + if (!res || !res.runInAsyncScope) { + return fn; + } + return res.runInAsyncScope.bind(res, fn, null); + } + } +}); + +// node_modules/ee-first/index.js +var require_ee_first = __commonJS({ + "node_modules/ee-first/index.js"(exports2, module2) { + "use strict"; + module2.exports = first; + function first(stuff, done) { + if (!Array.isArray(stuff)) + throw new TypeError("arg must be an array of [ee, events...] arrays"); + var cleanups = []; + for (var i = 0; i < stuff.length; i++) { + var arr = stuff[i]; + if (!Array.isArray(arr) || arr.length < 2) + throw new TypeError("each array member must be [ee, events...]"); + var ee = arr[0]; + for (var j = 1; j < arr.length; j++) { + var event = arr[j]; + var fn = listener(event, callback); + ee.on(event, fn); + cleanups.push({ + ee, + event, + fn + }); + } + } + function callback() { + cleanup(); + done.apply(null, arguments); + } + function cleanup() { + var x; + for (var i2 = 0; i2 < cleanups.length; i2++) { + x = cleanups[i2]; + x.ee.removeListener(x.event, x.fn); + } + } + function thunk(fn2) { + done = fn2; + } + thunk.cancel = cleanup; + return thunk; + } + function listener(event, done) { + return function onevent(arg1) { + var args = new Array(arguments.length); + var ee = this; + var err = event === "error" ? arg1 : null; + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + done(err, ee, event, args); + }; + } + } +}); + +// node_modules/on-finished/index.js +var require_on_finished = __commonJS({ + "node_modules/on-finished/index.js"(exports2, module2) { + "use strict"; + module2.exports = onFinished; + module2.exports.isFinished = isFinished; + var asyncHooks = tryRequireAsyncHooks(); + var first = require_ee_first(); + var defer = typeof setImmediate === "function" ? setImmediate : function(fn) { + process.nextTick(fn.bind.apply(fn, arguments)); + }; + function onFinished(msg, listener) { + if (isFinished(msg) !== false) { + defer(listener, null, msg); + return msg; + } + attachListener(msg, wrap(listener)); + return msg; + } + function isFinished(msg) { + var socket = msg.socket; + if (typeof msg.finished === "boolean") { + return Boolean(msg.finished || socket && !socket.writable); + } + if (typeof msg.complete === "boolean") { + return Boolean(msg.upgrade || !socket || !socket.readable || msg.complete && !msg.readable); + } + return void 0; + } + function attachFinishedListener(msg, callback) { + var eeMsg; + var eeSocket; + var finished = false; + function onFinish(error) { + eeMsg.cancel(); + eeSocket.cancel(); + finished = true; + callback(error); + } + eeMsg = eeSocket = first([[msg, "end", "finish"]], onFinish); + function onSocket(socket) { + msg.removeListener("socket", onSocket); + if (finished) return; + if (eeMsg !== eeSocket) return; + eeSocket = first([[socket, "error", "close"]], onFinish); + } + if (msg.socket) { + onSocket(msg.socket); + return; + } + msg.on("socket", onSocket); + if (msg.socket === void 0) { + patchAssignSocket(msg, onSocket); + } + } + function attachListener(msg, listener) { + var attached = msg.__onFinished; + if (!attached || !attached.queue) { + attached = msg.__onFinished = createListener(msg); + attachFinishedListener(msg, attached); + } + attached.queue.push(listener); + } + function createListener(msg) { + function listener(err) { + if (msg.__onFinished === listener) msg.__onFinished = null; + if (!listener.queue) return; + var queue = listener.queue; + listener.queue = null; + for (var i = 0; i < queue.length; i++) { + queue[i](err, msg); + } + } + listener.queue = []; + return listener; + } + function patchAssignSocket(res, callback) { + var assignSocket = res.assignSocket; + if (typeof assignSocket !== "function") return; + res.assignSocket = function _assignSocket(socket) { + assignSocket.call(this, socket); + callback(socket); + }; + } + function tryRequireAsyncHooks() { + try { + return require("async_hooks"); + } catch (e) { + return {}; + } + } + function wrap(fn) { + var res; + if (asyncHooks.AsyncResource) { + res = new asyncHooks.AsyncResource(fn.name || "bound-anonymous-fn"); + } + if (!res || !res.runInAsyncScope) { + return fn; + } + return res.runInAsyncScope.bind(res, fn, null); + } + } +}); + +// node_modules/body-parser/lib/read.js +var require_read = __commonJS({ + "node_modules/body-parser/lib/read.js"(exports2, module2) { + "use strict"; + var createError = require_http_errors(); + var destroy = require_destroy(); + var getBody = require_raw_body(); + var iconv = require_lib(); + var onFinished = require_on_finished(); + var unpipe = require_unpipe(); + var zlib = require("zlib"); + module2.exports = read; + function read(req, res, next, parse4, debug, options) { + var length; + var opts = options; + var stream; + req._body = true; + var encoding = opts.encoding !== null ? opts.encoding : null; + var verify = opts.verify; + try { + stream = contentstream(req, debug, opts.inflate); + length = stream.length; + stream.length = void 0; + } catch (err) { + return next(err); + } + opts.length = length; + opts.encoding = verify ? null : encoding; + if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { + return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { + charset: encoding.toLowerCase(), + type: "charset.unsupported" + })); + } + debug("read body"); + getBody(stream, opts, function(error, body) { + if (error) { + var _error; + if (error.type === "encoding.unsupported") { + _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { + charset: encoding.toLowerCase(), + type: "charset.unsupported" + }); + } else { + _error = createError(400, error); + } + if (stream !== req) { + unpipe(req); + destroy(stream, true); + } + dump(req, function onfinished() { + next(createError(400, _error)); + }); + return; + } + if (verify) { + try { + debug("verify body"); + verify(req, res, body, encoding); + } catch (err) { + next(createError(403, err, { + body, + type: err.type || "entity.verify.failed" + })); + return; + } + } + var str = body; + try { + debug("parse body"); + str = typeof body !== "string" && encoding !== null ? iconv.decode(body, encoding) : body; + req.body = parse4(str); + } catch (err) { + next(createError(400, err, { + body: str, + type: err.type || "entity.parse.failed" + })); + return; + } + next(); + }); + } + function contentstream(req, debug, inflate) { + var encoding = (req.headers["content-encoding"] || "identity").toLowerCase(); + var length = req.headers["content-length"]; + var stream; + debug('content-encoding "%s"', encoding); + if (inflate === false && encoding !== "identity") { + throw createError(415, "content encoding unsupported", { + encoding, + type: "encoding.unsupported" + }); + } + switch (encoding) { + case "deflate": + stream = zlib.createInflate(); + debug("inflate body"); + req.pipe(stream); + break; + case "gzip": + stream = zlib.createGunzip(); + debug("gunzip body"); + req.pipe(stream); + break; + case "identity": + stream = req; + stream.length = length; + break; + default: + throw createError(415, 'unsupported content encoding "' + encoding + '"', { + encoding, + type: "encoding.unsupported" + }); + } + return stream; + } + function dump(req, callback) { + if (onFinished.isFinished(req)) { + callback(null); + } else { + onFinished(req, callback); + req.resume(); + } + } + } +}); + +// node_modules/media-typer/index.js +var require_media_typer = __commonJS({ + "node_modules/media-typer/index.js"(exports2) { + var paramRegExp = /; *([!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) *= *("(?:[ !\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u0020-\u007e])*"|[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) */g; + var textRegExp = /^[\u0020-\u007e\u0080-\u00ff]+$/; + var tokenRegExp = /^[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+$/; + var qescRegExp = /\\([\u0000-\u007f])/g; + var quoteRegExp = /([\\"])/g; + var subtypeNameRegExp = /^[A-Za-z0-9][A-Za-z0-9!#$&^_.-]{0,126}$/; + var typeNameRegExp = /^[A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126}$/; + var typeRegExp = /^ *([A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126})\/([A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}) *$/; + exports2.format = format; + exports2.parse = parse4; + function format(obj) { + if (!obj || typeof obj !== "object") { + throw new TypeError("argument obj is required"); + } + var parameters = obj.parameters; + var subtype = obj.subtype; + var suffix = obj.suffix; + var type = obj.type; + if (!type || !typeNameRegExp.test(type)) { + throw new TypeError("invalid type"); + } + if (!subtype || !subtypeNameRegExp.test(subtype)) { + throw new TypeError("invalid subtype"); + } + var string = type + "/" + subtype; + if (suffix) { + if (!typeNameRegExp.test(suffix)) { + throw new TypeError("invalid suffix"); + } + string += "+" + suffix; + } + if (parameters && typeof parameters === "object") { + var param; + var params = Object.keys(parameters).sort(); + for (var i = 0; i < params.length; i++) { + param = params[i]; + if (!tokenRegExp.test(param)) { + throw new TypeError("invalid parameter name"); + } + string += "; " + param + "=" + qstring(parameters[param]); + } + } + return string; + } + function parse4(string) { + if (!string) { + throw new TypeError("argument string is required"); + } + if (typeof string === "object") { + string = getcontenttype(string); + } + if (typeof string !== "string") { + throw new TypeError("argument string is required to be a string"); + } + var index = string.indexOf(";"); + var type = index !== -1 ? string.substr(0, index) : string; + var key; + var match; + var obj = splitType(type); + var params = {}; + var value; + paramRegExp.lastIndex = index; + while (match = paramRegExp.exec(string)) { + if (match.index !== index) { + throw new TypeError("invalid parameter format"); + } + index += match[0].length; + key = match[1].toLowerCase(); + value = match[2]; + if (value[0] === '"') { + value = value.substr(1, value.length - 2).replace(qescRegExp, "$1"); + } + params[key] = value; + } + if (index !== -1 && index !== string.length) { + throw new TypeError("invalid parameter format"); + } + obj.parameters = params; + return obj; + } + function getcontenttype(obj) { + if (typeof obj.getHeader === "function") { + return obj.getHeader("content-type"); + } + if (typeof obj.headers === "object") { + return obj.headers && obj.headers["content-type"]; + } + } + function qstring(val) { + var str = String(val); + if (tokenRegExp.test(str)) { + return str; + } + if (str.length > 0 && !textRegExp.test(str)) { + throw new TypeError("invalid parameter value"); + } + return '"' + str.replace(quoteRegExp, "\\$1") + '"'; + } + function splitType(string) { + var match = typeRegExp.exec(string.toLowerCase()); + if (!match) { + throw new TypeError("invalid media type"); + } + var type = match[1]; + var subtype = match[2]; + var suffix; + var index = subtype.lastIndexOf("+"); + if (index !== -1) { + suffix = subtype.substr(index + 1); + subtype = subtype.substr(0, index); + } + var obj = { + type, + subtype, + suffix + }; + return obj; + } + } +}); + +// node_modules/mime-db/db.json +var require_db = __commonJS({ + "node_modules/mime-db/db.json"(exports2, module2) { + module2.exports = { + "application/1d-interleaved-parityfec": { + source: "iana" + }, + "application/3gpdash-qoe-report+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/3gpp-ims+xml": { + source: "iana", + compressible: true + }, + "application/3gpphal+json": { + source: "iana", + compressible: true + }, + "application/3gpphalforms+json": { + source: "iana", + compressible: true + }, + "application/a2l": { + source: "iana" + }, + "application/ace+cbor": { + source: "iana" + }, + "application/activemessage": { + source: "iana" + }, + "application/activity+json": { + source: "iana", + compressible: true + }, + "application/alto-costmap+json": { + source: "iana", + compressible: true + }, + "application/alto-costmapfilter+json": { + source: "iana", + compressible: true + }, + "application/alto-directory+json": { + source: "iana", + compressible: true + }, + "application/alto-endpointcost+json": { + source: "iana", + compressible: true + }, + "application/alto-endpointcostparams+json": { + source: "iana", + compressible: true + }, + "application/alto-endpointprop+json": { + source: "iana", + compressible: true + }, + "application/alto-endpointpropparams+json": { + source: "iana", + compressible: true + }, + "application/alto-error+json": { + source: "iana", + compressible: true + }, + "application/alto-networkmap+json": { + source: "iana", + compressible: true + }, + "application/alto-networkmapfilter+json": { + source: "iana", + compressible: true + }, + "application/alto-updatestreamcontrol+json": { + source: "iana", + compressible: true + }, + "application/alto-updatestreamparams+json": { + source: "iana", + compressible: true + }, + "application/aml": { + source: "iana" + }, + "application/andrew-inset": { + source: "iana", + extensions: ["ez"] + }, + "application/applefile": { + source: "iana" + }, + "application/applixware": { + source: "apache", + extensions: ["aw"] + }, + "application/at+jwt": { + source: "iana" + }, + "application/atf": { + source: "iana" + }, + "application/atfx": { + source: "iana" + }, + "application/atom+xml": { + source: "iana", + compressible: true, + extensions: ["atom"] + }, + "application/atomcat+xml": { + source: "iana", + compressible: true, + extensions: ["atomcat"] + }, + "application/atomdeleted+xml": { + source: "iana", + compressible: true, + extensions: ["atomdeleted"] + }, + "application/atomicmail": { + source: "iana" + }, + "application/atomsvc+xml": { + source: "iana", + compressible: true, + extensions: ["atomsvc"] + }, + "application/atsc-dwd+xml": { + source: "iana", + compressible: true, + extensions: ["dwd"] + }, + "application/atsc-dynamic-event-message": { + source: "iana" + }, + "application/atsc-held+xml": { + source: "iana", + compressible: true, + extensions: ["held"] + }, + "application/atsc-rdt+json": { + source: "iana", + compressible: true + }, + "application/atsc-rsat+xml": { + source: "iana", + compressible: true, + extensions: ["rsat"] + }, + "application/atxml": { + source: "iana" + }, + "application/auth-policy+xml": { + source: "iana", + compressible: true + }, + "application/bacnet-xdd+zip": { + source: "iana", + compressible: false + }, + "application/batch-smtp": { + source: "iana" + }, + "application/bdoc": { + compressible: false, + extensions: ["bdoc"] + }, + "application/beep+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/calendar+json": { + source: "iana", + compressible: true + }, + "application/calendar+xml": { + source: "iana", + compressible: true, + extensions: ["xcs"] + }, + "application/call-completion": { + source: "iana" + }, + "application/cals-1840": { + source: "iana" + }, + "application/captive+json": { + source: "iana", + compressible: true + }, + "application/cbor": { + source: "iana" + }, + "application/cbor-seq": { + source: "iana" + }, + "application/cccex": { + source: "iana" + }, + "application/ccmp+xml": { + source: "iana", + compressible: true + }, + "application/ccxml+xml": { + source: "iana", + compressible: true, + extensions: ["ccxml"] + }, + "application/cdfx+xml": { + source: "iana", + compressible: true, + extensions: ["cdfx"] + }, + "application/cdmi-capability": { + source: "iana", + extensions: ["cdmia"] + }, + "application/cdmi-container": { + source: "iana", + extensions: ["cdmic"] + }, + "application/cdmi-domain": { + source: "iana", + extensions: ["cdmid"] + }, + "application/cdmi-object": { + source: "iana", + extensions: ["cdmio"] + }, + "application/cdmi-queue": { + source: "iana", + extensions: ["cdmiq"] + }, + "application/cdni": { + source: "iana" + }, + "application/cea": { + source: "iana" + }, + "application/cea-2018+xml": { + source: "iana", + compressible: true + }, + "application/cellml+xml": { + source: "iana", + compressible: true + }, + "application/cfw": { + source: "iana" + }, + "application/city+json": { + source: "iana", + compressible: true + }, + "application/clr": { + source: "iana" + }, + "application/clue+xml": { + source: "iana", + compressible: true + }, + "application/clue_info+xml": { + source: "iana", + compressible: true + }, + "application/cms": { + source: "iana" + }, + "application/cnrp+xml": { + source: "iana", + compressible: true + }, + "application/coap-group+json": { + source: "iana", + compressible: true + }, + "application/coap-payload": { + source: "iana" + }, + "application/commonground": { + source: "iana" + }, + "application/conference-info+xml": { + source: "iana", + compressible: true + }, + "application/cose": { + source: "iana" + }, + "application/cose-key": { + source: "iana" + }, + "application/cose-key-set": { + source: "iana" + }, + "application/cpl+xml": { + source: "iana", + compressible: true, + extensions: ["cpl"] + }, + "application/csrattrs": { + source: "iana" + }, + "application/csta+xml": { + source: "iana", + compressible: true + }, + "application/cstadata+xml": { + source: "iana", + compressible: true + }, + "application/csvm+json": { + source: "iana", + compressible: true + }, + "application/cu-seeme": { + source: "apache", + extensions: ["cu"] + }, + "application/cwt": { + source: "iana" + }, + "application/cybercash": { + source: "iana" + }, + "application/dart": { + compressible: true + }, + "application/dash+xml": { + source: "iana", + compressible: true, + extensions: ["mpd"] + }, + "application/dash-patch+xml": { + source: "iana", + compressible: true, + extensions: ["mpp"] + }, + "application/dashdelta": { + source: "iana" + }, + "application/davmount+xml": { + source: "iana", + compressible: true, + extensions: ["davmount"] + }, + "application/dca-rft": { + source: "iana" + }, + "application/dcd": { + source: "iana" + }, + "application/dec-dx": { + source: "iana" + }, + "application/dialog-info+xml": { + source: "iana", + compressible: true + }, + "application/dicom": { + source: "iana" + }, + "application/dicom+json": { + source: "iana", + compressible: true + }, + "application/dicom+xml": { + source: "iana", + compressible: true + }, + "application/dii": { + source: "iana" + }, + "application/dit": { + source: "iana" + }, + "application/dns": { + source: "iana" + }, + "application/dns+json": { + source: "iana", + compressible: true + }, + "application/dns-message": { + source: "iana" + }, + "application/docbook+xml": { + source: "apache", + compressible: true, + extensions: ["dbk"] + }, + "application/dots+cbor": { + source: "iana" + }, + "application/dskpp+xml": { + source: "iana", + compressible: true + }, + "application/dssc+der": { + source: "iana", + extensions: ["dssc"] + }, + "application/dssc+xml": { + source: "iana", + compressible: true, + extensions: ["xdssc"] + }, + "application/dvcs": { + source: "iana" + }, + "application/ecmascript": { + source: "iana", + compressible: true, + extensions: ["es", "ecma"] + }, + "application/edi-consent": { + source: "iana" + }, + "application/edi-x12": { + source: "iana", + compressible: false + }, + "application/edifact": { + source: "iana", + compressible: false + }, + "application/efi": { + source: "iana" + }, + "application/elm+json": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/elm+xml": { + source: "iana", + compressible: true + }, + "application/emergencycalldata.cap+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/emergencycalldata.comment+xml": { + source: "iana", + compressible: true + }, + "application/emergencycalldata.control+xml": { + source: "iana", + compressible: true + }, + "application/emergencycalldata.deviceinfo+xml": { + source: "iana", + compressible: true + }, + "application/emergencycalldata.ecall.msd": { + source: "iana" + }, + "application/emergencycalldata.providerinfo+xml": { + source: "iana", + compressible: true + }, + "application/emergencycalldata.serviceinfo+xml": { + source: "iana", + compressible: true + }, + "application/emergencycalldata.subscriberinfo+xml": { + source: "iana", + compressible: true + }, + "application/emergencycalldata.veds+xml": { + source: "iana", + compressible: true + }, + "application/emma+xml": { + source: "iana", + compressible: true, + extensions: ["emma"] + }, + "application/emotionml+xml": { + source: "iana", + compressible: true, + extensions: ["emotionml"] + }, + "application/encaprtp": { + source: "iana" + }, + "application/epp+xml": { + source: "iana", + compressible: true + }, + "application/epub+zip": { + source: "iana", + compressible: false, + extensions: ["epub"] + }, + "application/eshop": { + source: "iana" + }, + "application/exi": { + source: "iana", + extensions: ["exi"] + }, + "application/expect-ct-report+json": { + source: "iana", + compressible: true + }, + "application/express": { + source: "iana", + extensions: ["exp"] + }, + "application/fastinfoset": { + source: "iana" + }, + "application/fastsoap": { + source: "iana" + }, + "application/fdt+xml": { + source: "iana", + compressible: true, + extensions: ["fdt"] + }, + "application/fhir+json": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/fhir+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/fido.trusted-apps+json": { + compressible: true + }, + "application/fits": { + source: "iana" + }, + "application/flexfec": { + source: "iana" + }, + "application/font-sfnt": { + source: "iana" + }, + "application/font-tdpfr": { + source: "iana", + extensions: ["pfr"] + }, + "application/font-woff": { + source: "iana", + compressible: false + }, + "application/framework-attributes+xml": { + source: "iana", + compressible: true + }, + "application/geo+json": { + source: "iana", + compressible: true, + extensions: ["geojson"] + }, + "application/geo+json-seq": { + source: "iana" + }, + "application/geopackage+sqlite3": { + source: "iana" + }, + "application/geoxacml+xml": { + source: "iana", + compressible: true + }, + "application/gltf-buffer": { + source: "iana" + }, + "application/gml+xml": { + source: "iana", + compressible: true, + extensions: ["gml"] + }, + "application/gpx+xml": { + source: "apache", + compressible: true, + extensions: ["gpx"] + }, + "application/gxf": { + source: "apache", + extensions: ["gxf"] + }, + "application/gzip": { + source: "iana", + compressible: false, + extensions: ["gz"] + }, + "application/h224": { + source: "iana" + }, + "application/held+xml": { + source: "iana", + compressible: true + }, + "application/hjson": { + extensions: ["hjson"] + }, + "application/http": { + source: "iana" + }, + "application/hyperstudio": { + source: "iana", + extensions: ["stk"] + }, + "application/ibe-key-request+xml": { + source: "iana", + compressible: true + }, + "application/ibe-pkg-reply+xml": { + source: "iana", + compressible: true + }, + "application/ibe-pp-data": { + source: "iana" + }, + "application/iges": { + source: "iana" + }, + "application/im-iscomposing+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/index": { + source: "iana" + }, + "application/index.cmd": { + source: "iana" + }, + "application/index.obj": { + source: "iana" + }, + "application/index.response": { + source: "iana" + }, + "application/index.vnd": { + source: "iana" + }, + "application/inkml+xml": { + source: "iana", + compressible: true, + extensions: ["ink", "inkml"] + }, + "application/iotp": { + source: "iana" + }, + "application/ipfix": { + source: "iana", + extensions: ["ipfix"] + }, + "application/ipp": { + source: "iana" + }, + "application/isup": { + source: "iana" + }, + "application/its+xml": { + source: "iana", + compressible: true, + extensions: ["its"] + }, + "application/java-archive": { + source: "apache", + compressible: false, + extensions: ["jar", "war", "ear"] + }, + "application/java-serialized-object": { + source: "apache", + compressible: false, + extensions: ["ser"] + }, + "application/java-vm": { + source: "apache", + compressible: false, + extensions: ["class"] + }, + "application/javascript": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["js", "mjs"] + }, + "application/jf2feed+json": { + source: "iana", + compressible: true + }, + "application/jose": { + source: "iana" + }, + "application/jose+json": { + source: "iana", + compressible: true + }, + "application/jrd+json": { + source: "iana", + compressible: true + }, + "application/jscalendar+json": { + source: "iana", + compressible: true + }, + "application/json": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["json", "map"] + }, + "application/json-patch+json": { + source: "iana", + compressible: true + }, + "application/json-seq": { + source: "iana" + }, + "application/json5": { + extensions: ["json5"] + }, + "application/jsonml+json": { + source: "apache", + compressible: true, + extensions: ["jsonml"] + }, + "application/jwk+json": { + source: "iana", + compressible: true + }, + "application/jwk-set+json": { + source: "iana", + compressible: true + }, + "application/jwt": { + source: "iana" + }, + "application/kpml-request+xml": { + source: "iana", + compressible: true + }, + "application/kpml-response+xml": { + source: "iana", + compressible: true + }, + "application/ld+json": { + source: "iana", + compressible: true, + extensions: ["jsonld"] + }, + "application/lgr+xml": { + source: "iana", + compressible: true, + extensions: ["lgr"] + }, + "application/link-format": { + source: "iana" + }, + "application/load-control+xml": { + source: "iana", + compressible: true + }, + "application/lost+xml": { + source: "iana", + compressible: true, + extensions: ["lostxml"] + }, + "application/lostsync+xml": { + source: "iana", + compressible: true + }, + "application/lpf+zip": { + source: "iana", + compressible: false + }, + "application/lxf": { + source: "iana" + }, + "application/mac-binhex40": { + source: "iana", + extensions: ["hqx"] + }, + "application/mac-compactpro": { + source: "apache", + extensions: ["cpt"] + }, + "application/macwriteii": { + source: "iana" + }, + "application/mads+xml": { + source: "iana", + compressible: true, + extensions: ["mads"] + }, + "application/manifest+json": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["webmanifest"] + }, + "application/marc": { + source: "iana", + extensions: ["mrc"] + }, + "application/marcxml+xml": { + source: "iana", + compressible: true, + extensions: ["mrcx"] + }, + "application/mathematica": { + source: "iana", + extensions: ["ma", "nb", "mb"] + }, + "application/mathml+xml": { + source: "iana", + compressible: true, + extensions: ["mathml"] + }, + "application/mathml-content+xml": { + source: "iana", + compressible: true + }, + "application/mathml-presentation+xml": { + source: "iana", + compressible: true + }, + "application/mbms-associated-procedure-description+xml": { + source: "iana", + compressible: true + }, + "application/mbms-deregister+xml": { + source: "iana", + compressible: true + }, + "application/mbms-envelope+xml": { + source: "iana", + compressible: true + }, + "application/mbms-msk+xml": { + source: "iana", + compressible: true + }, + "application/mbms-msk-response+xml": { + source: "iana", + compressible: true + }, + "application/mbms-protection-description+xml": { + source: "iana", + compressible: true + }, + "application/mbms-reception-report+xml": { + source: "iana", + compressible: true + }, + "application/mbms-register+xml": { + source: "iana", + compressible: true + }, + "application/mbms-register-response+xml": { + source: "iana", + compressible: true + }, + "application/mbms-schedule+xml": { + source: "iana", + compressible: true + }, + "application/mbms-user-service-description+xml": { + source: "iana", + compressible: true + }, + "application/mbox": { + source: "iana", + extensions: ["mbox"] + }, + "application/media-policy-dataset+xml": { + source: "iana", + compressible: true, + extensions: ["mpf"] + }, + "application/media_control+xml": { + source: "iana", + compressible: true + }, + "application/mediaservercontrol+xml": { + source: "iana", + compressible: true, + extensions: ["mscml"] + }, + "application/merge-patch+json": { + source: "iana", + compressible: true + }, + "application/metalink+xml": { + source: "apache", + compressible: true, + extensions: ["metalink"] + }, + "application/metalink4+xml": { + source: "iana", + compressible: true, + extensions: ["meta4"] + }, + "application/mets+xml": { + source: "iana", + compressible: true, + extensions: ["mets"] + }, + "application/mf4": { + source: "iana" + }, + "application/mikey": { + source: "iana" + }, + "application/mipc": { + source: "iana" + }, + "application/missing-blocks+cbor-seq": { + source: "iana" + }, + "application/mmt-aei+xml": { + source: "iana", + compressible: true, + extensions: ["maei"] + }, + "application/mmt-usd+xml": { + source: "iana", + compressible: true, + extensions: ["musd"] + }, + "application/mods+xml": { + source: "iana", + compressible: true, + extensions: ["mods"] + }, + "application/moss-keys": { + source: "iana" + }, + "application/moss-signature": { + source: "iana" + }, + "application/mosskey-data": { + source: "iana" + }, + "application/mosskey-request": { + source: "iana" + }, + "application/mp21": { + source: "iana", + extensions: ["m21", "mp21"] + }, + "application/mp4": { + source: "iana", + extensions: ["mp4s", "m4p"] + }, + "application/mpeg4-generic": { + source: "iana" + }, + "application/mpeg4-iod": { + source: "iana" + }, + "application/mpeg4-iod-xmt": { + source: "iana" + }, + "application/mrb-consumer+xml": { + source: "iana", + compressible: true + }, + "application/mrb-publish+xml": { + source: "iana", + compressible: true + }, + "application/msc-ivr+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/msc-mixer+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/msword": { + source: "iana", + compressible: false, + extensions: ["doc", "dot"] + }, + "application/mud+json": { + source: "iana", + compressible: true + }, + "application/multipart-core": { + source: "iana" + }, + "application/mxf": { + source: "iana", + extensions: ["mxf"] + }, + "application/n-quads": { + source: "iana", + extensions: ["nq"] + }, + "application/n-triples": { + source: "iana", + extensions: ["nt"] + }, + "application/nasdata": { + source: "iana" + }, + "application/news-checkgroups": { + source: "iana", + charset: "US-ASCII" + }, + "application/news-groupinfo": { + source: "iana", + charset: "US-ASCII" + }, + "application/news-transmission": { + source: "iana" + }, + "application/nlsml+xml": { + source: "iana", + compressible: true + }, + "application/node": { + source: "iana", + extensions: ["cjs"] + }, + "application/nss": { + source: "iana" + }, + "application/oauth-authz-req+jwt": { + source: "iana" + }, + "application/oblivious-dns-message": { + source: "iana" + }, + "application/ocsp-request": { + source: "iana" + }, + "application/ocsp-response": { + source: "iana" + }, + "application/octet-stream": { + source: "iana", + compressible: false, + extensions: ["bin", "dms", "lrf", "mar", "so", "dist", "distz", "pkg", "bpk", "dump", "elc", "deploy", "exe", "dll", "deb", "dmg", "iso", "img", "msi", "msp", "msm", "buffer"] + }, + "application/oda": { + source: "iana", + extensions: ["oda"] + }, + "application/odm+xml": { + source: "iana", + compressible: true + }, + "application/odx": { + source: "iana" + }, + "application/oebps-package+xml": { + source: "iana", + compressible: true, + extensions: ["opf"] + }, + "application/ogg": { + source: "iana", + compressible: false, + extensions: ["ogx"] + }, + "application/omdoc+xml": { + source: "apache", + compressible: true, + extensions: ["omdoc"] + }, + "application/onenote": { + source: "apache", + extensions: ["onetoc", "onetoc2", "onetmp", "onepkg"] + }, + "application/opc-nodeset+xml": { + source: "iana", + compressible: true + }, + "application/oscore": { + source: "iana" + }, + "application/oxps": { + source: "iana", + extensions: ["oxps"] + }, + "application/p21": { + source: "iana" + }, + "application/p21+zip": { + source: "iana", + compressible: false + }, + "application/p2p-overlay+xml": { + source: "iana", + compressible: true, + extensions: ["relo"] + }, + "application/parityfec": { + source: "iana" + }, + "application/passport": { + source: "iana" + }, + "application/patch-ops-error+xml": { + source: "iana", + compressible: true, + extensions: ["xer"] + }, + "application/pdf": { + source: "iana", + compressible: false, + extensions: ["pdf"] + }, + "application/pdx": { + source: "iana" + }, + "application/pem-certificate-chain": { + source: "iana" + }, + "application/pgp-encrypted": { + source: "iana", + compressible: false, + extensions: ["pgp"] + }, + "application/pgp-keys": { + source: "iana", + extensions: ["asc"] + }, + "application/pgp-signature": { + source: "iana", + extensions: ["asc", "sig"] + }, + "application/pics-rules": { + source: "apache", + extensions: ["prf"] + }, + "application/pidf+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/pidf-diff+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/pkcs10": { + source: "iana", + extensions: ["p10"] + }, + "application/pkcs12": { + source: "iana" + }, + "application/pkcs7-mime": { + source: "iana", + extensions: ["p7m", "p7c"] + }, + "application/pkcs7-signature": { + source: "iana", + extensions: ["p7s"] + }, + "application/pkcs8": { + source: "iana", + extensions: ["p8"] + }, + "application/pkcs8-encrypted": { + source: "iana" + }, + "application/pkix-attr-cert": { + source: "iana", + extensions: ["ac"] + }, + "application/pkix-cert": { + source: "iana", + extensions: ["cer"] + }, + "application/pkix-crl": { + source: "iana", + extensions: ["crl"] + }, + "application/pkix-pkipath": { + source: "iana", + extensions: ["pkipath"] + }, + "application/pkixcmp": { + source: "iana", + extensions: ["pki"] + }, + "application/pls+xml": { + source: "iana", + compressible: true, + extensions: ["pls"] + }, + "application/poc-settings+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/postscript": { + source: "iana", + compressible: true, + extensions: ["ai", "eps", "ps"] + }, + "application/ppsp-tracker+json": { + source: "iana", + compressible: true + }, + "application/problem+json": { + source: "iana", + compressible: true + }, + "application/problem+xml": { + source: "iana", + compressible: true + }, + "application/provenance+xml": { + source: "iana", + compressible: true, + extensions: ["provx"] + }, + "application/prs.alvestrand.titrax-sheet": { + source: "iana" + }, + "application/prs.cww": { + source: "iana", + extensions: ["cww"] + }, + "application/prs.cyn": { + source: "iana", + charset: "7-BIT" + }, + "application/prs.hpub+zip": { + source: "iana", + compressible: false + }, + "application/prs.nprend": { + source: "iana" + }, + "application/prs.plucker": { + source: "iana" + }, + "application/prs.rdf-xml-crypt": { + source: "iana" + }, + "application/prs.xsf+xml": { + source: "iana", + compressible: true + }, + "application/pskc+xml": { + source: "iana", + compressible: true, + extensions: ["pskcxml"] + }, + "application/pvd+json": { + source: "iana", + compressible: true + }, + "application/qsig": { + source: "iana" + }, + "application/raml+yaml": { + compressible: true, + extensions: ["raml"] + }, + "application/raptorfec": { + source: "iana" + }, + "application/rdap+json": { + source: "iana", + compressible: true + }, + "application/rdf+xml": { + source: "iana", + compressible: true, + extensions: ["rdf", "owl"] + }, + "application/reginfo+xml": { + source: "iana", + compressible: true, + extensions: ["rif"] + }, + "application/relax-ng-compact-syntax": { + source: "iana", + extensions: ["rnc"] + }, + "application/remote-printing": { + source: "iana" + }, + "application/reputon+json": { + source: "iana", + compressible: true + }, + "application/resource-lists+xml": { + source: "iana", + compressible: true, + extensions: ["rl"] + }, + "application/resource-lists-diff+xml": { + source: "iana", + compressible: true, + extensions: ["rld"] + }, + "application/rfc+xml": { + source: "iana", + compressible: true + }, + "application/riscos": { + source: "iana" + }, + "application/rlmi+xml": { + source: "iana", + compressible: true + }, + "application/rls-services+xml": { + source: "iana", + compressible: true, + extensions: ["rs"] + }, + "application/route-apd+xml": { + source: "iana", + compressible: true, + extensions: ["rapd"] + }, + "application/route-s-tsid+xml": { + source: "iana", + compressible: true, + extensions: ["sls"] + }, + "application/route-usd+xml": { + source: "iana", + compressible: true, + extensions: ["rusd"] + }, + "application/rpki-ghostbusters": { + source: "iana", + extensions: ["gbr"] + }, + "application/rpki-manifest": { + source: "iana", + extensions: ["mft"] + }, + "application/rpki-publication": { + source: "iana" + }, + "application/rpki-roa": { + source: "iana", + extensions: ["roa"] + }, + "application/rpki-updown": { + source: "iana" + }, + "application/rsd+xml": { + source: "apache", + compressible: true, + extensions: ["rsd"] + }, + "application/rss+xml": { + source: "apache", + compressible: true, + extensions: ["rss"] + }, + "application/rtf": { + source: "iana", + compressible: true, + extensions: ["rtf"] + }, + "application/rtploopback": { + source: "iana" + }, + "application/rtx": { + source: "iana" + }, + "application/samlassertion+xml": { + source: "iana", + compressible: true + }, + "application/samlmetadata+xml": { + source: "iana", + compressible: true + }, + "application/sarif+json": { + source: "iana", + compressible: true + }, + "application/sarif-external-properties+json": { + source: "iana", + compressible: true + }, + "application/sbe": { + source: "iana" + }, + "application/sbml+xml": { + source: "iana", + compressible: true, + extensions: ["sbml"] + }, + "application/scaip+xml": { + source: "iana", + compressible: true + }, + "application/scim+json": { + source: "iana", + compressible: true + }, + "application/scvp-cv-request": { + source: "iana", + extensions: ["scq"] + }, + "application/scvp-cv-response": { + source: "iana", + extensions: ["scs"] + }, + "application/scvp-vp-request": { + source: "iana", + extensions: ["spq"] + }, + "application/scvp-vp-response": { + source: "iana", + extensions: ["spp"] + }, + "application/sdp": { + source: "iana", + extensions: ["sdp"] + }, + "application/secevent+jwt": { + source: "iana" + }, + "application/senml+cbor": { + source: "iana" + }, + "application/senml+json": { + source: "iana", + compressible: true + }, + "application/senml+xml": { + source: "iana", + compressible: true, + extensions: ["senmlx"] + }, + "application/senml-etch+cbor": { + source: "iana" + }, + "application/senml-etch+json": { + source: "iana", + compressible: true + }, + "application/senml-exi": { + source: "iana" + }, + "application/sensml+cbor": { + source: "iana" + }, + "application/sensml+json": { + source: "iana", + compressible: true + }, + "application/sensml+xml": { + source: "iana", + compressible: true, + extensions: ["sensmlx"] + }, + "application/sensml-exi": { + source: "iana" + }, + "application/sep+xml": { + source: "iana", + compressible: true + }, + "application/sep-exi": { + source: "iana" + }, + "application/session-info": { + source: "iana" + }, + "application/set-payment": { + source: "iana" + }, + "application/set-payment-initiation": { + source: "iana", + extensions: ["setpay"] + }, + "application/set-registration": { + source: "iana" + }, + "application/set-registration-initiation": { + source: "iana", + extensions: ["setreg"] + }, + "application/sgml": { + source: "iana" + }, + "application/sgml-open-catalog": { + source: "iana" + }, + "application/shf+xml": { + source: "iana", + compressible: true, + extensions: ["shf"] + }, + "application/sieve": { + source: "iana", + extensions: ["siv", "sieve"] + }, + "application/simple-filter+xml": { + source: "iana", + compressible: true + }, + "application/simple-message-summary": { + source: "iana" + }, + "application/simplesymbolcontainer": { + source: "iana" + }, + "application/sipc": { + source: "iana" + }, + "application/slate": { + source: "iana" + }, + "application/smil": { + source: "iana" + }, + "application/smil+xml": { + source: "iana", + compressible: true, + extensions: ["smi", "smil"] + }, + "application/smpte336m": { + source: "iana" + }, + "application/soap+fastinfoset": { + source: "iana" + }, + "application/soap+xml": { + source: "iana", + compressible: true + }, + "application/sparql-query": { + source: "iana", + extensions: ["rq"] + }, + "application/sparql-results+xml": { + source: "iana", + compressible: true, + extensions: ["srx"] + }, + "application/spdx+json": { + source: "iana", + compressible: true + }, + "application/spirits-event+xml": { + source: "iana", + compressible: true + }, + "application/sql": { + source: "iana" + }, + "application/srgs": { + source: "iana", + extensions: ["gram"] + }, + "application/srgs+xml": { + source: "iana", + compressible: true, + extensions: ["grxml"] + }, + "application/sru+xml": { + source: "iana", + compressible: true, + extensions: ["sru"] + }, + "application/ssdl+xml": { + source: "apache", + compressible: true, + extensions: ["ssdl"] + }, + "application/ssml+xml": { + source: "iana", + compressible: true, + extensions: ["ssml"] + }, + "application/stix+json": { + source: "iana", + compressible: true + }, + "application/swid+xml": { + source: "iana", + compressible: true, + extensions: ["swidtag"] + }, + "application/tamp-apex-update": { + source: "iana" + }, + "application/tamp-apex-update-confirm": { + source: "iana" + }, + "application/tamp-community-update": { + source: "iana" + }, + "application/tamp-community-update-confirm": { + source: "iana" + }, + "application/tamp-error": { + source: "iana" + }, + "application/tamp-sequence-adjust": { + source: "iana" + }, + "application/tamp-sequence-adjust-confirm": { + source: "iana" + }, + "application/tamp-status-query": { + source: "iana" + }, + "application/tamp-status-response": { + source: "iana" + }, + "application/tamp-update": { + source: "iana" + }, + "application/tamp-update-confirm": { + source: "iana" + }, + "application/tar": { + compressible: true + }, + "application/taxii+json": { + source: "iana", + compressible: true + }, + "application/td+json": { + source: "iana", + compressible: true + }, + "application/tei+xml": { + source: "iana", + compressible: true, + extensions: ["tei", "teicorpus"] + }, + "application/tetra_isi": { + source: "iana" + }, + "application/thraud+xml": { + source: "iana", + compressible: true, + extensions: ["tfi"] + }, + "application/timestamp-query": { + source: "iana" + }, + "application/timestamp-reply": { + source: "iana" + }, + "application/timestamped-data": { + source: "iana", + extensions: ["tsd"] + }, + "application/tlsrpt+gzip": { + source: "iana" + }, + "application/tlsrpt+json": { + source: "iana", + compressible: true + }, + "application/tnauthlist": { + source: "iana" + }, + "application/token-introspection+jwt": { + source: "iana" + }, + "application/toml": { + compressible: true, + extensions: ["toml"] + }, + "application/trickle-ice-sdpfrag": { + source: "iana" + }, + "application/trig": { + source: "iana", + extensions: ["trig"] + }, + "application/ttml+xml": { + source: "iana", + compressible: true, + extensions: ["ttml"] + }, + "application/tve-trigger": { + source: "iana" + }, + "application/tzif": { + source: "iana" + }, + "application/tzif-leap": { + source: "iana" + }, + "application/ubjson": { + compressible: false, + extensions: ["ubj"] + }, + "application/ulpfec": { + source: "iana" + }, + "application/urc-grpsheet+xml": { + source: "iana", + compressible: true + }, + "application/urc-ressheet+xml": { + source: "iana", + compressible: true, + extensions: ["rsheet"] + }, + "application/urc-targetdesc+xml": { + source: "iana", + compressible: true, + extensions: ["td"] + }, + "application/urc-uisocketdesc+xml": { + source: "iana", + compressible: true + }, + "application/vcard+json": { + source: "iana", + compressible: true + }, + "application/vcard+xml": { + source: "iana", + compressible: true + }, + "application/vemmi": { + source: "iana" + }, + "application/vividence.scriptfile": { + source: "apache" + }, + "application/vnd.1000minds.decision-model+xml": { + source: "iana", + compressible: true, + extensions: ["1km"] + }, + "application/vnd.3gpp-prose+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp-prose-pc3ch+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp-v2x-local-service-information": { + source: "iana" + }, + "application/vnd.3gpp.5gnas": { + source: "iana" + }, + "application/vnd.3gpp.access-transfer-events+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.bsf+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.gmop+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.gtpc": { + source: "iana" + }, + "application/vnd.3gpp.interworking-data": { + source: "iana" + }, + "application/vnd.3gpp.lpp": { + source: "iana" + }, + "application/vnd.3gpp.mc-signalling-ear": { + source: "iana" + }, + "application/vnd.3gpp.mcdata-affiliation-command+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcdata-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcdata-payload": { + source: "iana" + }, + "application/vnd.3gpp.mcdata-service-config+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcdata-signalling": { + source: "iana" + }, + "application/vnd.3gpp.mcdata-ue-config+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcdata-user-profile+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-affiliation-command+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-floor-request+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-location-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-mbms-usage-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-service-config+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-signed+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-ue-config+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-ue-init-config+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcptt-user-profile+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-affiliation-command+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-affiliation-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-location-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-mbms-usage-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-service-config+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-transmission-request+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-ue-config+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mcvideo-user-profile+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.mid-call+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.ngap": { + source: "iana" + }, + "application/vnd.3gpp.pfcp": { + source: "iana" + }, + "application/vnd.3gpp.pic-bw-large": { + source: "iana", + extensions: ["plb"] + }, + "application/vnd.3gpp.pic-bw-small": { + source: "iana", + extensions: ["psb"] + }, + "application/vnd.3gpp.pic-bw-var": { + source: "iana", + extensions: ["pvb"] + }, + "application/vnd.3gpp.s1ap": { + source: "iana" + }, + "application/vnd.3gpp.sms": { + source: "iana" + }, + "application/vnd.3gpp.sms+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.srvcc-ext+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.srvcc-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.state-and-event-info+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp.ussd+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp2.bcmcsinfo+xml": { + source: "iana", + compressible: true + }, + "application/vnd.3gpp2.sms": { + source: "iana" + }, + "application/vnd.3gpp2.tcap": { + source: "iana", + extensions: ["tcap"] + }, + "application/vnd.3lightssoftware.imagescal": { + source: "iana" + }, + "application/vnd.3m.post-it-notes": { + source: "iana", + extensions: ["pwn"] + }, + "application/vnd.accpac.simply.aso": { + source: "iana", + extensions: ["aso"] + }, + "application/vnd.accpac.simply.imp": { + source: "iana", + extensions: ["imp"] + }, + "application/vnd.acucobol": { + source: "iana", + extensions: ["acu"] + }, + "application/vnd.acucorp": { + source: "iana", + extensions: ["atc", "acutc"] + }, + "application/vnd.adobe.air-application-installer-package+zip": { + source: "apache", + compressible: false, + extensions: ["air"] + }, + "application/vnd.adobe.flash.movie": { + source: "iana" + }, + "application/vnd.adobe.formscentral.fcdt": { + source: "iana", + extensions: ["fcdt"] + }, + "application/vnd.adobe.fxp": { + source: "iana", + extensions: ["fxp", "fxpl"] + }, + "application/vnd.adobe.partial-upload": { + source: "iana" + }, + "application/vnd.adobe.xdp+xml": { + source: "iana", + compressible: true, + extensions: ["xdp"] + }, + "application/vnd.adobe.xfdf": { + source: "iana", + extensions: ["xfdf"] + }, + "application/vnd.aether.imp": { + source: "iana" + }, + "application/vnd.afpc.afplinedata": { + source: "iana" + }, + "application/vnd.afpc.afplinedata-pagedef": { + source: "iana" + }, + "application/vnd.afpc.cmoca-cmresource": { + source: "iana" + }, + "application/vnd.afpc.foca-charset": { + source: "iana" + }, + "application/vnd.afpc.foca-codedfont": { + source: "iana" + }, + "application/vnd.afpc.foca-codepage": { + source: "iana" + }, + "application/vnd.afpc.modca": { + source: "iana" + }, + "application/vnd.afpc.modca-cmtable": { + source: "iana" + }, + "application/vnd.afpc.modca-formdef": { + source: "iana" + }, + "application/vnd.afpc.modca-mediummap": { + source: "iana" + }, + "application/vnd.afpc.modca-objectcontainer": { + source: "iana" + }, + "application/vnd.afpc.modca-overlay": { + source: "iana" + }, + "application/vnd.afpc.modca-pagesegment": { + source: "iana" + }, + "application/vnd.age": { + source: "iana", + extensions: ["age"] + }, + "application/vnd.ah-barcode": { + source: "iana" + }, + "application/vnd.ahead.space": { + source: "iana", + extensions: ["ahead"] + }, + "application/vnd.airzip.filesecure.azf": { + source: "iana", + extensions: ["azf"] + }, + "application/vnd.airzip.filesecure.azs": { + source: "iana", + extensions: ["azs"] + }, + "application/vnd.amadeus+json": { + source: "iana", + compressible: true + }, + "application/vnd.amazon.ebook": { + source: "apache", + extensions: ["azw"] + }, + "application/vnd.amazon.mobi8-ebook": { + source: "iana" + }, + "application/vnd.americandynamics.acc": { + source: "iana", + extensions: ["acc"] + }, + "application/vnd.amiga.ami": { + source: "iana", + extensions: ["ami"] + }, + "application/vnd.amundsen.maze+xml": { + source: "iana", + compressible: true + }, + "application/vnd.android.ota": { + source: "iana" + }, + "application/vnd.android.package-archive": { + source: "apache", + compressible: false, + extensions: ["apk"] + }, + "application/vnd.anki": { + source: "iana" + }, + "application/vnd.anser-web-certificate-issue-initiation": { + source: "iana", + extensions: ["cii"] + }, + "application/vnd.anser-web-funds-transfer-initiation": { + source: "apache", + extensions: ["fti"] + }, + "application/vnd.antix.game-component": { + source: "iana", + extensions: ["atx"] + }, + "application/vnd.apache.arrow.file": { + source: "iana" + }, + "application/vnd.apache.arrow.stream": { + source: "iana" + }, + "application/vnd.apache.thrift.binary": { + source: "iana" + }, + "application/vnd.apache.thrift.compact": { + source: "iana" + }, + "application/vnd.apache.thrift.json": { + source: "iana" + }, + "application/vnd.api+json": { + source: "iana", + compressible: true + }, + "application/vnd.aplextor.warrp+json": { + source: "iana", + compressible: true + }, + "application/vnd.apothekende.reservation+json": { + source: "iana", + compressible: true + }, + "application/vnd.apple.installer+xml": { + source: "iana", + compressible: true, + extensions: ["mpkg"] + }, + "application/vnd.apple.keynote": { + source: "iana", + extensions: ["key"] + }, + "application/vnd.apple.mpegurl": { + source: "iana", + extensions: ["m3u8"] + }, + "application/vnd.apple.numbers": { + source: "iana", + extensions: ["numbers"] + }, + "application/vnd.apple.pages": { + source: "iana", + extensions: ["pages"] + }, + "application/vnd.apple.pkpass": { + compressible: false, + extensions: ["pkpass"] + }, + "application/vnd.arastra.swi": { + source: "iana" + }, + "application/vnd.aristanetworks.swi": { + source: "iana", + extensions: ["swi"] + }, + "application/vnd.artisan+json": { + source: "iana", + compressible: true + }, + "application/vnd.artsquare": { + source: "iana" + }, + "application/vnd.astraea-software.iota": { + source: "iana", + extensions: ["iota"] + }, + "application/vnd.audiograph": { + source: "iana", + extensions: ["aep"] + }, + "application/vnd.autopackage": { + source: "iana" + }, + "application/vnd.avalon+json": { + source: "iana", + compressible: true + }, + "application/vnd.avistar+xml": { + source: "iana", + compressible: true + }, + "application/vnd.balsamiq.bmml+xml": { + source: "iana", + compressible: true, + extensions: ["bmml"] + }, + "application/vnd.balsamiq.bmpr": { + source: "iana" + }, + "application/vnd.banana-accounting": { + source: "iana" + }, + "application/vnd.bbf.usp.error": { + source: "iana" + }, + "application/vnd.bbf.usp.msg": { + source: "iana" + }, + "application/vnd.bbf.usp.msg+json": { + source: "iana", + compressible: true + }, + "application/vnd.bekitzur-stech+json": { + source: "iana", + compressible: true + }, + "application/vnd.bint.med-content": { + source: "iana" + }, + "application/vnd.biopax.rdf+xml": { + source: "iana", + compressible: true + }, + "application/vnd.blink-idb-value-wrapper": { + source: "iana" + }, + "application/vnd.blueice.multipass": { + source: "iana", + extensions: ["mpm"] + }, + "application/vnd.bluetooth.ep.oob": { + source: "iana" + }, + "application/vnd.bluetooth.le.oob": { + source: "iana" + }, + "application/vnd.bmi": { + source: "iana", + extensions: ["bmi"] + }, + "application/vnd.bpf": { + source: "iana" + }, + "application/vnd.bpf3": { + source: "iana" + }, + "application/vnd.businessobjects": { + source: "iana", + extensions: ["rep"] + }, + "application/vnd.byu.uapi+json": { + source: "iana", + compressible: true + }, + "application/vnd.cab-jscript": { + source: "iana" + }, + "application/vnd.canon-cpdl": { + source: "iana" + }, + "application/vnd.canon-lips": { + source: "iana" + }, + "application/vnd.capasystems-pg+json": { + source: "iana", + compressible: true + }, + "application/vnd.cendio.thinlinc.clientconf": { + source: "iana" + }, + "application/vnd.century-systems.tcp_stream": { + source: "iana" + }, + "application/vnd.chemdraw+xml": { + source: "iana", + compressible: true, + extensions: ["cdxml"] + }, + "application/vnd.chess-pgn": { + source: "iana" + }, + "application/vnd.chipnuts.karaoke-mmd": { + source: "iana", + extensions: ["mmd"] + }, + "application/vnd.ciedi": { + source: "iana" + }, + "application/vnd.cinderella": { + source: "iana", + extensions: ["cdy"] + }, + "application/vnd.cirpack.isdn-ext": { + source: "iana" + }, + "application/vnd.citationstyles.style+xml": { + source: "iana", + compressible: true, + extensions: ["csl"] + }, + "application/vnd.claymore": { + source: "iana", + extensions: ["cla"] + }, + "application/vnd.cloanto.rp9": { + source: "iana", + extensions: ["rp9"] + }, + "application/vnd.clonk.c4group": { + source: "iana", + extensions: ["c4g", "c4d", "c4f", "c4p", "c4u"] + }, + "application/vnd.cluetrust.cartomobile-config": { + source: "iana", + extensions: ["c11amc"] + }, + "application/vnd.cluetrust.cartomobile-config-pkg": { + source: "iana", + extensions: ["c11amz"] + }, + "application/vnd.coffeescript": { + source: "iana" + }, + "application/vnd.collabio.xodocuments.document": { + source: "iana" + }, + "application/vnd.collabio.xodocuments.document-template": { + source: "iana" + }, + "application/vnd.collabio.xodocuments.presentation": { + source: "iana" + }, + "application/vnd.collabio.xodocuments.presentation-template": { + source: "iana" + }, + "application/vnd.collabio.xodocuments.spreadsheet": { + source: "iana" + }, + "application/vnd.collabio.xodocuments.spreadsheet-template": { + source: "iana" + }, + "application/vnd.collection+json": { + source: "iana", + compressible: true + }, + "application/vnd.collection.doc+json": { + source: "iana", + compressible: true + }, + "application/vnd.collection.next+json": { + source: "iana", + compressible: true + }, + "application/vnd.comicbook+zip": { + source: "iana", + compressible: false + }, + "application/vnd.comicbook-rar": { + source: "iana" + }, + "application/vnd.commerce-battelle": { + source: "iana" + }, + "application/vnd.commonspace": { + source: "iana", + extensions: ["csp"] + }, + "application/vnd.contact.cmsg": { + source: "iana", + extensions: ["cdbcmsg"] + }, + "application/vnd.coreos.ignition+json": { + source: "iana", + compressible: true + }, + "application/vnd.cosmocaller": { + source: "iana", + extensions: ["cmc"] + }, + "application/vnd.crick.clicker": { + source: "iana", + extensions: ["clkx"] + }, + "application/vnd.crick.clicker.keyboard": { + source: "iana", + extensions: ["clkk"] + }, + "application/vnd.crick.clicker.palette": { + source: "iana", + extensions: ["clkp"] + }, + "application/vnd.crick.clicker.template": { + source: "iana", + extensions: ["clkt"] + }, + "application/vnd.crick.clicker.wordbank": { + source: "iana", + extensions: ["clkw"] + }, + "application/vnd.criticaltools.wbs+xml": { + source: "iana", + compressible: true, + extensions: ["wbs"] + }, + "application/vnd.cryptii.pipe+json": { + source: "iana", + compressible: true + }, + "application/vnd.crypto-shade-file": { + source: "iana" + }, + "application/vnd.cryptomator.encrypted": { + source: "iana" + }, + "application/vnd.cryptomator.vault": { + source: "iana" + }, + "application/vnd.ctc-posml": { + source: "iana", + extensions: ["pml"] + }, + "application/vnd.ctct.ws+xml": { + source: "iana", + compressible: true + }, + "application/vnd.cups-pdf": { + source: "iana" + }, + "application/vnd.cups-postscript": { + source: "iana" + }, + "application/vnd.cups-ppd": { + source: "iana", + extensions: ["ppd"] + }, + "application/vnd.cups-raster": { + source: "iana" + }, + "application/vnd.cups-raw": { + source: "iana" + }, + "application/vnd.curl": { + source: "iana" + }, + "application/vnd.curl.car": { + source: "apache", + extensions: ["car"] + }, + "application/vnd.curl.pcurl": { + source: "apache", + extensions: ["pcurl"] + }, + "application/vnd.cyan.dean.root+xml": { + source: "iana", + compressible: true + }, + "application/vnd.cybank": { + source: "iana" + }, + "application/vnd.cyclonedx+json": { + source: "iana", + compressible: true + }, + "application/vnd.cyclonedx+xml": { + source: "iana", + compressible: true + }, + "application/vnd.d2l.coursepackage1p0+zip": { + source: "iana", + compressible: false + }, + "application/vnd.d3m-dataset": { + source: "iana" + }, + "application/vnd.d3m-problem": { + source: "iana" + }, + "application/vnd.dart": { + source: "iana", + compressible: true, + extensions: ["dart"] + }, + "application/vnd.data-vision.rdz": { + source: "iana", + extensions: ["rdz"] + }, + "application/vnd.datapackage+json": { + source: "iana", + compressible: true + }, + "application/vnd.dataresource+json": { + source: "iana", + compressible: true + }, + "application/vnd.dbf": { + source: "iana", + extensions: ["dbf"] + }, + "application/vnd.debian.binary-package": { + source: "iana" + }, + "application/vnd.dece.data": { + source: "iana", + extensions: ["uvf", "uvvf", "uvd", "uvvd"] + }, + "application/vnd.dece.ttml+xml": { + source: "iana", + compressible: true, + extensions: ["uvt", "uvvt"] + }, + "application/vnd.dece.unspecified": { + source: "iana", + extensions: ["uvx", "uvvx"] + }, + "application/vnd.dece.zip": { + source: "iana", + extensions: ["uvz", "uvvz"] + }, + "application/vnd.denovo.fcselayout-link": { + source: "iana", + extensions: ["fe_launch"] + }, + "application/vnd.desmume.movie": { + source: "iana" + }, + "application/vnd.dir-bi.plate-dl-nosuffix": { + source: "iana" + }, + "application/vnd.dm.delegation+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dna": { + source: "iana", + extensions: ["dna"] + }, + "application/vnd.document+json": { + source: "iana", + compressible: true + }, + "application/vnd.dolby.mlp": { + source: "apache", + extensions: ["mlp"] + }, + "application/vnd.dolby.mobile.1": { + source: "iana" + }, + "application/vnd.dolby.mobile.2": { + source: "iana" + }, + "application/vnd.doremir.scorecloud-binary-document": { + source: "iana" + }, + "application/vnd.dpgraph": { + source: "iana", + extensions: ["dpg"] + }, + "application/vnd.dreamfactory": { + source: "iana", + extensions: ["dfac"] + }, + "application/vnd.drive+json": { + source: "iana", + compressible: true + }, + "application/vnd.ds-keypoint": { + source: "apache", + extensions: ["kpxx"] + }, + "application/vnd.dtg.local": { + source: "iana" + }, + "application/vnd.dtg.local.flash": { + source: "iana" + }, + "application/vnd.dtg.local.html": { + source: "iana" + }, + "application/vnd.dvb.ait": { + source: "iana", + extensions: ["ait"] + }, + "application/vnd.dvb.dvbisl+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dvb.dvbj": { + source: "iana" + }, + "application/vnd.dvb.esgcontainer": { + source: "iana" + }, + "application/vnd.dvb.ipdcdftnotifaccess": { + source: "iana" + }, + "application/vnd.dvb.ipdcesgaccess": { + source: "iana" + }, + "application/vnd.dvb.ipdcesgaccess2": { + source: "iana" + }, + "application/vnd.dvb.ipdcesgpdd": { + source: "iana" + }, + "application/vnd.dvb.ipdcroaming": { + source: "iana" + }, + "application/vnd.dvb.iptv.alfec-base": { + source: "iana" + }, + "application/vnd.dvb.iptv.alfec-enhancement": { + source: "iana" + }, + "application/vnd.dvb.notif-aggregate-root+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dvb.notif-container+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dvb.notif-generic+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dvb.notif-ia-msglist+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dvb.notif-ia-registration-request+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dvb.notif-ia-registration-response+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dvb.notif-init+xml": { + source: "iana", + compressible: true + }, + "application/vnd.dvb.pfr": { + source: "iana" + }, + "application/vnd.dvb.service": { + source: "iana", + extensions: ["svc"] + }, + "application/vnd.dxr": { + source: "iana" + }, + "application/vnd.dynageo": { + source: "iana", + extensions: ["geo"] + }, + "application/vnd.dzr": { + source: "iana" + }, + "application/vnd.easykaraoke.cdgdownload": { + source: "iana" + }, + "application/vnd.ecdis-update": { + source: "iana" + }, + "application/vnd.ecip.rlp": { + source: "iana" + }, + "application/vnd.eclipse.ditto+json": { + source: "iana", + compressible: true + }, + "application/vnd.ecowin.chart": { + source: "iana", + extensions: ["mag"] + }, + "application/vnd.ecowin.filerequest": { + source: "iana" + }, + "application/vnd.ecowin.fileupdate": { + source: "iana" + }, + "application/vnd.ecowin.series": { + source: "iana" + }, + "application/vnd.ecowin.seriesrequest": { + source: "iana" + }, + "application/vnd.ecowin.seriesupdate": { + source: "iana" + }, + "application/vnd.efi.img": { + source: "iana" + }, + "application/vnd.efi.iso": { + source: "iana" + }, + "application/vnd.emclient.accessrequest+xml": { + source: "iana", + compressible: true + }, + "application/vnd.enliven": { + source: "iana", + extensions: ["nml"] + }, + "application/vnd.enphase.envoy": { + source: "iana" + }, + "application/vnd.eprints.data+xml": { + source: "iana", + compressible: true + }, + "application/vnd.epson.esf": { + source: "iana", + extensions: ["esf"] + }, + "application/vnd.epson.msf": { + source: "iana", + extensions: ["msf"] + }, + "application/vnd.epson.quickanime": { + source: "iana", + extensions: ["qam"] + }, + "application/vnd.epson.salt": { + source: "iana", + extensions: ["slt"] + }, + "application/vnd.epson.ssf": { + source: "iana", + extensions: ["ssf"] + }, + "application/vnd.ericsson.quickcall": { + source: "iana" + }, + "application/vnd.espass-espass+zip": { + source: "iana", + compressible: false + }, + "application/vnd.eszigno3+xml": { + source: "iana", + compressible: true, + extensions: ["es3", "et3"] + }, + "application/vnd.etsi.aoc+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.asic-e+zip": { + source: "iana", + compressible: false + }, + "application/vnd.etsi.asic-s+zip": { + source: "iana", + compressible: false + }, + "application/vnd.etsi.cug+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvcommand+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvdiscovery+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvprofile+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvsad-bc+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvsad-cod+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvsad-npvr+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvservice+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvsync+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.iptvueprofile+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.mcid+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.mheg5": { + source: "iana" + }, + "application/vnd.etsi.overload-control-policy-dataset+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.pstn+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.sci+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.simservs+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.timestamp-token": { + source: "iana" + }, + "application/vnd.etsi.tsl+xml": { + source: "iana", + compressible: true + }, + "application/vnd.etsi.tsl.der": { + source: "iana" + }, + "application/vnd.eu.kasparian.car+json": { + source: "iana", + compressible: true + }, + "application/vnd.eudora.data": { + source: "iana" + }, + "application/vnd.evolv.ecig.profile": { + source: "iana" + }, + "application/vnd.evolv.ecig.settings": { + source: "iana" + }, + "application/vnd.evolv.ecig.theme": { + source: "iana" + }, + "application/vnd.exstream-empower+zip": { + source: "iana", + compressible: false + }, + "application/vnd.exstream-package": { + source: "iana" + }, + "application/vnd.ezpix-album": { + source: "iana", + extensions: ["ez2"] + }, + "application/vnd.ezpix-package": { + source: "iana", + extensions: ["ez3"] + }, + "application/vnd.f-secure.mobile": { + source: "iana" + }, + "application/vnd.familysearch.gedcom+zip": { + source: "iana", + compressible: false + }, + "application/vnd.fastcopy-disk-image": { + source: "iana" + }, + "application/vnd.fdf": { + source: "iana", + extensions: ["fdf"] + }, + "application/vnd.fdsn.mseed": { + source: "iana", + extensions: ["mseed"] + }, + "application/vnd.fdsn.seed": { + source: "iana", + extensions: ["seed", "dataless"] + }, + "application/vnd.ffsns": { + source: "iana" + }, + "application/vnd.ficlab.flb+zip": { + source: "iana", + compressible: false + }, + "application/vnd.filmit.zfc": { + source: "iana" + }, + "application/vnd.fints": { + source: "iana" + }, + "application/vnd.firemonkeys.cloudcell": { + source: "iana" + }, + "application/vnd.flographit": { + source: "iana", + extensions: ["gph"] + }, + "application/vnd.fluxtime.clip": { + source: "iana", + extensions: ["ftc"] + }, + "application/vnd.font-fontforge-sfd": { + source: "iana" + }, + "application/vnd.framemaker": { + source: "iana", + extensions: ["fm", "frame", "maker", "book"] + }, + "application/vnd.frogans.fnc": { + source: "iana", + extensions: ["fnc"] + }, + "application/vnd.frogans.ltf": { + source: "iana", + extensions: ["ltf"] + }, + "application/vnd.fsc.weblaunch": { + source: "iana", + extensions: ["fsc"] + }, + "application/vnd.fujifilm.fb.docuworks": { + source: "iana" + }, + "application/vnd.fujifilm.fb.docuworks.binder": { + source: "iana" + }, + "application/vnd.fujifilm.fb.docuworks.container": { + source: "iana" + }, + "application/vnd.fujifilm.fb.jfi+xml": { + source: "iana", + compressible: true + }, + "application/vnd.fujitsu.oasys": { + source: "iana", + extensions: ["oas"] + }, + "application/vnd.fujitsu.oasys2": { + source: "iana", + extensions: ["oa2"] + }, + "application/vnd.fujitsu.oasys3": { + source: "iana", + extensions: ["oa3"] + }, + "application/vnd.fujitsu.oasysgp": { + source: "iana", + extensions: ["fg5"] + }, + "application/vnd.fujitsu.oasysprs": { + source: "iana", + extensions: ["bh2"] + }, + "application/vnd.fujixerox.art-ex": { + source: "iana" + }, + "application/vnd.fujixerox.art4": { + source: "iana" + }, + "application/vnd.fujixerox.ddd": { + source: "iana", + extensions: ["ddd"] + }, + "application/vnd.fujixerox.docuworks": { + source: "iana", + extensions: ["xdw"] + }, + "application/vnd.fujixerox.docuworks.binder": { + source: "iana", + extensions: ["xbd"] + }, + "application/vnd.fujixerox.docuworks.container": { + source: "iana" + }, + "application/vnd.fujixerox.hbpl": { + source: "iana" + }, + "application/vnd.fut-misnet": { + source: "iana" + }, + "application/vnd.futoin+cbor": { + source: "iana" + }, + "application/vnd.futoin+json": { + source: "iana", + compressible: true + }, + "application/vnd.fuzzysheet": { + source: "iana", + extensions: ["fzs"] + }, + "application/vnd.genomatix.tuxedo": { + source: "iana", + extensions: ["txd"] + }, + "application/vnd.gentics.grd+json": { + source: "iana", + compressible: true + }, + "application/vnd.geo+json": { + source: "iana", + compressible: true + }, + "application/vnd.geocube+xml": { + source: "iana", + compressible: true + }, + "application/vnd.geogebra.file": { + source: "iana", + extensions: ["ggb"] + }, + "application/vnd.geogebra.slides": { + source: "iana" + }, + "application/vnd.geogebra.tool": { + source: "iana", + extensions: ["ggt"] + }, + "application/vnd.geometry-explorer": { + source: "iana", + extensions: ["gex", "gre"] + }, + "application/vnd.geonext": { + source: "iana", + extensions: ["gxt"] + }, + "application/vnd.geoplan": { + source: "iana", + extensions: ["g2w"] + }, + "application/vnd.geospace": { + source: "iana", + extensions: ["g3w"] + }, + "application/vnd.gerber": { + source: "iana" + }, + "application/vnd.globalplatform.card-content-mgt": { + source: "iana" + }, + "application/vnd.globalplatform.card-content-mgt-response": { + source: "iana" + }, + "application/vnd.gmx": { + source: "iana", + extensions: ["gmx"] + }, + "application/vnd.google-apps.document": { + compressible: false, + extensions: ["gdoc"] + }, + "application/vnd.google-apps.presentation": { + compressible: false, + extensions: ["gslides"] + }, + "application/vnd.google-apps.spreadsheet": { + compressible: false, + extensions: ["gsheet"] + }, + "application/vnd.google-earth.kml+xml": { + source: "iana", + compressible: true, + extensions: ["kml"] + }, + "application/vnd.google-earth.kmz": { + source: "iana", + compressible: false, + extensions: ["kmz"] + }, + "application/vnd.gov.sk.e-form+xml": { + source: "iana", + compressible: true + }, + "application/vnd.gov.sk.e-form+zip": { + source: "iana", + compressible: false + }, + "application/vnd.gov.sk.xmldatacontainer+xml": { + source: "iana", + compressible: true + }, + "application/vnd.grafeq": { + source: "iana", + extensions: ["gqf", "gqs"] + }, + "application/vnd.gridmp": { + source: "iana" + }, + "application/vnd.groove-account": { + source: "iana", + extensions: ["gac"] + }, + "application/vnd.groove-help": { + source: "iana", + extensions: ["ghf"] + }, + "application/vnd.groove-identity-message": { + source: "iana", + extensions: ["gim"] + }, + "application/vnd.groove-injector": { + source: "iana", + extensions: ["grv"] + }, + "application/vnd.groove-tool-message": { + source: "iana", + extensions: ["gtm"] + }, + "application/vnd.groove-tool-template": { + source: "iana", + extensions: ["tpl"] + }, + "application/vnd.groove-vcard": { + source: "iana", + extensions: ["vcg"] + }, + "application/vnd.hal+json": { + source: "iana", + compressible: true + }, + "application/vnd.hal+xml": { + source: "iana", + compressible: true, + extensions: ["hal"] + }, + "application/vnd.handheld-entertainment+xml": { + source: "iana", + compressible: true, + extensions: ["zmm"] + }, + "application/vnd.hbci": { + source: "iana", + extensions: ["hbci"] + }, + "application/vnd.hc+json": { + source: "iana", + compressible: true + }, + "application/vnd.hcl-bireports": { + source: "iana" + }, + "application/vnd.hdt": { + source: "iana" + }, + "application/vnd.heroku+json": { + source: "iana", + compressible: true + }, + "application/vnd.hhe.lesson-player": { + source: "iana", + extensions: ["les"] + }, + "application/vnd.hl7cda+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/vnd.hl7v2+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/vnd.hp-hpgl": { + source: "iana", + extensions: ["hpgl"] + }, + "application/vnd.hp-hpid": { + source: "iana", + extensions: ["hpid"] + }, + "application/vnd.hp-hps": { + source: "iana", + extensions: ["hps"] + }, + "application/vnd.hp-jlyt": { + source: "iana", + extensions: ["jlt"] + }, + "application/vnd.hp-pcl": { + source: "iana", + extensions: ["pcl"] + }, + "application/vnd.hp-pclxl": { + source: "iana", + extensions: ["pclxl"] + }, + "application/vnd.httphone": { + source: "iana" + }, + "application/vnd.hydrostatix.sof-data": { + source: "iana", + extensions: ["sfd-hdstx"] + }, + "application/vnd.hyper+json": { + source: "iana", + compressible: true + }, + "application/vnd.hyper-item+json": { + source: "iana", + compressible: true + }, + "application/vnd.hyperdrive+json": { + source: "iana", + compressible: true + }, + "application/vnd.hzn-3d-crossword": { + source: "iana" + }, + "application/vnd.ibm.afplinedata": { + source: "iana" + }, + "application/vnd.ibm.electronic-media": { + source: "iana" + }, + "application/vnd.ibm.minipay": { + source: "iana", + extensions: ["mpy"] + }, + "application/vnd.ibm.modcap": { + source: "iana", + extensions: ["afp", "listafp", "list3820"] + }, + "application/vnd.ibm.rights-management": { + source: "iana", + extensions: ["irm"] + }, + "application/vnd.ibm.secure-container": { + source: "iana", + extensions: ["sc"] + }, + "application/vnd.iccprofile": { + source: "iana", + extensions: ["icc", "icm"] + }, + "application/vnd.ieee.1905": { + source: "iana" + }, + "application/vnd.igloader": { + source: "iana", + extensions: ["igl"] + }, + "application/vnd.imagemeter.folder+zip": { + source: "iana", + compressible: false + }, + "application/vnd.imagemeter.image+zip": { + source: "iana", + compressible: false + }, + "application/vnd.immervision-ivp": { + source: "iana", + extensions: ["ivp"] + }, + "application/vnd.immervision-ivu": { + source: "iana", + extensions: ["ivu"] + }, + "application/vnd.ims.imsccv1p1": { + source: "iana" + }, + "application/vnd.ims.imsccv1p2": { + source: "iana" + }, + "application/vnd.ims.imsccv1p3": { + source: "iana" + }, + "application/vnd.ims.lis.v2.result+json": { + source: "iana", + compressible: true + }, + "application/vnd.ims.lti.v2.toolconsumerprofile+json": { + source: "iana", + compressible: true + }, + "application/vnd.ims.lti.v2.toolproxy+json": { + source: "iana", + compressible: true + }, + "application/vnd.ims.lti.v2.toolproxy.id+json": { + source: "iana", + compressible: true + }, + "application/vnd.ims.lti.v2.toolsettings+json": { + source: "iana", + compressible: true + }, + "application/vnd.ims.lti.v2.toolsettings.simple+json": { + source: "iana", + compressible: true + }, + "application/vnd.informedcontrol.rms+xml": { + source: "iana", + compressible: true + }, + "application/vnd.informix-visionary": { + source: "iana" + }, + "application/vnd.infotech.project": { + source: "iana" + }, + "application/vnd.infotech.project+xml": { + source: "iana", + compressible: true + }, + "application/vnd.innopath.wamp.notification": { + source: "iana" + }, + "application/vnd.insors.igm": { + source: "iana", + extensions: ["igm"] + }, + "application/vnd.intercon.formnet": { + source: "iana", + extensions: ["xpw", "xpx"] + }, + "application/vnd.intergeo": { + source: "iana", + extensions: ["i2g"] + }, + "application/vnd.intertrust.digibox": { + source: "iana" + }, + "application/vnd.intertrust.nncp": { + source: "iana" + }, + "application/vnd.intu.qbo": { + source: "iana", + extensions: ["qbo"] + }, + "application/vnd.intu.qfx": { + source: "iana", + extensions: ["qfx"] + }, + "application/vnd.iptc.g2.catalogitem+xml": { + source: "iana", + compressible: true + }, + "application/vnd.iptc.g2.conceptitem+xml": { + source: "iana", + compressible: true + }, + "application/vnd.iptc.g2.knowledgeitem+xml": { + source: "iana", + compressible: true + }, + "application/vnd.iptc.g2.newsitem+xml": { + source: "iana", + compressible: true + }, + "application/vnd.iptc.g2.newsmessage+xml": { + source: "iana", + compressible: true + }, + "application/vnd.iptc.g2.packageitem+xml": { + source: "iana", + compressible: true + }, + "application/vnd.iptc.g2.planningitem+xml": { + source: "iana", + compressible: true + }, + "application/vnd.ipunplugged.rcprofile": { + source: "iana", + extensions: ["rcprofile"] + }, + "application/vnd.irepository.package+xml": { + source: "iana", + compressible: true, + extensions: ["irp"] + }, + "application/vnd.is-xpr": { + source: "iana", + extensions: ["xpr"] + }, + "application/vnd.isac.fcs": { + source: "iana", + extensions: ["fcs"] + }, + "application/vnd.iso11783-10+zip": { + source: "iana", + compressible: false + }, + "application/vnd.jam": { + source: "iana", + extensions: ["jam"] + }, + "application/vnd.japannet-directory-service": { + source: "iana" + }, + "application/vnd.japannet-jpnstore-wakeup": { + source: "iana" + }, + "application/vnd.japannet-payment-wakeup": { + source: "iana" + }, + "application/vnd.japannet-registration": { + source: "iana" + }, + "application/vnd.japannet-registration-wakeup": { + source: "iana" + }, + "application/vnd.japannet-setstore-wakeup": { + source: "iana" + }, + "application/vnd.japannet-verification": { + source: "iana" + }, + "application/vnd.japannet-verification-wakeup": { + source: "iana" + }, + "application/vnd.jcp.javame.midlet-rms": { + source: "iana", + extensions: ["rms"] + }, + "application/vnd.jisp": { + source: "iana", + extensions: ["jisp"] + }, + "application/vnd.joost.joda-archive": { + source: "iana", + extensions: ["joda"] + }, + "application/vnd.jsk.isdn-ngn": { + source: "iana" + }, + "application/vnd.kahootz": { + source: "iana", + extensions: ["ktz", "ktr"] + }, + "application/vnd.kde.karbon": { + source: "iana", + extensions: ["karbon"] + }, + "application/vnd.kde.kchart": { + source: "iana", + extensions: ["chrt"] + }, + "application/vnd.kde.kformula": { + source: "iana", + extensions: ["kfo"] + }, + "application/vnd.kde.kivio": { + source: "iana", + extensions: ["flw"] + }, + "application/vnd.kde.kontour": { + source: "iana", + extensions: ["kon"] + }, + "application/vnd.kde.kpresenter": { + source: "iana", + extensions: ["kpr", "kpt"] + }, + "application/vnd.kde.kspread": { + source: "iana", + extensions: ["ksp"] + }, + "application/vnd.kde.kword": { + source: "iana", + extensions: ["kwd", "kwt"] + }, + "application/vnd.kenameaapp": { + source: "iana", + extensions: ["htke"] + }, + "application/vnd.kidspiration": { + source: "iana", + extensions: ["kia"] + }, + "application/vnd.kinar": { + source: "iana", + extensions: ["kne", "knp"] + }, + "application/vnd.koan": { + source: "iana", + extensions: ["skp", "skd", "skt", "skm"] + }, + "application/vnd.kodak-descriptor": { + source: "iana", + extensions: ["sse"] + }, + "application/vnd.las": { + source: "iana" + }, + "application/vnd.las.las+json": { + source: "iana", + compressible: true + }, + "application/vnd.las.las+xml": { + source: "iana", + compressible: true, + extensions: ["lasxml"] + }, + "application/vnd.laszip": { + source: "iana" + }, + "application/vnd.leap+json": { + source: "iana", + compressible: true + }, + "application/vnd.liberty-request+xml": { + source: "iana", + compressible: true + }, + "application/vnd.llamagraphics.life-balance.desktop": { + source: "iana", + extensions: ["lbd"] + }, + "application/vnd.llamagraphics.life-balance.exchange+xml": { + source: "iana", + compressible: true, + extensions: ["lbe"] + }, + "application/vnd.logipipe.circuit+zip": { + source: "iana", + compressible: false + }, + "application/vnd.loom": { + source: "iana" + }, + "application/vnd.lotus-1-2-3": { + source: "iana", + extensions: ["123"] + }, + "application/vnd.lotus-approach": { + source: "iana", + extensions: ["apr"] + }, + "application/vnd.lotus-freelance": { + source: "iana", + extensions: ["pre"] + }, + "application/vnd.lotus-notes": { + source: "iana", + extensions: ["nsf"] + }, + "application/vnd.lotus-organizer": { + source: "iana", + extensions: ["org"] + }, + "application/vnd.lotus-screencam": { + source: "iana", + extensions: ["scm"] + }, + "application/vnd.lotus-wordpro": { + source: "iana", + extensions: ["lwp"] + }, + "application/vnd.macports.portpkg": { + source: "iana", + extensions: ["portpkg"] + }, + "application/vnd.mapbox-vector-tile": { + source: "iana", + extensions: ["mvt"] + }, + "application/vnd.marlin.drm.actiontoken+xml": { + source: "iana", + compressible: true + }, + "application/vnd.marlin.drm.conftoken+xml": { + source: "iana", + compressible: true + }, + "application/vnd.marlin.drm.license+xml": { + source: "iana", + compressible: true + }, + "application/vnd.marlin.drm.mdcf": { + source: "iana" + }, + "application/vnd.mason+json": { + source: "iana", + compressible: true + }, + "application/vnd.maxar.archive.3tz+zip": { + source: "iana", + compressible: false + }, + "application/vnd.maxmind.maxmind-db": { + source: "iana" + }, + "application/vnd.mcd": { + source: "iana", + extensions: ["mcd"] + }, + "application/vnd.medcalcdata": { + source: "iana", + extensions: ["mc1"] + }, + "application/vnd.mediastation.cdkey": { + source: "iana", + extensions: ["cdkey"] + }, + "application/vnd.meridian-slingshot": { + source: "iana" + }, + "application/vnd.mfer": { + source: "iana", + extensions: ["mwf"] + }, + "application/vnd.mfmp": { + source: "iana", + extensions: ["mfm"] + }, + "application/vnd.micro+json": { + source: "iana", + compressible: true + }, + "application/vnd.micrografx.flo": { + source: "iana", + extensions: ["flo"] + }, + "application/vnd.micrografx.igx": { + source: "iana", + extensions: ["igx"] + }, + "application/vnd.microsoft.portable-executable": { + source: "iana" + }, + "application/vnd.microsoft.windows.thumbnail-cache": { + source: "iana" + }, + "application/vnd.miele+json": { + source: "iana", + compressible: true + }, + "application/vnd.mif": { + source: "iana", + extensions: ["mif"] + }, + "application/vnd.minisoft-hp3000-save": { + source: "iana" + }, + "application/vnd.mitsubishi.misty-guard.trustweb": { + source: "iana" + }, + "application/vnd.mobius.daf": { + source: "iana", + extensions: ["daf"] + }, + "application/vnd.mobius.dis": { + source: "iana", + extensions: ["dis"] + }, + "application/vnd.mobius.mbk": { + source: "iana", + extensions: ["mbk"] + }, + "application/vnd.mobius.mqy": { + source: "iana", + extensions: ["mqy"] + }, + "application/vnd.mobius.msl": { + source: "iana", + extensions: ["msl"] + }, + "application/vnd.mobius.plc": { + source: "iana", + extensions: ["plc"] + }, + "application/vnd.mobius.txf": { + source: "iana", + extensions: ["txf"] + }, + "application/vnd.mophun.application": { + source: "iana", + extensions: ["mpn"] + }, + "application/vnd.mophun.certificate": { + source: "iana", + extensions: ["mpc"] + }, + "application/vnd.motorola.flexsuite": { + source: "iana" + }, + "application/vnd.motorola.flexsuite.adsi": { + source: "iana" + }, + "application/vnd.motorola.flexsuite.fis": { + source: "iana" + }, + "application/vnd.motorola.flexsuite.gotap": { + source: "iana" + }, + "application/vnd.motorola.flexsuite.kmr": { + source: "iana" + }, + "application/vnd.motorola.flexsuite.ttc": { + source: "iana" + }, + "application/vnd.motorola.flexsuite.wem": { + source: "iana" + }, + "application/vnd.motorola.iprm": { + source: "iana" + }, + "application/vnd.mozilla.xul+xml": { + source: "iana", + compressible: true, + extensions: ["xul"] + }, + "application/vnd.ms-3mfdocument": { + source: "iana" + }, + "application/vnd.ms-artgalry": { + source: "iana", + extensions: ["cil"] + }, + "application/vnd.ms-asf": { + source: "iana" + }, + "application/vnd.ms-cab-compressed": { + source: "iana", + extensions: ["cab"] + }, + "application/vnd.ms-color.iccprofile": { + source: "apache" + }, + "application/vnd.ms-excel": { + source: "iana", + compressible: false, + extensions: ["xls", "xlm", "xla", "xlc", "xlt", "xlw"] + }, + "application/vnd.ms-excel.addin.macroenabled.12": { + source: "iana", + extensions: ["xlam"] + }, + "application/vnd.ms-excel.sheet.binary.macroenabled.12": { + source: "iana", + extensions: ["xlsb"] + }, + "application/vnd.ms-excel.sheet.macroenabled.12": { + source: "iana", + extensions: ["xlsm"] + }, + "application/vnd.ms-excel.template.macroenabled.12": { + source: "iana", + extensions: ["xltm"] + }, + "application/vnd.ms-fontobject": { + source: "iana", + compressible: true, + extensions: ["eot"] + }, + "application/vnd.ms-htmlhelp": { + source: "iana", + extensions: ["chm"] + }, + "application/vnd.ms-ims": { + source: "iana", + extensions: ["ims"] + }, + "application/vnd.ms-lrm": { + source: "iana", + extensions: ["lrm"] + }, + "application/vnd.ms-office.activex+xml": { + source: "iana", + compressible: true + }, + "application/vnd.ms-officetheme": { + source: "iana", + extensions: ["thmx"] + }, + "application/vnd.ms-opentype": { + source: "apache", + compressible: true + }, + "application/vnd.ms-outlook": { + compressible: false, + extensions: ["msg"] + }, + "application/vnd.ms-package.obfuscated-opentype": { + source: "apache" + }, + "application/vnd.ms-pki.seccat": { + source: "apache", + extensions: ["cat"] + }, + "application/vnd.ms-pki.stl": { + source: "apache", + extensions: ["stl"] + }, + "application/vnd.ms-playready.initiator+xml": { + source: "iana", + compressible: true + }, + "application/vnd.ms-powerpoint": { + source: "iana", + compressible: false, + extensions: ["ppt", "pps", "pot"] + }, + "application/vnd.ms-powerpoint.addin.macroenabled.12": { + source: "iana", + extensions: ["ppam"] + }, + "application/vnd.ms-powerpoint.presentation.macroenabled.12": { + source: "iana", + extensions: ["pptm"] + }, + "application/vnd.ms-powerpoint.slide.macroenabled.12": { + source: "iana", + extensions: ["sldm"] + }, + "application/vnd.ms-powerpoint.slideshow.macroenabled.12": { + source: "iana", + extensions: ["ppsm"] + }, + "application/vnd.ms-powerpoint.template.macroenabled.12": { + source: "iana", + extensions: ["potm"] + }, + "application/vnd.ms-printdevicecapabilities+xml": { + source: "iana", + compressible: true + }, + "application/vnd.ms-printing.printticket+xml": { + source: "apache", + compressible: true + }, + "application/vnd.ms-printschematicket+xml": { + source: "iana", + compressible: true + }, + "application/vnd.ms-project": { + source: "iana", + extensions: ["mpp", "mpt"] + }, + "application/vnd.ms-tnef": { + source: "iana" + }, + "application/vnd.ms-windows.devicepairing": { + source: "iana" + }, + "application/vnd.ms-windows.nwprinting.oob": { + source: "iana" + }, + "application/vnd.ms-windows.printerpairing": { + source: "iana" + }, + "application/vnd.ms-windows.wsd.oob": { + source: "iana" + }, + "application/vnd.ms-wmdrm.lic-chlg-req": { + source: "iana" + }, + "application/vnd.ms-wmdrm.lic-resp": { + source: "iana" + }, + "application/vnd.ms-wmdrm.meter-chlg-req": { + source: "iana" + }, + "application/vnd.ms-wmdrm.meter-resp": { + source: "iana" + }, + "application/vnd.ms-word.document.macroenabled.12": { + source: "iana", + extensions: ["docm"] + }, + "application/vnd.ms-word.template.macroenabled.12": { + source: "iana", + extensions: ["dotm"] + }, + "application/vnd.ms-works": { + source: "iana", + extensions: ["wps", "wks", "wcm", "wdb"] + }, + "application/vnd.ms-wpl": { + source: "iana", + extensions: ["wpl"] + }, + "application/vnd.ms-xpsdocument": { + source: "iana", + compressible: false, + extensions: ["xps"] + }, + "application/vnd.msa-disk-image": { + source: "iana" + }, + "application/vnd.mseq": { + source: "iana", + extensions: ["mseq"] + }, + "application/vnd.msign": { + source: "iana" + }, + "application/vnd.multiad.creator": { + source: "iana" + }, + "application/vnd.multiad.creator.cif": { + source: "iana" + }, + "application/vnd.music-niff": { + source: "iana" + }, + "application/vnd.musician": { + source: "iana", + extensions: ["mus"] + }, + "application/vnd.muvee.style": { + source: "iana", + extensions: ["msty"] + }, + "application/vnd.mynfc": { + source: "iana", + extensions: ["taglet"] + }, + "application/vnd.nacamar.ybrid+json": { + source: "iana", + compressible: true + }, + "application/vnd.ncd.control": { + source: "iana" + }, + "application/vnd.ncd.reference": { + source: "iana" + }, + "application/vnd.nearst.inv+json": { + source: "iana", + compressible: true + }, + "application/vnd.nebumind.line": { + source: "iana" + }, + "application/vnd.nervana": { + source: "iana" + }, + "application/vnd.netfpx": { + source: "iana" + }, + "application/vnd.neurolanguage.nlu": { + source: "iana", + extensions: ["nlu"] + }, + "application/vnd.nimn": { + source: "iana" + }, + "application/vnd.nintendo.nitro.rom": { + source: "iana" + }, + "application/vnd.nintendo.snes.rom": { + source: "iana" + }, + "application/vnd.nitf": { + source: "iana", + extensions: ["ntf", "nitf"] + }, + "application/vnd.noblenet-directory": { + source: "iana", + extensions: ["nnd"] + }, + "application/vnd.noblenet-sealer": { + source: "iana", + extensions: ["nns"] + }, + "application/vnd.noblenet-web": { + source: "iana", + extensions: ["nnw"] + }, + "application/vnd.nokia.catalogs": { + source: "iana" + }, + "application/vnd.nokia.conml+wbxml": { + source: "iana" + }, + "application/vnd.nokia.conml+xml": { + source: "iana", + compressible: true + }, + "application/vnd.nokia.iptv.config+xml": { + source: "iana", + compressible: true + }, + "application/vnd.nokia.isds-radio-presets": { + source: "iana" + }, + "application/vnd.nokia.landmark+wbxml": { + source: "iana" + }, + "application/vnd.nokia.landmark+xml": { + source: "iana", + compressible: true + }, + "application/vnd.nokia.landmarkcollection+xml": { + source: "iana", + compressible: true + }, + "application/vnd.nokia.n-gage.ac+xml": { + source: "iana", + compressible: true, + extensions: ["ac"] + }, + "application/vnd.nokia.n-gage.data": { + source: "iana", + extensions: ["ngdat"] + }, + "application/vnd.nokia.n-gage.symbian.install": { + source: "iana", + extensions: ["n-gage"] + }, + "application/vnd.nokia.ncd": { + source: "iana" + }, + "application/vnd.nokia.pcd+wbxml": { + source: "iana" + }, + "application/vnd.nokia.pcd+xml": { + source: "iana", + compressible: true + }, + "application/vnd.nokia.radio-preset": { + source: "iana", + extensions: ["rpst"] + }, + "application/vnd.nokia.radio-presets": { + source: "iana", + extensions: ["rpss"] + }, + "application/vnd.novadigm.edm": { + source: "iana", + extensions: ["edm"] + }, + "application/vnd.novadigm.edx": { + source: "iana", + extensions: ["edx"] + }, + "application/vnd.novadigm.ext": { + source: "iana", + extensions: ["ext"] + }, + "application/vnd.ntt-local.content-share": { + source: "iana" + }, + "application/vnd.ntt-local.file-transfer": { + source: "iana" + }, + "application/vnd.ntt-local.ogw_remote-access": { + source: "iana" + }, + "application/vnd.ntt-local.sip-ta_remote": { + source: "iana" + }, + "application/vnd.ntt-local.sip-ta_tcp_stream": { + source: "iana" + }, + "application/vnd.oasis.opendocument.chart": { + source: "iana", + extensions: ["odc"] + }, + "application/vnd.oasis.opendocument.chart-template": { + source: "iana", + extensions: ["otc"] + }, + "application/vnd.oasis.opendocument.database": { + source: "iana", + extensions: ["odb"] + }, + "application/vnd.oasis.opendocument.formula": { + source: "iana", + extensions: ["odf"] + }, + "application/vnd.oasis.opendocument.formula-template": { + source: "iana", + extensions: ["odft"] + }, + "application/vnd.oasis.opendocument.graphics": { + source: "iana", + compressible: false, + extensions: ["odg"] + }, + "application/vnd.oasis.opendocument.graphics-template": { + source: "iana", + extensions: ["otg"] + }, + "application/vnd.oasis.opendocument.image": { + source: "iana", + extensions: ["odi"] + }, + "application/vnd.oasis.opendocument.image-template": { + source: "iana", + extensions: ["oti"] + }, + "application/vnd.oasis.opendocument.presentation": { + source: "iana", + compressible: false, + extensions: ["odp"] + }, + "application/vnd.oasis.opendocument.presentation-template": { + source: "iana", + extensions: ["otp"] + }, + "application/vnd.oasis.opendocument.spreadsheet": { + source: "iana", + compressible: false, + extensions: ["ods"] + }, + "application/vnd.oasis.opendocument.spreadsheet-template": { + source: "iana", + extensions: ["ots"] + }, + "application/vnd.oasis.opendocument.text": { + source: "iana", + compressible: false, + extensions: ["odt"] + }, + "application/vnd.oasis.opendocument.text-master": { + source: "iana", + extensions: ["odm"] + }, + "application/vnd.oasis.opendocument.text-template": { + source: "iana", + extensions: ["ott"] + }, + "application/vnd.oasis.opendocument.text-web": { + source: "iana", + extensions: ["oth"] + }, + "application/vnd.obn": { + source: "iana" + }, + "application/vnd.ocf+cbor": { + source: "iana" + }, + "application/vnd.oci.image.manifest.v1+json": { + source: "iana", + compressible: true + }, + "application/vnd.oftn.l10n+json": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.contentaccessdownload+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.contentaccessstreaming+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.cspg-hexbinary": { + source: "iana" + }, + "application/vnd.oipf.dae.svg+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.dae.xhtml+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.mippvcontrolmessage+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.pae.gem": { + source: "iana" + }, + "application/vnd.oipf.spdiscovery+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.spdlist+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.ueprofile+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oipf.userprofile+xml": { + source: "iana", + compressible: true + }, + "application/vnd.olpc-sugar": { + source: "iana", + extensions: ["xo"] + }, + "application/vnd.oma-scws-config": { + source: "iana" + }, + "application/vnd.oma-scws-http-request": { + source: "iana" + }, + "application/vnd.oma-scws-http-response": { + source: "iana" + }, + "application/vnd.oma.bcast.associated-procedure-parameter+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.bcast.drm-trigger+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.bcast.imd+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.bcast.ltkm": { + source: "iana" + }, + "application/vnd.oma.bcast.notification+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.bcast.provisioningtrigger": { + source: "iana" + }, + "application/vnd.oma.bcast.sgboot": { + source: "iana" + }, + "application/vnd.oma.bcast.sgdd+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.bcast.sgdu": { + source: "iana" + }, + "application/vnd.oma.bcast.simple-symbol-container": { + source: "iana" + }, + "application/vnd.oma.bcast.smartcard-trigger+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.bcast.sprov+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.bcast.stkm": { + source: "iana" + }, + "application/vnd.oma.cab-address-book+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.cab-feature-handler+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.cab-pcc+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.cab-subs-invite+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.cab-user-prefs+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.dcd": { + source: "iana" + }, + "application/vnd.oma.dcdc": { + source: "iana" + }, + "application/vnd.oma.dd2+xml": { + source: "iana", + compressible: true, + extensions: ["dd2"] + }, + "application/vnd.oma.drm.risd+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.group-usage-list+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.lwm2m+cbor": { + source: "iana" + }, + "application/vnd.oma.lwm2m+json": { + source: "iana", + compressible: true + }, + "application/vnd.oma.lwm2m+tlv": { + source: "iana" + }, + "application/vnd.oma.pal+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.poc.detailed-progress-report+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.poc.final-report+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.poc.groups+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.poc.invocation-descriptor+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.poc.optimized-progress-report+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.push": { + source: "iana" + }, + "application/vnd.oma.scidm.messages+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oma.xcap-directory+xml": { + source: "iana", + compressible: true + }, + "application/vnd.omads-email+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/vnd.omads-file+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/vnd.omads-folder+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/vnd.omaloc-supl-init": { + source: "iana" + }, + "application/vnd.onepager": { + source: "iana" + }, + "application/vnd.onepagertamp": { + source: "iana" + }, + "application/vnd.onepagertamx": { + source: "iana" + }, + "application/vnd.onepagertat": { + source: "iana" + }, + "application/vnd.onepagertatp": { + source: "iana" + }, + "application/vnd.onepagertatx": { + source: "iana" + }, + "application/vnd.openblox.game+xml": { + source: "iana", + compressible: true, + extensions: ["obgx"] + }, + "application/vnd.openblox.game-binary": { + source: "iana" + }, + "application/vnd.openeye.oeb": { + source: "iana" + }, + "application/vnd.openofficeorg.extension": { + source: "apache", + extensions: ["oxt"] + }, + "application/vnd.openstreetmap.data+xml": { + source: "iana", + compressible: true, + extensions: ["osm"] + }, + "application/vnd.opentimestamps.ots": { + source: "iana" + }, + "application/vnd.openxmlformats-officedocument.custom-properties+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.drawing+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.extended-properties+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation": { + source: "iana", + compressible: false, + extensions: ["pptx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slide": { + source: "iana", + extensions: ["sldx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow": { + source: "iana", + extensions: ["ppsx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.template": { + source: "iana", + extensions: ["potx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + source: "iana", + compressible: false, + extensions: ["xlsx"] + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template": { + source: "iana", + extensions: ["xltx"] + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.theme+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.themeoverride+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.vmldrawing": { + source: "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": { + source: "iana", + compressible: false, + extensions: ["docx"] + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template": { + source: "iana", + extensions: ["dotx"] + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-package.core-properties+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": { + source: "iana", + compressible: true + }, + "application/vnd.openxmlformats-package.relationships+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oracle.resource+json": { + source: "iana", + compressible: true + }, + "application/vnd.orange.indata": { + source: "iana" + }, + "application/vnd.osa.netdeploy": { + source: "iana" + }, + "application/vnd.osgeo.mapguide.package": { + source: "iana", + extensions: ["mgp"] + }, + "application/vnd.osgi.bundle": { + source: "iana" + }, + "application/vnd.osgi.dp": { + source: "iana", + extensions: ["dp"] + }, + "application/vnd.osgi.subsystem": { + source: "iana", + extensions: ["esa"] + }, + "application/vnd.otps.ct-kip+xml": { + source: "iana", + compressible: true + }, + "application/vnd.oxli.countgraph": { + source: "iana" + }, + "application/vnd.pagerduty+json": { + source: "iana", + compressible: true + }, + "application/vnd.palm": { + source: "iana", + extensions: ["pdb", "pqa", "oprc"] + }, + "application/vnd.panoply": { + source: "iana" + }, + "application/vnd.paos.xml": { + source: "iana" + }, + "application/vnd.patentdive": { + source: "iana" + }, + "application/vnd.patientecommsdoc": { + source: "iana" + }, + "application/vnd.pawaafile": { + source: "iana", + extensions: ["paw"] + }, + "application/vnd.pcos": { + source: "iana" + }, + "application/vnd.pg.format": { + source: "iana", + extensions: ["str"] + }, + "application/vnd.pg.osasli": { + source: "iana", + extensions: ["ei6"] + }, + "application/vnd.piaccess.application-licence": { + source: "iana" + }, + "application/vnd.picsel": { + source: "iana", + extensions: ["efif"] + }, + "application/vnd.pmi.widget": { + source: "iana", + extensions: ["wg"] + }, + "application/vnd.poc.group-advertisement+xml": { + source: "iana", + compressible: true + }, + "application/vnd.pocketlearn": { + source: "iana", + extensions: ["plf"] + }, + "application/vnd.powerbuilder6": { + source: "iana", + extensions: ["pbd"] + }, + "application/vnd.powerbuilder6-s": { + source: "iana" + }, + "application/vnd.powerbuilder7": { + source: "iana" + }, + "application/vnd.powerbuilder7-s": { + source: "iana" + }, + "application/vnd.powerbuilder75": { + source: "iana" + }, + "application/vnd.powerbuilder75-s": { + source: "iana" + }, + "application/vnd.preminet": { + source: "iana" + }, + "application/vnd.previewsystems.box": { + source: "iana", + extensions: ["box"] + }, + "application/vnd.proteus.magazine": { + source: "iana", + extensions: ["mgz"] + }, + "application/vnd.psfs": { + source: "iana" + }, + "application/vnd.publishare-delta-tree": { + source: "iana", + extensions: ["qps"] + }, + "application/vnd.pvi.ptid1": { + source: "iana", + extensions: ["ptid"] + }, + "application/vnd.pwg-multiplexed": { + source: "iana" + }, + "application/vnd.pwg-xhtml-print+xml": { + source: "iana", + compressible: true + }, + "application/vnd.qualcomm.brew-app-res": { + source: "iana" + }, + "application/vnd.quarantainenet": { + source: "iana" + }, + "application/vnd.quark.quarkxpress": { + source: "iana", + extensions: ["qxd", "qxt", "qwd", "qwt", "qxl", "qxb"] + }, + "application/vnd.quobject-quoxdocument": { + source: "iana" + }, + "application/vnd.radisys.moml+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-audit+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-audit-conf+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-audit-conn+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-audit-dialog+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-audit-stream+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-conf+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-dialog+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-dialog-base+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-dialog-fax-detect+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-dialog-group+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-dialog-speech+xml": { + source: "iana", + compressible: true + }, + "application/vnd.radisys.msml-dialog-transform+xml": { + source: "iana", + compressible: true + }, + "application/vnd.rainstor.data": { + source: "iana" + }, + "application/vnd.rapid": { + source: "iana" + }, + "application/vnd.rar": { + source: "iana", + extensions: ["rar"] + }, + "application/vnd.realvnc.bed": { + source: "iana", + extensions: ["bed"] + }, + "application/vnd.recordare.musicxml": { + source: "iana", + extensions: ["mxl"] + }, + "application/vnd.recordare.musicxml+xml": { + source: "iana", + compressible: true, + extensions: ["musicxml"] + }, + "application/vnd.renlearn.rlprint": { + source: "iana" + }, + "application/vnd.resilient.logic": { + source: "iana" + }, + "application/vnd.restful+json": { + source: "iana", + compressible: true + }, + "application/vnd.rig.cryptonote": { + source: "iana", + extensions: ["cryptonote"] + }, + "application/vnd.rim.cod": { + source: "apache", + extensions: ["cod"] + }, + "application/vnd.rn-realmedia": { + source: "apache", + extensions: ["rm"] + }, + "application/vnd.rn-realmedia-vbr": { + source: "apache", + extensions: ["rmvb"] + }, + "application/vnd.route66.link66+xml": { + source: "iana", + compressible: true, + extensions: ["link66"] + }, + "application/vnd.rs-274x": { + source: "iana" + }, + "application/vnd.ruckus.download": { + source: "iana" + }, + "application/vnd.s3sms": { + source: "iana" + }, + "application/vnd.sailingtracker.track": { + source: "iana", + extensions: ["st"] + }, + "application/vnd.sar": { + source: "iana" + }, + "application/vnd.sbm.cid": { + source: "iana" + }, + "application/vnd.sbm.mid2": { + source: "iana" + }, + "application/vnd.scribus": { + source: "iana" + }, + "application/vnd.sealed.3df": { + source: "iana" + }, + "application/vnd.sealed.csf": { + source: "iana" + }, + "application/vnd.sealed.doc": { + source: "iana" + }, + "application/vnd.sealed.eml": { + source: "iana" + }, + "application/vnd.sealed.mht": { + source: "iana" + }, + "application/vnd.sealed.net": { + source: "iana" + }, + "application/vnd.sealed.ppt": { + source: "iana" + }, + "application/vnd.sealed.tiff": { + source: "iana" + }, + "application/vnd.sealed.xls": { + source: "iana" + }, + "application/vnd.sealedmedia.softseal.html": { + source: "iana" + }, + "application/vnd.sealedmedia.softseal.pdf": { + source: "iana" + }, + "application/vnd.seemail": { + source: "iana", + extensions: ["see"] + }, + "application/vnd.seis+json": { + source: "iana", + compressible: true + }, + "application/vnd.sema": { + source: "iana", + extensions: ["sema"] + }, + "application/vnd.semd": { + source: "iana", + extensions: ["semd"] + }, + "application/vnd.semf": { + source: "iana", + extensions: ["semf"] + }, + "application/vnd.shade-save-file": { + source: "iana" + }, + "application/vnd.shana.informed.formdata": { + source: "iana", + extensions: ["ifm"] + }, + "application/vnd.shana.informed.formtemplate": { + source: "iana", + extensions: ["itp"] + }, + "application/vnd.shana.informed.interchange": { + source: "iana", + extensions: ["iif"] + }, + "application/vnd.shana.informed.package": { + source: "iana", + extensions: ["ipk"] + }, + "application/vnd.shootproof+json": { + source: "iana", + compressible: true + }, + "application/vnd.shopkick+json": { + source: "iana", + compressible: true + }, + "application/vnd.shp": { + source: "iana" + }, + "application/vnd.shx": { + source: "iana" + }, + "application/vnd.sigrok.session": { + source: "iana" + }, + "application/vnd.simtech-mindmapper": { + source: "iana", + extensions: ["twd", "twds"] + }, + "application/vnd.siren+json": { + source: "iana", + compressible: true + }, + "application/vnd.smaf": { + source: "iana", + extensions: ["mmf"] + }, + "application/vnd.smart.notebook": { + source: "iana" + }, + "application/vnd.smart.teacher": { + source: "iana", + extensions: ["teacher"] + }, + "application/vnd.snesdev-page-table": { + source: "iana" + }, + "application/vnd.software602.filler.form+xml": { + source: "iana", + compressible: true, + extensions: ["fo"] + }, + "application/vnd.software602.filler.form-xml-zip": { + source: "iana" + }, + "application/vnd.solent.sdkm+xml": { + source: "iana", + compressible: true, + extensions: ["sdkm", "sdkd"] + }, + "application/vnd.spotfire.dxp": { + source: "iana", + extensions: ["dxp"] + }, + "application/vnd.spotfire.sfs": { + source: "iana", + extensions: ["sfs"] + }, + "application/vnd.sqlite3": { + source: "iana" + }, + "application/vnd.sss-cod": { + source: "iana" + }, + "application/vnd.sss-dtf": { + source: "iana" + }, + "application/vnd.sss-ntf": { + source: "iana" + }, + "application/vnd.stardivision.calc": { + source: "apache", + extensions: ["sdc"] + }, + "application/vnd.stardivision.draw": { + source: "apache", + extensions: ["sda"] + }, + "application/vnd.stardivision.impress": { + source: "apache", + extensions: ["sdd"] + }, + "application/vnd.stardivision.math": { + source: "apache", + extensions: ["smf"] + }, + "application/vnd.stardivision.writer": { + source: "apache", + extensions: ["sdw", "vor"] + }, + "application/vnd.stardivision.writer-global": { + source: "apache", + extensions: ["sgl"] + }, + "application/vnd.stepmania.package": { + source: "iana", + extensions: ["smzip"] + }, + "application/vnd.stepmania.stepchart": { + source: "iana", + extensions: ["sm"] + }, + "application/vnd.street-stream": { + source: "iana" + }, + "application/vnd.sun.wadl+xml": { + source: "iana", + compressible: true, + extensions: ["wadl"] + }, + "application/vnd.sun.xml.calc": { + source: "apache", + extensions: ["sxc"] + }, + "application/vnd.sun.xml.calc.template": { + source: "apache", + extensions: ["stc"] + }, + "application/vnd.sun.xml.draw": { + source: "apache", + extensions: ["sxd"] + }, + "application/vnd.sun.xml.draw.template": { + source: "apache", + extensions: ["std"] + }, + "application/vnd.sun.xml.impress": { + source: "apache", + extensions: ["sxi"] + }, + "application/vnd.sun.xml.impress.template": { + source: "apache", + extensions: ["sti"] + }, + "application/vnd.sun.xml.math": { + source: "apache", + extensions: ["sxm"] + }, + "application/vnd.sun.xml.writer": { + source: "apache", + extensions: ["sxw"] + }, + "application/vnd.sun.xml.writer.global": { + source: "apache", + extensions: ["sxg"] + }, + "application/vnd.sun.xml.writer.template": { + source: "apache", + extensions: ["stw"] + }, + "application/vnd.sus-calendar": { + source: "iana", + extensions: ["sus", "susp"] + }, + "application/vnd.svd": { + source: "iana", + extensions: ["svd"] + }, + "application/vnd.swiftview-ics": { + source: "iana" + }, + "application/vnd.sycle+xml": { + source: "iana", + compressible: true + }, + "application/vnd.syft+json": { + source: "iana", + compressible: true + }, + "application/vnd.symbian.install": { + source: "apache", + extensions: ["sis", "sisx"] + }, + "application/vnd.syncml+xml": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["xsm"] + }, + "application/vnd.syncml.dm+wbxml": { + source: "iana", + charset: "UTF-8", + extensions: ["bdm"] + }, + "application/vnd.syncml.dm+xml": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["xdm"] + }, + "application/vnd.syncml.dm.notification": { + source: "iana" + }, + "application/vnd.syncml.dmddf+wbxml": { + source: "iana" + }, + "application/vnd.syncml.dmddf+xml": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["ddf"] + }, + "application/vnd.syncml.dmtnds+wbxml": { + source: "iana" + }, + "application/vnd.syncml.dmtnds+xml": { + source: "iana", + charset: "UTF-8", + compressible: true + }, + "application/vnd.syncml.ds.notification": { + source: "iana" + }, + "application/vnd.tableschema+json": { + source: "iana", + compressible: true + }, + "application/vnd.tao.intent-module-archive": { + source: "iana", + extensions: ["tao"] + }, + "application/vnd.tcpdump.pcap": { + source: "iana", + extensions: ["pcap", "cap", "dmp"] + }, + "application/vnd.think-cell.ppttc+json": { + source: "iana", + compressible: true + }, + "application/vnd.tmd.mediaflex.api+xml": { + source: "iana", + compressible: true + }, + "application/vnd.tml": { + source: "iana" + }, + "application/vnd.tmobile-livetv": { + source: "iana", + extensions: ["tmo"] + }, + "application/vnd.tri.onesource": { + source: "iana" + }, + "application/vnd.trid.tpt": { + source: "iana", + extensions: ["tpt"] + }, + "application/vnd.triscape.mxs": { + source: "iana", + extensions: ["mxs"] + }, + "application/vnd.trueapp": { + source: "iana", + extensions: ["tra"] + }, + "application/vnd.truedoc": { + source: "iana" + }, + "application/vnd.ubisoft.webplayer": { + source: "iana" + }, + "application/vnd.ufdl": { + source: "iana", + extensions: ["ufd", "ufdl"] + }, + "application/vnd.uiq.theme": { + source: "iana", + extensions: ["utz"] + }, + "application/vnd.umajin": { + source: "iana", + extensions: ["umj"] + }, + "application/vnd.unity": { + source: "iana", + extensions: ["unityweb"] + }, + "application/vnd.uoml+xml": { + source: "iana", + compressible: true, + extensions: ["uoml"] + }, + "application/vnd.uplanet.alert": { + source: "iana" + }, + "application/vnd.uplanet.alert-wbxml": { + source: "iana" + }, + "application/vnd.uplanet.bearer-choice": { + source: "iana" + }, + "application/vnd.uplanet.bearer-choice-wbxml": { + source: "iana" + }, + "application/vnd.uplanet.cacheop": { + source: "iana" + }, + "application/vnd.uplanet.cacheop-wbxml": { + source: "iana" + }, + "application/vnd.uplanet.channel": { + source: "iana" + }, + "application/vnd.uplanet.channel-wbxml": { + source: "iana" + }, + "application/vnd.uplanet.list": { + source: "iana" + }, + "application/vnd.uplanet.list-wbxml": { + source: "iana" + }, + "application/vnd.uplanet.listcmd": { + source: "iana" + }, + "application/vnd.uplanet.listcmd-wbxml": { + source: "iana" + }, + "application/vnd.uplanet.signal": { + source: "iana" + }, + "application/vnd.uri-map": { + source: "iana" + }, + "application/vnd.valve.source.material": { + source: "iana" + }, + "application/vnd.vcx": { + source: "iana", + extensions: ["vcx"] + }, + "application/vnd.vd-study": { + source: "iana" + }, + "application/vnd.vectorworks": { + source: "iana" + }, + "application/vnd.vel+json": { + source: "iana", + compressible: true + }, + "application/vnd.verimatrix.vcas": { + source: "iana" + }, + "application/vnd.veritone.aion+json": { + source: "iana", + compressible: true + }, + "application/vnd.veryant.thin": { + source: "iana" + }, + "application/vnd.ves.encrypted": { + source: "iana" + }, + "application/vnd.vidsoft.vidconference": { + source: "iana" + }, + "application/vnd.visio": { + source: "iana", + extensions: ["vsd", "vst", "vss", "vsw"] + }, + "application/vnd.visionary": { + source: "iana", + extensions: ["vis"] + }, + "application/vnd.vividence.scriptfile": { + source: "iana" + }, + "application/vnd.vsf": { + source: "iana", + extensions: ["vsf"] + }, + "application/vnd.wap.sic": { + source: "iana" + }, + "application/vnd.wap.slc": { + source: "iana" + }, + "application/vnd.wap.wbxml": { + source: "iana", + charset: "UTF-8", + extensions: ["wbxml"] + }, + "application/vnd.wap.wmlc": { + source: "iana", + extensions: ["wmlc"] + }, + "application/vnd.wap.wmlscriptc": { + source: "iana", + extensions: ["wmlsc"] + }, + "application/vnd.webturbo": { + source: "iana", + extensions: ["wtb"] + }, + "application/vnd.wfa.dpp": { + source: "iana" + }, + "application/vnd.wfa.p2p": { + source: "iana" + }, + "application/vnd.wfa.wsc": { + source: "iana" + }, + "application/vnd.windows.devicepairing": { + source: "iana" + }, + "application/vnd.wmc": { + source: "iana" + }, + "application/vnd.wmf.bootstrap": { + source: "iana" + }, + "application/vnd.wolfram.mathematica": { + source: "iana" + }, + "application/vnd.wolfram.mathematica.package": { + source: "iana" + }, + "application/vnd.wolfram.player": { + source: "iana", + extensions: ["nbp"] + }, + "application/vnd.wordperfect": { + source: "iana", + extensions: ["wpd"] + }, + "application/vnd.wqd": { + source: "iana", + extensions: ["wqd"] + }, + "application/vnd.wrq-hp3000-labelled": { + source: "iana" + }, + "application/vnd.wt.stf": { + source: "iana", + extensions: ["stf"] + }, + "application/vnd.wv.csp+wbxml": { + source: "iana" + }, + "application/vnd.wv.csp+xml": { + source: "iana", + compressible: true + }, + "application/vnd.wv.ssp+xml": { + source: "iana", + compressible: true + }, + "application/vnd.xacml+json": { + source: "iana", + compressible: true + }, + "application/vnd.xara": { + source: "iana", + extensions: ["xar"] + }, + "application/vnd.xfdl": { + source: "iana", + extensions: ["xfdl"] + }, + "application/vnd.xfdl.webform": { + source: "iana" + }, + "application/vnd.xmi+xml": { + source: "iana", + compressible: true + }, + "application/vnd.xmpie.cpkg": { + source: "iana" + }, + "application/vnd.xmpie.dpkg": { + source: "iana" + }, + "application/vnd.xmpie.plan": { + source: "iana" + }, + "application/vnd.xmpie.ppkg": { + source: "iana" + }, + "application/vnd.xmpie.xlim": { + source: "iana" + }, + "application/vnd.yamaha.hv-dic": { + source: "iana", + extensions: ["hvd"] + }, + "application/vnd.yamaha.hv-script": { + source: "iana", + extensions: ["hvs"] + }, + "application/vnd.yamaha.hv-voice": { + source: "iana", + extensions: ["hvp"] + }, + "application/vnd.yamaha.openscoreformat": { + source: "iana", + extensions: ["osf"] + }, + "application/vnd.yamaha.openscoreformat.osfpvg+xml": { + source: "iana", + compressible: true, + extensions: ["osfpvg"] + }, + "application/vnd.yamaha.remote-setup": { + source: "iana" + }, + "application/vnd.yamaha.smaf-audio": { + source: "iana", + extensions: ["saf"] + }, + "application/vnd.yamaha.smaf-phrase": { + source: "iana", + extensions: ["spf"] + }, + "application/vnd.yamaha.through-ngn": { + source: "iana" + }, + "application/vnd.yamaha.tunnel-udpencap": { + source: "iana" + }, + "application/vnd.yaoweme": { + source: "iana" + }, + "application/vnd.yellowriver-custom-menu": { + source: "iana", + extensions: ["cmp"] + }, + "application/vnd.youtube.yt": { + source: "iana" + }, + "application/vnd.zul": { + source: "iana", + extensions: ["zir", "zirz"] + }, + "application/vnd.zzazz.deck+xml": { + source: "iana", + compressible: true, + extensions: ["zaz"] + }, + "application/voicexml+xml": { + source: "iana", + compressible: true, + extensions: ["vxml"] + }, + "application/voucher-cms+json": { + source: "iana", + compressible: true + }, + "application/vq-rtcpxr": { + source: "iana" + }, + "application/wasm": { + source: "iana", + compressible: true, + extensions: ["wasm"] + }, + "application/watcherinfo+xml": { + source: "iana", + compressible: true, + extensions: ["wif"] + }, + "application/webpush-options+json": { + source: "iana", + compressible: true + }, + "application/whoispp-query": { + source: "iana" + }, + "application/whoispp-response": { + source: "iana" + }, + "application/widget": { + source: "iana", + extensions: ["wgt"] + }, + "application/winhlp": { + source: "apache", + extensions: ["hlp"] + }, + "application/wita": { + source: "iana" + }, + "application/wordperfect5.1": { + source: "iana" + }, + "application/wsdl+xml": { + source: "iana", + compressible: true, + extensions: ["wsdl"] + }, + "application/wspolicy+xml": { + source: "iana", + compressible: true, + extensions: ["wspolicy"] + }, + "application/x-7z-compressed": { + source: "apache", + compressible: false, + extensions: ["7z"] + }, + "application/x-abiword": { + source: "apache", + extensions: ["abw"] + }, + "application/x-ace-compressed": { + source: "apache", + extensions: ["ace"] + }, + "application/x-amf": { + source: "apache" + }, + "application/x-apple-diskimage": { + source: "apache", + extensions: ["dmg"] + }, + "application/x-arj": { + compressible: false, + extensions: ["arj"] + }, + "application/x-authorware-bin": { + source: "apache", + extensions: ["aab", "x32", "u32", "vox"] + }, + "application/x-authorware-map": { + source: "apache", + extensions: ["aam"] + }, + "application/x-authorware-seg": { + source: "apache", + extensions: ["aas"] + }, + "application/x-bcpio": { + source: "apache", + extensions: ["bcpio"] + }, + "application/x-bdoc": { + compressible: false, + extensions: ["bdoc"] + }, + "application/x-bittorrent": { + source: "apache", + extensions: ["torrent"] + }, + "application/x-blorb": { + source: "apache", + extensions: ["blb", "blorb"] + }, + "application/x-bzip": { + source: "apache", + compressible: false, + extensions: ["bz"] + }, + "application/x-bzip2": { + source: "apache", + compressible: false, + extensions: ["bz2", "boz"] + }, + "application/x-cbr": { + source: "apache", + extensions: ["cbr", "cba", "cbt", "cbz", "cb7"] + }, + "application/x-cdlink": { + source: "apache", + extensions: ["vcd"] + }, + "application/x-cfs-compressed": { + source: "apache", + extensions: ["cfs"] + }, + "application/x-chat": { + source: "apache", + extensions: ["chat"] + }, + "application/x-chess-pgn": { + source: "apache", + extensions: ["pgn"] + }, + "application/x-chrome-extension": { + extensions: ["crx"] + }, + "application/x-cocoa": { + source: "nginx", + extensions: ["cco"] + }, + "application/x-compress": { + source: "apache" + }, + "application/x-conference": { + source: "apache", + extensions: ["nsc"] + }, + "application/x-cpio": { + source: "apache", + extensions: ["cpio"] + }, + "application/x-csh": { + source: "apache", + extensions: ["csh"] + }, + "application/x-deb": { + compressible: false + }, + "application/x-debian-package": { + source: "apache", + extensions: ["deb", "udeb"] + }, + "application/x-dgc-compressed": { + source: "apache", + extensions: ["dgc"] + }, + "application/x-director": { + source: "apache", + extensions: ["dir", "dcr", "dxr", "cst", "cct", "cxt", "w3d", "fgd", "swa"] + }, + "application/x-doom": { + source: "apache", + extensions: ["wad"] + }, + "application/x-dtbncx+xml": { + source: "apache", + compressible: true, + extensions: ["ncx"] + }, + "application/x-dtbook+xml": { + source: "apache", + compressible: true, + extensions: ["dtb"] + }, + "application/x-dtbresource+xml": { + source: "apache", + compressible: true, + extensions: ["res"] + }, + "application/x-dvi": { + source: "apache", + compressible: false, + extensions: ["dvi"] + }, + "application/x-envoy": { + source: "apache", + extensions: ["evy"] + }, + "application/x-eva": { + source: "apache", + extensions: ["eva"] + }, + "application/x-font-bdf": { + source: "apache", + extensions: ["bdf"] + }, + "application/x-font-dos": { + source: "apache" + }, + "application/x-font-framemaker": { + source: "apache" + }, + "application/x-font-ghostscript": { + source: "apache", + extensions: ["gsf"] + }, + "application/x-font-libgrx": { + source: "apache" + }, + "application/x-font-linux-psf": { + source: "apache", + extensions: ["psf"] + }, + "application/x-font-pcf": { + source: "apache", + extensions: ["pcf"] + }, + "application/x-font-snf": { + source: "apache", + extensions: ["snf"] + }, + "application/x-font-speedo": { + source: "apache" + }, + "application/x-font-sunos-news": { + source: "apache" + }, + "application/x-font-type1": { + source: "apache", + extensions: ["pfa", "pfb", "pfm", "afm"] + }, + "application/x-font-vfont": { + source: "apache" + }, + "application/x-freearc": { + source: "apache", + extensions: ["arc"] + }, + "application/x-futuresplash": { + source: "apache", + extensions: ["spl"] + }, + "application/x-gca-compressed": { + source: "apache", + extensions: ["gca"] + }, + "application/x-glulx": { + source: "apache", + extensions: ["ulx"] + }, + "application/x-gnumeric": { + source: "apache", + extensions: ["gnumeric"] + }, + "application/x-gramps-xml": { + source: "apache", + extensions: ["gramps"] + }, + "application/x-gtar": { + source: "apache", + extensions: ["gtar"] + }, + "application/x-gzip": { + source: "apache" + }, + "application/x-hdf": { + source: "apache", + extensions: ["hdf"] + }, + "application/x-httpd-php": { + compressible: true, + extensions: ["php"] + }, + "application/x-install-instructions": { + source: "apache", + extensions: ["install"] + }, + "application/x-iso9660-image": { + source: "apache", + extensions: ["iso"] + }, + "application/x-iwork-keynote-sffkey": { + extensions: ["key"] + }, + "application/x-iwork-numbers-sffnumbers": { + extensions: ["numbers"] + }, + "application/x-iwork-pages-sffpages": { + extensions: ["pages"] + }, + "application/x-java-archive-diff": { + source: "nginx", + extensions: ["jardiff"] + }, + "application/x-java-jnlp-file": { + source: "apache", + compressible: false, + extensions: ["jnlp"] + }, + "application/x-javascript": { + compressible: true + }, + "application/x-keepass2": { + extensions: ["kdbx"] + }, + "application/x-latex": { + source: "apache", + compressible: false, + extensions: ["latex"] + }, + "application/x-lua-bytecode": { + extensions: ["luac"] + }, + "application/x-lzh-compressed": { + source: "apache", + extensions: ["lzh", "lha"] + }, + "application/x-makeself": { + source: "nginx", + extensions: ["run"] + }, + "application/x-mie": { + source: "apache", + extensions: ["mie"] + }, + "application/x-mobipocket-ebook": { + source: "apache", + extensions: ["prc", "mobi"] + }, + "application/x-mpegurl": { + compressible: false + }, + "application/x-ms-application": { + source: "apache", + extensions: ["application"] + }, + "application/x-ms-shortcut": { + source: "apache", + extensions: ["lnk"] + }, + "application/x-ms-wmd": { + source: "apache", + extensions: ["wmd"] + }, + "application/x-ms-wmz": { + source: "apache", + extensions: ["wmz"] + }, + "application/x-ms-xbap": { + source: "apache", + extensions: ["xbap"] + }, + "application/x-msaccess": { + source: "apache", + extensions: ["mdb"] + }, + "application/x-msbinder": { + source: "apache", + extensions: ["obd"] + }, + "application/x-mscardfile": { + source: "apache", + extensions: ["crd"] + }, + "application/x-msclip": { + source: "apache", + extensions: ["clp"] + }, + "application/x-msdos-program": { + extensions: ["exe"] + }, + "application/x-msdownload": { + source: "apache", + extensions: ["exe", "dll", "com", "bat", "msi"] + }, + "application/x-msmediaview": { + source: "apache", + extensions: ["mvb", "m13", "m14"] + }, + "application/x-msmetafile": { + source: "apache", + extensions: ["wmf", "wmz", "emf", "emz"] + }, + "application/x-msmoney": { + source: "apache", + extensions: ["mny"] + }, + "application/x-mspublisher": { + source: "apache", + extensions: ["pub"] + }, + "application/x-msschedule": { + source: "apache", + extensions: ["scd"] + }, + "application/x-msterminal": { + source: "apache", + extensions: ["trm"] + }, + "application/x-mswrite": { + source: "apache", + extensions: ["wri"] + }, + "application/x-netcdf": { + source: "apache", + extensions: ["nc", "cdf"] + }, + "application/x-ns-proxy-autoconfig": { + compressible: true, + extensions: ["pac"] + }, + "application/x-nzb": { + source: "apache", + extensions: ["nzb"] + }, + "application/x-perl": { + source: "nginx", + extensions: ["pl", "pm"] + }, + "application/x-pilot": { + source: "nginx", + extensions: ["prc", "pdb"] + }, + "application/x-pkcs12": { + source: "apache", + compressible: false, + extensions: ["p12", "pfx"] + }, + "application/x-pkcs7-certificates": { + source: "apache", + extensions: ["p7b", "spc"] + }, + "application/x-pkcs7-certreqresp": { + source: "apache", + extensions: ["p7r"] + }, + "application/x-pki-message": { + source: "iana" + }, + "application/x-rar-compressed": { + source: "apache", + compressible: false, + extensions: ["rar"] + }, + "application/x-redhat-package-manager": { + source: "nginx", + extensions: ["rpm"] + }, + "application/x-research-info-systems": { + source: "apache", + extensions: ["ris"] + }, + "application/x-sea": { + source: "nginx", + extensions: ["sea"] + }, + "application/x-sh": { + source: "apache", + compressible: true, + extensions: ["sh"] + }, + "application/x-shar": { + source: "apache", + extensions: ["shar"] + }, + "application/x-shockwave-flash": { + source: "apache", + compressible: false, + extensions: ["swf"] + }, + "application/x-silverlight-app": { + source: "apache", + extensions: ["xap"] + }, + "application/x-sql": { + source: "apache", + extensions: ["sql"] + }, + "application/x-stuffit": { + source: "apache", + compressible: false, + extensions: ["sit"] + }, + "application/x-stuffitx": { + source: "apache", + extensions: ["sitx"] + }, + "application/x-subrip": { + source: "apache", + extensions: ["srt"] + }, + "application/x-sv4cpio": { + source: "apache", + extensions: ["sv4cpio"] + }, + "application/x-sv4crc": { + source: "apache", + extensions: ["sv4crc"] + }, + "application/x-t3vm-image": { + source: "apache", + extensions: ["t3"] + }, + "application/x-tads": { + source: "apache", + extensions: ["gam"] + }, + "application/x-tar": { + source: "apache", + compressible: true, + extensions: ["tar"] + }, + "application/x-tcl": { + source: "apache", + extensions: ["tcl", "tk"] + }, + "application/x-tex": { + source: "apache", + extensions: ["tex"] + }, + "application/x-tex-tfm": { + source: "apache", + extensions: ["tfm"] + }, + "application/x-texinfo": { + source: "apache", + extensions: ["texinfo", "texi"] + }, + "application/x-tgif": { + source: "apache", + extensions: ["obj"] + }, + "application/x-ustar": { + source: "apache", + extensions: ["ustar"] + }, + "application/x-virtualbox-hdd": { + compressible: true, + extensions: ["hdd"] + }, + "application/x-virtualbox-ova": { + compressible: true, + extensions: ["ova"] + }, + "application/x-virtualbox-ovf": { + compressible: true, + extensions: ["ovf"] + }, + "application/x-virtualbox-vbox": { + compressible: true, + extensions: ["vbox"] + }, + "application/x-virtualbox-vbox-extpack": { + compressible: false, + extensions: ["vbox-extpack"] + }, + "application/x-virtualbox-vdi": { + compressible: true, + extensions: ["vdi"] + }, + "application/x-virtualbox-vhd": { + compressible: true, + extensions: ["vhd"] + }, + "application/x-virtualbox-vmdk": { + compressible: true, + extensions: ["vmdk"] + }, + "application/x-wais-source": { + source: "apache", + extensions: ["src"] + }, + "application/x-web-app-manifest+json": { + compressible: true, + extensions: ["webapp"] + }, + "application/x-www-form-urlencoded": { + source: "iana", + compressible: true + }, + "application/x-x509-ca-cert": { + source: "iana", + extensions: ["der", "crt", "pem"] + }, + "application/x-x509-ca-ra-cert": { + source: "iana" + }, + "application/x-x509-next-ca-cert": { + source: "iana" + }, + "application/x-xfig": { + source: "apache", + extensions: ["fig"] + }, + "application/x-xliff+xml": { + source: "apache", + compressible: true, + extensions: ["xlf"] + }, + "application/x-xpinstall": { + source: "apache", + compressible: false, + extensions: ["xpi"] + }, + "application/x-xz": { + source: "apache", + extensions: ["xz"] + }, + "application/x-zmachine": { + source: "apache", + extensions: ["z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8"] + }, + "application/x400-bp": { + source: "iana" + }, + "application/xacml+xml": { + source: "iana", + compressible: true + }, + "application/xaml+xml": { + source: "apache", + compressible: true, + extensions: ["xaml"] + }, + "application/xcap-att+xml": { + source: "iana", + compressible: true, + extensions: ["xav"] + }, + "application/xcap-caps+xml": { + source: "iana", + compressible: true, + extensions: ["xca"] + }, + "application/xcap-diff+xml": { + source: "iana", + compressible: true, + extensions: ["xdf"] + }, + "application/xcap-el+xml": { + source: "iana", + compressible: true, + extensions: ["xel"] + }, + "application/xcap-error+xml": { + source: "iana", + compressible: true + }, + "application/xcap-ns+xml": { + source: "iana", + compressible: true, + extensions: ["xns"] + }, + "application/xcon-conference-info+xml": { + source: "iana", + compressible: true + }, + "application/xcon-conference-info-diff+xml": { + source: "iana", + compressible: true + }, + "application/xenc+xml": { + source: "iana", + compressible: true, + extensions: ["xenc"] + }, + "application/xhtml+xml": { + source: "iana", + compressible: true, + extensions: ["xhtml", "xht"] + }, + "application/xhtml-voice+xml": { + source: "apache", + compressible: true + }, + "application/xliff+xml": { + source: "iana", + compressible: true, + extensions: ["xlf"] + }, + "application/xml": { + source: "iana", + compressible: true, + extensions: ["xml", "xsl", "xsd", "rng"] + }, + "application/xml-dtd": { + source: "iana", + compressible: true, + extensions: ["dtd"] + }, + "application/xml-external-parsed-entity": { + source: "iana" + }, + "application/xml-patch+xml": { + source: "iana", + compressible: true + }, + "application/xmpp+xml": { + source: "iana", + compressible: true + }, + "application/xop+xml": { + source: "iana", + compressible: true, + extensions: ["xop"] + }, + "application/xproc+xml": { + source: "apache", + compressible: true, + extensions: ["xpl"] + }, + "application/xslt+xml": { + source: "iana", + compressible: true, + extensions: ["xsl", "xslt"] + }, + "application/xspf+xml": { + source: "apache", + compressible: true, + extensions: ["xspf"] + }, + "application/xv+xml": { + source: "iana", + compressible: true, + extensions: ["mxml", "xhvml", "xvml", "xvm"] + }, + "application/yang": { + source: "iana", + extensions: ["yang"] + }, + "application/yang-data+json": { + source: "iana", + compressible: true + }, + "application/yang-data+xml": { + source: "iana", + compressible: true + }, + "application/yang-patch+json": { + source: "iana", + compressible: true + }, + "application/yang-patch+xml": { + source: "iana", + compressible: true + }, + "application/yin+xml": { + source: "iana", + compressible: true, + extensions: ["yin"] + }, + "application/zip": { + source: "iana", + compressible: false, + extensions: ["zip"] + }, + "application/zlib": { + source: "iana" + }, + "application/zstd": { + source: "iana" + }, + "audio/1d-interleaved-parityfec": { + source: "iana" + }, + "audio/32kadpcm": { + source: "iana" + }, + "audio/3gpp": { + source: "iana", + compressible: false, + extensions: ["3gpp"] + }, + "audio/3gpp2": { + source: "iana" + }, + "audio/aac": { + source: "iana" + }, + "audio/ac3": { + source: "iana" + }, + "audio/adpcm": { + source: "apache", + extensions: ["adp"] + }, + "audio/amr": { + source: "iana", + extensions: ["amr"] + }, + "audio/amr-wb": { + source: "iana" + }, + "audio/amr-wb+": { + source: "iana" + }, + "audio/aptx": { + source: "iana" + }, + "audio/asc": { + source: "iana" + }, + "audio/atrac-advanced-lossless": { + source: "iana" + }, + "audio/atrac-x": { + source: "iana" + }, + "audio/atrac3": { + source: "iana" + }, + "audio/basic": { + source: "iana", + compressible: false, + extensions: ["au", "snd"] + }, + "audio/bv16": { + source: "iana" + }, + "audio/bv32": { + source: "iana" + }, + "audio/clearmode": { + source: "iana" + }, + "audio/cn": { + source: "iana" + }, + "audio/dat12": { + source: "iana" + }, + "audio/dls": { + source: "iana" + }, + "audio/dsr-es201108": { + source: "iana" + }, + "audio/dsr-es202050": { + source: "iana" + }, + "audio/dsr-es202211": { + source: "iana" + }, + "audio/dsr-es202212": { + source: "iana" + }, + "audio/dv": { + source: "iana" + }, + "audio/dvi4": { + source: "iana" + }, + "audio/eac3": { + source: "iana" + }, + "audio/encaprtp": { + source: "iana" + }, + "audio/evrc": { + source: "iana" + }, + "audio/evrc-qcp": { + source: "iana" + }, + "audio/evrc0": { + source: "iana" + }, + "audio/evrc1": { + source: "iana" + }, + "audio/evrcb": { + source: "iana" + }, + "audio/evrcb0": { + source: "iana" + }, + "audio/evrcb1": { + source: "iana" + }, + "audio/evrcnw": { + source: "iana" + }, + "audio/evrcnw0": { + source: "iana" + }, + "audio/evrcnw1": { + source: "iana" + }, + "audio/evrcwb": { + source: "iana" + }, + "audio/evrcwb0": { + source: "iana" + }, + "audio/evrcwb1": { + source: "iana" + }, + "audio/evs": { + source: "iana" + }, + "audio/flexfec": { + source: "iana" + }, + "audio/fwdred": { + source: "iana" + }, + "audio/g711-0": { + source: "iana" + }, + "audio/g719": { + source: "iana" + }, + "audio/g722": { + source: "iana" + }, + "audio/g7221": { + source: "iana" + }, + "audio/g723": { + source: "iana" + }, + "audio/g726-16": { + source: "iana" + }, + "audio/g726-24": { + source: "iana" + }, + "audio/g726-32": { + source: "iana" + }, + "audio/g726-40": { + source: "iana" + }, + "audio/g728": { + source: "iana" + }, + "audio/g729": { + source: "iana" + }, + "audio/g7291": { + source: "iana" + }, + "audio/g729d": { + source: "iana" + }, + "audio/g729e": { + source: "iana" + }, + "audio/gsm": { + source: "iana" + }, + "audio/gsm-efr": { + source: "iana" + }, + "audio/gsm-hr-08": { + source: "iana" + }, + "audio/ilbc": { + source: "iana" + }, + "audio/ip-mr_v2.5": { + source: "iana" + }, + "audio/isac": { + source: "apache" + }, + "audio/l16": { + source: "iana" + }, + "audio/l20": { + source: "iana" + }, + "audio/l24": { + source: "iana", + compressible: false + }, + "audio/l8": { + source: "iana" + }, + "audio/lpc": { + source: "iana" + }, + "audio/melp": { + source: "iana" + }, + "audio/melp1200": { + source: "iana" + }, + "audio/melp2400": { + source: "iana" + }, + "audio/melp600": { + source: "iana" + }, + "audio/mhas": { + source: "iana" + }, + "audio/midi": { + source: "apache", + extensions: ["mid", "midi", "kar", "rmi"] + }, + "audio/mobile-xmf": { + source: "iana", + extensions: ["mxmf"] + }, + "audio/mp3": { + compressible: false, + extensions: ["mp3"] + }, + "audio/mp4": { + source: "iana", + compressible: false, + extensions: ["m4a", "mp4a"] + }, + "audio/mp4a-latm": { + source: "iana" + }, + "audio/mpa": { + source: "iana" + }, + "audio/mpa-robust": { + source: "iana" + }, + "audio/mpeg": { + source: "iana", + compressible: false, + extensions: ["mpga", "mp2", "mp2a", "mp3", "m2a", "m3a"] + }, + "audio/mpeg4-generic": { + source: "iana" + }, + "audio/musepack": { + source: "apache" + }, + "audio/ogg": { + source: "iana", + compressible: false, + extensions: ["oga", "ogg", "spx", "opus"] + }, + "audio/opus": { + source: "iana" + }, + "audio/parityfec": { + source: "iana" + }, + "audio/pcma": { + source: "iana" + }, + "audio/pcma-wb": { + source: "iana" + }, + "audio/pcmu": { + source: "iana" + }, + "audio/pcmu-wb": { + source: "iana" + }, + "audio/prs.sid": { + source: "iana" + }, + "audio/qcelp": { + source: "iana" + }, + "audio/raptorfec": { + source: "iana" + }, + "audio/red": { + source: "iana" + }, + "audio/rtp-enc-aescm128": { + source: "iana" + }, + "audio/rtp-midi": { + source: "iana" + }, + "audio/rtploopback": { + source: "iana" + }, + "audio/rtx": { + source: "iana" + }, + "audio/s3m": { + source: "apache", + extensions: ["s3m"] + }, + "audio/scip": { + source: "iana" + }, + "audio/silk": { + source: "apache", + extensions: ["sil"] + }, + "audio/smv": { + source: "iana" + }, + "audio/smv-qcp": { + source: "iana" + }, + "audio/smv0": { + source: "iana" + }, + "audio/sofa": { + source: "iana" + }, + "audio/sp-midi": { + source: "iana" + }, + "audio/speex": { + source: "iana" + }, + "audio/t140c": { + source: "iana" + }, + "audio/t38": { + source: "iana" + }, + "audio/telephone-event": { + source: "iana" + }, + "audio/tetra_acelp": { + source: "iana" + }, + "audio/tetra_acelp_bb": { + source: "iana" + }, + "audio/tone": { + source: "iana" + }, + "audio/tsvcis": { + source: "iana" + }, + "audio/uemclip": { + source: "iana" + }, + "audio/ulpfec": { + source: "iana" + }, + "audio/usac": { + source: "iana" + }, + "audio/vdvi": { + source: "iana" + }, + "audio/vmr-wb": { + source: "iana" + }, + "audio/vnd.3gpp.iufp": { + source: "iana" + }, + "audio/vnd.4sb": { + source: "iana" + }, + "audio/vnd.audiokoz": { + source: "iana" + }, + "audio/vnd.celp": { + source: "iana" + }, + "audio/vnd.cisco.nse": { + source: "iana" + }, + "audio/vnd.cmles.radio-events": { + source: "iana" + }, + "audio/vnd.cns.anp1": { + source: "iana" + }, + "audio/vnd.cns.inf1": { + source: "iana" + }, + "audio/vnd.dece.audio": { + source: "iana", + extensions: ["uva", "uvva"] + }, + "audio/vnd.digital-winds": { + source: "iana", + extensions: ["eol"] + }, + "audio/vnd.dlna.adts": { + source: "iana" + }, + "audio/vnd.dolby.heaac.1": { + source: "iana" + }, + "audio/vnd.dolby.heaac.2": { + source: "iana" + }, + "audio/vnd.dolby.mlp": { + source: "iana" + }, + "audio/vnd.dolby.mps": { + source: "iana" + }, + "audio/vnd.dolby.pl2": { + source: "iana" + }, + "audio/vnd.dolby.pl2x": { + source: "iana" + }, + "audio/vnd.dolby.pl2z": { + source: "iana" + }, + "audio/vnd.dolby.pulse.1": { + source: "iana" + }, + "audio/vnd.dra": { + source: "iana", + extensions: ["dra"] + }, + "audio/vnd.dts": { + source: "iana", + extensions: ["dts"] + }, + "audio/vnd.dts.hd": { + source: "iana", + extensions: ["dtshd"] + }, + "audio/vnd.dts.uhd": { + source: "iana" + }, + "audio/vnd.dvb.file": { + source: "iana" + }, + "audio/vnd.everad.plj": { + source: "iana" + }, + "audio/vnd.hns.audio": { + source: "iana" + }, + "audio/vnd.lucent.voice": { + source: "iana", + extensions: ["lvp"] + }, + "audio/vnd.ms-playready.media.pya": { + source: "iana", + extensions: ["pya"] + }, + "audio/vnd.nokia.mobile-xmf": { + source: "iana" + }, + "audio/vnd.nortel.vbk": { + source: "iana" + }, + "audio/vnd.nuera.ecelp4800": { + source: "iana", + extensions: ["ecelp4800"] + }, + "audio/vnd.nuera.ecelp7470": { + source: "iana", + extensions: ["ecelp7470"] + }, + "audio/vnd.nuera.ecelp9600": { + source: "iana", + extensions: ["ecelp9600"] + }, + "audio/vnd.octel.sbc": { + source: "iana" + }, + "audio/vnd.presonus.multitrack": { + source: "iana" + }, + "audio/vnd.qcelp": { + source: "iana" + }, + "audio/vnd.rhetorex.32kadpcm": { + source: "iana" + }, + "audio/vnd.rip": { + source: "iana", + extensions: ["rip"] + }, + "audio/vnd.rn-realaudio": { + compressible: false + }, + "audio/vnd.sealedmedia.softseal.mpeg": { + source: "iana" + }, + "audio/vnd.vmx.cvsd": { + source: "iana" + }, + "audio/vnd.wave": { + compressible: false + }, + "audio/vorbis": { + source: "iana", + compressible: false + }, + "audio/vorbis-config": { + source: "iana" + }, + "audio/wav": { + compressible: false, + extensions: ["wav"] + }, + "audio/wave": { + compressible: false, + extensions: ["wav"] + }, + "audio/webm": { + source: "apache", + compressible: false, + extensions: ["weba"] + }, + "audio/x-aac": { + source: "apache", + compressible: false, + extensions: ["aac"] + }, + "audio/x-aiff": { + source: "apache", + extensions: ["aif", "aiff", "aifc"] + }, + "audio/x-caf": { + source: "apache", + compressible: false, + extensions: ["caf"] + }, + "audio/x-flac": { + source: "apache", + extensions: ["flac"] + }, + "audio/x-m4a": { + source: "nginx", + extensions: ["m4a"] + }, + "audio/x-matroska": { + source: "apache", + extensions: ["mka"] + }, + "audio/x-mpegurl": { + source: "apache", + extensions: ["m3u"] + }, + "audio/x-ms-wax": { + source: "apache", + extensions: ["wax"] + }, + "audio/x-ms-wma": { + source: "apache", + extensions: ["wma"] + }, + "audio/x-pn-realaudio": { + source: "apache", + extensions: ["ram", "ra"] + }, + "audio/x-pn-realaudio-plugin": { + source: "apache", + extensions: ["rmp"] + }, + "audio/x-realaudio": { + source: "nginx", + extensions: ["ra"] + }, + "audio/x-tta": { + source: "apache" + }, + "audio/x-wav": { + source: "apache", + extensions: ["wav"] + }, + "audio/xm": { + source: "apache", + extensions: ["xm"] + }, + "chemical/x-cdx": { + source: "apache", + extensions: ["cdx"] + }, + "chemical/x-cif": { + source: "apache", + extensions: ["cif"] + }, + "chemical/x-cmdf": { + source: "apache", + extensions: ["cmdf"] + }, + "chemical/x-cml": { + source: "apache", + extensions: ["cml"] + }, + "chemical/x-csml": { + source: "apache", + extensions: ["csml"] + }, + "chemical/x-pdb": { + source: "apache" + }, + "chemical/x-xyz": { + source: "apache", + extensions: ["xyz"] + }, + "font/collection": { + source: "iana", + extensions: ["ttc"] + }, + "font/otf": { + source: "iana", + compressible: true, + extensions: ["otf"] + }, + "font/sfnt": { + source: "iana" + }, + "font/ttf": { + source: "iana", + compressible: true, + extensions: ["ttf"] + }, + "font/woff": { + source: "iana", + extensions: ["woff"] + }, + "font/woff2": { + source: "iana", + extensions: ["woff2"] + }, + "image/aces": { + source: "iana", + extensions: ["exr"] + }, + "image/apng": { + compressible: false, + extensions: ["apng"] + }, + "image/avci": { + source: "iana", + extensions: ["avci"] + }, + "image/avcs": { + source: "iana", + extensions: ["avcs"] + }, + "image/avif": { + source: "iana", + compressible: false, + extensions: ["avif"] + }, + "image/bmp": { + source: "iana", + compressible: true, + extensions: ["bmp"] + }, + "image/cgm": { + source: "iana", + extensions: ["cgm"] + }, + "image/dicom-rle": { + source: "iana", + extensions: ["drle"] + }, + "image/emf": { + source: "iana", + extensions: ["emf"] + }, + "image/fits": { + source: "iana", + extensions: ["fits"] + }, + "image/g3fax": { + source: "iana", + extensions: ["g3"] + }, + "image/gif": { + source: "iana", + compressible: false, + extensions: ["gif"] + }, + "image/heic": { + source: "iana", + extensions: ["heic"] + }, + "image/heic-sequence": { + source: "iana", + extensions: ["heics"] + }, + "image/heif": { + source: "iana", + extensions: ["heif"] + }, + "image/heif-sequence": { + source: "iana", + extensions: ["heifs"] + }, + "image/hej2k": { + source: "iana", + extensions: ["hej2"] + }, + "image/hsj2": { + source: "iana", + extensions: ["hsj2"] + }, + "image/ief": { + source: "iana", + extensions: ["ief"] + }, + "image/jls": { + source: "iana", + extensions: ["jls"] + }, + "image/jp2": { + source: "iana", + compressible: false, + extensions: ["jp2", "jpg2"] + }, + "image/jpeg": { + source: "iana", + compressible: false, + extensions: ["jpeg", "jpg", "jpe"] + }, + "image/jph": { + source: "iana", + extensions: ["jph"] + }, + "image/jphc": { + source: "iana", + extensions: ["jhc"] + }, + "image/jpm": { + source: "iana", + compressible: false, + extensions: ["jpm"] + }, + "image/jpx": { + source: "iana", + compressible: false, + extensions: ["jpx", "jpf"] + }, + "image/jxr": { + source: "iana", + extensions: ["jxr"] + }, + "image/jxra": { + source: "iana", + extensions: ["jxra"] + }, + "image/jxrs": { + source: "iana", + extensions: ["jxrs"] + }, + "image/jxs": { + source: "iana", + extensions: ["jxs"] + }, + "image/jxsc": { + source: "iana", + extensions: ["jxsc"] + }, + "image/jxsi": { + source: "iana", + extensions: ["jxsi"] + }, + "image/jxss": { + source: "iana", + extensions: ["jxss"] + }, + "image/ktx": { + source: "iana", + extensions: ["ktx"] + }, + "image/ktx2": { + source: "iana", + extensions: ["ktx2"] + }, + "image/naplps": { + source: "iana" + }, + "image/pjpeg": { + compressible: false + }, + "image/png": { + source: "iana", + compressible: false, + extensions: ["png"] + }, + "image/prs.btif": { + source: "iana", + extensions: ["btif"] + }, + "image/prs.pti": { + source: "iana", + extensions: ["pti"] + }, + "image/pwg-raster": { + source: "iana" + }, + "image/sgi": { + source: "apache", + extensions: ["sgi"] + }, + "image/svg+xml": { + source: "iana", + compressible: true, + extensions: ["svg", "svgz"] + }, + "image/t38": { + source: "iana", + extensions: ["t38"] + }, + "image/tiff": { + source: "iana", + compressible: false, + extensions: ["tif", "tiff"] + }, + "image/tiff-fx": { + source: "iana", + extensions: ["tfx"] + }, + "image/vnd.adobe.photoshop": { + source: "iana", + compressible: true, + extensions: ["psd"] + }, + "image/vnd.airzip.accelerator.azv": { + source: "iana", + extensions: ["azv"] + }, + "image/vnd.cns.inf2": { + source: "iana" + }, + "image/vnd.dece.graphic": { + source: "iana", + extensions: ["uvi", "uvvi", "uvg", "uvvg"] + }, + "image/vnd.djvu": { + source: "iana", + extensions: ["djvu", "djv"] + }, + "image/vnd.dvb.subtitle": { + source: "iana", + extensions: ["sub"] + }, + "image/vnd.dwg": { + source: "iana", + extensions: ["dwg"] + }, + "image/vnd.dxf": { + source: "iana", + extensions: ["dxf"] + }, + "image/vnd.fastbidsheet": { + source: "iana", + extensions: ["fbs"] + }, + "image/vnd.fpx": { + source: "iana", + extensions: ["fpx"] + }, + "image/vnd.fst": { + source: "iana", + extensions: ["fst"] + }, + "image/vnd.fujixerox.edmics-mmr": { + source: "iana", + extensions: ["mmr"] + }, + "image/vnd.fujixerox.edmics-rlc": { + source: "iana", + extensions: ["rlc"] + }, + "image/vnd.globalgraphics.pgb": { + source: "iana" + }, + "image/vnd.microsoft.icon": { + source: "iana", + compressible: true, + extensions: ["ico"] + }, + "image/vnd.mix": { + source: "iana" + }, + "image/vnd.mozilla.apng": { + source: "iana" + }, + "image/vnd.ms-dds": { + compressible: true, + extensions: ["dds"] + }, + "image/vnd.ms-modi": { + source: "iana", + extensions: ["mdi"] + }, + "image/vnd.ms-photo": { + source: "apache", + extensions: ["wdp"] + }, + "image/vnd.net-fpx": { + source: "iana", + extensions: ["npx"] + }, + "image/vnd.pco.b16": { + source: "iana", + extensions: ["b16"] + }, + "image/vnd.radiance": { + source: "iana" + }, + "image/vnd.sealed.png": { + source: "iana" + }, + "image/vnd.sealedmedia.softseal.gif": { + source: "iana" + }, + "image/vnd.sealedmedia.softseal.jpg": { + source: "iana" + }, + "image/vnd.svf": { + source: "iana" + }, + "image/vnd.tencent.tap": { + source: "iana", + extensions: ["tap"] + }, + "image/vnd.valve.source.texture": { + source: "iana", + extensions: ["vtf"] + }, + "image/vnd.wap.wbmp": { + source: "iana", + extensions: ["wbmp"] + }, + "image/vnd.xiff": { + source: "iana", + extensions: ["xif"] + }, + "image/vnd.zbrush.pcx": { + source: "iana", + extensions: ["pcx"] + }, + "image/webp": { + source: "apache", + extensions: ["webp"] + }, + "image/wmf": { + source: "iana", + extensions: ["wmf"] + }, + "image/x-3ds": { + source: "apache", + extensions: ["3ds"] + }, + "image/x-cmu-raster": { + source: "apache", + extensions: ["ras"] + }, + "image/x-cmx": { + source: "apache", + extensions: ["cmx"] + }, + "image/x-freehand": { + source: "apache", + extensions: ["fh", "fhc", "fh4", "fh5", "fh7"] + }, + "image/x-icon": { + source: "apache", + compressible: true, + extensions: ["ico"] + }, + "image/x-jng": { + source: "nginx", + extensions: ["jng"] + }, + "image/x-mrsid-image": { + source: "apache", + extensions: ["sid"] + }, + "image/x-ms-bmp": { + source: "nginx", + compressible: true, + extensions: ["bmp"] + }, + "image/x-pcx": { + source: "apache", + extensions: ["pcx"] + }, + "image/x-pict": { + source: "apache", + extensions: ["pic", "pct"] + }, + "image/x-portable-anymap": { + source: "apache", + extensions: ["pnm"] + }, + "image/x-portable-bitmap": { + source: "apache", + extensions: ["pbm"] + }, + "image/x-portable-graymap": { + source: "apache", + extensions: ["pgm"] + }, + "image/x-portable-pixmap": { + source: "apache", + extensions: ["ppm"] + }, + "image/x-rgb": { + source: "apache", + extensions: ["rgb"] + }, + "image/x-tga": { + source: "apache", + extensions: ["tga"] + }, + "image/x-xbitmap": { + source: "apache", + extensions: ["xbm"] + }, + "image/x-xcf": { + compressible: false + }, + "image/x-xpixmap": { + source: "apache", + extensions: ["xpm"] + }, + "image/x-xwindowdump": { + source: "apache", + extensions: ["xwd"] + }, + "message/cpim": { + source: "iana" + }, + "message/delivery-status": { + source: "iana" + }, + "message/disposition-notification": { + source: "iana", + extensions: [ + "disposition-notification" + ] + }, + "message/external-body": { + source: "iana" + }, + "message/feedback-report": { + source: "iana" + }, + "message/global": { + source: "iana", + extensions: ["u8msg"] + }, + "message/global-delivery-status": { + source: "iana", + extensions: ["u8dsn"] + }, + "message/global-disposition-notification": { + source: "iana", + extensions: ["u8mdn"] + }, + "message/global-headers": { + source: "iana", + extensions: ["u8hdr"] + }, + "message/http": { + source: "iana", + compressible: false + }, + "message/imdn+xml": { + source: "iana", + compressible: true + }, + "message/news": { + source: "iana" + }, + "message/partial": { + source: "iana", + compressible: false + }, + "message/rfc822": { + source: "iana", + compressible: true, + extensions: ["eml", "mime"] + }, + "message/s-http": { + source: "iana" + }, + "message/sip": { + source: "iana" + }, + "message/sipfrag": { + source: "iana" + }, + "message/tracking-status": { + source: "iana" + }, + "message/vnd.si.simp": { + source: "iana" + }, + "message/vnd.wfa.wsc": { + source: "iana", + extensions: ["wsc"] + }, + "model/3mf": { + source: "iana", + extensions: ["3mf"] + }, + "model/e57": { + source: "iana" + }, + "model/gltf+json": { + source: "iana", + compressible: true, + extensions: ["gltf"] + }, + "model/gltf-binary": { + source: "iana", + compressible: true, + extensions: ["glb"] + }, + "model/iges": { + source: "iana", + compressible: false, + extensions: ["igs", "iges"] + }, + "model/mesh": { + source: "iana", + compressible: false, + extensions: ["msh", "mesh", "silo"] + }, + "model/mtl": { + source: "iana", + extensions: ["mtl"] + }, + "model/obj": { + source: "iana", + extensions: ["obj"] + }, + "model/step": { + source: "iana" + }, + "model/step+xml": { + source: "iana", + compressible: true, + extensions: ["stpx"] + }, + "model/step+zip": { + source: "iana", + compressible: false, + extensions: ["stpz"] + }, + "model/step-xml+zip": { + source: "iana", + compressible: false, + extensions: ["stpxz"] + }, + "model/stl": { + source: "iana", + extensions: ["stl"] + }, + "model/vnd.collada+xml": { + source: "iana", + compressible: true, + extensions: ["dae"] + }, + "model/vnd.dwf": { + source: "iana", + extensions: ["dwf"] + }, + "model/vnd.flatland.3dml": { + source: "iana" + }, + "model/vnd.gdl": { + source: "iana", + extensions: ["gdl"] + }, + "model/vnd.gs-gdl": { + source: "apache" + }, + "model/vnd.gs.gdl": { + source: "iana" + }, + "model/vnd.gtw": { + source: "iana", + extensions: ["gtw"] + }, + "model/vnd.moml+xml": { + source: "iana", + compressible: true + }, + "model/vnd.mts": { + source: "iana", + extensions: ["mts"] + }, + "model/vnd.opengex": { + source: "iana", + extensions: ["ogex"] + }, + "model/vnd.parasolid.transmit.binary": { + source: "iana", + extensions: ["x_b"] + }, + "model/vnd.parasolid.transmit.text": { + source: "iana", + extensions: ["x_t"] + }, + "model/vnd.pytha.pyox": { + source: "iana" + }, + "model/vnd.rosette.annotated-data-model": { + source: "iana" + }, + "model/vnd.sap.vds": { + source: "iana", + extensions: ["vds"] + }, + "model/vnd.usdz+zip": { + source: "iana", + compressible: false, + extensions: ["usdz"] + }, + "model/vnd.valve.source.compiled-map": { + source: "iana", + extensions: ["bsp"] + }, + "model/vnd.vtu": { + source: "iana", + extensions: ["vtu"] + }, + "model/vrml": { + source: "iana", + compressible: false, + extensions: ["wrl", "vrml"] + }, + "model/x3d+binary": { + source: "apache", + compressible: false, + extensions: ["x3db", "x3dbz"] + }, + "model/x3d+fastinfoset": { + source: "iana", + extensions: ["x3db"] + }, + "model/x3d+vrml": { + source: "apache", + compressible: false, + extensions: ["x3dv", "x3dvz"] + }, + "model/x3d+xml": { + source: "iana", + compressible: true, + extensions: ["x3d", "x3dz"] + }, + "model/x3d-vrml": { + source: "iana", + extensions: ["x3dv"] + }, + "multipart/alternative": { + source: "iana", + compressible: false + }, + "multipart/appledouble": { + source: "iana" + }, + "multipart/byteranges": { + source: "iana" + }, + "multipart/digest": { + source: "iana" + }, + "multipart/encrypted": { + source: "iana", + compressible: false + }, + "multipart/form-data": { + source: "iana", + compressible: false + }, + "multipart/header-set": { + source: "iana" + }, + "multipart/mixed": { + source: "iana" + }, + "multipart/multilingual": { + source: "iana" + }, + "multipart/parallel": { + source: "iana" + }, + "multipart/related": { + source: "iana", + compressible: false + }, + "multipart/report": { + source: "iana" + }, + "multipart/signed": { + source: "iana", + compressible: false + }, + "multipart/vnd.bint.med-plus": { + source: "iana" + }, + "multipart/voice-message": { + source: "iana" + }, + "multipart/x-mixed-replace": { + source: "iana" + }, + "text/1d-interleaved-parityfec": { + source: "iana" + }, + "text/cache-manifest": { + source: "iana", + compressible: true, + extensions: ["appcache", "manifest"] + }, + "text/calendar": { + source: "iana", + extensions: ["ics", "ifb"] + }, + "text/calender": { + compressible: true + }, + "text/cmd": { + compressible: true + }, + "text/coffeescript": { + extensions: ["coffee", "litcoffee"] + }, + "text/cql": { + source: "iana" + }, + "text/cql-expression": { + source: "iana" + }, + "text/cql-identifier": { + source: "iana" + }, + "text/css": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["css"] + }, + "text/csv": { + source: "iana", + compressible: true, + extensions: ["csv"] + }, + "text/csv-schema": { + source: "iana" + }, + "text/directory": { + source: "iana" + }, + "text/dns": { + source: "iana" + }, + "text/ecmascript": { + source: "iana" + }, + "text/encaprtp": { + source: "iana" + }, + "text/enriched": { + source: "iana" + }, + "text/fhirpath": { + source: "iana" + }, + "text/flexfec": { + source: "iana" + }, + "text/fwdred": { + source: "iana" + }, + "text/gff3": { + source: "iana" + }, + "text/grammar-ref-list": { + source: "iana" + }, + "text/html": { + source: "iana", + compressible: true, + extensions: ["html", "htm", "shtml"] + }, + "text/jade": { + extensions: ["jade"] + }, + "text/javascript": { + source: "iana", + compressible: true + }, + "text/jcr-cnd": { + source: "iana" + }, + "text/jsx": { + compressible: true, + extensions: ["jsx"] + }, + "text/less": { + compressible: true, + extensions: ["less"] + }, + "text/markdown": { + source: "iana", + compressible: true, + extensions: ["markdown", "md"] + }, + "text/mathml": { + source: "nginx", + extensions: ["mml"] + }, + "text/mdx": { + compressible: true, + extensions: ["mdx"] + }, + "text/mizar": { + source: "iana" + }, + "text/n3": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["n3"] + }, + "text/parameters": { + source: "iana", + charset: "UTF-8" + }, + "text/parityfec": { + source: "iana" + }, + "text/plain": { + source: "iana", + compressible: true, + extensions: ["txt", "text", "conf", "def", "list", "log", "in", "ini"] + }, + "text/provenance-notation": { + source: "iana", + charset: "UTF-8" + }, + "text/prs.fallenstein.rst": { + source: "iana" + }, + "text/prs.lines.tag": { + source: "iana", + extensions: ["dsc"] + }, + "text/prs.prop.logic": { + source: "iana" + }, + "text/raptorfec": { + source: "iana" + }, + "text/red": { + source: "iana" + }, + "text/rfc822-headers": { + source: "iana" + }, + "text/richtext": { + source: "iana", + compressible: true, + extensions: ["rtx"] + }, + "text/rtf": { + source: "iana", + compressible: true, + extensions: ["rtf"] + }, + "text/rtp-enc-aescm128": { + source: "iana" + }, + "text/rtploopback": { + source: "iana" + }, + "text/rtx": { + source: "iana" + }, + "text/sgml": { + source: "iana", + extensions: ["sgml", "sgm"] + }, + "text/shaclc": { + source: "iana" + }, + "text/shex": { + source: "iana", + extensions: ["shex"] + }, + "text/slim": { + extensions: ["slim", "slm"] + }, + "text/spdx": { + source: "iana", + extensions: ["spdx"] + }, + "text/strings": { + source: "iana" + }, + "text/stylus": { + extensions: ["stylus", "styl"] + }, + "text/t140": { + source: "iana" + }, + "text/tab-separated-values": { + source: "iana", + compressible: true, + extensions: ["tsv"] + }, + "text/troff": { + source: "iana", + extensions: ["t", "tr", "roff", "man", "me", "ms"] + }, + "text/turtle": { + source: "iana", + charset: "UTF-8", + extensions: ["ttl"] + }, + "text/ulpfec": { + source: "iana" + }, + "text/uri-list": { + source: "iana", + compressible: true, + extensions: ["uri", "uris", "urls"] + }, + "text/vcard": { + source: "iana", + compressible: true, + extensions: ["vcard"] + }, + "text/vnd.a": { + source: "iana" + }, + "text/vnd.abc": { + source: "iana" + }, + "text/vnd.ascii-art": { + source: "iana" + }, + "text/vnd.curl": { + source: "iana", + extensions: ["curl"] + }, + "text/vnd.curl.dcurl": { + source: "apache", + extensions: ["dcurl"] + }, + "text/vnd.curl.mcurl": { + source: "apache", + extensions: ["mcurl"] + }, + "text/vnd.curl.scurl": { + source: "apache", + extensions: ["scurl"] + }, + "text/vnd.debian.copyright": { + source: "iana", + charset: "UTF-8" + }, + "text/vnd.dmclientscript": { + source: "iana" + }, + "text/vnd.dvb.subtitle": { + source: "iana", + extensions: ["sub"] + }, + "text/vnd.esmertec.theme-descriptor": { + source: "iana", + charset: "UTF-8" + }, + "text/vnd.familysearch.gedcom": { + source: "iana", + extensions: ["ged"] + }, + "text/vnd.ficlab.flt": { + source: "iana" + }, + "text/vnd.fly": { + source: "iana", + extensions: ["fly"] + }, + "text/vnd.fmi.flexstor": { + source: "iana", + extensions: ["flx"] + }, + "text/vnd.gml": { + source: "iana" + }, + "text/vnd.graphviz": { + source: "iana", + extensions: ["gv"] + }, + "text/vnd.hans": { + source: "iana" + }, + "text/vnd.hgl": { + source: "iana" + }, + "text/vnd.in3d.3dml": { + source: "iana", + extensions: ["3dml"] + }, + "text/vnd.in3d.spot": { + source: "iana", + extensions: ["spot"] + }, + "text/vnd.iptc.newsml": { + source: "iana" + }, + "text/vnd.iptc.nitf": { + source: "iana" + }, + "text/vnd.latex-z": { + source: "iana" + }, + "text/vnd.motorola.reflex": { + source: "iana" + }, + "text/vnd.ms-mediapackage": { + source: "iana" + }, + "text/vnd.net2phone.commcenter.command": { + source: "iana" + }, + "text/vnd.radisys.msml-basic-layout": { + source: "iana" + }, + "text/vnd.senx.warpscript": { + source: "iana" + }, + "text/vnd.si.uricatalogue": { + source: "iana" + }, + "text/vnd.sosi": { + source: "iana" + }, + "text/vnd.sun.j2me.app-descriptor": { + source: "iana", + charset: "UTF-8", + extensions: ["jad"] + }, + "text/vnd.trolltech.linguist": { + source: "iana", + charset: "UTF-8" + }, + "text/vnd.wap.si": { + source: "iana" + }, + "text/vnd.wap.sl": { + source: "iana" + }, + "text/vnd.wap.wml": { + source: "iana", + extensions: ["wml"] + }, + "text/vnd.wap.wmlscript": { + source: "iana", + extensions: ["wmls"] + }, + "text/vtt": { + source: "iana", + charset: "UTF-8", + compressible: true, + extensions: ["vtt"] + }, + "text/x-asm": { + source: "apache", + extensions: ["s", "asm"] + }, + "text/x-c": { + source: "apache", + extensions: ["c", "cc", "cxx", "cpp", "h", "hh", "dic"] + }, + "text/x-component": { + source: "nginx", + extensions: ["htc"] + }, + "text/x-fortran": { + source: "apache", + extensions: ["f", "for", "f77", "f90"] + }, + "text/x-gwt-rpc": { + compressible: true + }, + "text/x-handlebars-template": { + extensions: ["hbs"] + }, + "text/x-java-source": { + source: "apache", + extensions: ["java"] + }, + "text/x-jquery-tmpl": { + compressible: true + }, + "text/x-lua": { + extensions: ["lua"] + }, + "text/x-markdown": { + compressible: true, + extensions: ["mkd"] + }, + "text/x-nfo": { + source: "apache", + extensions: ["nfo"] + }, + "text/x-opml": { + source: "apache", + extensions: ["opml"] + }, + "text/x-org": { + compressible: true, + extensions: ["org"] + }, + "text/x-pascal": { + source: "apache", + extensions: ["p", "pas"] + }, + "text/x-processing": { + compressible: true, + extensions: ["pde"] + }, + "text/x-sass": { + extensions: ["sass"] + }, + "text/x-scss": { + extensions: ["scss"] + }, + "text/x-setext": { + source: "apache", + extensions: ["etx"] + }, + "text/x-sfv": { + source: "apache", + extensions: ["sfv"] + }, + "text/x-suse-ymp": { + compressible: true, + extensions: ["ymp"] + }, + "text/x-uuencode": { + source: "apache", + extensions: ["uu"] + }, + "text/x-vcalendar": { + source: "apache", + extensions: ["vcs"] + }, + "text/x-vcard": { + source: "apache", + extensions: ["vcf"] + }, + "text/xml": { + source: "iana", + compressible: true, + extensions: ["xml"] + }, + "text/xml-external-parsed-entity": { + source: "iana" + }, + "text/yaml": { + compressible: true, + extensions: ["yaml", "yml"] + }, + "video/1d-interleaved-parityfec": { + source: "iana" + }, + "video/3gpp": { + source: "iana", + extensions: ["3gp", "3gpp"] + }, + "video/3gpp-tt": { + source: "iana" + }, + "video/3gpp2": { + source: "iana", + extensions: ["3g2"] + }, + "video/av1": { + source: "iana" + }, + "video/bmpeg": { + source: "iana" + }, + "video/bt656": { + source: "iana" + }, + "video/celb": { + source: "iana" + }, + "video/dv": { + source: "iana" + }, + "video/encaprtp": { + source: "iana" + }, + "video/ffv1": { + source: "iana" + }, + "video/flexfec": { + source: "iana" + }, + "video/h261": { + source: "iana", + extensions: ["h261"] + }, + "video/h263": { + source: "iana", + extensions: ["h263"] + }, + "video/h263-1998": { + source: "iana" + }, + "video/h263-2000": { + source: "iana" + }, + "video/h264": { + source: "iana", + extensions: ["h264"] + }, + "video/h264-rcdo": { + source: "iana" + }, + "video/h264-svc": { + source: "iana" + }, + "video/h265": { + source: "iana" + }, + "video/iso.segment": { + source: "iana", + extensions: ["m4s"] + }, + "video/jpeg": { + source: "iana", + extensions: ["jpgv"] + }, + "video/jpeg2000": { + source: "iana" + }, + "video/jpm": { + source: "apache", + extensions: ["jpm", "jpgm"] + }, + "video/jxsv": { + source: "iana" + }, + "video/mj2": { + source: "iana", + extensions: ["mj2", "mjp2"] + }, + "video/mp1s": { + source: "iana" + }, + "video/mp2p": { + source: "iana" + }, + "video/mp2t": { + source: "iana", + extensions: ["ts"] + }, + "video/mp4": { + source: "iana", + compressible: false, + extensions: ["mp4", "mp4v", "mpg4"] + }, + "video/mp4v-es": { + source: "iana" + }, + "video/mpeg": { + source: "iana", + compressible: false, + extensions: ["mpeg", "mpg", "mpe", "m1v", "m2v"] + }, + "video/mpeg4-generic": { + source: "iana" + }, + "video/mpv": { + source: "iana" + }, + "video/nv": { + source: "iana" + }, + "video/ogg": { + source: "iana", + compressible: false, + extensions: ["ogv"] + }, + "video/parityfec": { + source: "iana" + }, + "video/pointer": { + source: "iana" + }, + "video/quicktime": { + source: "iana", + compressible: false, + extensions: ["qt", "mov"] + }, + "video/raptorfec": { + source: "iana" + }, + "video/raw": { + source: "iana" + }, + "video/rtp-enc-aescm128": { + source: "iana" + }, + "video/rtploopback": { + source: "iana" + }, + "video/rtx": { + source: "iana" + }, + "video/scip": { + source: "iana" + }, + "video/smpte291": { + source: "iana" + }, + "video/smpte292m": { + source: "iana" + }, + "video/ulpfec": { + source: "iana" + }, + "video/vc1": { + source: "iana" + }, + "video/vc2": { + source: "iana" + }, + "video/vnd.cctv": { + source: "iana" + }, + "video/vnd.dece.hd": { + source: "iana", + extensions: ["uvh", "uvvh"] + }, + "video/vnd.dece.mobile": { + source: "iana", + extensions: ["uvm", "uvvm"] + }, + "video/vnd.dece.mp4": { + source: "iana" + }, + "video/vnd.dece.pd": { + source: "iana", + extensions: ["uvp", "uvvp"] + }, + "video/vnd.dece.sd": { + source: "iana", + extensions: ["uvs", "uvvs"] + }, + "video/vnd.dece.video": { + source: "iana", + extensions: ["uvv", "uvvv"] + }, + "video/vnd.directv.mpeg": { + source: "iana" + }, + "video/vnd.directv.mpeg-tts": { + source: "iana" + }, + "video/vnd.dlna.mpeg-tts": { + source: "iana" + }, + "video/vnd.dvb.file": { + source: "iana", + extensions: ["dvb"] + }, + "video/vnd.fvt": { + source: "iana", + extensions: ["fvt"] + }, + "video/vnd.hns.video": { + source: "iana" + }, + "video/vnd.iptvforum.1dparityfec-1010": { + source: "iana" + }, + "video/vnd.iptvforum.1dparityfec-2005": { + source: "iana" + }, + "video/vnd.iptvforum.2dparityfec-1010": { + source: "iana" + }, + "video/vnd.iptvforum.2dparityfec-2005": { + source: "iana" + }, + "video/vnd.iptvforum.ttsavc": { + source: "iana" + }, + "video/vnd.iptvforum.ttsmpeg2": { + source: "iana" + }, + "video/vnd.motorola.video": { + source: "iana" + }, + "video/vnd.motorola.videop": { + source: "iana" + }, + "video/vnd.mpegurl": { + source: "iana", + extensions: ["mxu", "m4u"] + }, + "video/vnd.ms-playready.media.pyv": { + source: "iana", + extensions: ["pyv"] + }, + "video/vnd.nokia.interleaved-multimedia": { + source: "iana" + }, + "video/vnd.nokia.mp4vr": { + source: "iana" + }, + "video/vnd.nokia.videovoip": { + source: "iana" + }, + "video/vnd.objectvideo": { + source: "iana" + }, + "video/vnd.radgamettools.bink": { + source: "iana" + }, + "video/vnd.radgamettools.smacker": { + source: "iana" + }, + "video/vnd.sealed.mpeg1": { + source: "iana" + }, + "video/vnd.sealed.mpeg4": { + source: "iana" + }, + "video/vnd.sealed.swf": { + source: "iana" + }, + "video/vnd.sealedmedia.softseal.mov": { + source: "iana" + }, + "video/vnd.uvvu.mp4": { + source: "iana", + extensions: ["uvu", "uvvu"] + }, + "video/vnd.vivo": { + source: "iana", + extensions: ["viv"] + }, + "video/vnd.youtube.yt": { + source: "iana" + }, + "video/vp8": { + source: "iana" + }, + "video/vp9": { + source: "iana" + }, + "video/webm": { + source: "apache", + compressible: false, + extensions: ["webm"] + }, + "video/x-f4v": { + source: "apache", + extensions: ["f4v"] + }, + "video/x-fli": { + source: "apache", + extensions: ["fli"] + }, + "video/x-flv": { + source: "apache", + compressible: false, + extensions: ["flv"] + }, + "video/x-m4v": { + source: "apache", + extensions: ["m4v"] + }, + "video/x-matroska": { + source: "apache", + compressible: false, + extensions: ["mkv", "mk3d", "mks"] + }, + "video/x-mng": { + source: "apache", + extensions: ["mng"] + }, + "video/x-ms-asf": { + source: "apache", + extensions: ["asf", "asx"] + }, + "video/x-ms-vob": { + source: "apache", + extensions: ["vob"] + }, + "video/x-ms-wm": { + source: "apache", + extensions: ["wm"] + }, + "video/x-ms-wmv": { + source: "apache", + compressible: false, + extensions: ["wmv"] + }, + "video/x-ms-wmx": { + source: "apache", + extensions: ["wmx"] + }, + "video/x-ms-wvx": { + source: "apache", + extensions: ["wvx"] + }, + "video/x-msvideo": { + source: "apache", + extensions: ["avi"] + }, + "video/x-sgi-movie": { + source: "apache", + extensions: ["movie"] + }, + "video/x-smv": { + source: "apache", + extensions: ["smv"] + }, + "x-conference/x-cooltalk": { + source: "apache", + extensions: ["ice"] + }, + "x-shader/x-fragment": { + compressible: true + }, + "x-shader/x-vertex": { + compressible: true + } + }; + } +}); + +// node_modules/mime-db/index.js +var require_mime_db = __commonJS({ + "node_modules/mime-db/index.js"(exports2, module2) { + module2.exports = require_db(); + } +}); + +// node_modules/mime-types/index.js +var require_mime_types = __commonJS({ + "node_modules/mime-types/index.js"(exports2) { + "use strict"; + var db = require_mime_db(); + var extname = require("path").extname; + var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/; + var TEXT_TYPE_REGEXP = /^text\//i; + exports2.charset = charset; + exports2.charsets = { lookup: charset }; + exports2.contentType = contentType; + exports2.extension = extension; + exports2.extensions = /* @__PURE__ */ Object.create(null); + exports2.lookup = lookup; + exports2.types = /* @__PURE__ */ Object.create(null); + populateMaps(exports2.extensions, exports2.types); + function charset(type) { + if (!type || typeof type !== "string") { + return false; + } + var match = EXTRACT_TYPE_REGEXP.exec(type); + var mime = match && db[match[1].toLowerCase()]; + if (mime && mime.charset) { + return mime.charset; + } + if (match && TEXT_TYPE_REGEXP.test(match[1])) { + return "UTF-8"; + } + return false; + } + function contentType(str) { + if (!str || typeof str !== "string") { + return false; + } + var mime = str.indexOf("/") === -1 ? exports2.lookup(str) : str; + if (!mime) { + return false; + } + if (mime.indexOf("charset") === -1) { + var charset2 = exports2.charset(mime); + if (charset2) mime += "; charset=" + charset2.toLowerCase(); + } + return mime; + } + function extension(type) { + if (!type || typeof type !== "string") { + return false; + } + var match = EXTRACT_TYPE_REGEXP.exec(type); + var exts = match && exports2.extensions[match[1].toLowerCase()]; + if (!exts || !exts.length) { + return false; + } + return exts[0]; + } + function lookup(path3) { + if (!path3 || typeof path3 !== "string") { + return false; + } + var extension2 = extname("x." + path3).toLowerCase().substr(1); + if (!extension2) { + return false; + } + return exports2.types[extension2] || false; + } + function populateMaps(extensions, types) { + var preference = ["nginx", "apache", void 0, "iana"]; + Object.keys(db).forEach(function forEachMimeType(type) { + var mime = db[type]; + var exts = mime.extensions; + if (!exts || !exts.length) { + return; + } + extensions[type] = exts; + for (var i = 0; i < exts.length; i++) { + var extension2 = exts[i]; + if (types[extension2]) { + var from = preference.indexOf(db[types[extension2]].source); + var to = preference.indexOf(mime.source); + if (types[extension2] !== "application/octet-stream" && (from > to || from === to && types[extension2].substr(0, 12) === "application/")) { + continue; + } + } + types[extension2] = type; + } + }); + } + } +}); + +// node_modules/type-is/index.js +var require_type_is = __commonJS({ + "node_modules/type-is/index.js"(exports2, module2) { + "use strict"; + var typer = require_media_typer(); + var mime = require_mime_types(); + module2.exports = typeofrequest; + module2.exports.is = typeis; + module2.exports.hasBody = hasbody; + module2.exports.normalize = normalize; + module2.exports.match = mimeMatch; + function typeis(value, types_) { + var i; + var types = types_; + var val = tryNormalizeType(value); + if (!val) { + return false; + } + if (types && !Array.isArray(types)) { + types = new Array(arguments.length - 1); + for (i = 0; i < types.length; i++) { + types[i] = arguments[i + 1]; + } + } + if (!types || !types.length) { + return val; + } + var type; + for (i = 0; i < types.length; i++) { + if (mimeMatch(normalize(type = types[i]), val)) { + return type[0] === "+" || type.indexOf("*") !== -1 ? val : type; + } + } + return false; + } + function hasbody(req) { + return req.headers["transfer-encoding"] !== void 0 || !isNaN(req.headers["content-length"]); + } + function typeofrequest(req, types_) { + var types = types_; + if (!hasbody(req)) { + return null; + } + if (arguments.length > 2) { + types = new Array(arguments.length - 1); + for (var i = 0; i < types.length; i++) { + types[i] = arguments[i + 1]; + } + } + var value = req.headers["content-type"]; + return typeis(value, types); + } + function normalize(type) { + if (typeof type !== "string") { + return false; + } + switch (type) { + case "urlencoded": + return "application/x-www-form-urlencoded"; + case "multipart": + return "multipart/*"; + } + if (type[0] === "+") { + return "*/*" + type; + } + return type.indexOf("/") === -1 ? mime.lookup(type) : type; + } + function mimeMatch(expected, actual) { + if (expected === false) { + return false; + } + var actualParts = actual.split("/"); + var expectedParts = expected.split("/"); + if (actualParts.length !== 2 || expectedParts.length !== 2) { + return false; + } + if (expectedParts[0] !== "*" && expectedParts[0] !== actualParts[0]) { + return false; + } + if (expectedParts[1].substr(0, 2) === "*+") { + return expectedParts[1].length <= actualParts[1].length + 1 && expectedParts[1].substr(1) === actualParts[1].substr(1 - expectedParts[1].length); + } + if (expectedParts[1] !== "*" && expectedParts[1] !== actualParts[1]) { + return false; + } + return true; + } + function normalizeType(value) { + var type = typer.parse(value); + type.parameters = void 0; + return typer.format(type); + } + function tryNormalizeType(value) { + if (!value) { + return null; + } + try { + return normalizeType(value); + } catch (err) { + return null; + } + } + } +}); + +// node_modules/body-parser/lib/types/json.js +var require_json = __commonJS({ + "node_modules/body-parser/lib/types/json.js"(exports2, module2) { + "use strict"; + var bytes = require_bytes(); + var contentType = require_content_type(); + var createError = require_http_errors(); + var debug = require_src()("body-parser:json"); + var read = require_read(); + var typeis = require_type_is(); + module2.exports = json; + var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/; + var JSON_SYNTAX_CHAR = "#"; + var JSON_SYNTAX_REGEXP = /#+/g; + function json(options) { + var opts = options || {}; + var limit = typeof opts.limit !== "number" ? bytes.parse(opts.limit || "100kb") : opts.limit; + var inflate = opts.inflate !== false; + var reviver = opts.reviver; + var strict = opts.strict !== false; + var type = opts.type || "application/json"; + var verify = opts.verify || false; + if (verify !== false && typeof verify !== "function") { + throw new TypeError("option verify must be function"); + } + var shouldParse = typeof type !== "function" ? typeChecker(type) : type; + function parse4(body) { + if (body.length === 0) { + return {}; + } + if (strict) { + var first = firstchar(body); + if (first !== "{" && first !== "[") { + debug("strict violation"); + throw createStrictSyntaxError(body, first); + } + } + try { + debug("parse json"); + return JSON.parse(body, reviver); + } catch (e) { + throw normalizeJsonSyntaxError(e, { + message: e.message, + stack: e.stack + }); + } + } + return function jsonParser(req, res, next) { + if (req._body) { + debug("body already parsed"); + next(); + return; + } + req.body = req.body || {}; + if (!typeis.hasBody(req)) { + debug("skip empty body"); + next(); + return; + } + debug("content-type %j", req.headers["content-type"]); + if (!shouldParse(req)) { + debug("skip parsing"); + next(); + return; + } + var charset = getCharset(req) || "utf-8"; + if (charset.slice(0, 4) !== "utf-") { + debug("invalid charset"); + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset, + type: "charset.unsupported" + })); + return; + } + read(req, res, next, parse4, debug, { + encoding: charset, + inflate, + limit, + verify + }); + }; + } + function createStrictSyntaxError(str, char) { + var index = str.indexOf(char); + var partial = ""; + if (index !== -1) { + partial = str.substring(0, index) + JSON_SYNTAX_CHAR; + for (var i = index + 1; i < str.length; i++) { + partial += JSON_SYNTAX_CHAR; + } + } + try { + JSON.parse(partial); + throw new SyntaxError("strict violation"); + } catch (e) { + return normalizeJsonSyntaxError(e, { + message: e.message.replace(JSON_SYNTAX_REGEXP, function(placeholder) { + return str.substring(index, index + placeholder.length); + }), + stack: e.stack + }); + } + } + function firstchar(str) { + var match = FIRST_CHAR_REGEXP.exec(str); + return match ? match[1] : void 0; + } + function getCharset(req) { + try { + return (contentType.parse(req).parameters.charset || "").toLowerCase(); + } catch (e) { + return void 0; + } + } + function normalizeJsonSyntaxError(error, obj) { + var keys = Object.getOwnPropertyNames(error); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (key !== "stack" && key !== "message") { + delete error[key]; + } + } + error.stack = obj.stack.replace(error.message, obj.message); + error.message = obj.message; + return error; + } + function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)); + }; + } + } +}); + +// node_modules/body-parser/lib/types/raw.js +var require_raw = __commonJS({ + "node_modules/body-parser/lib/types/raw.js"(exports2, module2) { + "use strict"; + var bytes = require_bytes(); + var debug = require_src()("body-parser:raw"); + var read = require_read(); + var typeis = require_type_is(); + module2.exports = raw; + function raw(options) { + var opts = options || {}; + var inflate = opts.inflate !== false; + var limit = typeof opts.limit !== "number" ? bytes.parse(opts.limit || "100kb") : opts.limit; + var type = opts.type || "application/octet-stream"; + var verify = opts.verify || false; + if (verify !== false && typeof verify !== "function") { + throw new TypeError("option verify must be function"); + } + var shouldParse = typeof type !== "function" ? typeChecker(type) : type; + function parse4(buf) { + return buf; + } + return function rawParser(req, res, next) { + if (req._body) { + debug("body already parsed"); + next(); + return; + } + req.body = req.body || {}; + if (!typeis.hasBody(req)) { + debug("skip empty body"); + next(); + return; + } + debug("content-type %j", req.headers["content-type"]); + if (!shouldParse(req)) { + debug("skip parsing"); + next(); + return; + } + read(req, res, next, parse4, debug, { + encoding: null, + inflate, + limit, + verify + }); + }; + } + function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)); + }; + } + } +}); + +// node_modules/body-parser/lib/types/text.js +var require_text = __commonJS({ + "node_modules/body-parser/lib/types/text.js"(exports2, module2) { + "use strict"; + var bytes = require_bytes(); + var contentType = require_content_type(); + var debug = require_src()("body-parser:text"); + var read = require_read(); + var typeis = require_type_is(); + module2.exports = text; + function text(options) { + var opts = options || {}; + var defaultCharset = opts.defaultCharset || "utf-8"; + var inflate = opts.inflate !== false; + var limit = typeof opts.limit !== "number" ? bytes.parse(opts.limit || "100kb") : opts.limit; + var type = opts.type || "text/plain"; + var verify = opts.verify || false; + if (verify !== false && typeof verify !== "function") { + throw new TypeError("option verify must be function"); + } + var shouldParse = typeof type !== "function" ? typeChecker(type) : type; + function parse4(buf) { + return buf; + } + return function textParser(req, res, next) { + if (req._body) { + debug("body already parsed"); + next(); + return; + } + req.body = req.body || {}; + if (!typeis.hasBody(req)) { + debug("skip empty body"); + next(); + return; + } + debug("content-type %j", req.headers["content-type"]); + if (!shouldParse(req)) { + debug("skip parsing"); + next(); + return; + } + var charset = getCharset(req) || defaultCharset; + read(req, res, next, parse4, debug, { + encoding: charset, + inflate, + limit, + verify + }); + }; + } + function getCharset(req) { + try { + return (contentType.parse(req).parameters.charset || "").toLowerCase(); + } catch (e) { + return void 0; + } + } + function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)); + }; + } + } +}); + +// node_modules/es-errors/type.js +var require_type = __commonJS({ + "node_modules/es-errors/type.js"(exports2, module2) { + "use strict"; + module2.exports = TypeError; + } +}); + +// node_modules/object-inspect/util.inspect.js +var require_util_inspect = __commonJS({ + "node_modules/object-inspect/util.inspect.js"(exports2, module2) { + module2.exports = require("util").inspect; + } +}); + +// node_modules/object-inspect/index.js +var require_object_inspect = __commonJS({ + "node_modules/object-inspect/index.js"(exports2, module2) { + var hasMap = typeof Map === "function" && Map.prototype; + var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, "size") : null; + var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === "function" ? mapSizeDescriptor.get : null; + var mapForEach = hasMap && Map.prototype.forEach; + var hasSet = typeof Set === "function" && Set.prototype; + var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, "size") : null; + var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === "function" ? setSizeDescriptor.get : null; + var setForEach = hasSet && Set.prototype.forEach; + var hasWeakMap = typeof WeakMap === "function" && WeakMap.prototype; + var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null; + var hasWeakSet = typeof WeakSet === "function" && WeakSet.prototype; + var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null; + var hasWeakRef = typeof WeakRef === "function" && WeakRef.prototype; + var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null; + var booleanValueOf = Boolean.prototype.valueOf; + var objectToString = Object.prototype.toString; + var functionToString = Function.prototype.toString; + var $match = String.prototype.match; + var $slice = String.prototype.slice; + var $replace = String.prototype.replace; + var $toUpperCase = String.prototype.toUpperCase; + var $toLowerCase = String.prototype.toLowerCase; + var $test = RegExp.prototype.test; + var $concat = Array.prototype.concat; + var $join = Array.prototype.join; + var $arrSlice = Array.prototype.slice; + var $floor = Math.floor; + var bigIntValueOf = typeof BigInt === "function" ? BigInt.prototype.valueOf : null; + var gOPS = Object.getOwnPropertySymbols; + var symToString = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? Symbol.prototype.toString : null; + var hasShammedSymbols = typeof Symbol === "function" && typeof Symbol.iterator === "object"; + var toStringTag = typeof Symbol === "function" && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? "object" : "symbol") ? Symbol.toStringTag : null; + var isEnumerable = Object.prototype.propertyIsEnumerable; + var gPO = (typeof Reflect === "function" ? Reflect.getPrototypeOf : Object.getPrototypeOf) || ([].__proto__ === Array.prototype ? function(O) { + return O.__proto__; + } : null); + function addNumericSeparator(num, str) { + if (num === Infinity || num === -Infinity || num !== num || num && num > -1e3 && num < 1e3 || $test.call(/e/, str)) { + return str; + } + var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g; + if (typeof num === "number") { + var int = num < 0 ? -$floor(-num) : $floor(num); + if (int !== num) { + var intStr = String(int); + var dec = $slice.call(str, intStr.length + 1); + return $replace.call(intStr, sepRegex, "$&_") + "." + $replace.call($replace.call(dec, /([0-9]{3})/g, "$&_"), /_$/, ""); + } + } + return $replace.call(str, sepRegex, "$&_"); + } + var utilInspect = require_util_inspect(); + var inspectCustom = utilInspect.custom; + var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null; + var quotes = { + __proto__: null, + "double": '"', + single: "'" + }; + var quoteREs = { + __proto__: null, + "double": /(["\\])/g, + single: /(['\\])/g + }; + module2.exports = function inspect_(obj, options, depth, seen) { + var opts = options || {}; + if (has(opts, "quoteStyle") && !has(quotes, opts.quoteStyle)) { + throw new TypeError('option "quoteStyle" must be "single" or "double"'); + } + if (has(opts, "maxStringLength") && (typeof opts.maxStringLength === "number" ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity : opts.maxStringLength !== null)) { + throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`'); + } + var customInspect = has(opts, "customInspect") ? opts.customInspect : true; + if (typeof customInspect !== "boolean" && customInspect !== "symbol") { + throw new TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`"); + } + if (has(opts, "indent") && opts.indent !== null && opts.indent !== " " && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)) { + throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`'); + } + if (has(opts, "numericSeparator") && typeof opts.numericSeparator !== "boolean") { + throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`'); + } + var numericSeparator = opts.numericSeparator; + if (typeof obj === "undefined") { + return "undefined"; + } + if (obj === null) { + return "null"; + } + if (typeof obj === "boolean") { + return obj ? "true" : "false"; + } + if (typeof obj === "string") { + return inspectString(obj, opts); + } + if (typeof obj === "number") { + if (obj === 0) { + return Infinity / obj > 0 ? "0" : "-0"; + } + var str = String(obj); + return numericSeparator ? addNumericSeparator(obj, str) : str; + } + if (typeof obj === "bigint") { + var bigIntStr = String(obj) + "n"; + return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr; + } + var maxDepth = typeof opts.depth === "undefined" ? 5 : opts.depth; + if (typeof depth === "undefined") { + depth = 0; + } + if (depth >= maxDepth && maxDepth > 0 && typeof obj === "object") { + return isArray(obj) ? "[Array]" : "[Object]"; + } + var indent = getIndent(opts, depth); + if (typeof seen === "undefined") { + seen = []; + } else if (indexOf(seen, obj) >= 0) { + return "[Circular]"; + } + function inspect(value, from, noIndent) { + if (from) { + seen = $arrSlice.call(seen); + seen.push(from); + } + if (noIndent) { + var newOpts = { + depth: opts.depth + }; + if (has(opts, "quoteStyle")) { + newOpts.quoteStyle = opts.quoteStyle; + } + return inspect_(value, newOpts, depth + 1, seen); + } + return inspect_(value, opts, depth + 1, seen); + } + if (typeof obj === "function" && !isRegExp(obj)) { + var name = nameOf(obj); + var keys = arrObjKeys(obj, inspect); + return "[Function" + (name ? ": " + name : " (anonymous)") + "]" + (keys.length > 0 ? " { " + $join.call(keys, ", ") + " }" : ""); + } + if (isSymbol(obj)) { + var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, "$1") : symToString.call(obj); + return typeof obj === "object" && !hasShammedSymbols ? markBoxed(symString) : symString; + } + if (isElement(obj)) { + var s = "<" + $toLowerCase.call(String(obj.nodeName)); + var attrs = obj.attributes || []; + for (var i = 0; i < attrs.length; i++) { + s += " " + attrs[i].name + "=" + wrapQuotes(quote(attrs[i].value), "double", opts); + } + s += ">"; + if (obj.childNodes && obj.childNodes.length) { + s += "..."; + } + s += ""; + return s; + } + if (isArray(obj)) { + if (obj.length === 0) { + return "[]"; + } + var xs = arrObjKeys(obj, inspect); + if (indent && !singleLineValues(xs)) { + return "[" + indentedJoin(xs, indent) + "]"; + } + return "[ " + $join.call(xs, ", ") + " ]"; + } + if (isError2(obj)) { + var parts = arrObjKeys(obj, inspect); + if (!("cause" in Error.prototype) && "cause" in obj && !isEnumerable.call(obj, "cause")) { + return "{ [" + String(obj) + "] " + $join.call($concat.call("[cause]: " + inspect(obj.cause), parts), ", ") + " }"; + } + if (parts.length === 0) { + return "[" + String(obj) + "]"; + } + return "{ [" + String(obj) + "] " + $join.call(parts, ", ") + " }"; + } + if (typeof obj === "object" && customInspect) { + if (inspectSymbol && typeof obj[inspectSymbol] === "function" && utilInspect) { + return utilInspect(obj, { depth: maxDepth - depth }); + } else if (customInspect !== "symbol" && typeof obj.inspect === "function") { + return obj.inspect(); + } + } + if (isMap(obj)) { + var mapParts = []; + if (mapForEach) { + mapForEach.call(obj, function(value, key) { + mapParts.push(inspect(key, obj, true) + " => " + inspect(value, obj)); + }); + } + return collectionOf("Map", mapSize.call(obj), mapParts, indent); + } + if (isSet(obj)) { + var setParts = []; + if (setForEach) { + setForEach.call(obj, function(value) { + setParts.push(inspect(value, obj)); + }); + } + return collectionOf("Set", setSize.call(obj), setParts, indent); + } + if (isWeakMap(obj)) { + return weakCollectionOf("WeakMap"); + } + if (isWeakSet(obj)) { + return weakCollectionOf("WeakSet"); + } + if (isWeakRef(obj)) { + return weakCollectionOf("WeakRef"); + } + if (isNumber(obj)) { + return markBoxed(inspect(Number(obj))); + } + if (isBigInt(obj)) { + return markBoxed(inspect(bigIntValueOf.call(obj))); + } + if (isBoolean(obj)) { + return markBoxed(booleanValueOf.call(obj)); + } + if (isString(obj)) { + return markBoxed(inspect(String(obj))); + } + if (typeof window !== "undefined" && obj === window) { + return "{ [object Window] }"; + } + if (typeof globalThis !== "undefined" && obj === globalThis || typeof global !== "undefined" && obj === global) { + return "{ [object globalThis] }"; + } + if (!isDate(obj) && !isRegExp(obj)) { + var ys = arrObjKeys(obj, inspect); + var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object; + var protoTag = obj instanceof Object ? "" : "null prototype"; + var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? "Object" : ""; + var constructorTag = isPlainObject || typeof obj.constructor !== "function" ? "" : obj.constructor.name ? obj.constructor.name + " " : ""; + var tag = constructorTag + (stringTag || protoTag ? "[" + $join.call($concat.call([], stringTag || [], protoTag || []), ": ") + "] " : ""); + if (ys.length === 0) { + return tag + "{}"; + } + if (indent) { + return tag + "{" + indentedJoin(ys, indent) + "}"; + } + return tag + "{ " + $join.call(ys, ", ") + " }"; + } + return String(obj); + }; + function wrapQuotes(s, defaultStyle, opts) { + var style = opts.quoteStyle || defaultStyle; + var quoteChar = quotes[style]; + return quoteChar + s + quoteChar; + } + function quote(s) { + return $replace.call(String(s), /"/g, """); + } + function canTrustToString(obj) { + return !toStringTag || !(typeof obj === "object" && (toStringTag in obj || typeof obj[toStringTag] !== "undefined")); + } + function isArray(obj) { + return toStr(obj) === "[object Array]" && canTrustToString(obj); + } + function isDate(obj) { + return toStr(obj) === "[object Date]" && canTrustToString(obj); + } + function isRegExp(obj) { + return toStr(obj) === "[object RegExp]" && canTrustToString(obj); + } + function isError2(obj) { + return toStr(obj) === "[object Error]" && canTrustToString(obj); + } + function isString(obj) { + return toStr(obj) === "[object String]" && canTrustToString(obj); + } + function isNumber(obj) { + return toStr(obj) === "[object Number]" && canTrustToString(obj); + } + function isBoolean(obj) { + return toStr(obj) === "[object Boolean]" && canTrustToString(obj); + } + function isSymbol(obj) { + if (hasShammedSymbols) { + return obj && typeof obj === "object" && obj instanceof Symbol; + } + if (typeof obj === "symbol") { + return true; + } + if (!obj || typeof obj !== "object" || !symToString) { + return false; + } + try { + symToString.call(obj); + return true; + } catch (e) { + } + return false; + } + function isBigInt(obj) { + if (!obj || typeof obj !== "object" || !bigIntValueOf) { + return false; + } + try { + bigIntValueOf.call(obj); + return true; + } catch (e) { + } + return false; + } + var hasOwn = Object.prototype.hasOwnProperty || function(key) { + return key in this; + }; + function has(obj, key) { + return hasOwn.call(obj, key); + } + function toStr(obj) { + return objectToString.call(obj); + } + function nameOf(f) { + if (f.name) { + return f.name; + } + var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/); + if (m) { + return m[1]; + } + return null; + } + function indexOf(xs, x) { + if (xs.indexOf) { + return xs.indexOf(x); + } + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) { + return i; + } + } + return -1; + } + function isMap(x) { + if (!mapSize || !x || typeof x !== "object") { + return false; + } + try { + mapSize.call(x); + try { + setSize.call(x); + } catch (s) { + return true; + } + return x instanceof Map; + } catch (e) { + } + return false; + } + function isWeakMap(x) { + if (!weakMapHas || !x || typeof x !== "object") { + return false; + } + try { + weakMapHas.call(x, weakMapHas); + try { + weakSetHas.call(x, weakSetHas); + } catch (s) { + return true; + } + return x instanceof WeakMap; + } catch (e) { + } + return false; + } + function isWeakRef(x) { + if (!weakRefDeref || !x || typeof x !== "object") { + return false; + } + try { + weakRefDeref.call(x); + return true; + } catch (e) { + } + return false; + } + function isSet(x) { + if (!setSize || !x || typeof x !== "object") { + return false; + } + try { + setSize.call(x); + try { + mapSize.call(x); + } catch (m) { + return true; + } + return x instanceof Set; + } catch (e) { + } + return false; + } + function isWeakSet(x) { + if (!weakSetHas || !x || typeof x !== "object") { + return false; + } + try { + weakSetHas.call(x, weakSetHas); + try { + weakMapHas.call(x, weakMapHas); + } catch (s) { + return true; + } + return x instanceof WeakSet; + } catch (e) { + } + return false; + } + function isElement(x) { + if (!x || typeof x !== "object") { + return false; + } + if (typeof HTMLElement !== "undefined" && x instanceof HTMLElement) { + return true; + } + return typeof x.nodeName === "string" && typeof x.getAttribute === "function"; + } + function inspectString(str, opts) { + if (str.length > opts.maxStringLength) { + var remaining = str.length - opts.maxStringLength; + var trailer = "... " + remaining + " more character" + (remaining > 1 ? "s" : ""); + return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer; + } + var quoteRE = quoteREs[opts.quoteStyle || "single"]; + quoteRE.lastIndex = 0; + var s = $replace.call($replace.call(str, quoteRE, "\\$1"), /[\x00-\x1f]/g, lowbyte); + return wrapQuotes(s, "single", opts); + } + function lowbyte(c) { + var n = c.charCodeAt(0); + var x = { + 8: "b", + 9: "t", + 10: "n", + 12: "f", + 13: "r" + }[n]; + if (x) { + return "\\" + x; + } + return "\\x" + (n < 16 ? "0" : "") + $toUpperCase.call(n.toString(16)); + } + function markBoxed(str) { + return "Object(" + str + ")"; + } + function weakCollectionOf(type) { + return type + " { ? }"; + } + function collectionOf(type, size, entries, indent) { + var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ", "); + return type + " (" + size + ") {" + joinedEntries + "}"; + } + function singleLineValues(xs) { + for (var i = 0; i < xs.length; i++) { + if (indexOf(xs[i], "\n") >= 0) { + return false; + } + } + return true; + } + function getIndent(opts, depth) { + var baseIndent; + if (opts.indent === " ") { + baseIndent = " "; + } else if (typeof opts.indent === "number" && opts.indent > 0) { + baseIndent = $join.call(Array(opts.indent + 1), " "); + } else { + return null; + } + return { + base: baseIndent, + prev: $join.call(Array(depth + 1), baseIndent) + }; + } + function indentedJoin(xs, indent) { + if (xs.length === 0) { + return ""; + } + var lineJoiner = "\n" + indent.prev + indent.base; + return lineJoiner + $join.call(xs, "," + lineJoiner) + "\n" + indent.prev; + } + function arrObjKeys(obj, inspect) { + var isArr = isArray(obj); + var xs = []; + if (isArr) { + xs.length = obj.length; + for (var i = 0; i < obj.length; i++) { + xs[i] = has(obj, i) ? inspect(obj[i], obj) : ""; + } + } + var syms = typeof gOPS === "function" ? gOPS(obj) : []; + var symMap; + if (hasShammedSymbols) { + symMap = {}; + for (var k = 0; k < syms.length; k++) { + symMap["$" + syms[k]] = syms[k]; + } + } + for (var key in obj) { + if (!has(obj, key)) { + continue; + } + if (isArr && String(Number(key)) === key && key < obj.length) { + continue; + } + if (hasShammedSymbols && symMap["$" + key] instanceof Symbol) { + continue; + } else if ($test.call(/[^\w$]/, key)) { + xs.push(inspect(key, obj) + ": " + inspect(obj[key], obj)); + } else { + xs.push(key + ": " + inspect(obj[key], obj)); + } + } + if (typeof gOPS === "function") { + for (var j = 0; j < syms.length; j++) { + if (isEnumerable.call(obj, syms[j])) { + xs.push("[" + inspect(syms[j]) + "]: " + inspect(obj[syms[j]], obj)); + } + } + } + return xs; + } + } +}); + +// node_modules/side-channel-list/index.js +var require_side_channel_list = __commonJS({ + "node_modules/side-channel-list/index.js"(exports2, module2) { + "use strict"; + var inspect = require_object_inspect(); + var $TypeError = require_type(); + var listGetNode = function(list, key, isDelete) { + var prev = list; + var curr; + for (; (curr = prev.next) != null; prev = curr) { + if (curr.key === key) { + prev.next = curr.next; + if (!isDelete) { + curr.next = /** @type {NonNullable} */ + list.next; + list.next = curr; + } + return curr; + } + } + }; + var listGet = function(objects, key) { + if (!objects) { + return void 0; + } + var node = listGetNode(objects, key); + return node && node.value; + }; + var listSet = function(objects, key, value) { + var node = listGetNode(objects, key); + if (node) { + node.value = value; + } else { + objects.next = /** @type {import('./list.d.ts').ListNode} */ + { + // eslint-disable-line no-param-reassign, no-extra-parens + key, + next: objects.next, + value + }; + } + }; + var listHas = function(objects, key) { + if (!objects) { + return false; + } + return !!listGetNode(objects, key); + }; + var listDelete = function(objects, key) { + if (objects) { + return listGetNode(objects, key, true); + } + }; + module2.exports = function getSideChannelList() { + var $o; + var channel = { + assert: function(key) { + if (!channel.has(key)) { + throw new $TypeError("Side channel does not contain " + inspect(key)); + } + }, + "delete": function(key) { + var deletedNode = listDelete($o, key); + if (deletedNode && $o && !$o.next) { + $o = void 0; + } + return !!deletedNode; + }, + get: function(key) { + return listGet($o, key); + }, + has: function(key) { + return listHas($o, key); + }, + set: function(key, value) { + if (!$o) { + $o = { + next: void 0 + }; + } + listSet( + /** @type {NonNullable} */ + $o, + key, + value + ); + } + }; + return channel; + }; + } +}); + +// node_modules/es-object-atoms/index.js +var require_es_object_atoms = __commonJS({ + "node_modules/es-object-atoms/index.js"(exports2, module2) { + "use strict"; + module2.exports = Object; + } +}); + +// node_modules/es-errors/index.js +var require_es_errors = __commonJS({ + "node_modules/es-errors/index.js"(exports2, module2) { + "use strict"; + module2.exports = Error; + } +}); + +// node_modules/es-errors/eval.js +var require_eval = __commonJS({ + "node_modules/es-errors/eval.js"(exports2, module2) { + "use strict"; + module2.exports = EvalError; + } +}); + +// node_modules/es-errors/range.js +var require_range = __commonJS({ + "node_modules/es-errors/range.js"(exports2, module2) { + "use strict"; + module2.exports = RangeError; + } +}); + +// node_modules/es-errors/ref.js +var require_ref = __commonJS({ + "node_modules/es-errors/ref.js"(exports2, module2) { + "use strict"; + module2.exports = ReferenceError; + } +}); + +// node_modules/es-errors/syntax.js +var require_syntax = __commonJS({ + "node_modules/es-errors/syntax.js"(exports2, module2) { + "use strict"; + module2.exports = SyntaxError; + } +}); + +// node_modules/es-errors/uri.js +var require_uri = __commonJS({ + "node_modules/es-errors/uri.js"(exports2, module2) { + "use strict"; + module2.exports = URIError; + } +}); + +// node_modules/math-intrinsics/abs.js +var require_abs = __commonJS({ + "node_modules/math-intrinsics/abs.js"(exports2, module2) { + "use strict"; + module2.exports = Math.abs; + } +}); + +// node_modules/math-intrinsics/floor.js +var require_floor = __commonJS({ + "node_modules/math-intrinsics/floor.js"(exports2, module2) { + "use strict"; + module2.exports = Math.floor; + } +}); + +// node_modules/math-intrinsics/max.js +var require_max = __commonJS({ + "node_modules/math-intrinsics/max.js"(exports2, module2) { + "use strict"; + module2.exports = Math.max; + } +}); + +// node_modules/math-intrinsics/min.js +var require_min = __commonJS({ + "node_modules/math-intrinsics/min.js"(exports2, module2) { + "use strict"; + module2.exports = Math.min; + } +}); + +// node_modules/math-intrinsics/pow.js +var require_pow = __commonJS({ + "node_modules/math-intrinsics/pow.js"(exports2, module2) { + "use strict"; + module2.exports = Math.pow; + } +}); + +// node_modules/math-intrinsics/round.js +var require_round = __commonJS({ + "node_modules/math-intrinsics/round.js"(exports2, module2) { + "use strict"; + module2.exports = Math.round; + } +}); + +// node_modules/math-intrinsics/isNaN.js +var require_isNaN = __commonJS({ + "node_modules/math-intrinsics/isNaN.js"(exports2, module2) { + "use strict"; + module2.exports = Number.isNaN || function isNaN2(a) { + return a !== a; + }; + } +}); + +// node_modules/math-intrinsics/sign.js +var require_sign = __commonJS({ + "node_modules/math-intrinsics/sign.js"(exports2, module2) { + "use strict"; + var $isNaN = require_isNaN(); + module2.exports = function sign(number) { + if ($isNaN(number) || number === 0) { + return number; + } + return number < 0 ? -1 : 1; + }; + } +}); + +// node_modules/gopd/gOPD.js +var require_gOPD = __commonJS({ + "node_modules/gopd/gOPD.js"(exports2, module2) { + "use strict"; + module2.exports = Object.getOwnPropertyDescriptor; + } +}); + +// node_modules/gopd/index.js +var require_gopd = __commonJS({ + "node_modules/gopd/index.js"(exports2, module2) { + "use strict"; + var $gOPD = require_gOPD(); + if ($gOPD) { + try { + $gOPD([], "length"); + } catch (e) { + $gOPD = null; + } + } + module2.exports = $gOPD; + } +}); + +// node_modules/es-define-property/index.js +var require_es_define_property = __commonJS({ + "node_modules/es-define-property/index.js"(exports2, module2) { + "use strict"; + var $defineProperty = Object.defineProperty || false; + if ($defineProperty) { + try { + $defineProperty({}, "a", { value: 1 }); + } catch (e) { + $defineProperty = false; + } + } + module2.exports = $defineProperty; + } +}); + +// node_modules/has-symbols/shams.js +var require_shams = __commonJS({ + "node_modules/has-symbols/shams.js"(exports2, module2) { + "use strict"; + module2.exports = function hasSymbols() { + if (typeof Symbol !== "function" || typeof Object.getOwnPropertySymbols !== "function") { + return false; + } + if (typeof Symbol.iterator === "symbol") { + return true; + } + var obj = {}; + var sym = Symbol("test"); + var symObj = Object(sym); + if (typeof sym === "string") { + return false; + } + if (Object.prototype.toString.call(sym) !== "[object Symbol]") { + return false; + } + if (Object.prototype.toString.call(symObj) !== "[object Symbol]") { + return false; + } + var symVal = 42; + obj[sym] = symVal; + for (var _ in obj) { + return false; + } + if (typeof Object.keys === "function" && Object.keys(obj).length !== 0) { + return false; + } + if (typeof Object.getOwnPropertyNames === "function" && Object.getOwnPropertyNames(obj).length !== 0) { + return false; + } + var syms = Object.getOwnPropertySymbols(obj); + if (syms.length !== 1 || syms[0] !== sym) { + return false; + } + if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { + return false; + } + if (typeof Object.getOwnPropertyDescriptor === "function") { + var descriptor = ( + /** @type {PropertyDescriptor} */ + Object.getOwnPropertyDescriptor(obj, sym) + ); + if (descriptor.value !== symVal || descriptor.enumerable !== true) { + return false; + } + } + return true; + }; + } +}); + +// node_modules/has-symbols/index.js +var require_has_symbols = __commonJS({ + "node_modules/has-symbols/index.js"(exports2, module2) { + "use strict"; + var origSymbol = typeof Symbol !== "undefined" && Symbol; + var hasSymbolSham = require_shams(); + module2.exports = function hasNativeSymbols() { + if (typeof origSymbol !== "function") { + return false; + } + if (typeof Symbol !== "function") { + return false; + } + if (typeof origSymbol("foo") !== "symbol") { + return false; + } + if (typeof Symbol("bar") !== "symbol") { + return false; + } + return hasSymbolSham(); + }; + } +}); + +// node_modules/get-proto/Reflect.getPrototypeOf.js +var require_Reflect_getPrototypeOf = __commonJS({ + "node_modules/get-proto/Reflect.getPrototypeOf.js"(exports2, module2) { + "use strict"; + module2.exports = typeof Reflect !== "undefined" && Reflect.getPrototypeOf || null; + } +}); + +// node_modules/get-proto/Object.getPrototypeOf.js +var require_Object_getPrototypeOf = __commonJS({ + "node_modules/get-proto/Object.getPrototypeOf.js"(exports2, module2) { + "use strict"; + var $Object = require_es_object_atoms(); + module2.exports = $Object.getPrototypeOf || null; + } +}); + +// node_modules/function-bind/implementation.js +var require_implementation = __commonJS({ + "node_modules/function-bind/implementation.js"(exports2, module2) { + "use strict"; + var ERROR_MESSAGE = "Function.prototype.bind called on incompatible "; + var toStr = Object.prototype.toString; + var max = Math.max; + var funcType = "[object Function]"; + var concatty = function concatty2(a, b) { + var arr = []; + for (var i = 0; i < a.length; i += 1) { + arr[i] = a[i]; + } + for (var j = 0; j < b.length; j += 1) { + arr[j + a.length] = b[j]; + } + return arr; + }; + var slicy = function slicy2(arrLike, offset) { + var arr = []; + for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) { + arr[j] = arrLike[i]; + } + return arr; + }; + var joiny = function(arr, joiner) { + var str = ""; + for (var i = 0; i < arr.length; i += 1) { + str += arr[i]; + if (i + 1 < arr.length) { + str += joiner; + } + } + return str; + }; + module2.exports = function bind(that) { + var target = this; + if (typeof target !== "function" || toStr.apply(target) !== funcType) { + throw new TypeError(ERROR_MESSAGE + target); + } + var args = slicy(arguments, 1); + var bound; + var binder = function() { + if (this instanceof bound) { + var result = target.apply( + this, + concatty(args, arguments) + ); + if (Object(result) === result) { + return result; + } + return this; + } + return target.apply( + that, + concatty(args, arguments) + ); + }; + var boundLength = max(0, target.length - args.length); + var boundArgs = []; + for (var i = 0; i < boundLength; i++) { + boundArgs[i] = "$" + i; + } + bound = Function("binder", "return function (" + joiny(boundArgs, ",") + "){ return binder.apply(this,arguments); }")(binder); + if (target.prototype) { + var Empty = function Empty2() { + }; + Empty.prototype = target.prototype; + bound.prototype = new Empty(); + Empty.prototype = null; + } + return bound; + }; + } +}); + +// node_modules/function-bind/index.js +var require_function_bind = __commonJS({ + "node_modules/function-bind/index.js"(exports2, module2) { + "use strict"; + var implementation = require_implementation(); + module2.exports = Function.prototype.bind || implementation; + } +}); + +// node_modules/call-bind-apply-helpers/functionCall.js +var require_functionCall = __commonJS({ + "node_modules/call-bind-apply-helpers/functionCall.js"(exports2, module2) { + "use strict"; + module2.exports = Function.prototype.call; + } +}); + +// node_modules/call-bind-apply-helpers/functionApply.js +var require_functionApply = __commonJS({ + "node_modules/call-bind-apply-helpers/functionApply.js"(exports2, module2) { + "use strict"; + module2.exports = Function.prototype.apply; + } +}); + +// node_modules/call-bind-apply-helpers/reflectApply.js +var require_reflectApply = __commonJS({ + "node_modules/call-bind-apply-helpers/reflectApply.js"(exports2, module2) { + "use strict"; + module2.exports = typeof Reflect !== "undefined" && Reflect && Reflect.apply; + } +}); + +// node_modules/call-bind-apply-helpers/actualApply.js +var require_actualApply = __commonJS({ + "node_modules/call-bind-apply-helpers/actualApply.js"(exports2, module2) { + "use strict"; + var bind = require_function_bind(); + var $apply = require_functionApply(); + var $call = require_functionCall(); + var $reflectApply = require_reflectApply(); + module2.exports = $reflectApply || bind.call($call, $apply); + } +}); + +// node_modules/call-bind-apply-helpers/index.js +var require_call_bind_apply_helpers = __commonJS({ + "node_modules/call-bind-apply-helpers/index.js"(exports2, module2) { + "use strict"; + var bind = require_function_bind(); + var $TypeError = require_type(); + var $call = require_functionCall(); + var $actualApply = require_actualApply(); + module2.exports = function callBindBasic(args) { + if (args.length < 1 || typeof args[0] !== "function") { + throw new $TypeError("a function is required"); + } + return $actualApply(bind, $call, args); + }; + } +}); + +// node_modules/dunder-proto/get.js +var require_get = __commonJS({ + "node_modules/dunder-proto/get.js"(exports2, module2) { + "use strict"; + var callBind = require_call_bind_apply_helpers(); + var gOPD = require_gopd(); + var hasProtoAccessor; + try { + hasProtoAccessor = /** @type {{ __proto__?: typeof Array.prototype }} */ + [].__proto__ === Array.prototype; + } catch (e) { + if (!e || typeof e !== "object" || !("code" in e) || e.code !== "ERR_PROTO_ACCESS") { + throw e; + } + } + var desc = !!hasProtoAccessor && gOPD && gOPD( + Object.prototype, + /** @type {keyof typeof Object.prototype} */ + "__proto__" + ); + var $Object = Object; + var $getPrototypeOf = $Object.getPrototypeOf; + module2.exports = desc && typeof desc.get === "function" ? callBind([desc.get]) : typeof $getPrototypeOf === "function" ? ( + /** @type {import('./get')} */ + function getDunder(value) { + return $getPrototypeOf(value == null ? value : $Object(value)); + } + ) : false; + } +}); + +// node_modules/get-proto/index.js +var require_get_proto = __commonJS({ + "node_modules/get-proto/index.js"(exports2, module2) { + "use strict"; + var reflectGetProto = require_Reflect_getPrototypeOf(); + var originalGetProto = require_Object_getPrototypeOf(); + var getDunderProto = require_get(); + module2.exports = reflectGetProto ? function getProto(O) { + return reflectGetProto(O); + } : originalGetProto ? function getProto(O) { + if (!O || typeof O !== "object" && typeof O !== "function") { + throw new TypeError("getProto: not an object"); + } + return originalGetProto(O); + } : getDunderProto ? function getProto(O) { + return getDunderProto(O); + } : null; + } +}); + +// node_modules/hasown/index.js +var require_hasown = __commonJS({ + "node_modules/hasown/index.js"(exports2, module2) { + "use strict"; + var call = Function.prototype.call; + var $hasOwn = Object.prototype.hasOwnProperty; + var bind = require_function_bind(); + module2.exports = bind.call(call, $hasOwn); + } +}); + +// node_modules/get-intrinsic/index.js +var require_get_intrinsic = __commonJS({ + "node_modules/get-intrinsic/index.js"(exports2, module2) { + "use strict"; + var undefined2; + var $Object = require_es_object_atoms(); + var $Error = require_es_errors(); + var $EvalError = require_eval(); + var $RangeError = require_range(); + var $ReferenceError = require_ref(); + var $SyntaxError = require_syntax(); + var $TypeError = require_type(); + var $URIError = require_uri(); + var abs = require_abs(); + var floor = require_floor(); + var max = require_max(); + var min = require_min(); + var pow = require_pow(); + var round = require_round(); + var sign = require_sign(); + var $Function = Function; + var getEvalledConstructor = function(expressionSyntax) { + try { + return $Function('"use strict"; return (' + expressionSyntax + ").constructor;")(); + } catch (e) { + } + }; + var $gOPD = require_gopd(); + var $defineProperty = require_es_define_property(); + var throwTypeError = function() { + throw new $TypeError(); + }; + var ThrowTypeError = $gOPD ? (function() { + try { + arguments.callee; + return throwTypeError; + } catch (calleeThrows) { + try { + return $gOPD(arguments, "callee").get; + } catch (gOPDthrows) { + return throwTypeError; + } + } + })() : throwTypeError; + var hasSymbols = require_has_symbols()(); + var getProto = require_get_proto(); + var $ObjectGPO = require_Object_getPrototypeOf(); + var $ReflectGPO = require_Reflect_getPrototypeOf(); + var $apply = require_functionApply(); + var $call = require_functionCall(); + var needsEval = {}; + var TypedArray = typeof Uint8Array === "undefined" || !getProto ? undefined2 : getProto(Uint8Array); + var INTRINSICS = { + __proto__: null, + "%AggregateError%": typeof AggregateError === "undefined" ? undefined2 : AggregateError, + "%Array%": Array, + "%ArrayBuffer%": typeof ArrayBuffer === "undefined" ? undefined2 : ArrayBuffer, + "%ArrayIteratorPrototype%": hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined2, + "%AsyncFromSyncIteratorPrototype%": undefined2, + "%AsyncFunction%": needsEval, + "%AsyncGenerator%": needsEval, + "%AsyncGeneratorFunction%": needsEval, + "%AsyncIteratorPrototype%": needsEval, + "%Atomics%": typeof Atomics === "undefined" ? undefined2 : Atomics, + "%BigInt%": typeof BigInt === "undefined" ? undefined2 : BigInt, + "%BigInt64Array%": typeof BigInt64Array === "undefined" ? undefined2 : BigInt64Array, + "%BigUint64Array%": typeof BigUint64Array === "undefined" ? undefined2 : BigUint64Array, + "%Boolean%": Boolean, + "%DataView%": typeof DataView === "undefined" ? undefined2 : DataView, + "%Date%": Date, + "%decodeURI%": decodeURI, + "%decodeURIComponent%": decodeURIComponent, + "%encodeURI%": encodeURI, + "%encodeURIComponent%": encodeURIComponent, + "%Error%": $Error, + "%eval%": eval, + // eslint-disable-line no-eval + "%EvalError%": $EvalError, + "%Float16Array%": typeof Float16Array === "undefined" ? undefined2 : Float16Array, + "%Float32Array%": typeof Float32Array === "undefined" ? undefined2 : Float32Array, + "%Float64Array%": typeof Float64Array === "undefined" ? undefined2 : Float64Array, + "%FinalizationRegistry%": typeof FinalizationRegistry === "undefined" ? undefined2 : FinalizationRegistry, + "%Function%": $Function, + "%GeneratorFunction%": needsEval, + "%Int8Array%": typeof Int8Array === "undefined" ? undefined2 : Int8Array, + "%Int16Array%": typeof Int16Array === "undefined" ? undefined2 : Int16Array, + "%Int32Array%": typeof Int32Array === "undefined" ? undefined2 : Int32Array, + "%isFinite%": isFinite, + "%isNaN%": isNaN, + "%IteratorPrototype%": hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined2, + "%JSON%": typeof JSON === "object" ? JSON : undefined2, + "%Map%": typeof Map === "undefined" ? undefined2 : Map, + "%MapIteratorPrototype%": typeof Map === "undefined" || !hasSymbols || !getProto ? undefined2 : getProto((/* @__PURE__ */ new Map())[Symbol.iterator]()), + "%Math%": Math, + "%Number%": Number, + "%Object%": $Object, + "%Object.getOwnPropertyDescriptor%": $gOPD, + "%parseFloat%": parseFloat, + "%parseInt%": parseInt, + "%Promise%": typeof Promise === "undefined" ? undefined2 : Promise, + "%Proxy%": typeof Proxy === "undefined" ? undefined2 : Proxy, + "%RangeError%": $RangeError, + "%ReferenceError%": $ReferenceError, + "%Reflect%": typeof Reflect === "undefined" ? undefined2 : Reflect, + "%RegExp%": RegExp, + "%Set%": typeof Set === "undefined" ? undefined2 : Set, + "%SetIteratorPrototype%": typeof Set === "undefined" || !hasSymbols || !getProto ? undefined2 : getProto((/* @__PURE__ */ new Set())[Symbol.iterator]()), + "%SharedArrayBuffer%": typeof SharedArrayBuffer === "undefined" ? undefined2 : SharedArrayBuffer, + "%String%": String, + "%StringIteratorPrototype%": hasSymbols && getProto ? getProto(""[Symbol.iterator]()) : undefined2, + "%Symbol%": hasSymbols ? Symbol : undefined2, + "%SyntaxError%": $SyntaxError, + "%ThrowTypeError%": ThrowTypeError, + "%TypedArray%": TypedArray, + "%TypeError%": $TypeError, + "%Uint8Array%": typeof Uint8Array === "undefined" ? undefined2 : Uint8Array, + "%Uint8ClampedArray%": typeof Uint8ClampedArray === "undefined" ? undefined2 : Uint8ClampedArray, + "%Uint16Array%": typeof Uint16Array === "undefined" ? undefined2 : Uint16Array, + "%Uint32Array%": typeof Uint32Array === "undefined" ? undefined2 : Uint32Array, + "%URIError%": $URIError, + "%WeakMap%": typeof WeakMap === "undefined" ? undefined2 : WeakMap, + "%WeakRef%": typeof WeakRef === "undefined" ? undefined2 : WeakRef, + "%WeakSet%": typeof WeakSet === "undefined" ? undefined2 : WeakSet, + "%Function.prototype.call%": $call, + "%Function.prototype.apply%": $apply, + "%Object.defineProperty%": $defineProperty, + "%Object.getPrototypeOf%": $ObjectGPO, + "%Math.abs%": abs, + "%Math.floor%": floor, + "%Math.max%": max, + "%Math.min%": min, + "%Math.pow%": pow, + "%Math.round%": round, + "%Math.sign%": sign, + "%Reflect.getPrototypeOf%": $ReflectGPO + }; + if (getProto) { + try { + null.error; + } catch (e) { + errorProto = getProto(getProto(e)); + INTRINSICS["%Error.prototype%"] = errorProto; + } + } + var errorProto; + var doEval = function doEval2(name) { + var value; + if (name === "%AsyncFunction%") { + value = getEvalledConstructor("async function () {}"); + } else if (name === "%GeneratorFunction%") { + value = getEvalledConstructor("function* () {}"); + } else if (name === "%AsyncGeneratorFunction%") { + value = getEvalledConstructor("async function* () {}"); + } else if (name === "%AsyncGenerator%") { + var fn = doEval2("%AsyncGeneratorFunction%"); + if (fn) { + value = fn.prototype; + } + } else if (name === "%AsyncIteratorPrototype%") { + var gen = doEval2("%AsyncGenerator%"); + if (gen && getProto) { + value = getProto(gen.prototype); + } + } + INTRINSICS[name] = value; + return value; + }; + var LEGACY_ALIASES = { + __proto__: null, + "%ArrayBufferPrototype%": ["ArrayBuffer", "prototype"], + "%ArrayPrototype%": ["Array", "prototype"], + "%ArrayProto_entries%": ["Array", "prototype", "entries"], + "%ArrayProto_forEach%": ["Array", "prototype", "forEach"], + "%ArrayProto_keys%": ["Array", "prototype", "keys"], + "%ArrayProto_values%": ["Array", "prototype", "values"], + "%AsyncFunctionPrototype%": ["AsyncFunction", "prototype"], + "%AsyncGenerator%": ["AsyncGeneratorFunction", "prototype"], + "%AsyncGeneratorPrototype%": ["AsyncGeneratorFunction", "prototype", "prototype"], + "%BooleanPrototype%": ["Boolean", "prototype"], + "%DataViewPrototype%": ["DataView", "prototype"], + "%DatePrototype%": ["Date", "prototype"], + "%ErrorPrototype%": ["Error", "prototype"], + "%EvalErrorPrototype%": ["EvalError", "prototype"], + "%Float32ArrayPrototype%": ["Float32Array", "prototype"], + "%Float64ArrayPrototype%": ["Float64Array", "prototype"], + "%FunctionPrototype%": ["Function", "prototype"], + "%Generator%": ["GeneratorFunction", "prototype"], + "%GeneratorPrototype%": ["GeneratorFunction", "prototype", "prototype"], + "%Int8ArrayPrototype%": ["Int8Array", "prototype"], + "%Int16ArrayPrototype%": ["Int16Array", "prototype"], + "%Int32ArrayPrototype%": ["Int32Array", "prototype"], + "%JSONParse%": ["JSON", "parse"], + "%JSONStringify%": ["JSON", "stringify"], + "%MapPrototype%": ["Map", "prototype"], + "%NumberPrototype%": ["Number", "prototype"], + "%ObjectPrototype%": ["Object", "prototype"], + "%ObjProto_toString%": ["Object", "prototype", "toString"], + "%ObjProto_valueOf%": ["Object", "prototype", "valueOf"], + "%PromisePrototype%": ["Promise", "prototype"], + "%PromiseProto_then%": ["Promise", "prototype", "then"], + "%Promise_all%": ["Promise", "all"], + "%Promise_reject%": ["Promise", "reject"], + "%Promise_resolve%": ["Promise", "resolve"], + "%RangeErrorPrototype%": ["RangeError", "prototype"], + "%ReferenceErrorPrototype%": ["ReferenceError", "prototype"], + "%RegExpPrototype%": ["RegExp", "prototype"], + "%SetPrototype%": ["Set", "prototype"], + "%SharedArrayBufferPrototype%": ["SharedArrayBuffer", "prototype"], + "%StringPrototype%": ["String", "prototype"], + "%SymbolPrototype%": ["Symbol", "prototype"], + "%SyntaxErrorPrototype%": ["SyntaxError", "prototype"], + "%TypedArrayPrototype%": ["TypedArray", "prototype"], + "%TypeErrorPrototype%": ["TypeError", "prototype"], + "%Uint8ArrayPrototype%": ["Uint8Array", "prototype"], + "%Uint8ClampedArrayPrototype%": ["Uint8ClampedArray", "prototype"], + "%Uint16ArrayPrototype%": ["Uint16Array", "prototype"], + "%Uint32ArrayPrototype%": ["Uint32Array", "prototype"], + "%URIErrorPrototype%": ["URIError", "prototype"], + "%WeakMapPrototype%": ["WeakMap", "prototype"], + "%WeakSetPrototype%": ["WeakSet", "prototype"] + }; + var bind = require_function_bind(); + var hasOwn = require_hasown(); + var $concat = bind.call($call, Array.prototype.concat); + var $spliceApply = bind.call($apply, Array.prototype.splice); + var $replace = bind.call($call, String.prototype.replace); + var $strSlice = bind.call($call, String.prototype.slice); + var $exec = bind.call($call, RegExp.prototype.exec); + var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; + var reEscapeChar = /\\(\\)?/g; + var stringToPath = function stringToPath2(string) { + var first = $strSlice(string, 0, 1); + var last = $strSlice(string, -1); + if (first === "%" && last !== "%") { + throw new $SyntaxError("invalid intrinsic syntax, expected closing `%`"); + } else if (last === "%" && first !== "%") { + throw new $SyntaxError("invalid intrinsic syntax, expected opening `%`"); + } + var result = []; + $replace(string, rePropName, function(match, number, quote, subString) { + result[result.length] = quote ? $replace(subString, reEscapeChar, "$1") : number || match; + }); + return result; + }; + var getBaseIntrinsic = function getBaseIntrinsic2(name, allowMissing) { + var intrinsicName = name; + var alias; + if (hasOwn(LEGACY_ALIASES, intrinsicName)) { + alias = LEGACY_ALIASES[intrinsicName]; + intrinsicName = "%" + alias[0] + "%"; + } + if (hasOwn(INTRINSICS, intrinsicName)) { + var value = INTRINSICS[intrinsicName]; + if (value === needsEval) { + value = doEval(intrinsicName); + } + if (typeof value === "undefined" && !allowMissing) { + throw new $TypeError("intrinsic " + name + " exists, but is not available. Please file an issue!"); + } + return { + alias, + name: intrinsicName, + value + }; + } + throw new $SyntaxError("intrinsic " + name + " does not exist!"); + }; + module2.exports = function GetIntrinsic(name, allowMissing) { + if (typeof name !== "string" || name.length === 0) { + throw new $TypeError("intrinsic name must be a non-empty string"); + } + if (arguments.length > 1 && typeof allowMissing !== "boolean") { + throw new $TypeError('"allowMissing" argument must be a boolean'); + } + if ($exec(/^%?[^%]*%?$/, name) === null) { + throw new $SyntaxError("`%` may not be present anywhere but at the beginning and end of the intrinsic name"); + } + var parts = stringToPath(name); + var intrinsicBaseName = parts.length > 0 ? parts[0] : ""; + var intrinsic = getBaseIntrinsic("%" + intrinsicBaseName + "%", allowMissing); + var intrinsicRealName = intrinsic.name; + var value = intrinsic.value; + var skipFurtherCaching = false; + var alias = intrinsic.alias; + if (alias) { + intrinsicBaseName = alias[0]; + $spliceApply(parts, $concat([0, 1], alias)); + } + for (var i = 1, isOwn = true; i < parts.length; i += 1) { + var part = parts[i]; + var first = $strSlice(part, 0, 1); + var last = $strSlice(part, -1); + if ((first === '"' || first === "'" || first === "`" || (last === '"' || last === "'" || last === "`")) && first !== last) { + throw new $SyntaxError("property names with quotes must have matching quotes"); + } + if (part === "constructor" || !isOwn) { + skipFurtherCaching = true; + } + intrinsicBaseName += "." + part; + intrinsicRealName = "%" + intrinsicBaseName + "%"; + if (hasOwn(INTRINSICS, intrinsicRealName)) { + value = INTRINSICS[intrinsicRealName]; + } else if (value != null) { + if (!(part in value)) { + if (!allowMissing) { + throw new $TypeError("base intrinsic for " + name + " exists, but the property is not available."); + } + return void undefined2; + } + if ($gOPD && i + 1 >= parts.length) { + var desc = $gOPD(value, part); + isOwn = !!desc; + if (isOwn && "get" in desc && !("originalValue" in desc.get)) { + value = desc.get; + } else { + value = value[part]; + } + } else { + isOwn = hasOwn(value, part); + value = value[part]; + } + if (isOwn && !skipFurtherCaching) { + INTRINSICS[intrinsicRealName] = value; + } + } + } + return value; + }; + } +}); + +// node_modules/call-bound/index.js +var require_call_bound = __commonJS({ + "node_modules/call-bound/index.js"(exports2, module2) { + "use strict"; + var GetIntrinsic = require_get_intrinsic(); + var callBindBasic = require_call_bind_apply_helpers(); + var $indexOf = callBindBasic([GetIntrinsic("%String.prototype.indexOf%")]); + module2.exports = function callBoundIntrinsic(name, allowMissing) { + var intrinsic = ( + /** @type {(this: unknown, ...args: unknown[]) => unknown} */ + GetIntrinsic(name, !!allowMissing) + ); + if (typeof intrinsic === "function" && $indexOf(name, ".prototype.") > -1) { + return callBindBasic( + /** @type {const} */ + [intrinsic] + ); + } + return intrinsic; + }; + } +}); + +// node_modules/side-channel-map/index.js +var require_side_channel_map = __commonJS({ + "node_modules/side-channel-map/index.js"(exports2, module2) { + "use strict"; + var GetIntrinsic = require_get_intrinsic(); + var callBound = require_call_bound(); + var inspect = require_object_inspect(); + var $TypeError = require_type(); + var $Map = GetIntrinsic("%Map%", true); + var $mapGet = callBound("Map.prototype.get", true); + var $mapSet = callBound("Map.prototype.set", true); + var $mapHas = callBound("Map.prototype.has", true); + var $mapDelete = callBound("Map.prototype.delete", true); + var $mapSize = callBound("Map.prototype.size", true); + module2.exports = !!$Map && /** @type {Exclude} */ + function getSideChannelMap() { + var $m; + var channel = { + assert: function(key) { + if (!channel.has(key)) { + throw new $TypeError("Side channel does not contain " + inspect(key)); + } + }, + "delete": function(key) { + if ($m) { + var result = $mapDelete($m, key); + if ($mapSize($m) === 0) { + $m = void 0; + } + return result; + } + return false; + }, + get: function(key) { + if ($m) { + return $mapGet($m, key); + } + }, + has: function(key) { + if ($m) { + return $mapHas($m, key); + } + return false; + }, + set: function(key, value) { + if (!$m) { + $m = new $Map(); + } + $mapSet($m, key, value); + } + }; + return channel; + }; + } +}); + +// node_modules/side-channel-weakmap/index.js +var require_side_channel_weakmap = __commonJS({ + "node_modules/side-channel-weakmap/index.js"(exports2, module2) { + "use strict"; + var GetIntrinsic = require_get_intrinsic(); + var callBound = require_call_bound(); + var inspect = require_object_inspect(); + var getSideChannelMap = require_side_channel_map(); + var $TypeError = require_type(); + var $WeakMap = GetIntrinsic("%WeakMap%", true); + var $weakMapGet = callBound("WeakMap.prototype.get", true); + var $weakMapSet = callBound("WeakMap.prototype.set", true); + var $weakMapHas = callBound("WeakMap.prototype.has", true); + var $weakMapDelete = callBound("WeakMap.prototype.delete", true); + module2.exports = $WeakMap ? ( + /** @type {Exclude} */ + function getSideChannelWeakMap() { + var $wm; + var $m; + var channel = { + assert: function(key) { + if (!channel.has(key)) { + throw new $TypeError("Side channel does not contain " + inspect(key)); + } + }, + "delete": function(key) { + if ($WeakMap && key && (typeof key === "object" || typeof key === "function")) { + if ($wm) { + return $weakMapDelete($wm, key); + } + } else if (getSideChannelMap) { + if ($m) { + return $m["delete"](key); + } + } + return false; + }, + get: function(key) { + if ($WeakMap && key && (typeof key === "object" || typeof key === "function")) { + if ($wm) { + return $weakMapGet($wm, key); + } + } + return $m && $m.get(key); + }, + has: function(key) { + if ($WeakMap && key && (typeof key === "object" || typeof key === "function")) { + if ($wm) { + return $weakMapHas($wm, key); + } + } + return !!$m && $m.has(key); + }, + set: function(key, value) { + if ($WeakMap && key && (typeof key === "object" || typeof key === "function")) { + if (!$wm) { + $wm = new $WeakMap(); + } + $weakMapSet($wm, key, value); + } else if (getSideChannelMap) { + if (!$m) { + $m = getSideChannelMap(); + } + $m.set(key, value); + } + } + }; + return channel; + } + ) : getSideChannelMap; + } +}); + +// node_modules/side-channel/index.js +var require_side_channel = __commonJS({ + "node_modules/side-channel/index.js"(exports2, module2) { + "use strict"; + var $TypeError = require_type(); + var inspect = require_object_inspect(); + var getSideChannelList = require_side_channel_list(); + var getSideChannelMap = require_side_channel_map(); + var getSideChannelWeakMap = require_side_channel_weakmap(); + var makeChannel = getSideChannelWeakMap || getSideChannelMap || getSideChannelList; + module2.exports = function getSideChannel() { + var $channelData; + var channel = { + assert: function(key) { + if (!channel.has(key)) { + throw new $TypeError("Side channel does not contain " + inspect(key)); + } + }, + "delete": function(key) { + return !!$channelData && $channelData["delete"](key); + }, + get: function(key) { + return $channelData && $channelData.get(key); + }, + has: function(key) { + return !!$channelData && $channelData.has(key); + }, + set: function(key, value) { + if (!$channelData) { + $channelData = makeChannel(); + } + $channelData.set(key, value); + } + }; + return channel; + }; + } +}); + +// node_modules/qs/lib/formats.js +var require_formats = __commonJS({ + "node_modules/qs/lib/formats.js"(exports2, module2) { + "use strict"; + var replace = String.prototype.replace; + var percentTwenties = /%20/g; + var Format = { + RFC1738: "RFC1738", + RFC3986: "RFC3986" + }; + module2.exports = { + "default": Format.RFC3986, + formatters: { + RFC1738: function(value) { + return replace.call(value, percentTwenties, "+"); + }, + RFC3986: function(value) { + return String(value); + } + }, + RFC1738: Format.RFC1738, + RFC3986: Format.RFC3986 + }; + } +}); + +// node_modules/qs/lib/utils.js +var require_utils = __commonJS({ + "node_modules/qs/lib/utils.js"(exports2, module2) { + "use strict"; + var formats = require_formats(); + var getSideChannel = require_side_channel(); + var has = Object.prototype.hasOwnProperty; + var isArray = Array.isArray; + var overflowChannel = getSideChannel(); + var markOverflow = function markOverflow2(obj, maxIndex) { + overflowChannel.set(obj, maxIndex); + return obj; + }; + var isOverflow = function isOverflow2(obj) { + return overflowChannel.has(obj); + }; + var getMaxIndex = function getMaxIndex2(obj) { + return overflowChannel.get(obj); + }; + var setMaxIndex = function setMaxIndex2(obj, maxIndex) { + overflowChannel.set(obj, maxIndex); + }; + var hexTable = (function() { + var array = []; + for (var i = 0; i < 256; ++i) { + array[array.length] = "%" + ((i < 16 ? "0" : "") + i.toString(16)).toUpperCase(); + } + return array; + })(); + var compactQueue = function compactQueue2(queue) { + while (queue.length > 1) { + var item = queue.pop(); + var obj = item.obj[item.prop]; + if (isArray(obj)) { + var compacted = []; + for (var j = 0; j < obj.length; ++j) { + if (typeof obj[j] !== "undefined") { + compacted[compacted.length] = obj[j]; + } + } + item.obj[item.prop] = compacted; + } + } + }; + var arrayToObject = function arrayToObject2(source, options) { + var obj = options && options.plainObjects ? { __proto__: null } : {}; + for (var i = 0; i < source.length; ++i) { + if (typeof source[i] !== "undefined") { + obj[i] = source[i]; + } + } + return obj; + }; + var merge = function merge2(target, source, options) { + if (!source) { + return target; + } + if (typeof source !== "object" && typeof source !== "function") { + if (isArray(target)) { + var nextIndex = target.length; + if (options && typeof options.arrayLimit === "number" && nextIndex > options.arrayLimit) { + return markOverflow(arrayToObject(target.concat(source), options), nextIndex); + } + target[nextIndex] = source; + } else if (target && typeof target === "object") { + if (isOverflow(target)) { + var newIndex = getMaxIndex(target) + 1; + target[newIndex] = source; + setMaxIndex(target, newIndex); + } else if (options && (options.plainObjects || options.allowPrototypes) || !has.call(Object.prototype, source)) { + target[source] = true; + } + } else { + return [target, source]; + } + return target; + } + if (!target || typeof target !== "object") { + if (isOverflow(source)) { + var sourceKeys = Object.keys(source); + var result = options && options.plainObjects ? { __proto__: null, 0: target } : { 0: target }; + for (var m = 0; m < sourceKeys.length; m++) { + var oldKey = parseInt(sourceKeys[m], 10); + result[oldKey + 1] = source[sourceKeys[m]]; + } + return markOverflow(result, getMaxIndex(source) + 1); + } + var combined = [target].concat(source); + if (options && typeof options.arrayLimit === "number" && combined.length > options.arrayLimit) { + return markOverflow(arrayToObject(combined, options), combined.length - 1); + } + return combined; + } + var mergeTarget = target; + if (isArray(target) && !isArray(source)) { + mergeTarget = arrayToObject(target, options); + } + if (isArray(target) && isArray(source)) { + source.forEach(function(item, i) { + if (has.call(target, i)) { + var targetItem = target[i]; + if (targetItem && typeof targetItem === "object" && item && typeof item === "object") { + target[i] = merge2(targetItem, item, options); + } else { + target[target.length] = item; + } + } else { + target[i] = item; + } + }); + return target; + } + return Object.keys(source).reduce(function(acc, key) { + var value = source[key]; + if (has.call(acc, key)) { + acc[key] = merge2(acc[key], value, options); + } else { + acc[key] = value; + } + if (isOverflow(source) && !isOverflow(acc)) { + markOverflow(acc, getMaxIndex(source)); + } + if (isOverflow(acc)) { + var keyNum = parseInt(key, 10); + if (String(keyNum) === key && keyNum >= 0 && keyNum > getMaxIndex(acc)) { + setMaxIndex(acc, keyNum); + } + } + return acc; + }, mergeTarget); + }; + var assign = function assignSingleSource(target, source) { + return Object.keys(source).reduce(function(acc, key) { + acc[key] = source[key]; + return acc; + }, target); + }; + var decode = function(str, defaultDecoder, charset) { + var strWithoutPlus = str.replace(/\+/g, " "); + if (charset === "iso-8859-1") { + return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape); + } + try { + return decodeURIComponent(strWithoutPlus); + } catch (e) { + return strWithoutPlus; + } + }; + var limit = 1024; + var encode = function encode2(str, defaultEncoder, charset, kind, format) { + if (str.length === 0) { + return str; + } + var string = str; + if (typeof str === "symbol") { + string = Symbol.prototype.toString.call(str); + } else if (typeof str !== "string") { + string = String(str); + } + if (charset === "iso-8859-1") { + return escape(string).replace(/%u[0-9a-f]{4}/gi, function($0) { + return "%26%23" + parseInt($0.slice(2), 16) + "%3B"; + }); + } + var out = ""; + for (var j = 0; j < string.length; j += limit) { + var segment = string.length >= limit ? string.slice(j, j + limit) : string; + var arr = []; + for (var i = 0; i < segment.length; ++i) { + var c = segment.charCodeAt(i); + if (c === 45 || c === 46 || c === 95 || c === 126 || c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || format === formats.RFC1738 && (c === 40 || c === 41)) { + arr[arr.length] = segment.charAt(i); + continue; + } + if (c < 128) { + arr[arr.length] = hexTable[c]; + continue; + } + if (c < 2048) { + arr[arr.length] = hexTable[192 | c >> 6] + hexTable[128 | c & 63]; + continue; + } + if (c < 55296 || c >= 57344) { + arr[arr.length] = hexTable[224 | c >> 12] + hexTable[128 | c >> 6 & 63] + hexTable[128 | c & 63]; + continue; + } + i += 1; + c = 65536 + ((c & 1023) << 10 | segment.charCodeAt(i) & 1023); + arr[arr.length] = hexTable[240 | c >> 18] + hexTable[128 | c >> 12 & 63] + hexTable[128 | c >> 6 & 63] + hexTable[128 | c & 63]; + } + out += arr.join(""); + } + return out; + }; + var compact = function compact2(value) { + var queue = [{ obj: { o: value }, prop: "o" }]; + var refs = []; + for (var i = 0; i < queue.length; ++i) { + var item = queue[i]; + var obj = item.obj[item.prop]; + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + var val = obj[key]; + if (typeof val === "object" && val !== null && refs.indexOf(val) === -1) { + queue[queue.length] = { obj, prop: key }; + refs[refs.length] = val; + } + } + } + compactQueue(queue); + return value; + }; + var isRegExp = function isRegExp2(obj) { + return Object.prototype.toString.call(obj) === "[object RegExp]"; + }; + var isBuffer = function isBuffer2(obj) { + if (!obj || typeof obj !== "object") { + return false; + } + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); + }; + var combine = function combine2(a, b, arrayLimit, plainObjects) { + if (isOverflow(a)) { + var newIndex = getMaxIndex(a) + 1; + a[newIndex] = b; + setMaxIndex(a, newIndex); + return a; + } + var result = [].concat(a, b); + if (result.length > arrayLimit) { + return markOverflow(arrayToObject(result, { plainObjects }), result.length - 1); + } + return result; + }; + var maybeMap = function maybeMap2(val, fn) { + if (isArray(val)) { + var mapped = []; + for (var i = 0; i < val.length; i += 1) { + mapped[mapped.length] = fn(val[i]); + } + return mapped; + } + return fn(val); + }; + module2.exports = { + arrayToObject, + assign, + combine, + compact, + decode, + encode, + isBuffer, + isOverflow, + isRegExp, + markOverflow, + maybeMap, + merge + }; + } +}); + +// node_modules/qs/lib/stringify.js +var require_stringify = __commonJS({ + "node_modules/qs/lib/stringify.js"(exports2, module2) { + "use strict"; + var getSideChannel = require_side_channel(); + var utils = require_utils(); + var formats = require_formats(); + var has = Object.prototype.hasOwnProperty; + var arrayPrefixGenerators = { + brackets: function brackets(prefix) { + return prefix + "[]"; + }, + comma: "comma", + indices: function indices(prefix, key) { + return prefix + "[" + key + "]"; + }, + repeat: function repeat(prefix) { + return prefix; + } + }; + var isArray = Array.isArray; + var push = Array.prototype.push; + var pushToArray = function(arr, valueOrArray) { + push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]); + }; + var toISO = Date.prototype.toISOString; + var defaultFormat = formats["default"]; + var defaults = { + addQueryPrefix: false, + allowDots: false, + allowEmptyArrays: false, + arrayFormat: "indices", + charset: "utf-8", + charsetSentinel: false, + commaRoundTrip: false, + delimiter: "&", + encode: true, + encodeDotInKeys: false, + encoder: utils.encode, + encodeValuesOnly: false, + filter: void 0, + format: defaultFormat, + formatter: formats.formatters[defaultFormat], + // deprecated + indices: false, + serializeDate: function serializeDate(date) { + return toISO.call(date); + }, + skipNulls: false, + strictNullHandling: false + }; + var isNonNullishPrimitive = function isNonNullishPrimitive2(v) { + return typeof v === "string" || typeof v === "number" || typeof v === "boolean" || typeof v === "symbol" || typeof v === "bigint"; + }; + var sentinel = {}; + var stringify4 = function stringify5(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, sideChannel) { + var obj = object; + var tmpSc = sideChannel; + var step = 0; + var findFlag = false; + while ((tmpSc = tmpSc.get(sentinel)) !== void 0 && !findFlag) { + var pos = tmpSc.get(object); + step += 1; + if (typeof pos !== "undefined") { + if (pos === step) { + throw new RangeError("Cyclic object value"); + } else { + findFlag = true; + } + } + if (typeof tmpSc.get(sentinel) === "undefined") { + step = 0; + } + } + if (typeof filter === "function") { + obj = filter(prefix, obj); + } else if (obj instanceof Date) { + obj = serializeDate(obj); + } else if (generateArrayPrefix === "comma" && isArray(obj)) { + obj = utils.maybeMap(obj, function(value2) { + if (value2 instanceof Date) { + return serializeDate(value2); + } + return value2; + }); + } + if (obj === null) { + if (strictNullHandling) { + return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, "key", format) : prefix; + } + obj = ""; + } + if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) { + if (encoder) { + var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, "key", format); + return [formatter(keyValue) + "=" + formatter(encoder(obj, defaults.encoder, charset, "value", format))]; + } + return [formatter(prefix) + "=" + formatter(String(obj))]; + } + var values = []; + if (typeof obj === "undefined") { + return values; + } + var objKeys; + if (generateArrayPrefix === "comma" && isArray(obj)) { + if (encodeValuesOnly && encoder) { + obj = utils.maybeMap(obj, encoder); + } + objKeys = [{ value: obj.length > 0 ? obj.join(",") || null : void 0 }]; + } else if (isArray(filter)) { + objKeys = filter; + } else { + var keys = Object.keys(obj); + objKeys = sort ? keys.sort(sort) : keys; + } + var encodedPrefix = encodeDotInKeys ? String(prefix).replace(/\./g, "%2E") : String(prefix); + var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encodedPrefix + "[]" : encodedPrefix; + if (allowEmptyArrays && isArray(obj) && obj.length === 0) { + return adjustedPrefix + "[]"; + } + for (var j = 0; j < objKeys.length; ++j) { + var key = objKeys[j]; + var value = typeof key === "object" && key && typeof key.value !== "undefined" ? key.value : obj[key]; + if (skipNulls && value === null) { + continue; + } + var encodedKey = allowDots && encodeDotInKeys ? String(key).replace(/\./g, "%2E") : String(key); + var keyPrefix = isArray(obj) ? typeof generateArrayPrefix === "function" ? generateArrayPrefix(adjustedPrefix, encodedKey) : adjustedPrefix : adjustedPrefix + (allowDots ? "." + encodedKey : "[" + encodedKey + "]"); + sideChannel.set(object, step); + var valueSideChannel = getSideChannel(); + valueSideChannel.set(sentinel, sideChannel); + pushToArray(values, stringify5( + value, + keyPrefix, + generateArrayPrefix, + commaRoundTrip, + allowEmptyArrays, + strictNullHandling, + skipNulls, + encodeDotInKeys, + generateArrayPrefix === "comma" && encodeValuesOnly && isArray(obj) ? null : encoder, + filter, + sort, + allowDots, + serializeDate, + format, + formatter, + encodeValuesOnly, + charset, + valueSideChannel + )); + } + return values; + }; + var normalizeStringifyOptions = function normalizeStringifyOptions2(opts) { + if (!opts) { + return defaults; + } + if (typeof opts.allowEmptyArrays !== "undefined" && typeof opts.allowEmptyArrays !== "boolean") { + throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided"); + } + if (typeof opts.encodeDotInKeys !== "undefined" && typeof opts.encodeDotInKeys !== "boolean") { + throw new TypeError("`encodeDotInKeys` option can only be `true` or `false`, when provided"); + } + if (opts.encoder !== null && typeof opts.encoder !== "undefined" && typeof opts.encoder !== "function") { + throw new TypeError("Encoder has to be a function."); + } + var charset = opts.charset || defaults.charset; + if (typeof opts.charset !== "undefined" && opts.charset !== "utf-8" && opts.charset !== "iso-8859-1") { + throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined"); + } + var format = formats["default"]; + if (typeof opts.format !== "undefined") { + if (!has.call(formats.formatters, opts.format)) { + throw new TypeError("Unknown format option provided."); + } + format = opts.format; + } + var formatter = formats.formatters[format]; + var filter = defaults.filter; + if (typeof opts.filter === "function" || isArray(opts.filter)) { + filter = opts.filter; + } + var arrayFormat; + if (opts.arrayFormat in arrayPrefixGenerators) { + arrayFormat = opts.arrayFormat; + } else if ("indices" in opts) { + arrayFormat = opts.indices ? "indices" : "repeat"; + } else { + arrayFormat = defaults.arrayFormat; + } + if ("commaRoundTrip" in opts && typeof opts.commaRoundTrip !== "boolean") { + throw new TypeError("`commaRoundTrip` must be a boolean, or absent"); + } + var allowDots = typeof opts.allowDots === "undefined" ? opts.encodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots; + return { + addQueryPrefix: typeof opts.addQueryPrefix === "boolean" ? opts.addQueryPrefix : defaults.addQueryPrefix, + allowDots, + allowEmptyArrays: typeof opts.allowEmptyArrays === "boolean" ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays, + arrayFormat, + charset, + charsetSentinel: typeof opts.charsetSentinel === "boolean" ? opts.charsetSentinel : defaults.charsetSentinel, + commaRoundTrip: !!opts.commaRoundTrip, + delimiter: typeof opts.delimiter === "undefined" ? defaults.delimiter : opts.delimiter, + encode: typeof opts.encode === "boolean" ? opts.encode : defaults.encode, + encodeDotInKeys: typeof opts.encodeDotInKeys === "boolean" ? opts.encodeDotInKeys : defaults.encodeDotInKeys, + encoder: typeof opts.encoder === "function" ? opts.encoder : defaults.encoder, + encodeValuesOnly: typeof opts.encodeValuesOnly === "boolean" ? opts.encodeValuesOnly : defaults.encodeValuesOnly, + filter, + format, + formatter, + serializeDate: typeof opts.serializeDate === "function" ? opts.serializeDate : defaults.serializeDate, + skipNulls: typeof opts.skipNulls === "boolean" ? opts.skipNulls : defaults.skipNulls, + sort: typeof opts.sort === "function" ? opts.sort : null, + strictNullHandling: typeof opts.strictNullHandling === "boolean" ? opts.strictNullHandling : defaults.strictNullHandling + }; + }; + module2.exports = function(object, opts) { + var obj = object; + var options = normalizeStringifyOptions(opts); + var objKeys; + var filter; + if (typeof options.filter === "function") { + filter = options.filter; + obj = filter("", obj); + } else if (isArray(options.filter)) { + filter = options.filter; + objKeys = filter; + } + var keys = []; + if (typeof obj !== "object" || obj === null) { + return ""; + } + var generateArrayPrefix = arrayPrefixGenerators[options.arrayFormat]; + var commaRoundTrip = generateArrayPrefix === "comma" && options.commaRoundTrip; + if (!objKeys) { + objKeys = Object.keys(obj); + } + if (options.sort) { + objKeys.sort(options.sort); + } + var sideChannel = getSideChannel(); + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + var value = obj[key]; + if (options.skipNulls && value === null) { + continue; + } + pushToArray(keys, stringify4( + value, + key, + generateArrayPrefix, + commaRoundTrip, + options.allowEmptyArrays, + options.strictNullHandling, + options.skipNulls, + options.encodeDotInKeys, + options.encode ? options.encoder : null, + options.filter, + options.sort, + options.allowDots, + options.serializeDate, + options.format, + options.formatter, + options.encodeValuesOnly, + options.charset, + sideChannel + )); + } + var joined = keys.join(options.delimiter); + var prefix = options.addQueryPrefix === true ? "?" : ""; + if (options.charsetSentinel) { + if (options.charset === "iso-8859-1") { + prefix += "utf8=%26%2310003%3B&"; + } else { + prefix += "utf8=%E2%9C%93&"; + } + } + return joined.length > 0 ? prefix + joined : ""; + }; + } +}); + +// node_modules/qs/lib/parse.js +var require_parse = __commonJS({ + "node_modules/qs/lib/parse.js"(exports2, module2) { + "use strict"; + var utils = require_utils(); + var has = Object.prototype.hasOwnProperty; + var isArray = Array.isArray; + var defaults = { + allowDots: false, + allowEmptyArrays: false, + allowPrototypes: false, + allowSparse: false, + arrayLimit: 20, + charset: "utf-8", + charsetSentinel: false, + comma: false, + decodeDotInKeys: false, + decoder: utils.decode, + delimiter: "&", + depth: 5, + duplicates: "combine", + ignoreQueryPrefix: false, + interpretNumericEntities: false, + parameterLimit: 1e3, + parseArrays: true, + plainObjects: false, + strictDepth: false, + strictNullHandling: false, + throwOnLimitExceeded: false + }; + var interpretNumericEntities = function(str) { + return str.replace(/&#(\d+);/g, function($0, numberStr) { + return String.fromCharCode(parseInt(numberStr, 10)); + }); + }; + var parseArrayValue = function(val, options, currentArrayLength) { + if (val && typeof val === "string" && options.comma && val.indexOf(",") > -1) { + return val.split(","); + } + if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit) { + throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array."); + } + return val; + }; + var isoSentinel = "utf8=%26%2310003%3B"; + var charsetSentinel = "utf8=%E2%9C%93"; + var parseValues = function parseQueryStringValues(str, options) { + var obj = { __proto__: null }; + var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, "") : str; + cleanStr = cleanStr.replace(/%5B/gi, "[").replace(/%5D/gi, "]"); + var limit = options.parameterLimit === Infinity ? void 0 : options.parameterLimit; + var parts = cleanStr.split( + options.delimiter, + options.throwOnLimitExceeded ? limit + 1 : limit + ); + if (options.throwOnLimitExceeded && parts.length > limit) { + throw new RangeError("Parameter limit exceeded. Only " + limit + " parameter" + (limit === 1 ? "" : "s") + " allowed."); + } + var skipIndex = -1; + var i; + var charset = options.charset; + if (options.charsetSentinel) { + for (i = 0; i < parts.length; ++i) { + if (parts[i].indexOf("utf8=") === 0) { + if (parts[i] === charsetSentinel) { + charset = "utf-8"; + } else if (parts[i] === isoSentinel) { + charset = "iso-8859-1"; + } + skipIndex = i; + i = parts.length; + } + } + } + for (i = 0; i < parts.length; ++i) { + if (i === skipIndex) { + continue; + } + var part = parts[i]; + var bracketEqualsPos = part.indexOf("]="); + var pos = bracketEqualsPos === -1 ? part.indexOf("=") : bracketEqualsPos + 1; + var key; + var val; + if (pos === -1) { + key = options.decoder(part, defaults.decoder, charset, "key"); + val = options.strictNullHandling ? null : ""; + } else { + key = options.decoder(part.slice(0, pos), defaults.decoder, charset, "key"); + if (key !== null) { + val = utils.maybeMap( + parseArrayValue( + part.slice(pos + 1), + options, + isArray(obj[key]) ? obj[key].length : 0 + ), + function(encodedVal) { + return options.decoder(encodedVal, defaults.decoder, charset, "value"); + } + ); + } + } + if (val && options.interpretNumericEntities && charset === "iso-8859-1") { + val = interpretNumericEntities(String(val)); + } + if (part.indexOf("[]=") > -1) { + val = isArray(val) ? [val] : val; + } + if (options.comma && isArray(val) && val.length > options.arrayLimit) { + if (options.throwOnLimitExceeded) { + throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array."); + } + val = utils.combine([], val, options.arrayLimit, options.plainObjects); + } + if (key !== null) { + var existing = has.call(obj, key); + if (existing && options.duplicates === "combine") { + obj[key] = utils.combine( + obj[key], + val, + options.arrayLimit, + options.plainObjects + ); + } else if (!existing || options.duplicates === "last") { + obj[key] = val; + } + } + } + return obj; + }; + var parseObject = function(chain, val, options, valuesParsed) { + var currentArrayLength = 0; + if (chain.length > 0 && chain[chain.length - 1] === "[]") { + var parentKey = chain.slice(0, -1).join(""); + currentArrayLength = Array.isArray(val) && val[parentKey] ? val[parentKey].length : 0; + } + var leaf = valuesParsed ? val : parseArrayValue(val, options, currentArrayLength); + for (var i = chain.length - 1; i >= 0; --i) { + var obj; + var root = chain[i]; + if (root === "[]" && options.parseArrays) { + if (utils.isOverflow(leaf)) { + obj = leaf; + } else { + obj = options.allowEmptyArrays && (leaf === "" || options.strictNullHandling && leaf === null) ? [] : utils.combine( + [], + leaf, + options.arrayLimit, + options.plainObjects + ); + } + } else { + obj = options.plainObjects ? { __proto__: null } : {}; + var cleanRoot = root.charAt(0) === "[" && root.charAt(root.length - 1) === "]" ? root.slice(1, -1) : root; + var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, ".") : cleanRoot; + var index = parseInt(decodedRoot, 10); + var isValidArrayIndex = !isNaN(index) && root !== decodedRoot && String(index) === decodedRoot && index >= 0 && options.parseArrays; + if (!options.parseArrays && decodedRoot === "") { + obj = { 0: leaf }; + } else if (isValidArrayIndex && index < options.arrayLimit) { + obj = []; + obj[index] = leaf; + } else if (isValidArrayIndex && options.throwOnLimitExceeded) { + throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array."); + } else if (isValidArrayIndex) { + obj[index] = leaf; + utils.markOverflow(obj, index); + } else if (decodedRoot !== "__proto__") { + obj[decodedRoot] = leaf; + } + } + leaf = obj; + } + return leaf; + }; + var splitKeyIntoSegments = function splitKeyIntoSegments2(givenKey, options) { + var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, "[$1]") : givenKey; + if (options.depth <= 0) { + if (!options.plainObjects && has.call(Object.prototype, key)) { + if (!options.allowPrototypes) { + return; + } + } + return [key]; + } + var brackets = /(\[[^[\]]*])/; + var child = /(\[[^[\]]*])/g; + var segment = brackets.exec(key); + var parent = segment ? key.slice(0, segment.index) : key; + var keys = []; + if (parent) { + if (!options.plainObjects && has.call(Object.prototype, parent)) { + if (!options.allowPrototypes) { + return; + } + } + keys[keys.length] = parent; + } + var i = 0; + while ((segment = child.exec(key)) !== null && i < options.depth) { + i += 1; + var segmentContent = segment[1].slice(1, -1); + if (!options.plainObjects && has.call(Object.prototype, segmentContent)) { + if (!options.allowPrototypes) { + return; + } + } + keys[keys.length] = segment[1]; + } + if (segment) { + if (options.strictDepth === true) { + throw new RangeError("Input depth exceeded depth option of " + options.depth + " and strictDepth is true"); + } + keys[keys.length] = "[" + key.slice(segment.index) + "]"; + } + return keys; + }; + var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) { + if (!givenKey) { + return; + } + var keys = splitKeyIntoSegments(givenKey, options); + if (!keys) { + return; + } + return parseObject(keys, val, options, valuesParsed); + }; + var normalizeParseOptions = function normalizeParseOptions2(opts) { + if (!opts) { + return defaults; + } + if (typeof opts.allowEmptyArrays !== "undefined" && typeof opts.allowEmptyArrays !== "boolean") { + throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided"); + } + if (typeof opts.decodeDotInKeys !== "undefined" && typeof opts.decodeDotInKeys !== "boolean") { + throw new TypeError("`decodeDotInKeys` option can only be `true` or `false`, when provided"); + } + if (opts.decoder !== null && typeof opts.decoder !== "undefined" && typeof opts.decoder !== "function") { + throw new TypeError("Decoder has to be a function."); + } + if (typeof opts.charset !== "undefined" && opts.charset !== "utf-8" && opts.charset !== "iso-8859-1") { + throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined"); + } + if (typeof opts.throwOnLimitExceeded !== "undefined" && typeof opts.throwOnLimitExceeded !== "boolean") { + throw new TypeError("`throwOnLimitExceeded` option must be a boolean"); + } + var charset = typeof opts.charset === "undefined" ? defaults.charset : opts.charset; + var duplicates = typeof opts.duplicates === "undefined" ? defaults.duplicates : opts.duplicates; + if (duplicates !== "combine" && duplicates !== "first" && duplicates !== "last") { + throw new TypeError("The duplicates option must be either combine, first, or last"); + } + var allowDots = typeof opts.allowDots === "undefined" ? opts.decodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots; + return { + allowDots, + allowEmptyArrays: typeof opts.allowEmptyArrays === "boolean" ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays, + allowPrototypes: typeof opts.allowPrototypes === "boolean" ? opts.allowPrototypes : defaults.allowPrototypes, + allowSparse: typeof opts.allowSparse === "boolean" ? opts.allowSparse : defaults.allowSparse, + arrayLimit: typeof opts.arrayLimit === "number" ? opts.arrayLimit : defaults.arrayLimit, + charset, + charsetSentinel: typeof opts.charsetSentinel === "boolean" ? opts.charsetSentinel : defaults.charsetSentinel, + comma: typeof opts.comma === "boolean" ? opts.comma : defaults.comma, + decodeDotInKeys: typeof opts.decodeDotInKeys === "boolean" ? opts.decodeDotInKeys : defaults.decodeDotInKeys, + decoder: typeof opts.decoder === "function" ? opts.decoder : defaults.decoder, + delimiter: typeof opts.delimiter === "string" || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter, + // eslint-disable-next-line no-implicit-coercion, no-extra-parens + depth: typeof opts.depth === "number" || opts.depth === false ? +opts.depth : defaults.depth, + duplicates, + ignoreQueryPrefix: opts.ignoreQueryPrefix === true, + interpretNumericEntities: typeof opts.interpretNumericEntities === "boolean" ? opts.interpretNumericEntities : defaults.interpretNumericEntities, + parameterLimit: typeof opts.parameterLimit === "number" ? opts.parameterLimit : defaults.parameterLimit, + parseArrays: opts.parseArrays !== false, + plainObjects: typeof opts.plainObjects === "boolean" ? opts.plainObjects : defaults.plainObjects, + strictDepth: typeof opts.strictDepth === "boolean" ? !!opts.strictDepth : defaults.strictDepth, + strictNullHandling: typeof opts.strictNullHandling === "boolean" ? opts.strictNullHandling : defaults.strictNullHandling, + throwOnLimitExceeded: typeof opts.throwOnLimitExceeded === "boolean" ? opts.throwOnLimitExceeded : false + }; + }; + module2.exports = function(str, opts) { + var options = normalizeParseOptions(opts); + if (str === "" || str === null || typeof str === "undefined") { + return options.plainObjects ? { __proto__: null } : {}; + } + var tempObj = typeof str === "string" ? parseValues(str, options) : str; + var obj = options.plainObjects ? { __proto__: null } : {}; + var keys = Object.keys(tempObj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var newObj = parseKeys(key, tempObj[key], options, typeof str === "string"); + obj = utils.merge(obj, newObj, options); + } + if (options.allowSparse === true) { + return obj; + } + return utils.compact(obj); + }; + } +}); + +// node_modules/qs/lib/index.js +var require_lib2 = __commonJS({ + "node_modules/qs/lib/index.js"(exports2, module2) { + "use strict"; + var stringify4 = require_stringify(); + var parse4 = require_parse(); + var formats = require_formats(); + module2.exports = { + formats, + parse: parse4, + stringify: stringify4 + }; + } +}); + +// node_modules/body-parser/lib/types/urlencoded.js +var require_urlencoded = __commonJS({ + "node_modules/body-parser/lib/types/urlencoded.js"(exports2, module2) { + "use strict"; + var bytes = require_bytes(); + var contentType = require_content_type(); + var createError = require_http_errors(); + var debug = require_src()("body-parser:urlencoded"); + var deprecate = require_depd()("body-parser"); + var read = require_read(); + var typeis = require_type_is(); + module2.exports = urlencoded; + var parsers = /* @__PURE__ */ Object.create(null); + function urlencoded(options) { + var opts = options || {}; + if (opts.extended === void 0) { + deprecate("undefined extended: provide extended option"); + } + var extended = opts.extended !== false; + var inflate = opts.inflate !== false; + var limit = typeof opts.limit !== "number" ? bytes.parse(opts.limit || "100kb") : opts.limit; + var type = opts.type || "application/x-www-form-urlencoded"; + var verify = opts.verify || false; + if (verify !== false && typeof verify !== "function") { + throw new TypeError("option verify must be function"); + } + var queryparse = extended ? extendedparser(opts) : simpleparser(opts); + var shouldParse = typeof type !== "function" ? typeChecker(type) : type; + function parse4(body) { + return body.length ? queryparse(body) : {}; + } + return function urlencodedParser(req, res, next) { + if (req._body) { + debug("body already parsed"); + next(); + return; + } + req.body = req.body || {}; + if (!typeis.hasBody(req)) { + debug("skip empty body"); + next(); + return; + } + debug("content-type %j", req.headers["content-type"]); + if (!shouldParse(req)) { + debug("skip parsing"); + next(); + return; + } + var charset = getCharset(req) || "utf-8"; + if (charset !== "utf-8") { + debug("invalid charset"); + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset, + type: "charset.unsupported" + })); + return; + } + read(req, res, next, parse4, debug, { + debug, + encoding: charset, + inflate, + limit, + verify + }); + }; + } + function extendedparser(options) { + var parameterLimit = options.parameterLimit !== void 0 ? options.parameterLimit : 1e3; + var depth = options.depth !== void 0 ? options.depth : 32; + var parse4 = parser("qs"); + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError("option parameterLimit must be a positive number"); + } + if (isNaN(depth) || depth < 0) { + throw new TypeError("option depth must be a zero or a positive number"); + } + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0; + } + return function queryparse(body) { + var paramCount = parameterCount(body, parameterLimit); + if (paramCount === void 0) { + debug("too many parameters"); + throw createError(413, "too many parameters", { + type: "parameters.too.many" + }); + } + var arrayLimit = Math.max(100, paramCount); + debug("parse extended urlencoding"); + try { + return parse4(body, { + allowPrototypes: true, + arrayLimit, + depth, + strictDepth: true, + parameterLimit + }); + } catch (err) { + if (err instanceof RangeError) { + throw createError(400, "The input exceeded the depth", { + type: "querystring.parse.rangeError" + }); + } else { + throw err; + } + } + }; + } + function getCharset(req) { + try { + return (contentType.parse(req).parameters.charset || "").toLowerCase(); + } catch (e) { + return void 0; + } + } + function parameterCount(body, limit) { + var count = 0; + var index = 0; + while ((index = body.indexOf("&", index)) !== -1) { + count++; + index++; + if (count === limit) { + return void 0; + } + } + return count; + } + function parser(name) { + var mod = parsers[name]; + if (mod !== void 0) { + return mod.parse; + } + switch (name) { + case "qs": + mod = require_lib2(); + break; + case "querystring": + mod = require("querystring"); + break; + } + parsers[name] = mod; + return mod.parse; + } + function simpleparser(options) { + var parameterLimit = options.parameterLimit !== void 0 ? options.parameterLimit : 1e3; + var parse4 = parser("querystring"); + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError("option parameterLimit must be a positive number"); + } + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0; + } + return function queryparse(body) { + var paramCount = parameterCount(body, parameterLimit); + if (paramCount === void 0) { + debug("too many parameters"); + throw createError(413, "too many parameters", { + type: "parameters.too.many" + }); + } + debug("parse urlencoding"); + return parse4(body, void 0, void 0, { maxKeys: parameterLimit }); + }; + } + function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)); + }; + } + } +}); + +// node_modules/body-parser/index.js +var require_body_parser = __commonJS({ + "node_modules/body-parser/index.js"(exports2, module2) { + "use strict"; + var deprecate = require_depd()("body-parser"); + var parsers = /* @__PURE__ */ Object.create(null); + exports2 = module2.exports = deprecate.function( + bodyParser, + "bodyParser: use individual json/urlencoded middlewares" + ); + Object.defineProperty(exports2, "json", { + configurable: true, + enumerable: true, + get: createParserGetter("json") + }); + Object.defineProperty(exports2, "raw", { + configurable: true, + enumerable: true, + get: createParserGetter("raw") + }); + Object.defineProperty(exports2, "text", { + configurable: true, + enumerable: true, + get: createParserGetter("text") + }); + Object.defineProperty(exports2, "urlencoded", { + configurable: true, + enumerable: true, + get: createParserGetter("urlencoded") + }); + function bodyParser(options) { + var opts = Object.create(options || null, { + type: { + configurable: true, + enumerable: true, + value: void 0, + writable: true + } + }); + var _urlencoded = exports2.urlencoded(opts); + var _json = exports2.json(opts); + return function bodyParser2(req, res, next) { + _json(req, res, function(err) { + if (err) return next(err); + _urlencoded(req, res, next); + }); + }; + } + function createParserGetter(name) { + return function get() { + return loadParser(name); + }; + } + function loadParser(parserName) { + var parser = parsers[parserName]; + if (parser !== void 0) { + return parser; + } + switch (parserName) { + case "json": + parser = require_json(); + break; + case "raw": + parser = require_raw(); + break; + case "text": + parser = require_text(); + break; + case "urlencoded": + parser = require_urlencoded(); + break; + } + return parsers[parserName] = parser; + } + } +}); + +// node_modules/merge-descriptors/index.js +var require_merge_descriptors = __commonJS({ + "node_modules/merge-descriptors/index.js"(exports2, module2) { + "use strict"; + module2.exports = merge; + var hasOwnProperty = Object.prototype.hasOwnProperty; + function merge(dest, src, redefine) { + if (!dest) { + throw new TypeError("argument dest is required"); + } + if (!src) { + throw new TypeError("argument src is required"); + } + if (redefine === void 0) { + redefine = true; + } + Object.getOwnPropertyNames(src).forEach(function forEachOwnPropertyName(name) { + if (!redefine && hasOwnProperty.call(dest, name)) { + return; + } + var descriptor = Object.getOwnPropertyDescriptor(src, name); + Object.defineProperty(dest, name, descriptor); + }); + return dest; + } + } +}); + +// node_modules/finalhandler/node_modules/ms/index.js +var require_ms2 = __commonJS({ + "node_modules/finalhandler/node_modules/ms/index.js"(exports2, module2) { + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var y = d * 365.25; + module2.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse4(val); + } else if (type === "number" && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); + }; + function parse4(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + "d"; + } + if (ms >= h) { + return Math.round(ms / h) + "h"; + } + if (ms >= m) { + return Math.round(ms / m) + "m"; + } + if (ms >= s) { + return Math.round(ms / s) + "s"; + } + return ms + "ms"; + } + function fmtLong(ms) { + return plural(ms, d, "day") || plural(ms, h, "hour") || plural(ms, m, "minute") || plural(ms, s, "second") || ms + " ms"; + } + function plural(ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + " " + name; + } + return Math.ceil(ms / n) + " " + name + "s"; + } + } +}); + +// node_modules/finalhandler/node_modules/debug/src/debug.js +var require_debug2 = __commonJS({ + "node_modules/finalhandler/node_modules/debug/src/debug.js"(exports2, module2) { + exports2 = module2.exports = createDebug.debug = createDebug["default"] = createDebug; + exports2.coerce = coerce; + exports2.disable = disable; + exports2.enable = enable; + exports2.enabled = enabled; + exports2.humanize = require_ms2(); + exports2.names = []; + exports2.skips = []; + exports2.formatters = {}; + var prevTime; + function selectColor(namespace) { + var hash = 0, i; + for (i in namespace) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return exports2.colors[Math.abs(hash) % exports2.colors.length]; + } + function createDebug(namespace) { + function debug() { + if (!debug.enabled) return; + var self2 = debug; + var curr = +/* @__PURE__ */ new Date(); + var ms = curr - (prevTime || curr); + self2.diff = ms; + self2.prev = prevTime; + self2.curr = curr; + prevTime = curr; + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + args[0] = exports2.coerce(args[0]); + if ("string" !== typeof args[0]) { + args.unshift("%O"); + } + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + if (match === "%%") return match; + index++; + var formatter = exports2.formatters[format]; + if ("function" === typeof formatter) { + var val = args[index]; + match = formatter.call(self2, val); + args.splice(index, 1); + index--; + } + return match; + }); + exports2.formatArgs.call(self2, args); + var logFn = debug.log || exports2.log || console.log.bind(console); + logFn.apply(self2, args); + } + debug.namespace = namespace; + debug.enabled = exports2.enabled(namespace); + debug.useColors = exports2.useColors(); + debug.color = selectColor(namespace); + if ("function" === typeof exports2.init) { + exports2.init(debug); + } + return debug; + } + function enable(namespaces) { + exports2.save(namespaces); + exports2.names = []; + exports2.skips = []; + var split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/); + var len = split.length; + for (var i = 0; i < len; i++) { + if (!split[i]) continue; + namespaces = split[i].replace(/\*/g, ".*?"); + if (namespaces[0] === "-") { + exports2.skips.push(new RegExp("^" + namespaces.substr(1) + "$")); + } else { + exports2.names.push(new RegExp("^" + namespaces + "$")); + } + } + } + function disable() { + exports2.enable(""); + } + function enabled(name) { + var i, len; + for (i = 0, len = exports2.skips.length; i < len; i++) { + if (exports2.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports2.names.length; i < len; i++) { + if (exports2.names[i].test(name)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; + } + } +}); + +// node_modules/finalhandler/node_modules/debug/src/browser.js +var require_browser2 = __commonJS({ + "node_modules/finalhandler/node_modules/debug/src/browser.js"(exports2, module2) { + exports2 = module2.exports = require_debug2(); + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.storage = "undefined" != typeof chrome && "undefined" != typeof chrome.storage ? chrome.storage.local : localstorage(); + exports2.colors = [ + "lightseagreen", + "forestgreen", + "goldenrod", + "dodgerblue", + "darkorchid", + "crimson" + ]; + function useColors() { + if (typeof window !== "undefined" && window.process && window.process.type === "renderer") { + return true; + } + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + exports2.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return "[UnexpectedJSONParseError]: " + err.message; + } + }; + function formatArgs(args) { + var useColors2 = this.useColors; + args[0] = (useColors2 ? "%c" : "") + this.namespace + (useColors2 ? " %c" : " ") + args[0] + (useColors2 ? "%c " : " ") + "+" + exports2.humanize(this.diff); + if (!useColors2) return; + var c = "color: " + this.color; + args.splice(1, 0, c, "color: inherit"); + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ("%%" === match) return; + index++; + if ("%c" === match) { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + function log() { + return "object" === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); + } + function save(namespaces) { + try { + if (null == namespaces) { + exports2.storage.removeItem("debug"); + } else { + exports2.storage.debug = namespaces; + } + } catch (e) { + } + } + function load() { + var r; + try { + r = exports2.storage.debug; + } catch (e) { + } + if (!r && typeof process !== "undefined" && "env" in process) { + r = process.env.DEBUG; + } + return r; + } + exports2.enable(load()); + function localstorage() { + try { + return window.localStorage; + } catch (e) { + } + } + } +}); + +// node_modules/finalhandler/node_modules/debug/src/node.js +var require_node2 = __commonJS({ + "node_modules/finalhandler/node_modules/debug/src/node.js"(exports2, module2) { + var tty = require("tty"); + var util = require("util"); + exports2 = module2.exports = require_debug2(); + exports2.init = init; + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.colors = [6, 2, 3, 4, 5, 1]; + exports2.inspectOpts = Object.keys(process.env).filter(function(key) { + return /^debug_/i.test(key); + }).reduce(function(obj, key) { + var prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, function(_, k) { + return k.toUpperCase(); + }); + var val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) val = true; + else if (/^(no|off|false|disabled)$/i.test(val)) val = false; + else if (val === "null") val = null; + else val = Number(val); + obj[prop] = val; + return obj; + }, {}); + var fd = parseInt(process.env.DEBUG_FD, 10) || 2; + if (1 !== fd && 2 !== fd) { + util.deprecate(function() { + }, "except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)")(); + } + var stream = 1 === fd ? process.stdout : 2 === fd ? process.stderr : createWritableStdioStream(fd); + function useColors() { + return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty.isatty(fd); + } + exports2.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts).split("\n").map(function(str) { + return str.trim(); + }).join(" "); + }; + exports2.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); + }; + function formatArgs(args) { + var name = this.namespace; + var useColors2 = this.useColors; + if (useColors2) { + var c = this.color; + var prefix = " \x1B[3" + c + ";1m" + name + " \x1B[0m"; + args[0] = prefix + args[0].split("\n").join("\n" + prefix); + args.push("\x1B[3" + c + "m+" + exports2.humanize(this.diff) + "\x1B[0m"); + } else { + args[0] = (/* @__PURE__ */ new Date()).toUTCString() + " " + name + " " + args[0]; + } + } + function log() { + return stream.write(util.format.apply(util, arguments) + "\n"); + } + function save(namespaces) { + if (null == namespaces) { + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; + } + } + function load() { + return process.env.DEBUG; + } + function createWritableStdioStream(fd2) { + var stream2; + var tty_wrap = process.binding("tty_wrap"); + switch (tty_wrap.guessHandleType(fd2)) { + case "TTY": + stream2 = new tty.WriteStream(fd2); + stream2._type = "tty"; + if (stream2._handle && stream2._handle.unref) { + stream2._handle.unref(); + } + break; + case "FILE": + var fs6 = require("fs"); + stream2 = new fs6.SyncWriteStream(fd2, { autoClose: false }); + stream2._type = "fs"; + break; + case "PIPE": + case "TCP": + var net = require("net"); + stream2 = new net.Socket({ + fd: fd2, + readable: false, + writable: true + }); + stream2.readable = false; + stream2.read = null; + stream2._type = "pipe"; + if (stream2._handle && stream2._handle.unref) { + stream2._handle.unref(); + } + break; + default: + throw new Error("Implement me. Unknown stream file type!"); + } + stream2.fd = fd2; + stream2._isStdio = true; + return stream2; + } + function init(debug) { + debug.inspectOpts = {}; + var keys = Object.keys(exports2.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports2.inspectOpts[keys[i]]; + } + } + exports2.enable(load()); + } +}); + +// node_modules/finalhandler/node_modules/debug/src/index.js +var require_src2 = __commonJS({ + "node_modules/finalhandler/node_modules/debug/src/index.js"(exports2, module2) { + if (typeof process !== "undefined" && process.type === "renderer") { + module2.exports = require_browser2(); + } else { + module2.exports = require_node2(); + } + } +}); + +// node_modules/encodeurl/index.js +var require_encodeurl = __commonJS({ + "node_modules/encodeurl/index.js"(exports2, module2) { + "use strict"; + module2.exports = encodeUrl; + var ENCODE_CHARS_REGEXP = /(?:[^\x21\x23-\x3B\x3D\x3F-\x5F\x61-\x7A\x7C\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g; + var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g; + var UNMATCHED_SURROGATE_PAIR_REPLACE = "$1\uFFFD$2"; + function encodeUrl(url) { + return String(url).replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE).replace(ENCODE_CHARS_REGEXP, encodeURI); + } + } +}); + +// node_modules/escape-html/index.js +var require_escape_html = __commonJS({ + "node_modules/escape-html/index.js"(exports2, module2) { + "use strict"; + var matchHtmlRegExp = /["'&<>]/; + module2.exports = escapeHtml; + function escapeHtml(string) { + var str = "" + string; + var match = matchHtmlRegExp.exec(str); + if (!match) { + return str; + } + var escape2; + var html = ""; + var index = 0; + var lastIndex = 0; + for (index = match.index; index < str.length; index++) { + switch (str.charCodeAt(index)) { + case 34: + escape2 = """; + break; + case 38: + escape2 = "&"; + break; + case 39: + escape2 = "'"; + break; + case 60: + escape2 = "<"; + break; + case 62: + escape2 = ">"; + break; + default: + continue; + } + if (lastIndex !== index) { + html += str.substring(lastIndex, index); + } + lastIndex = index + 1; + html += escape2; + } + return lastIndex !== index ? html + str.substring(lastIndex, index) : html; + } + } +}); + +// node_modules/parseurl/index.js +var require_parseurl = __commonJS({ + "node_modules/parseurl/index.js"(exports2, module2) { + "use strict"; + var url = require("url"); + var parse4 = url.parse; + var Url = url.Url; + module2.exports = parseurl; + module2.exports.original = originalurl; + function parseurl(req) { + var url2 = req.url; + if (url2 === void 0) { + return void 0; + } + var parsed = req._parsedUrl; + if (fresh(url2, parsed)) { + return parsed; + } + parsed = fastparse(url2); + parsed._raw = url2; + return req._parsedUrl = parsed; + } + function originalurl(req) { + var url2 = req.originalUrl; + if (typeof url2 !== "string") { + return parseurl(req); + } + var parsed = req._parsedOriginalUrl; + if (fresh(url2, parsed)) { + return parsed; + } + parsed = fastparse(url2); + parsed._raw = url2; + return req._parsedOriginalUrl = parsed; + } + function fastparse(str) { + if (typeof str !== "string" || str.charCodeAt(0) !== 47) { + return parse4(str); + } + var pathname = str; + var query = null; + var search = null; + for (var i = 1; i < str.length; i++) { + switch (str.charCodeAt(i)) { + case 63: + if (search === null) { + pathname = str.substring(0, i); + query = str.substring(i + 1); + search = str.substring(i); + } + break; + case 9: + /* \t */ + case 10: + /* \n */ + case 12: + /* \f */ + case 13: + /* \r */ + case 32: + /* */ + case 35: + /* # */ + case 160: + case 65279: + return parse4(str); + } + } + var url2 = Url !== void 0 ? new Url() : {}; + url2.path = str; + url2.href = str; + url2.pathname = pathname; + if (search !== null) { + url2.query = query; + url2.search = search; + } + return url2; + } + function fresh(url2, parsedUrl) { + return typeof parsedUrl === "object" && parsedUrl !== null && (Url === void 0 || parsedUrl instanceof Url) && parsedUrl._raw === url2; + } + } +}); + +// node_modules/finalhandler/index.js +var require_finalhandler = __commonJS({ + "node_modules/finalhandler/index.js"(exports2, module2) { + "use strict"; + var debug = require_src2()("finalhandler"); + var encodeUrl = require_encodeurl(); + var escapeHtml = require_escape_html(); + var onFinished = require_on_finished(); + var parseUrl = require_parseurl(); + var statuses = require_statuses(); + var unpipe = require_unpipe(); + var DOUBLE_SPACE_REGEXP = /\x20{2}/g; + var NEWLINE_REGEXP = /\n/g; + var defer = typeof setImmediate === "function" ? setImmediate : function(fn) { + process.nextTick(fn.bind.apply(fn, arguments)); + }; + var isFinished = onFinished.isFinished; + function createHtmlDocument(message) { + var body = escapeHtml(message).replace(NEWLINE_REGEXP, "
").replace(DOUBLE_SPACE_REGEXP, "  "); + return '\n\n\n\nError\n\n\n
' + body + "
\n\n\n"; + } + module2.exports = finalhandler; + function finalhandler(req, res, options) { + var opts = options || {}; + var env = opts.env || process.env.NODE_ENV || "development"; + var onerror = opts.onerror; + return function(err) { + var headers; + var msg; + var status; + if (!err && headersSent(res)) { + debug("cannot 404 after headers sent"); + return; + } + if (err) { + status = getErrorStatusCode(err); + if (status === void 0) { + status = getResponseStatusCode(res); + } else { + headers = getErrorHeaders(err); + } + msg = getErrorMessage(err, status, env); + } else { + status = 404; + msg = "Cannot " + req.method + " " + encodeUrl(getResourceName(req)); + } + debug("default %s", status); + if (err && onerror) { + defer(onerror, err, req, res); + } + if (headersSent(res)) { + debug("cannot %d after headers sent", status); + if (req.socket) { + req.socket.destroy(); + } + return; + } + send(req, res, status, headers, msg); + }; + } + function getErrorHeaders(err) { + if (!err.headers || typeof err.headers !== "object") { + return void 0; + } + var headers = /* @__PURE__ */ Object.create(null); + var keys = Object.keys(err.headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + headers[key] = err.headers[key]; + } + return headers; + } + function getErrorMessage(err, status, env) { + var msg; + if (env !== "production") { + msg = err.stack; + if (!msg && typeof err.toString === "function") { + msg = err.toString(); + } + } + return msg || statuses.message[status]; + } + function getErrorStatusCode(err) { + if (typeof err.status === "number" && err.status >= 400 && err.status < 600) { + return err.status; + } + if (typeof err.statusCode === "number" && err.statusCode >= 400 && err.statusCode < 600) { + return err.statusCode; + } + return void 0; + } + function getResourceName(req) { + try { + return parseUrl.original(req).pathname; + } catch (e) { + return "resource"; + } + } + function getResponseStatusCode(res) { + var status = res.statusCode; + if (typeof status !== "number" || status < 400 || status > 599) { + status = 500; + } + return status; + } + function headersSent(res) { + return typeof res.headersSent !== "boolean" ? Boolean(res._header) : res.headersSent; + } + function send(req, res, status, headers, message) { + function write() { + var body = createHtmlDocument(message); + res.statusCode = status; + if (req.httpVersionMajor < 2) { + res.statusMessage = statuses.message[status]; + } + res.removeHeader("Content-Encoding"); + res.removeHeader("Content-Language"); + res.removeHeader("Content-Range"); + setHeaders(res, headers); + res.setHeader("Content-Security-Policy", "default-src 'none'"); + res.setHeader("X-Content-Type-Options", "nosniff"); + res.setHeader("Content-Type", "text/html; charset=utf-8"); + res.setHeader("Content-Length", Buffer.byteLength(body, "utf8")); + if (req.method === "HEAD") { + res.end(); + return; + } + res.end(body, "utf8"); + } + if (isFinished(req)) { + write(); + return; + } + unpipe(req); + onFinished(req, write); + req.resume(); + } + function setHeaders(res, headers) { + if (!headers) { + return; + } + var keys = Object.keys(headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + res.setHeader(key, headers[key]); + } + } + } +}); + +// node_modules/express/node_modules/ms/index.js +var require_ms3 = __commonJS({ + "node_modules/express/node_modules/ms/index.js"(exports2, module2) { + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var y = d * 365.25; + module2.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse4(val); + } else if (type === "number" && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); + }; + function parse4(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + "d"; + } + if (ms >= h) { + return Math.round(ms / h) + "h"; + } + if (ms >= m) { + return Math.round(ms / m) + "m"; + } + if (ms >= s) { + return Math.round(ms / s) + "s"; + } + return ms + "ms"; + } + function fmtLong(ms) { + return plural(ms, d, "day") || plural(ms, h, "hour") || plural(ms, m, "minute") || plural(ms, s, "second") || ms + " ms"; + } + function plural(ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + " " + name; + } + return Math.ceil(ms / n) + " " + name + "s"; + } + } +}); + +// node_modules/express/node_modules/debug/src/debug.js +var require_debug3 = __commonJS({ + "node_modules/express/node_modules/debug/src/debug.js"(exports2, module2) { + exports2 = module2.exports = createDebug.debug = createDebug["default"] = createDebug; + exports2.coerce = coerce; + exports2.disable = disable; + exports2.enable = enable; + exports2.enabled = enabled; + exports2.humanize = require_ms3(); + exports2.names = []; + exports2.skips = []; + exports2.formatters = {}; + var prevTime; + function selectColor(namespace) { + var hash = 0, i; + for (i in namespace) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return exports2.colors[Math.abs(hash) % exports2.colors.length]; + } + function createDebug(namespace) { + function debug() { + if (!debug.enabled) return; + var self2 = debug; + var curr = +/* @__PURE__ */ new Date(); + var ms = curr - (prevTime || curr); + self2.diff = ms; + self2.prev = prevTime; + self2.curr = curr; + prevTime = curr; + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + args[0] = exports2.coerce(args[0]); + if ("string" !== typeof args[0]) { + args.unshift("%O"); + } + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + if (match === "%%") return match; + index++; + var formatter = exports2.formatters[format]; + if ("function" === typeof formatter) { + var val = args[index]; + match = formatter.call(self2, val); + args.splice(index, 1); + index--; + } + return match; + }); + exports2.formatArgs.call(self2, args); + var logFn = debug.log || exports2.log || console.log.bind(console); + logFn.apply(self2, args); + } + debug.namespace = namespace; + debug.enabled = exports2.enabled(namespace); + debug.useColors = exports2.useColors(); + debug.color = selectColor(namespace); + if ("function" === typeof exports2.init) { + exports2.init(debug); + } + return debug; + } + function enable(namespaces) { + exports2.save(namespaces); + exports2.names = []; + exports2.skips = []; + var split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/); + var len = split.length; + for (var i = 0; i < len; i++) { + if (!split[i]) continue; + namespaces = split[i].replace(/\*/g, ".*?"); + if (namespaces[0] === "-") { + exports2.skips.push(new RegExp("^" + namespaces.substr(1) + "$")); + } else { + exports2.names.push(new RegExp("^" + namespaces + "$")); + } + } + } + function disable() { + exports2.enable(""); + } + function enabled(name) { + var i, len; + for (i = 0, len = exports2.skips.length; i < len; i++) { + if (exports2.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports2.names.length; i < len; i++) { + if (exports2.names[i].test(name)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; + } + } +}); + +// node_modules/express/node_modules/debug/src/browser.js +var require_browser3 = __commonJS({ + "node_modules/express/node_modules/debug/src/browser.js"(exports2, module2) { + exports2 = module2.exports = require_debug3(); + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.storage = "undefined" != typeof chrome && "undefined" != typeof chrome.storage ? chrome.storage.local : localstorage(); + exports2.colors = [ + "lightseagreen", + "forestgreen", + "goldenrod", + "dodgerblue", + "darkorchid", + "crimson" + ]; + function useColors() { + if (typeof window !== "undefined" && window.process && window.process.type === "renderer") { + return true; + } + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + exports2.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return "[UnexpectedJSONParseError]: " + err.message; + } + }; + function formatArgs(args) { + var useColors2 = this.useColors; + args[0] = (useColors2 ? "%c" : "") + this.namespace + (useColors2 ? " %c" : " ") + args[0] + (useColors2 ? "%c " : " ") + "+" + exports2.humanize(this.diff); + if (!useColors2) return; + var c = "color: " + this.color; + args.splice(1, 0, c, "color: inherit"); + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ("%%" === match) return; + index++; + if ("%c" === match) { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + function log() { + return "object" === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); + } + function save(namespaces) { + try { + if (null == namespaces) { + exports2.storage.removeItem("debug"); + } else { + exports2.storage.debug = namespaces; + } + } catch (e) { + } + } + function load() { + var r; + try { + r = exports2.storage.debug; + } catch (e) { + } + if (!r && typeof process !== "undefined" && "env" in process) { + r = process.env.DEBUG; + } + return r; + } + exports2.enable(load()); + function localstorage() { + try { + return window.localStorage; + } catch (e) { + } + } + } +}); + +// node_modules/express/node_modules/debug/src/node.js +var require_node3 = __commonJS({ + "node_modules/express/node_modules/debug/src/node.js"(exports2, module2) { + var tty = require("tty"); + var util = require("util"); + exports2 = module2.exports = require_debug3(); + exports2.init = init; + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.colors = [6, 2, 3, 4, 5, 1]; + exports2.inspectOpts = Object.keys(process.env).filter(function(key) { + return /^debug_/i.test(key); + }).reduce(function(obj, key) { + var prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, function(_, k) { + return k.toUpperCase(); + }); + var val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) val = true; + else if (/^(no|off|false|disabled)$/i.test(val)) val = false; + else if (val === "null") val = null; + else val = Number(val); + obj[prop] = val; + return obj; + }, {}); + var fd = parseInt(process.env.DEBUG_FD, 10) || 2; + if (1 !== fd && 2 !== fd) { + util.deprecate(function() { + }, "except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)")(); + } + var stream = 1 === fd ? process.stdout : 2 === fd ? process.stderr : createWritableStdioStream(fd); + function useColors() { + return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty.isatty(fd); + } + exports2.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts).split("\n").map(function(str) { + return str.trim(); + }).join(" "); + }; + exports2.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); + }; + function formatArgs(args) { + var name = this.namespace; + var useColors2 = this.useColors; + if (useColors2) { + var c = this.color; + var prefix = " \x1B[3" + c + ";1m" + name + " \x1B[0m"; + args[0] = prefix + args[0].split("\n").join("\n" + prefix); + args.push("\x1B[3" + c + "m+" + exports2.humanize(this.diff) + "\x1B[0m"); + } else { + args[0] = (/* @__PURE__ */ new Date()).toUTCString() + " " + name + " " + args[0]; + } + } + function log() { + return stream.write(util.format.apply(util, arguments) + "\n"); + } + function save(namespaces) { + if (null == namespaces) { + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; + } + } + function load() { + return process.env.DEBUG; + } + function createWritableStdioStream(fd2) { + var stream2; + var tty_wrap = process.binding("tty_wrap"); + switch (tty_wrap.guessHandleType(fd2)) { + case "TTY": + stream2 = new tty.WriteStream(fd2); + stream2._type = "tty"; + if (stream2._handle && stream2._handle.unref) { + stream2._handle.unref(); + } + break; + case "FILE": + var fs6 = require("fs"); + stream2 = new fs6.SyncWriteStream(fd2, { autoClose: false }); + stream2._type = "fs"; + break; + case "PIPE": + case "TCP": + var net = require("net"); + stream2 = new net.Socket({ + fd: fd2, + readable: false, + writable: true + }); + stream2.readable = false; + stream2.read = null; + stream2._type = "pipe"; + if (stream2._handle && stream2._handle.unref) { + stream2._handle.unref(); + } + break; + default: + throw new Error("Implement me. Unknown stream file type!"); + } + stream2.fd = fd2; + stream2._isStdio = true; + return stream2; + } + function init(debug) { + debug.inspectOpts = {}; + var keys = Object.keys(exports2.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports2.inspectOpts[keys[i]]; + } + } + exports2.enable(load()); + } +}); + +// node_modules/express/node_modules/debug/src/index.js +var require_src3 = __commonJS({ + "node_modules/express/node_modules/debug/src/index.js"(exports2, module2) { + if (typeof process !== "undefined" && process.type === "renderer") { + module2.exports = require_browser3(); + } else { + module2.exports = require_node3(); + } + } +}); + +// node_modules/array-flatten/array-flatten.js +var require_array_flatten = __commonJS({ + "node_modules/array-flatten/array-flatten.js"(exports2, module2) { + "use strict"; + module2.exports = arrayFlatten; + function flattenWithDepth(array, result, depth) { + for (var i = 0; i < array.length; i++) { + var value = array[i]; + if (depth > 0 && Array.isArray(value)) { + flattenWithDepth(value, result, depth - 1); + } else { + result.push(value); + } + } + return result; + } + function flattenForever(array, result) { + for (var i = 0; i < array.length; i++) { + var value = array[i]; + if (Array.isArray(value)) { + flattenForever(value, result); + } else { + result.push(value); + } + } + return result; + } + function arrayFlatten(array, depth) { + if (depth == null) { + return flattenForever(array, []); + } + return flattenWithDepth(array, [], depth); + } + } +}); + +// node_modules/path-to-regexp/index.js +var require_path_to_regexp = __commonJS({ + "node_modules/path-to-regexp/index.js"(exports2, module2) { + module2.exports = pathToRegexp; + var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g; + function pathToRegexp(path3, keys, options) { + options = options || {}; + keys = keys || []; + var strict = options.strict; + var end = options.end !== false; + var flags = options.sensitive ? "" : "i"; + var lookahead = options.lookahead !== false; + var extraOffset = 0; + var keysOffset = keys.length; + var i = 0; + var name = 0; + var pos = 0; + var backtrack = ""; + var m; + if (path3 instanceof RegExp) { + while (m = MATCHING_GROUP_REGEXP.exec(path3.source)) { + if (m[0][0] === "\\") continue; + keys.push({ + name: m[1] || name++, + optional: false, + offset: m.index + }); + } + return path3; + } + if (Array.isArray(path3)) { + path3 = path3.map(function(value) { + return pathToRegexp(value, keys, options).source; + }); + return new RegExp(path3.join("|"), flags); + } + if (typeof path3 !== "string") { + throw new TypeError("path must be a string, array of strings, or regular expression"); + } + path3 = path3.replace( + /\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g, + function(match, slash, format, key, capture, star, optional, offset) { + if (match[0] === "\\") { + backtrack += match; + pos += 2; + return match; + } + if (match === ".") { + backtrack += "\\."; + extraOffset += 1; + pos += 1; + return "\\."; + } + if (slash || format) { + backtrack = ""; + } else { + backtrack += path3.slice(pos, offset); + } + pos = offset + match.length; + if (match === "*") { + backtrack = ""; + extraOffset += 3; + return "(.*)"; + } + if (match === "/(") { + backtrack += "/"; + extraOffset += 2; + return "/(?:"; + } + slash = slash || ""; + format = format ? "\\." : ""; + optional = optional || ""; + capture = capture ? capture.replace(/\\.|\*/, function(m2) { + return m2 === "*" ? "(.*)" : m2; + }) : backtrack ? "((?:(?!/|" + backtrack + ").)+?)" : "([^/" + format + "]+?)"; + keys.push({ + name: key, + optional: !!optional, + offset: offset + extraOffset + }); + var result = "(?:" + format + slash + capture + (star ? "((?:[/" + format + "].+?)?)" : "") + ")" + optional; + backtrack = ""; + extraOffset += result.length - match.length; + return result; + } + ); + while (m = MATCHING_GROUP_REGEXP.exec(path3)) { + if (m[0][0] === "\\") continue; + if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) { + keys.splice(keysOffset + i, 0, { + name: name++, + // Unnamed matching groups must be consistently linear. + optional: false, + offset: m.index + }); + } + i++; + } + path3 += strict ? "" : path3[path3.length - 1] === "/" ? "?" : "/?"; + if (end) { + path3 += "$"; + } else if (path3[path3.length - 1] !== "/") { + path3 += lookahead ? "(?=/|$)" : "(?:/|$)"; + } + return new RegExp("^" + path3, flags); + } + } +}); + +// node_modules/express/lib/router/layer.js +var require_layer = __commonJS({ + "node_modules/express/lib/router/layer.js"(exports2, module2) { + "use strict"; + var pathRegexp = require_path_to_regexp(); + var debug = require_src3()("express:router:layer"); + var hasOwnProperty = Object.prototype.hasOwnProperty; + module2.exports = Layer; + function Layer(path3, options, fn) { + if (!(this instanceof Layer)) { + return new Layer(path3, options, fn); + } + debug("new %o", path3); + var opts = options || {}; + this.handle = fn; + this.name = fn.name || ""; + this.params = void 0; + this.path = void 0; + this.regexp = pathRegexp(path3, this.keys = [], opts); + this.regexp.fast_star = path3 === "*"; + this.regexp.fast_slash = path3 === "/" && opts.end === false; + } + Layer.prototype.handle_error = function handle_error(error, req, res, next) { + var fn = this.handle; + if (fn.length !== 4) { + return next(error); + } + try { + fn(error, req, res, next); + } catch (err) { + next(err); + } + }; + Layer.prototype.handle_request = function handle(req, res, next) { + var fn = this.handle; + if (fn.length > 3) { + return next(); + } + try { + fn(req, res, next); + } catch (err) { + next(err); + } + }; + Layer.prototype.match = function match(path3) { + var match2; + if (path3 != null) { + if (this.regexp.fast_slash) { + this.params = {}; + this.path = ""; + return true; + } + if (this.regexp.fast_star) { + this.params = { "0": decode_param(path3) }; + this.path = path3; + return true; + } + match2 = this.regexp.exec(path3); + } + if (!match2) { + this.params = void 0; + this.path = void 0; + return false; + } + this.params = {}; + this.path = match2[0]; + var keys = this.keys; + var params = this.params; + for (var i = 1; i < match2.length; i++) { + var key = keys[i - 1]; + var prop = key.name; + var val = decode_param(match2[i]); + if (val !== void 0 || !hasOwnProperty.call(params, prop)) { + params[prop] = val; + } + } + return true; + }; + function decode_param(val) { + if (typeof val !== "string" || val.length === 0) { + return val; + } + try { + return decodeURIComponent(val); + } catch (err) { + if (err instanceof URIError) { + err.message = "Failed to decode param '" + val + "'"; + err.status = err.statusCode = 400; + } + throw err; + } + } + } +}); + +// node_modules/methods/index.js +var require_methods = __commonJS({ + "node_modules/methods/index.js"(exports2, module2) { + "use strict"; + var http = require("http"); + module2.exports = getCurrentNodeMethods() || getBasicNodeMethods(); + function getCurrentNodeMethods() { + return http.METHODS && http.METHODS.map(function lowerCaseMethod(method) { + return method.toLowerCase(); + }); + } + function getBasicNodeMethods() { + return [ + "get", + "post", + "put", + "head", + "delete", + "options", + "trace", + "copy", + "lock", + "mkcol", + "move", + "purge", + "propfind", + "proppatch", + "unlock", + "report", + "mkactivity", + "checkout", + "merge", + "m-search", + "notify", + "subscribe", + "unsubscribe", + "patch", + "search", + "connect" + ]; + } + } +}); + +// node_modules/express/lib/router/route.js +var require_route = __commonJS({ + "node_modules/express/lib/router/route.js"(exports2, module2) { + "use strict"; + var debug = require_src3()("express:router:route"); + var flatten = require_array_flatten(); + var Layer = require_layer(); + var methods = require_methods(); + var slice = Array.prototype.slice; + var toString = Object.prototype.toString; + module2.exports = Route; + function Route(path3) { + this.path = path3; + this.stack = []; + debug("new %o", path3); + this.methods = {}; + } + Route.prototype._handles_method = function _handles_method(method) { + if (this.methods._all) { + return true; + } + var name = typeof method === "string" ? method.toLowerCase() : method; + if (name === "head" && !this.methods["head"]) { + name = "get"; + } + return Boolean(this.methods[name]); + }; + Route.prototype._options = function _options() { + var methods2 = Object.keys(this.methods); + if (this.methods.get && !this.methods.head) { + methods2.push("head"); + } + for (var i = 0; i < methods2.length; i++) { + methods2[i] = methods2[i].toUpperCase(); + } + return methods2; + }; + Route.prototype.dispatch = function dispatch(req, res, done) { + var idx = 0; + var stack = this.stack; + var sync = 0; + if (stack.length === 0) { + return done(); + } + var method = typeof req.method === "string" ? req.method.toLowerCase() : req.method; + if (method === "head" && !this.methods["head"]) { + method = "get"; + } + req.route = this; + next(); + function next(err) { + if (err && err === "route") { + return done(); + } + if (err && err === "router") { + return done(err); + } + if (++sync > 100) { + return setImmediate(next, err); + } + var layer = stack[idx++]; + if (!layer) { + return done(err); + } + if (layer.method && layer.method !== method) { + next(err); + } else if (err) { + layer.handle_error(err, req, res, next); + } else { + layer.handle_request(req, res, next); + } + sync = 0; + } + }; + Route.prototype.all = function all() { + var handles = flatten(slice.call(arguments)); + for (var i = 0; i < handles.length; i++) { + var handle = handles[i]; + if (typeof handle !== "function") { + var type = toString.call(handle); + var msg = "Route.all() requires a callback function but got a " + type; + throw new TypeError(msg); + } + var layer = Layer("/", {}, handle); + layer.method = void 0; + this.methods._all = true; + this.stack.push(layer); + } + return this; + }; + methods.forEach(function(method) { + Route.prototype[method] = function() { + var handles = flatten(slice.call(arguments)); + for (var i = 0; i < handles.length; i++) { + var handle = handles[i]; + if (typeof handle !== "function") { + var type = toString.call(handle); + var msg = "Route." + method + "() requires a callback function but got a " + type; + throw new Error(msg); + } + debug("%s %o", method, this.path); + var layer = Layer("/", {}, handle); + layer.method = method; + this.methods[method] = true; + this.stack.push(layer); + } + return this; + }; + }); + } +}); + +// node_modules/utils-merge/index.js +var require_utils_merge = __commonJS({ + "node_modules/utils-merge/index.js"(exports2, module2) { + exports2 = module2.exports = function(a, b) { + if (a && b) { + for (var key in b) { + a[key] = b[key]; + } + } + return a; + }; + } +}); + +// node_modules/express/lib/router/index.js +var require_router = __commonJS({ + "node_modules/express/lib/router/index.js"(exports2, module2) { + "use strict"; + var Route = require_route(); + var Layer = require_layer(); + var methods = require_methods(); + var mixin = require_utils_merge(); + var debug = require_src3()("express:router"); + var deprecate = require_depd()("express"); + var flatten = require_array_flatten(); + var parseUrl = require_parseurl(); + var setPrototypeOf = require_setprototypeof(); + var objectRegExp = /^\[object (\S+)\]$/; + var slice = Array.prototype.slice; + var toString = Object.prototype.toString; + var proto = module2.exports = function(options) { + var opts = options || {}; + function router(req, res, next) { + router.handle(req, res, next); + } + setPrototypeOf(router, proto); + router.params = {}; + router._params = []; + router.caseSensitive = opts.caseSensitive; + router.mergeParams = opts.mergeParams; + router.strict = opts.strict; + router.stack = []; + return router; + }; + proto.param = function param(name, fn) { + if (typeof name === "function") { + deprecate("router.param(fn): Refactor to use path params"); + this._params.push(name); + return; + } + var params = this._params; + var len = params.length; + var ret; + if (name[0] === ":") { + deprecate("router.param(" + JSON.stringify(name) + ", fn): Use router.param(" + JSON.stringify(name.slice(1)) + ", fn) instead"); + name = name.slice(1); + } + for (var i = 0; i < len; ++i) { + if (ret = params[i](name, fn)) { + fn = ret; + } + } + if ("function" !== typeof fn) { + throw new Error("invalid param() call for " + name + ", got " + fn); + } + (this.params[name] = this.params[name] || []).push(fn); + return this; + }; + proto.handle = function handle(req, res, out) { + var self2 = this; + debug("dispatching %s %s", req.method, req.url); + var idx = 0; + var protohost = getProtohost(req.url) || ""; + var removed = ""; + var slashAdded = false; + var sync = 0; + var paramcalled = {}; + var options = []; + var stack = self2.stack; + var parentParams = req.params; + var parentUrl = req.baseUrl || ""; + var done = restore(out, req, "baseUrl", "next", "params"); + req.next = next; + if (req.method === "OPTIONS") { + done = wrap(done, function(old, err) { + if (err || options.length === 0) return old(err); + sendOptionsResponse(res, options, old); + }); + } + req.baseUrl = parentUrl; + req.originalUrl = req.originalUrl || req.url; + next(); + function next(err) { + var layerError = err === "route" ? null : err; + if (slashAdded) { + req.url = req.url.slice(1); + slashAdded = false; + } + if (removed.length !== 0) { + req.baseUrl = parentUrl; + req.url = protohost + removed + req.url.slice(protohost.length); + removed = ""; + } + if (layerError === "router") { + setImmediate(done, null); + return; + } + if (idx >= stack.length) { + setImmediate(done, layerError); + return; + } + if (++sync > 100) { + return setImmediate(next, err); + } + var path3 = getPathname(req); + if (path3 == null) { + return done(layerError); + } + var layer; + var match; + var route; + while (match !== true && idx < stack.length) { + layer = stack[idx++]; + match = matchLayer(layer, path3); + route = layer.route; + if (typeof match !== "boolean") { + layerError = layerError || match; + } + if (match !== true) { + continue; + } + if (!route) { + continue; + } + if (layerError) { + match = false; + continue; + } + var method = req.method; + var has_method = route._handles_method(method); + if (!has_method && method === "OPTIONS") { + appendMethods(options, route._options()); + } + if (!has_method && method !== "HEAD") { + match = false; + } + } + if (match !== true) { + return done(layerError); + } + if (route) { + req.route = route; + } + req.params = self2.mergeParams ? mergeParams(layer.params, parentParams) : layer.params; + var layerPath = layer.path; + self2.process_params(layer, paramcalled, req, res, function(err2) { + if (err2) { + next(layerError || err2); + } else if (route) { + layer.handle_request(req, res, next); + } else { + trim_prefix(layer, layerError, layerPath, path3); + } + sync = 0; + }); + } + function trim_prefix(layer, layerError, layerPath, path3) { + if (layerPath.length !== 0) { + if (layerPath !== path3.slice(0, layerPath.length)) { + next(layerError); + return; + } + var c = path3[layerPath.length]; + if (c && c !== "/" && c !== ".") return next(layerError); + debug("trim prefix (%s) from url %s", layerPath, req.url); + removed = layerPath; + req.url = protohost + req.url.slice(protohost.length + removed.length); + if (!protohost && req.url[0] !== "/") { + req.url = "/" + req.url; + slashAdded = true; + } + req.baseUrl = parentUrl + (removed[removed.length - 1] === "/" ? removed.substring(0, removed.length - 1) : removed); + } + debug("%s %s : %s", layer.name, layerPath, req.originalUrl); + if (layerError) { + layer.handle_error(layerError, req, res, next); + } else { + layer.handle_request(req, res, next); + } + } + }; + proto.process_params = function process_params(layer, called, req, res, done) { + var params = this.params; + var keys = layer.keys; + if (!keys || keys.length === 0) { + return done(); + } + var i = 0; + var name; + var paramIndex = 0; + var key; + var paramVal; + var paramCallbacks; + var paramCalled; + function param(err) { + if (err) { + return done(err); + } + if (i >= keys.length) { + return done(); + } + paramIndex = 0; + key = keys[i++]; + name = key.name; + paramVal = req.params[name]; + paramCallbacks = params[name]; + paramCalled = called[name]; + if (paramVal === void 0 || !paramCallbacks) { + return param(); + } + if (paramCalled && (paramCalled.match === paramVal || paramCalled.error && paramCalled.error !== "route")) { + req.params[name] = paramCalled.value; + return param(paramCalled.error); + } + called[name] = paramCalled = { + error: null, + match: paramVal, + value: paramVal + }; + paramCallback(); + } + function paramCallback(err) { + var fn = paramCallbacks[paramIndex++]; + paramCalled.value = req.params[key.name]; + if (err) { + paramCalled.error = err; + param(err); + return; + } + if (!fn) return param(); + try { + fn(req, res, paramCallback, paramVal, key.name); + } catch (e) { + paramCallback(e); + } + } + param(); + }; + proto.use = function use(fn) { + var offset = 0; + var path3 = "/"; + if (typeof fn !== "function") { + var arg = fn; + while (Array.isArray(arg) && arg.length !== 0) { + arg = arg[0]; + } + if (typeof arg !== "function") { + offset = 1; + path3 = fn; + } + } + var callbacks = flatten(slice.call(arguments, offset)); + if (callbacks.length === 0) { + throw new TypeError("Router.use() requires a middleware function"); + } + for (var i = 0; i < callbacks.length; i++) { + var fn = callbacks[i]; + if (typeof fn !== "function") { + throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn)); + } + debug("use %o %s", path3, fn.name || ""); + var layer = new Layer(path3, { + sensitive: this.caseSensitive, + strict: false, + end: false + }, fn); + layer.route = void 0; + this.stack.push(layer); + } + return this; + }; + proto.route = function route(path3) { + var route2 = new Route(path3); + var layer = new Layer(path3, { + sensitive: this.caseSensitive, + strict: this.strict, + end: true + }, route2.dispatch.bind(route2)); + layer.route = route2; + this.stack.push(layer); + return route2; + }; + methods.concat("all").forEach(function(method) { + proto[method] = function(path3) { + var route = this.route(path3); + route[method].apply(route, slice.call(arguments, 1)); + return this; + }; + }); + function appendMethods(list, addition) { + for (var i = 0; i < addition.length; i++) { + var method = addition[i]; + if (list.indexOf(method) === -1) { + list.push(method); + } + } + } + function getPathname(req) { + try { + return parseUrl(req).pathname; + } catch (err) { + return void 0; + } + } + function getProtohost(url) { + if (typeof url !== "string" || url.length === 0 || url[0] === "/") { + return void 0; + } + var searchIndex = url.indexOf("?"); + var pathLength = searchIndex !== -1 ? searchIndex : url.length; + var fqdnIndex = url.slice(0, pathLength).indexOf("://"); + return fqdnIndex !== -1 ? url.substring(0, url.indexOf("/", 3 + fqdnIndex)) : void 0; + } + function gettype(obj) { + var type = typeof obj; + if (type !== "object") { + return type; + } + return toString.call(obj).replace(objectRegExp, "$1"); + } + function matchLayer(layer, path3) { + try { + return layer.match(path3); + } catch (err) { + return err; + } + } + function mergeParams(params, parent) { + if (typeof parent !== "object" || !parent) { + return params; + } + var obj = mixin({}, parent); + if (!(0 in params) || !(0 in parent)) { + return mixin(obj, params); + } + var i = 0; + var o = 0; + while (i in params) { + i++; + } + while (o in parent) { + o++; + } + for (i--; i >= 0; i--) { + params[i + o] = params[i]; + if (i < o) { + delete params[i]; + } + } + return mixin(obj, params); + } + function restore(fn, obj) { + var props = new Array(arguments.length - 2); + var vals = new Array(arguments.length - 2); + for (var i = 0; i < props.length; i++) { + props[i] = arguments[i + 2]; + vals[i] = obj[props[i]]; + } + return function() { + for (var i2 = 0; i2 < props.length; i2++) { + obj[props[i2]] = vals[i2]; + } + return fn.apply(this, arguments); + }; + } + function sendOptionsResponse(res, options, next) { + try { + var body = options.join(","); + res.set("Allow", body); + res.send(body); + } catch (err) { + next(err); + } + } + function wrap(old, fn) { + return function proxy() { + var args = new Array(arguments.length + 1); + args[0] = old; + for (var i = 0, len = arguments.length; i < len; i++) { + args[i + 1] = arguments[i]; + } + fn.apply(this, args); + }; + } + } +}); + +// node_modules/express/lib/middleware/init.js +var require_init = __commonJS({ + "node_modules/express/lib/middleware/init.js"(exports2) { + "use strict"; + var setPrototypeOf = require_setprototypeof(); + exports2.init = function(app) { + return function expressInit(req, res, next) { + if (app.enabled("x-powered-by")) res.setHeader("X-Powered-By", "Express"); + req.res = res; + res.req = req; + req.next = next; + setPrototypeOf(req, app.request); + setPrototypeOf(res, app.response); + res.locals = res.locals || /* @__PURE__ */ Object.create(null); + next(); + }; + }; + } +}); + +// node_modules/express/lib/middleware/query.js +var require_query = __commonJS({ + "node_modules/express/lib/middleware/query.js"(exports2, module2) { + "use strict"; + var merge = require_utils_merge(); + var parseUrl = require_parseurl(); + var qs = require_lib2(); + module2.exports = function query(options) { + var opts = merge({}, options); + var queryparse = qs.parse; + if (typeof options === "function") { + queryparse = options; + opts = void 0; + } + if (opts !== void 0 && opts.allowPrototypes === void 0) { + opts.allowPrototypes = true; + } + return function query2(req, res, next) { + if (!req.query) { + var val = parseUrl(req).query; + req.query = queryparse(val, opts); + } + next(); + }; + }; + } +}); + +// node_modules/express/lib/view.js +var require_view = __commonJS({ + "node_modules/express/lib/view.js"(exports2, module2) { + "use strict"; + var debug = require_src3()("express:view"); + var path3 = require("path"); + var fs6 = require("fs"); + var dirname = path3.dirname; + var basename = path3.basename; + var extname = path3.extname; + var join = path3.join; + var resolve = path3.resolve; + module2.exports = View; + function View(name, options) { + var opts = options || {}; + this.defaultEngine = opts.defaultEngine; + this.ext = extname(name); + this.name = name; + this.root = opts.root; + if (!this.ext && !this.defaultEngine) { + throw new Error("No default engine was specified and no extension was provided."); + } + var fileName = name; + if (!this.ext) { + this.ext = this.defaultEngine[0] !== "." ? "." + this.defaultEngine : this.defaultEngine; + fileName += this.ext; + } + if (!opts.engines[this.ext]) { + var mod = this.ext.slice(1); + debug('require "%s"', mod); + var fn = require(mod).__express; + if (typeof fn !== "function") { + throw new Error('Module "' + mod + '" does not provide a view engine.'); + } + opts.engines[this.ext] = fn; + } + this.engine = opts.engines[this.ext]; + this.path = this.lookup(fileName); + } + View.prototype.lookup = function lookup(name) { + var path4; + var roots = [].concat(this.root); + debug('lookup "%s"', name); + for (var i = 0; i < roots.length && !path4; i++) { + var root = roots[i]; + var loc = resolve(root, name); + var dir = dirname(loc); + var file = basename(loc); + path4 = this.resolve(dir, file); + } + return path4; + }; + View.prototype.render = function render(options, callback) { + debug('render "%s"', this.path); + this.engine(this.path, options, callback); + }; + View.prototype.resolve = function resolve2(dir, file) { + var ext = this.ext; + var path4 = join(dir, file); + var stat = tryStat(path4); + if (stat && stat.isFile()) { + return path4; + } + path4 = join(dir, basename(file, ext), "index" + ext); + stat = tryStat(path4); + if (stat && stat.isFile()) { + return path4; + } + }; + function tryStat(path4) { + debug('stat "%s"', path4); + try { + return fs6.statSync(path4); + } catch (e) { + return void 0; + } + } + } +}); + +// node_modules/safe-buffer/index.js +var require_safe_buffer = __commonJS({ + "node_modules/safe-buffer/index.js"(exports2, module2) { + var buffer = require("buffer"); + var Buffer3 = buffer.Buffer; + function copyProps(src, dst) { + for (var key in src) { + dst[key] = src[key]; + } + } + if (Buffer3.from && Buffer3.alloc && Buffer3.allocUnsafe && Buffer3.allocUnsafeSlow) { + module2.exports = buffer; + } else { + copyProps(buffer, exports2); + exports2.Buffer = SafeBuffer; + } + function SafeBuffer(arg, encodingOrOffset, length) { + return Buffer3(arg, encodingOrOffset, length); + } + SafeBuffer.prototype = Object.create(Buffer3.prototype); + copyProps(Buffer3, SafeBuffer); + SafeBuffer.from = function(arg, encodingOrOffset, length) { + if (typeof arg === "number") { + throw new TypeError("Argument must not be a number"); + } + return Buffer3(arg, encodingOrOffset, length); + }; + SafeBuffer.alloc = function(size, fill, encoding) { + if (typeof size !== "number") { + throw new TypeError("Argument must be a number"); + } + var buf = Buffer3(size); + if (fill !== void 0) { + if (typeof encoding === "string") { + buf.fill(fill, encoding); + } else { + buf.fill(fill); + } + } else { + buf.fill(0); + } + return buf; + }; + SafeBuffer.allocUnsafe = function(size) { + if (typeof size !== "number") { + throw new TypeError("Argument must be a number"); + } + return Buffer3(size); + }; + SafeBuffer.allocUnsafeSlow = function(size) { + if (typeof size !== "number") { + throw new TypeError("Argument must be a number"); + } + return buffer.SlowBuffer(size); + }; + } +}); + +// node_modules/content-disposition/index.js +var require_content_disposition = __commonJS({ + "node_modules/content-disposition/index.js"(exports2, module2) { + "use strict"; + module2.exports = contentDisposition; + module2.exports.parse = parse4; + var basename = require("path").basename; + var Buffer3 = require_safe_buffer().Buffer; + var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g; + var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/; + var HEX_ESCAPE_REPLACE_REGEXP = /%([0-9A-Fa-f]{2})/g; + var NON_LATIN1_REGEXP = /[^\x20-\x7e\xa0-\xff]/g; + var QESC_REGEXP = /\\([\u0000-\u007f])/g; + var QUOTE_REGEXP = /([\\"])/g; + var PARAM_REGEXP = /;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g; + var TEXT_REGEXP = /^[\x20-\x7e\x80-\xff]+$/; + var TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/; + var EXT_VALUE_REGEXP = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/; + var DISPOSITION_TYPE_REGEXP = /^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/; + function contentDisposition(filename, options) { + var opts = options || {}; + var type = opts.type || "attachment"; + var params = createparams(filename, opts.fallback); + return format(new ContentDisposition(type, params)); + } + function createparams(filename, fallback) { + if (filename === void 0) { + return; + } + var params = {}; + if (typeof filename !== "string") { + throw new TypeError("filename must be a string"); + } + if (fallback === void 0) { + fallback = true; + } + if (typeof fallback !== "string" && typeof fallback !== "boolean") { + throw new TypeError("fallback must be a string or boolean"); + } + if (typeof fallback === "string" && NON_LATIN1_REGEXP.test(fallback)) { + throw new TypeError("fallback must be ISO-8859-1 string"); + } + var name = basename(filename); + var isQuotedString = TEXT_REGEXP.test(name); + var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename(fallback); + var hasFallback = typeof fallbackName === "string" && fallbackName !== name; + if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) { + params["filename*"] = name; + } + if (isQuotedString || hasFallback) { + params.filename = hasFallback ? fallbackName : name; + } + return params; + } + function format(obj) { + var parameters = obj.parameters; + var type = obj.type; + if (!type || typeof type !== "string" || !TOKEN_REGEXP.test(type)) { + throw new TypeError("invalid type"); + } + var string = String(type).toLowerCase(); + if (parameters && typeof parameters === "object") { + var param; + var params = Object.keys(parameters).sort(); + for (var i = 0; i < params.length; i++) { + param = params[i]; + var val = param.substr(-1) === "*" ? ustring(parameters[param]) : qstring(parameters[param]); + string += "; " + param + "=" + val; + } + } + return string; + } + function decodefield(str) { + var match = EXT_VALUE_REGEXP.exec(str); + if (!match) { + throw new TypeError("invalid extended field value"); + } + var charset = match[1].toLowerCase(); + var encoded = match[2]; + var value; + var binary = encoded.replace(HEX_ESCAPE_REPLACE_REGEXP, pdecode); + switch (charset) { + case "iso-8859-1": + value = getlatin1(binary); + break; + case "utf-8": + value = Buffer3.from(binary, "binary").toString("utf8"); + break; + default: + throw new TypeError("unsupported charset in extended field"); + } + return value; + } + function getlatin1(val) { + return String(val).replace(NON_LATIN1_REGEXP, "?"); + } + function parse4(string) { + if (!string || typeof string !== "string") { + throw new TypeError("argument string is required"); + } + var match = DISPOSITION_TYPE_REGEXP.exec(string); + if (!match) { + throw new TypeError("invalid type format"); + } + var index = match[0].length; + var type = match[1].toLowerCase(); + var key; + var names = []; + var params = {}; + var value; + index = PARAM_REGEXP.lastIndex = match[0].substr(-1) === ";" ? index - 1 : index; + while (match = PARAM_REGEXP.exec(string)) { + if (match.index !== index) { + throw new TypeError("invalid parameter format"); + } + index += match[0].length; + key = match[1].toLowerCase(); + value = match[2]; + if (names.indexOf(key) !== -1) { + throw new TypeError("invalid duplicate parameter"); + } + names.push(key); + if (key.indexOf("*") + 1 === key.length) { + key = key.slice(0, -1); + value = decodefield(value); + params[key] = value; + continue; + } + if (typeof params[key] === "string") { + continue; + } + if (value[0] === '"') { + value = value.substr(1, value.length - 2).replace(QESC_REGEXP, "$1"); + } + params[key] = value; + } + if (index !== -1 && index !== string.length) { + throw new TypeError("invalid parameter format"); + } + return new ContentDisposition(type, params); + } + function pdecode(str, hex) { + return String.fromCharCode(parseInt(hex, 16)); + } + function pencode(char) { + return "%" + String(char).charCodeAt(0).toString(16).toUpperCase(); + } + function qstring(val) { + var str = String(val); + return '"' + str.replace(QUOTE_REGEXP, "\\$1") + '"'; + } + function ustring(val) { + var str = String(val); + var encoded = encodeURIComponent(str).replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode); + return "UTF-8''" + encoded; + } + function ContentDisposition(type, parameters) { + this.type = type; + this.parameters = parameters; + } + } +}); + +// node_modules/send/node_modules/debug/node_modules/ms/index.js +var require_ms4 = __commonJS({ + "node_modules/send/node_modules/debug/node_modules/ms/index.js"(exports2, module2) { + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var y = d * 365.25; + module2.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse4(val); + } else if (type === "number" && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); + }; + function parse4(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + "d"; + } + if (ms >= h) { + return Math.round(ms / h) + "h"; + } + if (ms >= m) { + return Math.round(ms / m) + "m"; + } + if (ms >= s) { + return Math.round(ms / s) + "s"; + } + return ms + "ms"; + } + function fmtLong(ms) { + return plural(ms, d, "day") || plural(ms, h, "hour") || plural(ms, m, "minute") || plural(ms, s, "second") || ms + " ms"; + } + function plural(ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + " " + name; + } + return Math.ceil(ms / n) + " " + name + "s"; + } + } +}); + +// node_modules/send/node_modules/debug/src/debug.js +var require_debug4 = __commonJS({ + "node_modules/send/node_modules/debug/src/debug.js"(exports2, module2) { + exports2 = module2.exports = createDebug.debug = createDebug["default"] = createDebug; + exports2.coerce = coerce; + exports2.disable = disable; + exports2.enable = enable; + exports2.enabled = enabled; + exports2.humanize = require_ms4(); + exports2.names = []; + exports2.skips = []; + exports2.formatters = {}; + var prevTime; + function selectColor(namespace) { + var hash = 0, i; + for (i in namespace) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return exports2.colors[Math.abs(hash) % exports2.colors.length]; + } + function createDebug(namespace) { + function debug() { + if (!debug.enabled) return; + var self2 = debug; + var curr = +/* @__PURE__ */ new Date(); + var ms = curr - (prevTime || curr); + self2.diff = ms; + self2.prev = prevTime; + self2.curr = curr; + prevTime = curr; + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + args[0] = exports2.coerce(args[0]); + if ("string" !== typeof args[0]) { + args.unshift("%O"); + } + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + if (match === "%%") return match; + index++; + var formatter = exports2.formatters[format]; + if ("function" === typeof formatter) { + var val = args[index]; + match = formatter.call(self2, val); + args.splice(index, 1); + index--; + } + return match; + }); + exports2.formatArgs.call(self2, args); + var logFn = debug.log || exports2.log || console.log.bind(console); + logFn.apply(self2, args); + } + debug.namespace = namespace; + debug.enabled = exports2.enabled(namespace); + debug.useColors = exports2.useColors(); + debug.color = selectColor(namespace); + if ("function" === typeof exports2.init) { + exports2.init(debug); + } + return debug; + } + function enable(namespaces) { + exports2.save(namespaces); + exports2.names = []; + exports2.skips = []; + var split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/); + var len = split.length; + for (var i = 0; i < len; i++) { + if (!split[i]) continue; + namespaces = split[i].replace(/\*/g, ".*?"); + if (namespaces[0] === "-") { + exports2.skips.push(new RegExp("^" + namespaces.substr(1) + "$")); + } else { + exports2.names.push(new RegExp("^" + namespaces + "$")); + } + } + } + function disable() { + exports2.enable(""); + } + function enabled(name) { + var i, len; + for (i = 0, len = exports2.skips.length; i < len; i++) { + if (exports2.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports2.names.length; i < len; i++) { + if (exports2.names[i].test(name)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; + } + } +}); + +// node_modules/send/node_modules/debug/src/browser.js +var require_browser4 = __commonJS({ + "node_modules/send/node_modules/debug/src/browser.js"(exports2, module2) { + exports2 = module2.exports = require_debug4(); + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.storage = "undefined" != typeof chrome && "undefined" != typeof chrome.storage ? chrome.storage.local : localstorage(); + exports2.colors = [ + "lightseagreen", + "forestgreen", + "goldenrod", + "dodgerblue", + "darkorchid", + "crimson" + ]; + function useColors() { + if (typeof window !== "undefined" && window.process && window.process.type === "renderer") { + return true; + } + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + exports2.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return "[UnexpectedJSONParseError]: " + err.message; + } + }; + function formatArgs(args) { + var useColors2 = this.useColors; + args[0] = (useColors2 ? "%c" : "") + this.namespace + (useColors2 ? " %c" : " ") + args[0] + (useColors2 ? "%c " : " ") + "+" + exports2.humanize(this.diff); + if (!useColors2) return; + var c = "color: " + this.color; + args.splice(1, 0, c, "color: inherit"); + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ("%%" === match) return; + index++; + if ("%c" === match) { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + function log() { + return "object" === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); + } + function save(namespaces) { + try { + if (null == namespaces) { + exports2.storage.removeItem("debug"); + } else { + exports2.storage.debug = namespaces; + } + } catch (e) { + } + } + function load() { + var r; + try { + r = exports2.storage.debug; + } catch (e) { + } + if (!r && typeof process !== "undefined" && "env" in process) { + r = process.env.DEBUG; + } + return r; + } + exports2.enable(load()); + function localstorage() { + try { + return window.localStorage; + } catch (e) { + } + } + } +}); + +// node_modules/send/node_modules/debug/src/node.js +var require_node4 = __commonJS({ + "node_modules/send/node_modules/debug/src/node.js"(exports2, module2) { + var tty = require("tty"); + var util = require("util"); + exports2 = module2.exports = require_debug4(); + exports2.init = init; + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.colors = [6, 2, 3, 4, 5, 1]; + exports2.inspectOpts = Object.keys(process.env).filter(function(key) { + return /^debug_/i.test(key); + }).reduce(function(obj, key) { + var prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, function(_, k) { + return k.toUpperCase(); + }); + var val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) val = true; + else if (/^(no|off|false|disabled)$/i.test(val)) val = false; + else if (val === "null") val = null; + else val = Number(val); + obj[prop] = val; + return obj; + }, {}); + var fd = parseInt(process.env.DEBUG_FD, 10) || 2; + if (1 !== fd && 2 !== fd) { + util.deprecate(function() { + }, "except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)")(); + } + var stream = 1 === fd ? process.stdout : 2 === fd ? process.stderr : createWritableStdioStream(fd); + function useColors() { + return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty.isatty(fd); + } + exports2.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts).split("\n").map(function(str) { + return str.trim(); + }).join(" "); + }; + exports2.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); + }; + function formatArgs(args) { + var name = this.namespace; + var useColors2 = this.useColors; + if (useColors2) { + var c = this.color; + var prefix = " \x1B[3" + c + ";1m" + name + " \x1B[0m"; + args[0] = prefix + args[0].split("\n").join("\n" + prefix); + args.push("\x1B[3" + c + "m+" + exports2.humanize(this.diff) + "\x1B[0m"); + } else { + args[0] = (/* @__PURE__ */ new Date()).toUTCString() + " " + name + " " + args[0]; + } + } + function log() { + return stream.write(util.format.apply(util, arguments) + "\n"); + } + function save(namespaces) { + if (null == namespaces) { + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; + } + } + function load() { + return process.env.DEBUG; + } + function createWritableStdioStream(fd2) { + var stream2; + var tty_wrap = process.binding("tty_wrap"); + switch (tty_wrap.guessHandleType(fd2)) { + case "TTY": + stream2 = new tty.WriteStream(fd2); + stream2._type = "tty"; + if (stream2._handle && stream2._handle.unref) { + stream2._handle.unref(); + } + break; + case "FILE": + var fs6 = require("fs"); + stream2 = new fs6.SyncWriteStream(fd2, { autoClose: false }); + stream2._type = "fs"; + break; + case "PIPE": + case "TCP": + var net = require("net"); + stream2 = new net.Socket({ + fd: fd2, + readable: false, + writable: true + }); + stream2.readable = false; + stream2.read = null; + stream2._type = "pipe"; + if (stream2._handle && stream2._handle.unref) { + stream2._handle.unref(); + } + break; + default: + throw new Error("Implement me. Unknown stream file type!"); + } + stream2.fd = fd2; + stream2._isStdio = true; + return stream2; + } + function init(debug) { + debug.inspectOpts = {}; + var keys = Object.keys(exports2.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports2.inspectOpts[keys[i]]; + } + } + exports2.enable(load()); + } +}); + +// node_modules/send/node_modules/debug/src/index.js +var require_src4 = __commonJS({ + "node_modules/send/node_modules/debug/src/index.js"(exports2, module2) { + if (typeof process !== "undefined" && process.type === "renderer") { + module2.exports = require_browser4(); + } else { + module2.exports = require_node4(); + } + } +}); + +// node_modules/etag/index.js +var require_etag = __commonJS({ + "node_modules/etag/index.js"(exports2, module2) { + "use strict"; + module2.exports = etag; + var crypto12 = require("crypto"); + var Stats = require("fs").Stats; + var toString = Object.prototype.toString; + function entitytag(entity) { + if (entity.length === 0) { + return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"'; + } + var hash = crypto12.createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27); + var len = typeof entity === "string" ? Buffer.byteLength(entity, "utf8") : entity.length; + return '"' + len.toString(16) + "-" + hash + '"'; + } + function etag(entity, options) { + if (entity == null) { + throw new TypeError("argument entity is required"); + } + var isStats = isstats(entity); + var weak = options && typeof options.weak === "boolean" ? options.weak : isStats; + if (!isStats && typeof entity !== "string" && !Buffer.isBuffer(entity)) { + throw new TypeError("argument entity must be string, Buffer, or fs.Stats"); + } + var tag = isStats ? stattag(entity) : entitytag(entity); + return weak ? "W/" + tag : tag; + } + function isstats(obj) { + if (typeof Stats === "function" && obj instanceof Stats) { + return true; + } + return obj && typeof obj === "object" && "ctime" in obj && toString.call(obj.ctime) === "[object Date]" && "mtime" in obj && toString.call(obj.mtime) === "[object Date]" && "ino" in obj && typeof obj.ino === "number" && "size" in obj && typeof obj.size === "number"; + } + function stattag(stat) { + var mtime = stat.mtime.getTime().toString(16); + var size = stat.size.toString(16); + return '"' + size + "-" + mtime + '"'; + } + } +}); + +// node_modules/fresh/index.js +var require_fresh = __commonJS({ + "node_modules/fresh/index.js"(exports2, module2) { + "use strict"; + var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/; + module2.exports = fresh; + function fresh(reqHeaders, resHeaders) { + var modifiedSince = reqHeaders["if-modified-since"]; + var noneMatch = reqHeaders["if-none-match"]; + if (!modifiedSince && !noneMatch) { + return false; + } + var cacheControl = reqHeaders["cache-control"]; + if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) { + return false; + } + if (noneMatch && noneMatch !== "*") { + var etag = resHeaders["etag"]; + if (!etag) { + return false; + } + var etagStale = true; + var matches = parseTokenList(noneMatch); + for (var i = 0; i < matches.length; i++) { + var match = matches[i]; + if (match === etag || match === "W/" + etag || "W/" + match === etag) { + etagStale = false; + break; + } + } + if (etagStale) { + return false; + } + } + if (modifiedSince) { + var lastModified = resHeaders["last-modified"]; + var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince)); + if (modifiedStale) { + return false; + } + } + return true; + } + function parseHttpDate(date) { + var timestamp = date && Date.parse(date); + return typeof timestamp === "number" ? timestamp : NaN; + } + function parseTokenList(str) { + var end = 0; + var list = []; + var start = 0; + for (var i = 0, len = str.length; i < len; i++) { + switch (str.charCodeAt(i)) { + case 32: + if (start === end) { + start = end = i + 1; + } + break; + case 44: + list.push(str.substring(start, end)); + start = end = i + 1; + break; + default: + end = i + 1; + break; + } + } + list.push(str.substring(start, end)); + return list; + } + } +}); + +// node_modules/mime/types.json +var require_types = __commonJS({ + "node_modules/mime/types.json"(exports2, module2) { + module2.exports = { "application/andrew-inset": ["ez"], "application/applixware": ["aw"], "application/atom+xml": ["atom"], "application/atomcat+xml": ["atomcat"], "application/atomsvc+xml": ["atomsvc"], "application/bdoc": ["bdoc"], "application/ccxml+xml": ["ccxml"], "application/cdmi-capability": ["cdmia"], "application/cdmi-container": ["cdmic"], "application/cdmi-domain": ["cdmid"], "application/cdmi-object": ["cdmio"], "application/cdmi-queue": ["cdmiq"], "application/cu-seeme": ["cu"], "application/dash+xml": ["mpd"], "application/davmount+xml": ["davmount"], "application/docbook+xml": ["dbk"], "application/dssc+der": ["dssc"], "application/dssc+xml": ["xdssc"], "application/ecmascript": ["ecma"], "application/emma+xml": ["emma"], "application/epub+zip": ["epub"], "application/exi": ["exi"], "application/font-tdpfr": ["pfr"], "application/font-woff": [], "application/font-woff2": [], "application/geo+json": ["geojson"], "application/gml+xml": ["gml"], "application/gpx+xml": ["gpx"], "application/gxf": ["gxf"], "application/gzip": ["gz"], "application/hyperstudio": ["stk"], "application/inkml+xml": ["ink", "inkml"], "application/ipfix": ["ipfix"], "application/java-archive": ["jar", "war", "ear"], "application/java-serialized-object": ["ser"], "application/java-vm": ["class"], "application/javascript": ["js", "mjs"], "application/json": ["json", "map"], "application/json5": ["json5"], "application/jsonml+json": ["jsonml"], "application/ld+json": ["jsonld"], "application/lost+xml": ["lostxml"], "application/mac-binhex40": ["hqx"], "application/mac-compactpro": ["cpt"], "application/mads+xml": ["mads"], "application/manifest+json": ["webmanifest"], "application/marc": ["mrc"], "application/marcxml+xml": ["mrcx"], "application/mathematica": ["ma", "nb", "mb"], "application/mathml+xml": ["mathml"], "application/mbox": ["mbox"], "application/mediaservercontrol+xml": ["mscml"], "application/metalink+xml": ["metalink"], "application/metalink4+xml": ["meta4"], "application/mets+xml": ["mets"], "application/mods+xml": ["mods"], "application/mp21": ["m21", "mp21"], "application/mp4": ["mp4s", "m4p"], "application/msword": ["doc", "dot"], "application/mxf": ["mxf"], "application/octet-stream": ["bin", "dms", "lrf", "mar", "so", "dist", "distz", "pkg", "bpk", "dump", "elc", "deploy", "exe", "dll", "deb", "dmg", "iso", "img", "msi", "msp", "msm", "buffer"], "application/oda": ["oda"], "application/oebps-package+xml": ["opf"], "application/ogg": ["ogx"], "application/omdoc+xml": ["omdoc"], "application/onenote": ["onetoc", "onetoc2", "onetmp", "onepkg"], "application/oxps": ["oxps"], "application/patch-ops-error+xml": ["xer"], "application/pdf": ["pdf"], "application/pgp-encrypted": ["pgp"], "application/pgp-signature": ["asc", "sig"], "application/pics-rules": ["prf"], "application/pkcs10": ["p10"], "application/pkcs7-mime": ["p7m", "p7c"], "application/pkcs7-signature": ["p7s"], "application/pkcs8": ["p8"], "application/pkix-attr-cert": ["ac"], "application/pkix-cert": ["cer"], "application/pkix-crl": ["crl"], "application/pkix-pkipath": ["pkipath"], "application/pkixcmp": ["pki"], "application/pls+xml": ["pls"], "application/postscript": ["ai", "eps", "ps"], "application/prs.cww": ["cww"], "application/pskc+xml": ["pskcxml"], "application/raml+yaml": ["raml"], "application/rdf+xml": ["rdf"], "application/reginfo+xml": ["rif"], "application/relax-ng-compact-syntax": ["rnc"], "application/resource-lists+xml": ["rl"], "application/resource-lists-diff+xml": ["rld"], "application/rls-services+xml": ["rs"], "application/rpki-ghostbusters": ["gbr"], "application/rpki-manifest": ["mft"], "application/rpki-roa": ["roa"], "application/rsd+xml": ["rsd"], "application/rss+xml": ["rss"], "application/rtf": ["rtf"], "application/sbml+xml": ["sbml"], "application/scvp-cv-request": ["scq"], "application/scvp-cv-response": ["scs"], "application/scvp-vp-request": ["spq"], "application/scvp-vp-response": ["spp"], "application/sdp": ["sdp"], "application/set-payment-initiation": ["setpay"], "application/set-registration-initiation": ["setreg"], "application/shf+xml": ["shf"], "application/smil+xml": ["smi", "smil"], "application/sparql-query": ["rq"], "application/sparql-results+xml": ["srx"], "application/srgs": ["gram"], "application/srgs+xml": ["grxml"], "application/sru+xml": ["sru"], "application/ssdl+xml": ["ssdl"], "application/ssml+xml": ["ssml"], "application/tei+xml": ["tei", "teicorpus"], "application/thraud+xml": ["tfi"], "application/timestamped-data": ["tsd"], "application/vnd.3gpp.pic-bw-large": ["plb"], "application/vnd.3gpp.pic-bw-small": ["psb"], "application/vnd.3gpp.pic-bw-var": ["pvb"], "application/vnd.3gpp2.tcap": ["tcap"], "application/vnd.3m.post-it-notes": ["pwn"], "application/vnd.accpac.simply.aso": ["aso"], "application/vnd.accpac.simply.imp": ["imp"], "application/vnd.acucobol": ["acu"], "application/vnd.acucorp": ["atc", "acutc"], "application/vnd.adobe.air-application-installer-package+zip": ["air"], "application/vnd.adobe.formscentral.fcdt": ["fcdt"], "application/vnd.adobe.fxp": ["fxp", "fxpl"], "application/vnd.adobe.xdp+xml": ["xdp"], "application/vnd.adobe.xfdf": ["xfdf"], "application/vnd.ahead.space": ["ahead"], "application/vnd.airzip.filesecure.azf": ["azf"], "application/vnd.airzip.filesecure.azs": ["azs"], "application/vnd.amazon.ebook": ["azw"], "application/vnd.americandynamics.acc": ["acc"], "application/vnd.amiga.ami": ["ami"], "application/vnd.android.package-archive": ["apk"], "application/vnd.anser-web-certificate-issue-initiation": ["cii"], "application/vnd.anser-web-funds-transfer-initiation": ["fti"], "application/vnd.antix.game-component": ["atx"], "application/vnd.apple.installer+xml": ["mpkg"], "application/vnd.apple.mpegurl": ["m3u8"], "application/vnd.apple.pkpass": ["pkpass"], "application/vnd.aristanetworks.swi": ["swi"], "application/vnd.astraea-software.iota": ["iota"], "application/vnd.audiograph": ["aep"], "application/vnd.blueice.multipass": ["mpm"], "application/vnd.bmi": ["bmi"], "application/vnd.businessobjects": ["rep"], "application/vnd.chemdraw+xml": ["cdxml"], "application/vnd.chipnuts.karaoke-mmd": ["mmd"], "application/vnd.cinderella": ["cdy"], "application/vnd.claymore": ["cla"], "application/vnd.cloanto.rp9": ["rp9"], "application/vnd.clonk.c4group": ["c4g", "c4d", "c4f", "c4p", "c4u"], "application/vnd.cluetrust.cartomobile-config": ["c11amc"], "application/vnd.cluetrust.cartomobile-config-pkg": ["c11amz"], "application/vnd.commonspace": ["csp"], "application/vnd.contact.cmsg": ["cdbcmsg"], "application/vnd.cosmocaller": ["cmc"], "application/vnd.crick.clicker": ["clkx"], "application/vnd.crick.clicker.keyboard": ["clkk"], "application/vnd.crick.clicker.palette": ["clkp"], "application/vnd.crick.clicker.template": ["clkt"], "application/vnd.crick.clicker.wordbank": ["clkw"], "application/vnd.criticaltools.wbs+xml": ["wbs"], "application/vnd.ctc-posml": ["pml"], "application/vnd.cups-ppd": ["ppd"], "application/vnd.curl.car": ["car"], "application/vnd.curl.pcurl": ["pcurl"], "application/vnd.dart": ["dart"], "application/vnd.data-vision.rdz": ["rdz"], "application/vnd.dece.data": ["uvf", "uvvf", "uvd", "uvvd"], "application/vnd.dece.ttml+xml": ["uvt", "uvvt"], "application/vnd.dece.unspecified": ["uvx", "uvvx"], "application/vnd.dece.zip": ["uvz", "uvvz"], "application/vnd.denovo.fcselayout-link": ["fe_launch"], "application/vnd.dna": ["dna"], "application/vnd.dolby.mlp": ["mlp"], "application/vnd.dpgraph": ["dpg"], "application/vnd.dreamfactory": ["dfac"], "application/vnd.ds-keypoint": ["kpxx"], "application/vnd.dvb.ait": ["ait"], "application/vnd.dvb.service": ["svc"], "application/vnd.dynageo": ["geo"], "application/vnd.ecowin.chart": ["mag"], "application/vnd.enliven": ["nml"], "application/vnd.epson.esf": ["esf"], "application/vnd.epson.msf": ["msf"], "application/vnd.epson.quickanime": ["qam"], "application/vnd.epson.salt": ["slt"], "application/vnd.epson.ssf": ["ssf"], "application/vnd.eszigno3+xml": ["es3", "et3"], "application/vnd.ezpix-album": ["ez2"], "application/vnd.ezpix-package": ["ez3"], "application/vnd.fdf": ["fdf"], "application/vnd.fdsn.mseed": ["mseed"], "application/vnd.fdsn.seed": ["seed", "dataless"], "application/vnd.flographit": ["gph"], "application/vnd.fluxtime.clip": ["ftc"], "application/vnd.framemaker": ["fm", "frame", "maker", "book"], "application/vnd.frogans.fnc": ["fnc"], "application/vnd.frogans.ltf": ["ltf"], "application/vnd.fsc.weblaunch": ["fsc"], "application/vnd.fujitsu.oasys": ["oas"], "application/vnd.fujitsu.oasys2": ["oa2"], "application/vnd.fujitsu.oasys3": ["oa3"], "application/vnd.fujitsu.oasysgp": ["fg5"], "application/vnd.fujitsu.oasysprs": ["bh2"], "application/vnd.fujixerox.ddd": ["ddd"], "application/vnd.fujixerox.docuworks": ["xdw"], "application/vnd.fujixerox.docuworks.binder": ["xbd"], "application/vnd.fuzzysheet": ["fzs"], "application/vnd.genomatix.tuxedo": ["txd"], "application/vnd.geogebra.file": ["ggb"], "application/vnd.geogebra.tool": ["ggt"], "application/vnd.geometry-explorer": ["gex", "gre"], "application/vnd.geonext": ["gxt"], "application/vnd.geoplan": ["g2w"], "application/vnd.geospace": ["g3w"], "application/vnd.gmx": ["gmx"], "application/vnd.google-apps.document": ["gdoc"], "application/vnd.google-apps.presentation": ["gslides"], "application/vnd.google-apps.spreadsheet": ["gsheet"], "application/vnd.google-earth.kml+xml": ["kml"], "application/vnd.google-earth.kmz": ["kmz"], "application/vnd.grafeq": ["gqf", "gqs"], "application/vnd.groove-account": ["gac"], "application/vnd.groove-help": ["ghf"], "application/vnd.groove-identity-message": ["gim"], "application/vnd.groove-injector": ["grv"], "application/vnd.groove-tool-message": ["gtm"], "application/vnd.groove-tool-template": ["tpl"], "application/vnd.groove-vcard": ["vcg"], "application/vnd.hal+xml": ["hal"], "application/vnd.handheld-entertainment+xml": ["zmm"], "application/vnd.hbci": ["hbci"], "application/vnd.hhe.lesson-player": ["les"], "application/vnd.hp-hpgl": ["hpgl"], "application/vnd.hp-hpid": ["hpid"], "application/vnd.hp-hps": ["hps"], "application/vnd.hp-jlyt": ["jlt"], "application/vnd.hp-pcl": ["pcl"], "application/vnd.hp-pclxl": ["pclxl"], "application/vnd.hydrostatix.sof-data": ["sfd-hdstx"], "application/vnd.ibm.minipay": ["mpy"], "application/vnd.ibm.modcap": ["afp", "listafp", "list3820"], "application/vnd.ibm.rights-management": ["irm"], "application/vnd.ibm.secure-container": ["sc"], "application/vnd.iccprofile": ["icc", "icm"], "application/vnd.igloader": ["igl"], "application/vnd.immervision-ivp": ["ivp"], "application/vnd.immervision-ivu": ["ivu"], "application/vnd.insors.igm": ["igm"], "application/vnd.intercon.formnet": ["xpw", "xpx"], "application/vnd.intergeo": ["i2g"], "application/vnd.intu.qbo": ["qbo"], "application/vnd.intu.qfx": ["qfx"], "application/vnd.ipunplugged.rcprofile": ["rcprofile"], "application/vnd.irepository.package+xml": ["irp"], "application/vnd.is-xpr": ["xpr"], "application/vnd.isac.fcs": ["fcs"], "application/vnd.jam": ["jam"], "application/vnd.jcp.javame.midlet-rms": ["rms"], "application/vnd.jisp": ["jisp"], "application/vnd.joost.joda-archive": ["joda"], "application/vnd.kahootz": ["ktz", "ktr"], "application/vnd.kde.karbon": ["karbon"], "application/vnd.kde.kchart": ["chrt"], "application/vnd.kde.kformula": ["kfo"], "application/vnd.kde.kivio": ["flw"], "application/vnd.kde.kontour": ["kon"], "application/vnd.kde.kpresenter": ["kpr", "kpt"], "application/vnd.kde.kspread": ["ksp"], "application/vnd.kde.kword": ["kwd", "kwt"], "application/vnd.kenameaapp": ["htke"], "application/vnd.kidspiration": ["kia"], "application/vnd.kinar": ["kne", "knp"], "application/vnd.koan": ["skp", "skd", "skt", "skm"], "application/vnd.kodak-descriptor": ["sse"], "application/vnd.las.las+xml": ["lasxml"], "application/vnd.llamagraphics.life-balance.desktop": ["lbd"], "application/vnd.llamagraphics.life-balance.exchange+xml": ["lbe"], "application/vnd.lotus-1-2-3": ["123"], "application/vnd.lotus-approach": ["apr"], "application/vnd.lotus-freelance": ["pre"], "application/vnd.lotus-notes": ["nsf"], "application/vnd.lotus-organizer": ["org"], "application/vnd.lotus-screencam": ["scm"], "application/vnd.lotus-wordpro": ["lwp"], "application/vnd.macports.portpkg": ["portpkg"], "application/vnd.mcd": ["mcd"], "application/vnd.medcalcdata": ["mc1"], "application/vnd.mediastation.cdkey": ["cdkey"], "application/vnd.mfer": ["mwf"], "application/vnd.mfmp": ["mfm"], "application/vnd.micrografx.flo": ["flo"], "application/vnd.micrografx.igx": ["igx"], "application/vnd.mif": ["mif"], "application/vnd.mobius.daf": ["daf"], "application/vnd.mobius.dis": ["dis"], "application/vnd.mobius.mbk": ["mbk"], "application/vnd.mobius.mqy": ["mqy"], "application/vnd.mobius.msl": ["msl"], "application/vnd.mobius.plc": ["plc"], "application/vnd.mobius.txf": ["txf"], "application/vnd.mophun.application": ["mpn"], "application/vnd.mophun.certificate": ["mpc"], "application/vnd.mozilla.xul+xml": ["xul"], "application/vnd.ms-artgalry": ["cil"], "application/vnd.ms-cab-compressed": ["cab"], "application/vnd.ms-excel": ["xls", "xlm", "xla", "xlc", "xlt", "xlw"], "application/vnd.ms-excel.addin.macroenabled.12": ["xlam"], "application/vnd.ms-excel.sheet.binary.macroenabled.12": ["xlsb"], "application/vnd.ms-excel.sheet.macroenabled.12": ["xlsm"], "application/vnd.ms-excel.template.macroenabled.12": ["xltm"], "application/vnd.ms-fontobject": ["eot"], "application/vnd.ms-htmlhelp": ["chm"], "application/vnd.ms-ims": ["ims"], "application/vnd.ms-lrm": ["lrm"], "application/vnd.ms-officetheme": ["thmx"], "application/vnd.ms-outlook": ["msg"], "application/vnd.ms-pki.seccat": ["cat"], "application/vnd.ms-pki.stl": ["stl"], "application/vnd.ms-powerpoint": ["ppt", "pps", "pot"], "application/vnd.ms-powerpoint.addin.macroenabled.12": ["ppam"], "application/vnd.ms-powerpoint.presentation.macroenabled.12": ["pptm"], "application/vnd.ms-powerpoint.slide.macroenabled.12": ["sldm"], "application/vnd.ms-powerpoint.slideshow.macroenabled.12": ["ppsm"], "application/vnd.ms-powerpoint.template.macroenabled.12": ["potm"], "application/vnd.ms-project": ["mpp", "mpt"], "application/vnd.ms-word.document.macroenabled.12": ["docm"], "application/vnd.ms-word.template.macroenabled.12": ["dotm"], "application/vnd.ms-works": ["wps", "wks", "wcm", "wdb"], "application/vnd.ms-wpl": ["wpl"], "application/vnd.ms-xpsdocument": ["xps"], "application/vnd.mseq": ["mseq"], "application/vnd.musician": ["mus"], "application/vnd.muvee.style": ["msty"], "application/vnd.mynfc": ["taglet"], "application/vnd.neurolanguage.nlu": ["nlu"], "application/vnd.nitf": ["ntf", "nitf"], "application/vnd.noblenet-directory": ["nnd"], "application/vnd.noblenet-sealer": ["nns"], "application/vnd.noblenet-web": ["nnw"], "application/vnd.nokia.n-gage.data": ["ngdat"], "application/vnd.nokia.n-gage.symbian.install": ["n-gage"], "application/vnd.nokia.radio-preset": ["rpst"], "application/vnd.nokia.radio-presets": ["rpss"], "application/vnd.novadigm.edm": ["edm"], "application/vnd.novadigm.edx": ["edx"], "application/vnd.novadigm.ext": ["ext"], "application/vnd.oasis.opendocument.chart": ["odc"], "application/vnd.oasis.opendocument.chart-template": ["otc"], "application/vnd.oasis.opendocument.database": ["odb"], "application/vnd.oasis.opendocument.formula": ["odf"], "application/vnd.oasis.opendocument.formula-template": ["odft"], "application/vnd.oasis.opendocument.graphics": ["odg"], "application/vnd.oasis.opendocument.graphics-template": ["otg"], "application/vnd.oasis.opendocument.image": ["odi"], "application/vnd.oasis.opendocument.image-template": ["oti"], "application/vnd.oasis.opendocument.presentation": ["odp"], "application/vnd.oasis.opendocument.presentation-template": ["otp"], "application/vnd.oasis.opendocument.spreadsheet": ["ods"], "application/vnd.oasis.opendocument.spreadsheet-template": ["ots"], "application/vnd.oasis.opendocument.text": ["odt"], "application/vnd.oasis.opendocument.text-master": ["odm"], "application/vnd.oasis.opendocument.text-template": ["ott"], "application/vnd.oasis.opendocument.text-web": ["oth"], "application/vnd.olpc-sugar": ["xo"], "application/vnd.oma.dd2+xml": ["dd2"], "application/vnd.openofficeorg.extension": ["oxt"], "application/vnd.openxmlformats-officedocument.presentationml.presentation": ["pptx"], "application/vnd.openxmlformats-officedocument.presentationml.slide": ["sldx"], "application/vnd.openxmlformats-officedocument.presentationml.slideshow": ["ppsx"], "application/vnd.openxmlformats-officedocument.presentationml.template": ["potx"], "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ["xlsx"], "application/vnd.openxmlformats-officedocument.spreadsheetml.template": ["xltx"], "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ["docx"], "application/vnd.openxmlformats-officedocument.wordprocessingml.template": ["dotx"], "application/vnd.osgeo.mapguide.package": ["mgp"], "application/vnd.osgi.dp": ["dp"], "application/vnd.osgi.subsystem": ["esa"], "application/vnd.palm": ["pdb", "pqa", "oprc"], "application/vnd.pawaafile": ["paw"], "application/vnd.pg.format": ["str"], "application/vnd.pg.osasli": ["ei6"], "application/vnd.picsel": ["efif"], "application/vnd.pmi.widget": ["wg"], "application/vnd.pocketlearn": ["plf"], "application/vnd.powerbuilder6": ["pbd"], "application/vnd.previewsystems.box": ["box"], "application/vnd.proteus.magazine": ["mgz"], "application/vnd.publishare-delta-tree": ["qps"], "application/vnd.pvi.ptid1": ["ptid"], "application/vnd.quark.quarkxpress": ["qxd", "qxt", "qwd", "qwt", "qxl", "qxb"], "application/vnd.realvnc.bed": ["bed"], "application/vnd.recordare.musicxml": ["mxl"], "application/vnd.recordare.musicxml+xml": ["musicxml"], "application/vnd.rig.cryptonote": ["cryptonote"], "application/vnd.rim.cod": ["cod"], "application/vnd.rn-realmedia": ["rm"], "application/vnd.rn-realmedia-vbr": ["rmvb"], "application/vnd.route66.link66+xml": ["link66"], "application/vnd.sailingtracker.track": ["st"], "application/vnd.seemail": ["see"], "application/vnd.sema": ["sema"], "application/vnd.semd": ["semd"], "application/vnd.semf": ["semf"], "application/vnd.shana.informed.formdata": ["ifm"], "application/vnd.shana.informed.formtemplate": ["itp"], "application/vnd.shana.informed.interchange": ["iif"], "application/vnd.shana.informed.package": ["ipk"], "application/vnd.simtech-mindmapper": ["twd", "twds"], "application/vnd.smaf": ["mmf"], "application/vnd.smart.teacher": ["teacher"], "application/vnd.solent.sdkm+xml": ["sdkm", "sdkd"], "application/vnd.spotfire.dxp": ["dxp"], "application/vnd.spotfire.sfs": ["sfs"], "application/vnd.stardivision.calc": ["sdc"], "application/vnd.stardivision.draw": ["sda"], "application/vnd.stardivision.impress": ["sdd"], "application/vnd.stardivision.math": ["smf"], "application/vnd.stardivision.writer": ["sdw", "vor"], "application/vnd.stardivision.writer-global": ["sgl"], "application/vnd.stepmania.package": ["smzip"], "application/vnd.stepmania.stepchart": ["sm"], "application/vnd.sun.wadl+xml": ["wadl"], "application/vnd.sun.xml.calc": ["sxc"], "application/vnd.sun.xml.calc.template": ["stc"], "application/vnd.sun.xml.draw": ["sxd"], "application/vnd.sun.xml.draw.template": ["std"], "application/vnd.sun.xml.impress": ["sxi"], "application/vnd.sun.xml.impress.template": ["sti"], "application/vnd.sun.xml.math": ["sxm"], "application/vnd.sun.xml.writer": ["sxw"], "application/vnd.sun.xml.writer.global": ["sxg"], "application/vnd.sun.xml.writer.template": ["stw"], "application/vnd.sus-calendar": ["sus", "susp"], "application/vnd.svd": ["svd"], "application/vnd.symbian.install": ["sis", "sisx"], "application/vnd.syncml+xml": ["xsm"], "application/vnd.syncml.dm+wbxml": ["bdm"], "application/vnd.syncml.dm+xml": ["xdm"], "application/vnd.tao.intent-module-archive": ["tao"], "application/vnd.tcpdump.pcap": ["pcap", "cap", "dmp"], "application/vnd.tmobile-livetv": ["tmo"], "application/vnd.trid.tpt": ["tpt"], "application/vnd.triscape.mxs": ["mxs"], "application/vnd.trueapp": ["tra"], "application/vnd.ufdl": ["ufd", "ufdl"], "application/vnd.uiq.theme": ["utz"], "application/vnd.umajin": ["umj"], "application/vnd.unity": ["unityweb"], "application/vnd.uoml+xml": ["uoml"], "application/vnd.vcx": ["vcx"], "application/vnd.visio": ["vsd", "vst", "vss", "vsw"], "application/vnd.visionary": ["vis"], "application/vnd.vsf": ["vsf"], "application/vnd.wap.wbxml": ["wbxml"], "application/vnd.wap.wmlc": ["wmlc"], "application/vnd.wap.wmlscriptc": ["wmlsc"], "application/vnd.webturbo": ["wtb"], "application/vnd.wolfram.player": ["nbp"], "application/vnd.wordperfect": ["wpd"], "application/vnd.wqd": ["wqd"], "application/vnd.wt.stf": ["stf"], "application/vnd.xara": ["xar"], "application/vnd.xfdl": ["xfdl"], "application/vnd.yamaha.hv-dic": ["hvd"], "application/vnd.yamaha.hv-script": ["hvs"], "application/vnd.yamaha.hv-voice": ["hvp"], "application/vnd.yamaha.openscoreformat": ["osf"], "application/vnd.yamaha.openscoreformat.osfpvg+xml": ["osfpvg"], "application/vnd.yamaha.smaf-audio": ["saf"], "application/vnd.yamaha.smaf-phrase": ["spf"], "application/vnd.yellowriver-custom-menu": ["cmp"], "application/vnd.zul": ["zir", "zirz"], "application/vnd.zzazz.deck+xml": ["zaz"], "application/voicexml+xml": ["vxml"], "application/wasm": ["wasm"], "application/widget": ["wgt"], "application/winhlp": ["hlp"], "application/wsdl+xml": ["wsdl"], "application/wspolicy+xml": ["wspolicy"], "application/x-7z-compressed": ["7z"], "application/x-abiword": ["abw"], "application/x-ace-compressed": ["ace"], "application/x-apple-diskimage": [], "application/x-arj": ["arj"], "application/x-authorware-bin": ["aab", "x32", "u32", "vox"], "application/x-authorware-map": ["aam"], "application/x-authorware-seg": ["aas"], "application/x-bcpio": ["bcpio"], "application/x-bdoc": [], "application/x-bittorrent": ["torrent"], "application/x-blorb": ["blb", "blorb"], "application/x-bzip": ["bz"], "application/x-bzip2": ["bz2", "boz"], "application/x-cbr": ["cbr", "cba", "cbt", "cbz", "cb7"], "application/x-cdlink": ["vcd"], "application/x-cfs-compressed": ["cfs"], "application/x-chat": ["chat"], "application/x-chess-pgn": ["pgn"], "application/x-chrome-extension": ["crx"], "application/x-cocoa": ["cco"], "application/x-conference": ["nsc"], "application/x-cpio": ["cpio"], "application/x-csh": ["csh"], "application/x-debian-package": ["udeb"], "application/x-dgc-compressed": ["dgc"], "application/x-director": ["dir", "dcr", "dxr", "cst", "cct", "cxt", "w3d", "fgd", "swa"], "application/x-doom": ["wad"], "application/x-dtbncx+xml": ["ncx"], "application/x-dtbook+xml": ["dtb"], "application/x-dtbresource+xml": ["res"], "application/x-dvi": ["dvi"], "application/x-envoy": ["evy"], "application/x-eva": ["eva"], "application/x-font-bdf": ["bdf"], "application/x-font-ghostscript": ["gsf"], "application/x-font-linux-psf": ["psf"], "application/x-font-pcf": ["pcf"], "application/x-font-snf": ["snf"], "application/x-font-type1": ["pfa", "pfb", "pfm", "afm"], "application/x-freearc": ["arc"], "application/x-futuresplash": ["spl"], "application/x-gca-compressed": ["gca"], "application/x-glulx": ["ulx"], "application/x-gnumeric": ["gnumeric"], "application/x-gramps-xml": ["gramps"], "application/x-gtar": ["gtar"], "application/x-hdf": ["hdf"], "application/x-httpd-php": ["php"], "application/x-install-instructions": ["install"], "application/x-iso9660-image": [], "application/x-java-archive-diff": ["jardiff"], "application/x-java-jnlp-file": ["jnlp"], "application/x-latex": ["latex"], "application/x-lua-bytecode": ["luac"], "application/x-lzh-compressed": ["lzh", "lha"], "application/x-makeself": ["run"], "application/x-mie": ["mie"], "application/x-mobipocket-ebook": ["prc", "mobi"], "application/x-ms-application": ["application"], "application/x-ms-shortcut": ["lnk"], "application/x-ms-wmd": ["wmd"], "application/x-ms-wmz": ["wmz"], "application/x-ms-xbap": ["xbap"], "application/x-msaccess": ["mdb"], "application/x-msbinder": ["obd"], "application/x-mscardfile": ["crd"], "application/x-msclip": ["clp"], "application/x-msdos-program": [], "application/x-msdownload": ["com", "bat"], "application/x-msmediaview": ["mvb", "m13", "m14"], "application/x-msmetafile": ["wmf", "emf", "emz"], "application/x-msmoney": ["mny"], "application/x-mspublisher": ["pub"], "application/x-msschedule": ["scd"], "application/x-msterminal": ["trm"], "application/x-mswrite": ["wri"], "application/x-netcdf": ["nc", "cdf"], "application/x-ns-proxy-autoconfig": ["pac"], "application/x-nzb": ["nzb"], "application/x-perl": ["pl", "pm"], "application/x-pilot": [], "application/x-pkcs12": ["p12", "pfx"], "application/x-pkcs7-certificates": ["p7b", "spc"], "application/x-pkcs7-certreqresp": ["p7r"], "application/x-rar-compressed": ["rar"], "application/x-redhat-package-manager": ["rpm"], "application/x-research-info-systems": ["ris"], "application/x-sea": ["sea"], "application/x-sh": ["sh"], "application/x-shar": ["shar"], "application/x-shockwave-flash": ["swf"], "application/x-silverlight-app": ["xap"], "application/x-sql": ["sql"], "application/x-stuffit": ["sit"], "application/x-stuffitx": ["sitx"], "application/x-subrip": ["srt"], "application/x-sv4cpio": ["sv4cpio"], "application/x-sv4crc": ["sv4crc"], "application/x-t3vm-image": ["t3"], "application/x-tads": ["gam"], "application/x-tar": ["tar"], "application/x-tcl": ["tcl", "tk"], "application/x-tex": ["tex"], "application/x-tex-tfm": ["tfm"], "application/x-texinfo": ["texinfo", "texi"], "application/x-tgif": ["obj"], "application/x-ustar": ["ustar"], "application/x-virtualbox-hdd": ["hdd"], "application/x-virtualbox-ova": ["ova"], "application/x-virtualbox-ovf": ["ovf"], "application/x-virtualbox-vbox": ["vbox"], "application/x-virtualbox-vbox-extpack": ["vbox-extpack"], "application/x-virtualbox-vdi": ["vdi"], "application/x-virtualbox-vhd": ["vhd"], "application/x-virtualbox-vmdk": ["vmdk"], "application/x-wais-source": ["src"], "application/x-web-app-manifest+json": ["webapp"], "application/x-x509-ca-cert": ["der", "crt", "pem"], "application/x-xfig": ["fig"], "application/x-xliff+xml": ["xlf"], "application/x-xpinstall": ["xpi"], "application/x-xz": ["xz"], "application/x-zmachine": ["z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8"], "application/xaml+xml": ["xaml"], "application/xcap-diff+xml": ["xdf"], "application/xenc+xml": ["xenc"], "application/xhtml+xml": ["xhtml", "xht"], "application/xml": ["xml", "xsl", "xsd", "rng"], "application/xml-dtd": ["dtd"], "application/xop+xml": ["xop"], "application/xproc+xml": ["xpl"], "application/xslt+xml": ["xslt"], "application/xspf+xml": ["xspf"], "application/xv+xml": ["mxml", "xhvml", "xvml", "xvm"], "application/yang": ["yang"], "application/yin+xml": ["yin"], "application/zip": ["zip"], "audio/3gpp": [], "audio/adpcm": ["adp"], "audio/basic": ["au", "snd"], "audio/midi": ["mid", "midi", "kar", "rmi"], "audio/mp3": [], "audio/mp4": ["m4a", "mp4a"], "audio/mpeg": ["mpga", "mp2", "mp2a", "mp3", "m2a", "m3a"], "audio/ogg": ["oga", "ogg", "spx"], "audio/s3m": ["s3m"], "audio/silk": ["sil"], "audio/vnd.dece.audio": ["uva", "uvva"], "audio/vnd.digital-winds": ["eol"], "audio/vnd.dra": ["dra"], "audio/vnd.dts": ["dts"], "audio/vnd.dts.hd": ["dtshd"], "audio/vnd.lucent.voice": ["lvp"], "audio/vnd.ms-playready.media.pya": ["pya"], "audio/vnd.nuera.ecelp4800": ["ecelp4800"], "audio/vnd.nuera.ecelp7470": ["ecelp7470"], "audio/vnd.nuera.ecelp9600": ["ecelp9600"], "audio/vnd.rip": ["rip"], "audio/wav": ["wav"], "audio/wave": [], "audio/webm": ["weba"], "audio/x-aac": ["aac"], "audio/x-aiff": ["aif", "aiff", "aifc"], "audio/x-caf": ["caf"], "audio/x-flac": ["flac"], "audio/x-m4a": [], "audio/x-matroska": ["mka"], "audio/x-mpegurl": ["m3u"], "audio/x-ms-wax": ["wax"], "audio/x-ms-wma": ["wma"], "audio/x-pn-realaudio": ["ram", "ra"], "audio/x-pn-realaudio-plugin": ["rmp"], "audio/x-realaudio": [], "audio/x-wav": [], "audio/xm": ["xm"], "chemical/x-cdx": ["cdx"], "chemical/x-cif": ["cif"], "chemical/x-cmdf": ["cmdf"], "chemical/x-cml": ["cml"], "chemical/x-csml": ["csml"], "chemical/x-xyz": ["xyz"], "font/collection": ["ttc"], "font/otf": ["otf"], "font/ttf": ["ttf"], "font/woff": ["woff"], "font/woff2": ["woff2"], "image/apng": ["apng"], "image/bmp": ["bmp"], "image/cgm": ["cgm"], "image/g3fax": ["g3"], "image/gif": ["gif"], "image/ief": ["ief"], "image/jp2": ["jp2", "jpg2"], "image/jpeg": ["jpeg", "jpg", "jpe"], "image/jpm": ["jpm"], "image/jpx": ["jpx", "jpf"], "image/ktx": ["ktx"], "image/png": ["png"], "image/prs.btif": ["btif"], "image/sgi": ["sgi"], "image/svg+xml": ["svg", "svgz"], "image/tiff": ["tiff", "tif"], "image/vnd.adobe.photoshop": ["psd"], "image/vnd.dece.graphic": ["uvi", "uvvi", "uvg", "uvvg"], "image/vnd.djvu": ["djvu", "djv"], "image/vnd.dvb.subtitle": [], "image/vnd.dwg": ["dwg"], "image/vnd.dxf": ["dxf"], "image/vnd.fastbidsheet": ["fbs"], "image/vnd.fpx": ["fpx"], "image/vnd.fst": ["fst"], "image/vnd.fujixerox.edmics-mmr": ["mmr"], "image/vnd.fujixerox.edmics-rlc": ["rlc"], "image/vnd.ms-modi": ["mdi"], "image/vnd.ms-photo": ["wdp"], "image/vnd.net-fpx": ["npx"], "image/vnd.wap.wbmp": ["wbmp"], "image/vnd.xiff": ["xif"], "image/webp": ["webp"], "image/x-3ds": ["3ds"], "image/x-cmu-raster": ["ras"], "image/x-cmx": ["cmx"], "image/x-freehand": ["fh", "fhc", "fh4", "fh5", "fh7"], "image/x-icon": ["ico"], "image/x-jng": ["jng"], "image/x-mrsid-image": ["sid"], "image/x-ms-bmp": [], "image/x-pcx": ["pcx"], "image/x-pict": ["pic", "pct"], "image/x-portable-anymap": ["pnm"], "image/x-portable-bitmap": ["pbm"], "image/x-portable-graymap": ["pgm"], "image/x-portable-pixmap": ["ppm"], "image/x-rgb": ["rgb"], "image/x-tga": ["tga"], "image/x-xbitmap": ["xbm"], "image/x-xpixmap": ["xpm"], "image/x-xwindowdump": ["xwd"], "message/rfc822": ["eml", "mime"], "model/gltf+json": ["gltf"], "model/gltf-binary": ["glb"], "model/iges": ["igs", "iges"], "model/mesh": ["msh", "mesh", "silo"], "model/vnd.collada+xml": ["dae"], "model/vnd.dwf": ["dwf"], "model/vnd.gdl": ["gdl"], "model/vnd.gtw": ["gtw"], "model/vnd.mts": ["mts"], "model/vnd.vtu": ["vtu"], "model/vrml": ["wrl", "vrml"], "model/x3d+binary": ["x3db", "x3dbz"], "model/x3d+vrml": ["x3dv", "x3dvz"], "model/x3d+xml": ["x3d", "x3dz"], "text/cache-manifest": ["appcache", "manifest"], "text/calendar": ["ics", "ifb"], "text/coffeescript": ["coffee", "litcoffee"], "text/css": ["css"], "text/csv": ["csv"], "text/hjson": ["hjson"], "text/html": ["html", "htm", "shtml"], "text/jade": ["jade"], "text/jsx": ["jsx"], "text/less": ["less"], "text/markdown": ["markdown", "md"], "text/mathml": ["mml"], "text/n3": ["n3"], "text/plain": ["txt", "text", "conf", "def", "list", "log", "in", "ini"], "text/prs.lines.tag": ["dsc"], "text/richtext": ["rtx"], "text/rtf": [], "text/sgml": ["sgml", "sgm"], "text/slim": ["slim", "slm"], "text/stylus": ["stylus", "styl"], "text/tab-separated-values": ["tsv"], "text/troff": ["t", "tr", "roff", "man", "me", "ms"], "text/turtle": ["ttl"], "text/uri-list": ["uri", "uris", "urls"], "text/vcard": ["vcard"], "text/vnd.curl": ["curl"], "text/vnd.curl.dcurl": ["dcurl"], "text/vnd.curl.mcurl": ["mcurl"], "text/vnd.curl.scurl": ["scurl"], "text/vnd.dvb.subtitle": ["sub"], "text/vnd.fly": ["fly"], "text/vnd.fmi.flexstor": ["flx"], "text/vnd.graphviz": ["gv"], "text/vnd.in3d.3dml": ["3dml"], "text/vnd.in3d.spot": ["spot"], "text/vnd.sun.j2me.app-descriptor": ["jad"], "text/vnd.wap.wml": ["wml"], "text/vnd.wap.wmlscript": ["wmls"], "text/vtt": ["vtt"], "text/x-asm": ["s", "asm"], "text/x-c": ["c", "cc", "cxx", "cpp", "h", "hh", "dic"], "text/x-component": ["htc"], "text/x-fortran": ["f", "for", "f77", "f90"], "text/x-handlebars-template": ["hbs"], "text/x-java-source": ["java"], "text/x-lua": ["lua"], "text/x-markdown": ["mkd"], "text/x-nfo": ["nfo"], "text/x-opml": ["opml"], "text/x-org": [], "text/x-pascal": ["p", "pas"], "text/x-processing": ["pde"], "text/x-sass": ["sass"], "text/x-scss": ["scss"], "text/x-setext": ["etx"], "text/x-sfv": ["sfv"], "text/x-suse-ymp": ["ymp"], "text/x-uuencode": ["uu"], "text/x-vcalendar": ["vcs"], "text/x-vcard": ["vcf"], "text/xml": [], "text/yaml": ["yaml", "yml"], "video/3gpp": ["3gp", "3gpp"], "video/3gpp2": ["3g2"], "video/h261": ["h261"], "video/h263": ["h263"], "video/h264": ["h264"], "video/jpeg": ["jpgv"], "video/jpm": ["jpgm"], "video/mj2": ["mj2", "mjp2"], "video/mp2t": ["ts"], "video/mp4": ["mp4", "mp4v", "mpg4"], "video/mpeg": ["mpeg", "mpg", "mpe", "m1v", "m2v"], "video/ogg": ["ogv"], "video/quicktime": ["qt", "mov"], "video/vnd.dece.hd": ["uvh", "uvvh"], "video/vnd.dece.mobile": ["uvm", "uvvm"], "video/vnd.dece.pd": ["uvp", "uvvp"], "video/vnd.dece.sd": ["uvs", "uvvs"], "video/vnd.dece.video": ["uvv", "uvvv"], "video/vnd.dvb.file": ["dvb"], "video/vnd.fvt": ["fvt"], "video/vnd.mpegurl": ["mxu", "m4u"], "video/vnd.ms-playready.media.pyv": ["pyv"], "video/vnd.uvvu.mp4": ["uvu", "uvvu"], "video/vnd.vivo": ["viv"], "video/webm": ["webm"], "video/x-f4v": ["f4v"], "video/x-fli": ["fli"], "video/x-flv": ["flv"], "video/x-m4v": ["m4v"], "video/x-matroska": ["mkv", "mk3d", "mks"], "video/x-mng": ["mng"], "video/x-ms-asf": ["asf", "asx"], "video/x-ms-vob": ["vob"], "video/x-ms-wm": ["wm"], "video/x-ms-wmv": ["wmv"], "video/x-ms-wmx": ["wmx"], "video/x-ms-wvx": ["wvx"], "video/x-msvideo": ["avi"], "video/x-sgi-movie": ["movie"], "video/x-smv": ["smv"], "x-conference/x-cooltalk": ["ice"] }; + } +}); + +// node_modules/mime/mime.js +var require_mime = __commonJS({ + "node_modules/mime/mime.js"(exports2, module2) { + var path3 = require("path"); + var fs6 = require("fs"); + function Mime() { + this.types = /* @__PURE__ */ Object.create(null); + this.extensions = /* @__PURE__ */ Object.create(null); + } + Mime.prototype.define = function(map) { + for (var type in map) { + var exts = map[type]; + for (var i = 0; i < exts.length; i++) { + if (process.env.DEBUG_MIME && this.types[exts[i]]) { + console.warn((this._loading || "define()").replace(/.*\//, ""), 'changes "' + exts[i] + '" extension type from ' + this.types[exts[i]] + " to " + type); + } + this.types[exts[i]] = type; + } + if (!this.extensions[type]) { + this.extensions[type] = exts[0]; + } + } + }; + Mime.prototype.load = function(file) { + this._loading = file; + var map = {}, content = fs6.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/); + lines.forEach(function(line) { + var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/); + map[fields.shift()] = fields; + }); + this.define(map); + this._loading = null; + }; + Mime.prototype.lookup = function(path4, fallback) { + var ext = path4.replace(/^.*[\.\/\\]/, "").toLowerCase(); + return this.types[ext] || fallback || this.default_type; + }; + Mime.prototype.extension = function(mimeType) { + var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase(); + return this.extensions[type]; + }; + var mime = new Mime(); + mime.define(require_types()); + mime.default_type = mime.lookup("bin"); + mime.Mime = Mime; + mime.charsets = { + lookup: function(mimeType, fallback) { + return /^text\/|^application\/(javascript|json)/.test(mimeType) ? "UTF-8" : fallback; + } + }; + module2.exports = mime; + } +}); + +// node_modules/ms/index.js +var require_ms5 = __commonJS({ + "node_modules/ms/index.js"(exports2, module2) { + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var w = d * 7; + var y = d * 365.25; + module2.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse4(val); + } else if (type === "number" && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); + }; + function parse4(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "weeks": + case "week": + case "w": + return n * w; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + "d"; + } + if (msAbs >= h) { + return Math.round(ms / h) + "h"; + } + if (msAbs >= m) { + return Math.round(ms / m) + "m"; + } + if (msAbs >= s) { + return Math.round(ms / s) + "s"; + } + return ms + "ms"; + } + function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, "day"); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, "hour"); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, "minute"); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, "second"); + } + return ms + " ms"; + } + function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + " " + name + (isPlural ? "s" : ""); + } + } +}); + +// node_modules/range-parser/index.js +var require_range_parser = __commonJS({ + "node_modules/range-parser/index.js"(exports2, module2) { + "use strict"; + module2.exports = rangeParser; + function rangeParser(size, str, options) { + if (typeof str !== "string") { + throw new TypeError("argument str must be a string"); + } + var index = str.indexOf("="); + if (index === -1) { + return -2; + } + var arr = str.slice(index + 1).split(","); + var ranges = []; + ranges.type = str.slice(0, index); + for (var i = 0; i < arr.length; i++) { + var range = arr[i].split("-"); + var start = parseInt(range[0], 10); + var end = parseInt(range[1], 10); + if (isNaN(start)) { + start = size - end; + end = size - 1; + } else if (isNaN(end)) { + end = size - 1; + } + if (end > size - 1) { + end = size - 1; + } + if (isNaN(start) || isNaN(end) || start > end || start < 0) { + continue; + } + ranges.push({ + start, + end + }); + } + if (ranges.length < 1) { + return -1; + } + return options && options.combine ? combineRanges(ranges) : ranges; + } + function combineRanges(ranges) { + var ordered = ranges.map(mapWithIndex).sort(sortByRangeStart); + for (var j = 0, i = 1; i < ordered.length; i++) { + var range = ordered[i]; + var current = ordered[j]; + if (range.start > current.end + 1) { + ordered[++j] = range; + } else if (range.end > current.end) { + current.end = range.end; + current.index = Math.min(current.index, range.index); + } + } + ordered.length = j + 1; + var combined = ordered.sort(sortByRangeIndex).map(mapWithoutIndex); + combined.type = ranges.type; + return combined; + } + function mapWithIndex(range, index) { + return { + start: range.start, + end: range.end, + index + }; + } + function mapWithoutIndex(range) { + return { + start: range.start, + end: range.end + }; + } + function sortByRangeIndex(a, b) { + return a.index - b.index; + } + function sortByRangeStart(a, b) { + return a.start - b.start; + } + } +}); + +// node_modules/send/index.js +var require_send = __commonJS({ + "node_modules/send/index.js"(exports2, module2) { + "use strict"; + var createError = require_http_errors(); + var debug = require_src4()("send"); + var deprecate = require_depd()("send"); + var destroy = require_destroy(); + var encodeUrl = require_encodeurl(); + var escapeHtml = require_escape_html(); + var etag = require_etag(); + var fresh = require_fresh(); + var fs6 = require("fs"); + var mime = require_mime(); + var ms = require_ms5(); + var onFinished = require_on_finished(); + var parseRange = require_range_parser(); + var path3 = require("path"); + var statuses = require_statuses(); + var Stream = require("stream"); + var util = require("util"); + var extname = path3.extname; + var join = path3.join; + var normalize = path3.normalize; + var resolve = path3.resolve; + var sep = path3.sep; + var BYTES_RANGE_REGEXP = /^ *bytes=/; + var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3; + var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/; + module2.exports = send; + module2.exports.mime = mime; + function send(req, path4, options) { + return new SendStream(req, path4, options); + } + function SendStream(req, path4, options) { + Stream.call(this); + var opts = options || {}; + this.options = opts; + this.path = path4; + this.req = req; + this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true; + this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true; + this._etag = opts.etag !== void 0 ? Boolean(opts.etag) : true; + this._dotfiles = opts.dotfiles !== void 0 ? opts.dotfiles : "ignore"; + if (this._dotfiles !== "ignore" && this._dotfiles !== "allow" && this._dotfiles !== "deny") { + throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"'); + } + this._hidden = Boolean(opts.hidden); + if (opts.hidden !== void 0) { + deprecate("hidden: use dotfiles: '" + (this._hidden ? "allow" : "ignore") + "' instead"); + } + if (opts.dotfiles === void 0) { + this._dotfiles = void 0; + } + this._extensions = opts.extensions !== void 0 ? normalizeList(opts.extensions, "extensions option") : []; + this._immutable = opts.immutable !== void 0 ? Boolean(opts.immutable) : false; + this._index = opts.index !== void 0 ? normalizeList(opts.index, "index option") : ["index.html"]; + this._lastModified = opts.lastModified !== void 0 ? Boolean(opts.lastModified) : true; + this._maxage = opts.maxAge || opts.maxage; + this._maxage = typeof this._maxage === "string" ? ms(this._maxage) : Number(this._maxage); + this._maxage = !isNaN(this._maxage) ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) : 0; + this._root = opts.root ? resolve(opts.root) : null; + if (!this._root && opts.from) { + this.from(opts.from); + } + } + util.inherits(SendStream, Stream); + SendStream.prototype.etag = deprecate.function(function etag2(val) { + this._etag = Boolean(val); + debug("etag %s", this._etag); + return this; + }, "send.etag: pass etag as option"); + SendStream.prototype.hidden = deprecate.function(function hidden(val) { + this._hidden = Boolean(val); + this._dotfiles = void 0; + debug("hidden %s", this._hidden); + return this; + }, "send.hidden: use dotfiles option"); + SendStream.prototype.index = deprecate.function(function index(paths) { + var index2 = !paths ? [] : normalizeList(paths, "paths argument"); + debug("index %o", paths); + this._index = index2; + return this; + }, "send.index: pass index as option"); + SendStream.prototype.root = function root(path4) { + this._root = resolve(String(path4)); + debug("root %s", this._root); + return this; + }; + SendStream.prototype.from = deprecate.function( + SendStream.prototype.root, + "send.from: pass root as option" + ); + SendStream.prototype.root = deprecate.function( + SendStream.prototype.root, + "send.root: pass root as option" + ); + SendStream.prototype.maxage = deprecate.function(function maxage(maxAge) { + this._maxage = typeof maxAge === "string" ? ms(maxAge) : Number(maxAge); + this._maxage = !isNaN(this._maxage) ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) : 0; + debug("max-age %d", this._maxage); + return this; + }, "send.maxage: pass maxAge as option"); + SendStream.prototype.error = function error(status, err) { + if (hasListeners(this, "error")) { + return this.emit("error", createHttpError(status, err)); + } + var res = this.res; + var msg = statuses.message[status] || String(status); + var doc = createHtmlDocument("Error", escapeHtml(msg)); + clearHeaders(res); + if (err && err.headers) { + setHeaders(res, err.headers); + } + res.statusCode = status; + res.setHeader("Content-Type", "text/html; charset=UTF-8"); + res.setHeader("Content-Length", Buffer.byteLength(doc)); + res.setHeader("Content-Security-Policy", "default-src 'none'"); + res.setHeader("X-Content-Type-Options", "nosniff"); + res.end(doc); + }; + SendStream.prototype.hasTrailingSlash = function hasTrailingSlash() { + return this.path[this.path.length - 1] === "/"; + }; + SendStream.prototype.isConditionalGET = function isConditionalGET() { + return this.req.headers["if-match"] || this.req.headers["if-unmodified-since"] || this.req.headers["if-none-match"] || this.req.headers["if-modified-since"]; + }; + SendStream.prototype.isPreconditionFailure = function isPreconditionFailure() { + var req = this.req; + var res = this.res; + var match = req.headers["if-match"]; + if (match) { + var etag2 = res.getHeader("ETag"); + return !etag2 || match !== "*" && parseTokenList(match).every(function(match2) { + return match2 !== etag2 && match2 !== "W/" + etag2 && "W/" + match2 !== etag2; + }); + } + var unmodifiedSince = parseHttpDate(req.headers["if-unmodified-since"]); + if (!isNaN(unmodifiedSince)) { + var lastModified = parseHttpDate(res.getHeader("Last-Modified")); + return isNaN(lastModified) || lastModified > unmodifiedSince; + } + return false; + }; + SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields() { + var res = this.res; + res.removeHeader("Content-Encoding"); + res.removeHeader("Content-Language"); + res.removeHeader("Content-Length"); + res.removeHeader("Content-Range"); + res.removeHeader("Content-Type"); + }; + SendStream.prototype.notModified = function notModified() { + var res = this.res; + debug("not modified"); + this.removeContentHeaderFields(); + res.statusCode = 304; + res.end(); + }; + SendStream.prototype.headersAlreadySent = function headersAlreadySent() { + var err = new Error("Can't set headers after they are sent."); + debug("headers already sent"); + this.error(500, err); + }; + SendStream.prototype.isCachable = function isCachable() { + var statusCode = this.res.statusCode; + return statusCode >= 200 && statusCode < 300 || statusCode === 304; + }; + SendStream.prototype.onStatError = function onStatError(error) { + switch (error.code) { + case "ENAMETOOLONG": + case "ENOENT": + case "ENOTDIR": + this.error(404, error); + break; + default: + this.error(500, error); + break; + } + }; + SendStream.prototype.isFresh = function isFresh() { + return fresh(this.req.headers, { + etag: this.res.getHeader("ETag"), + "last-modified": this.res.getHeader("Last-Modified") + }); + }; + SendStream.prototype.isRangeFresh = function isRangeFresh() { + var ifRange = this.req.headers["if-range"]; + if (!ifRange) { + return true; + } + if (ifRange.indexOf('"') !== -1) { + var etag2 = this.res.getHeader("ETag"); + return Boolean(etag2 && ifRange.indexOf(etag2) !== -1); + } + var lastModified = this.res.getHeader("Last-Modified"); + return parseHttpDate(lastModified) <= parseHttpDate(ifRange); + }; + SendStream.prototype.redirect = function redirect(path4) { + var res = this.res; + if (hasListeners(this, "directory")) { + this.emit("directory", res, path4); + return; + } + if (this.hasTrailingSlash()) { + this.error(403); + return; + } + var loc = encodeUrl(collapseLeadingSlashes(this.path + "/")); + var doc = createHtmlDocument("Redirecting", "Redirecting to " + escapeHtml(loc)); + res.statusCode = 301; + res.setHeader("Content-Type", "text/html; charset=UTF-8"); + res.setHeader("Content-Length", Buffer.byteLength(doc)); + res.setHeader("Content-Security-Policy", "default-src 'none'"); + res.setHeader("X-Content-Type-Options", "nosniff"); + res.setHeader("Location", loc); + res.end(doc); + }; + SendStream.prototype.pipe = function pipe(res) { + var root = this._root; + this.res = res; + var path4 = decode(this.path); + if (path4 === -1) { + this.error(400); + return res; + } + if (~path4.indexOf("\0")) { + this.error(400); + return res; + } + var parts; + if (root !== null) { + if (path4) { + path4 = normalize("." + sep + path4); + } + if (UP_PATH_REGEXP.test(path4)) { + debug('malicious path "%s"', path4); + this.error(403); + return res; + } + parts = path4.split(sep); + path4 = normalize(join(root, path4)); + } else { + if (UP_PATH_REGEXP.test(path4)) { + debug('malicious path "%s"', path4); + this.error(403); + return res; + } + parts = normalize(path4).split(sep); + path4 = resolve(path4); + } + if (containsDotFile(parts)) { + var access = this._dotfiles; + if (access === void 0) { + access = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow"; + } + debug('%s dotfile "%s"', access, path4); + switch (access) { + case "allow": + break; + case "deny": + this.error(403); + return res; + case "ignore": + default: + this.error(404); + return res; + } + } + if (this._index.length && this.hasTrailingSlash()) { + this.sendIndex(path4); + return res; + } + this.sendFile(path4); + return res; + }; + SendStream.prototype.send = function send2(path4, stat) { + var len = stat.size; + var options = this.options; + var opts = {}; + var res = this.res; + var req = this.req; + var ranges = req.headers.range; + var offset = options.start || 0; + if (headersSent(res)) { + this.headersAlreadySent(); + return; + } + debug('pipe "%s"', path4); + this.setHeader(path4, stat); + this.type(path4); + if (this.isConditionalGET()) { + if (this.isPreconditionFailure()) { + this.error(412); + return; + } + if (this.isCachable() && this.isFresh()) { + this.notModified(); + return; + } + } + len = Math.max(0, len - offset); + if (options.end !== void 0) { + var bytes = options.end - offset + 1; + if (len > bytes) len = bytes; + } + if (this._acceptRanges && BYTES_RANGE_REGEXP.test(ranges)) { + ranges = parseRange(len, ranges, { + combine: true + }); + if (!this.isRangeFresh()) { + debug("range stale"); + ranges = -2; + } + if (ranges === -1) { + debug("range unsatisfiable"); + res.setHeader("Content-Range", contentRange("bytes", len)); + return this.error(416, { + headers: { "Content-Range": res.getHeader("Content-Range") } + }); + } + if (ranges !== -2 && ranges.length === 1) { + debug("range %j", ranges); + res.statusCode = 206; + res.setHeader("Content-Range", contentRange("bytes", len, ranges[0])); + offset += ranges[0].start; + len = ranges[0].end - ranges[0].start + 1; + } + } + for (var prop in options) { + opts[prop] = options[prop]; + } + opts.start = offset; + opts.end = Math.max(offset, offset + len - 1); + res.setHeader("Content-Length", len); + if (req.method === "HEAD") { + res.end(); + return; + } + this.stream(path4, opts); + }; + SendStream.prototype.sendFile = function sendFile(path4) { + var i = 0; + var self2 = this; + debug('stat "%s"', path4); + fs6.stat(path4, function onstat(err, stat) { + if (err && err.code === "ENOENT" && !extname(path4) && path4[path4.length - 1] !== sep) { + return next(err); + } + if (err) return self2.onStatError(err); + if (stat.isDirectory()) return self2.redirect(path4); + self2.emit("file", path4, stat); + self2.send(path4, stat); + }); + function next(err) { + if (self2._extensions.length <= i) { + return err ? self2.onStatError(err) : self2.error(404); + } + var p = path4 + "." + self2._extensions[i++]; + debug('stat "%s"', p); + fs6.stat(p, function(err2, stat) { + if (err2) return next(err2); + if (stat.isDirectory()) return next(); + self2.emit("file", p, stat); + self2.send(p, stat); + }); + } + }; + SendStream.prototype.sendIndex = function sendIndex(path4) { + var i = -1; + var self2 = this; + function next(err) { + if (++i >= self2._index.length) { + if (err) return self2.onStatError(err); + return self2.error(404); + } + var p = join(path4, self2._index[i]); + debug('stat "%s"', p); + fs6.stat(p, function(err2, stat) { + if (err2) return next(err2); + if (stat.isDirectory()) return next(); + self2.emit("file", p, stat); + self2.send(p, stat); + }); + } + next(); + }; + SendStream.prototype.stream = function stream(path4, options) { + var self2 = this; + var res = this.res; + var stream2 = fs6.createReadStream(path4, options); + this.emit("stream", stream2); + stream2.pipe(res); + function cleanup() { + destroy(stream2, true); + } + onFinished(res, cleanup); + stream2.on("error", function onerror(err) { + cleanup(); + self2.onStatError(err); + }); + stream2.on("end", function onend() { + self2.emit("end"); + }); + }; + SendStream.prototype.type = function type(path4) { + var res = this.res; + if (res.getHeader("Content-Type")) return; + var type2 = mime.lookup(path4); + if (!type2) { + debug("no content-type"); + return; + } + var charset = mime.charsets.lookup(type2); + debug("content-type %s", type2); + res.setHeader("Content-Type", type2 + (charset ? "; charset=" + charset : "")); + }; + SendStream.prototype.setHeader = function setHeader(path4, stat) { + var res = this.res; + this.emit("headers", res, path4, stat); + if (this._acceptRanges && !res.getHeader("Accept-Ranges")) { + debug("accept ranges"); + res.setHeader("Accept-Ranges", "bytes"); + } + if (this._cacheControl && !res.getHeader("Cache-Control")) { + var cacheControl = "public, max-age=" + Math.floor(this._maxage / 1e3); + if (this._immutable) { + cacheControl += ", immutable"; + } + debug("cache-control %s", cacheControl); + res.setHeader("Cache-Control", cacheControl); + } + if (this._lastModified && !res.getHeader("Last-Modified")) { + var modified = stat.mtime.toUTCString(); + debug("modified %s", modified); + res.setHeader("Last-Modified", modified); + } + if (this._etag && !res.getHeader("ETag")) { + var val = etag(stat); + debug("etag %s", val); + res.setHeader("ETag", val); + } + }; + function clearHeaders(res) { + var headers = getHeaderNames(res); + for (var i = 0; i < headers.length; i++) { + res.removeHeader(headers[i]); + } + } + function collapseLeadingSlashes(str) { + for (var i = 0; i < str.length; i++) { + if (str[i] !== "/") { + break; + } + } + return i > 1 ? "/" + str.substr(i) : str; + } + function containsDotFile(parts) { + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + if (part.length > 1 && part[0] === ".") { + return true; + } + } + return false; + } + function contentRange(type, size, range) { + return type + " " + (range ? range.start + "-" + range.end : "*") + "/" + size; + } + function createHtmlDocument(title, body) { + return '\n\n\n\n' + title + "\n\n\n
" + body + "
\n\n\n"; + } + function createHttpError(status, err) { + if (!err) { + return createError(status); + } + return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err); + } + function decode(path4) { + try { + return decodeURIComponent(path4); + } catch (err) { + return -1; + } + } + function getHeaderNames(res) { + return typeof res.getHeaderNames !== "function" ? Object.keys(res._headers || {}) : res.getHeaderNames(); + } + function hasListeners(emitter, type) { + var count = typeof emitter.listenerCount !== "function" ? emitter.listeners(type).length : emitter.listenerCount(type); + return count > 0; + } + function headersSent(res) { + return typeof res.headersSent !== "boolean" ? Boolean(res._header) : res.headersSent; + } + function normalizeList(val, name) { + var list = [].concat(val || []); + for (var i = 0; i < list.length; i++) { + if (typeof list[i] !== "string") { + throw new TypeError(name + " must be array of strings or false"); + } + } + return list; + } + function parseHttpDate(date) { + var timestamp = date && Date.parse(date); + return typeof timestamp === "number" ? timestamp : NaN; + } + function parseTokenList(str) { + var end = 0; + var list = []; + var start = 0; + for (var i = 0, len = str.length; i < len; i++) { + switch (str.charCodeAt(i)) { + case 32: + if (start === end) { + start = end = i + 1; + } + break; + case 44: + if (start !== end) { + list.push(str.substring(start, end)); + } + start = end = i + 1; + break; + default: + end = i + 1; + break; + } + } + if (start !== end) { + list.push(str.substring(start, end)); + } + return list; + } + function setHeaders(res, headers) { + var keys = Object.keys(headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + res.setHeader(key, headers[key]); + } + } + } +}); + +// node_modules/forwarded/index.js +var require_forwarded = __commonJS({ + "node_modules/forwarded/index.js"(exports2, module2) { + "use strict"; + module2.exports = forwarded; + function forwarded(req) { + if (!req) { + throw new TypeError("argument req is required"); + } + var proxyAddrs = parse4(req.headers["x-forwarded-for"] || ""); + var socketAddr = getSocketAddr(req); + var addrs = [socketAddr].concat(proxyAddrs); + return addrs; + } + function getSocketAddr(req) { + return req.socket ? req.socket.remoteAddress : req.connection.remoteAddress; + } + function parse4(header) { + var end = header.length; + var list = []; + var start = header.length; + for (var i = header.length - 1; i >= 0; i--) { + switch (header.charCodeAt(i)) { + case 32: + if (start === end) { + start = end = i; + } + break; + case 44: + if (start !== end) { + list.push(header.substring(start, end)); + } + start = end = i; + break; + default: + start = i; + break; + } + } + if (start !== end) { + list.push(header.substring(start, end)); + } + return list; + } + } +}); + +// node_modules/ipaddr.js/lib/ipaddr.js +var require_ipaddr = __commonJS({ + "node_modules/ipaddr.js/lib/ipaddr.js"(exports2, module2) { + (function() { + var expandIPv6, ipaddr, ipv4Part, ipv4Regexes, ipv6Part, ipv6Regexes, matchCIDR, root, zoneIndex; + ipaddr = {}; + root = this; + if (typeof module2 !== "undefined" && module2 !== null && module2.exports) { + module2.exports = ipaddr; + } else { + root["ipaddr"] = ipaddr; + } + matchCIDR = function(first, second, partSize, cidrBits) { + var part, shift; + if (first.length !== second.length) { + throw new Error("ipaddr: cannot match CIDR for objects with different lengths"); + } + part = 0; + while (cidrBits > 0) { + shift = partSize - cidrBits; + if (shift < 0) { + shift = 0; + } + if (first[part] >> shift !== second[part] >> shift) { + return false; + } + cidrBits -= partSize; + part += 1; + } + return true; + }; + ipaddr.subnetMatch = function(address, rangeList, defaultName) { + var k, len, rangeName, rangeSubnets, subnet; + if (defaultName == null) { + defaultName = "unicast"; + } + for (rangeName in rangeList) { + rangeSubnets = rangeList[rangeName]; + if (rangeSubnets[0] && !(rangeSubnets[0] instanceof Array)) { + rangeSubnets = [rangeSubnets]; + } + for (k = 0, len = rangeSubnets.length; k < len; k++) { + subnet = rangeSubnets[k]; + if (address.kind() === subnet[0].kind()) { + if (address.match.apply(address, subnet)) { + return rangeName; + } + } + } + } + return defaultName; + }; + ipaddr.IPv4 = (function() { + function IPv4(octets) { + var k, len, octet; + if (octets.length !== 4) { + throw new Error("ipaddr: ipv4 octet count should be 4"); + } + for (k = 0, len = octets.length; k < len; k++) { + octet = octets[k]; + if (!(0 <= octet && octet <= 255)) { + throw new Error("ipaddr: ipv4 octet should fit in 8 bits"); + } + } + this.octets = octets; + } + IPv4.prototype.kind = function() { + return "ipv4"; + }; + IPv4.prototype.toString = function() { + return this.octets.join("."); + }; + IPv4.prototype.toNormalizedString = function() { + return this.toString(); + }; + IPv4.prototype.toByteArray = function() { + return this.octets.slice(0); + }; + IPv4.prototype.match = function(other, cidrRange) { + var ref; + if (cidrRange === void 0) { + ref = other, other = ref[0], cidrRange = ref[1]; + } + if (other.kind() !== "ipv4") { + throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one"); + } + return matchCIDR(this.octets, other.octets, 8, cidrRange); + }; + IPv4.prototype.SpecialRanges = { + unspecified: [[new IPv4([0, 0, 0, 0]), 8]], + broadcast: [[new IPv4([255, 255, 255, 255]), 32]], + multicast: [[new IPv4([224, 0, 0, 0]), 4]], + linkLocal: [[new IPv4([169, 254, 0, 0]), 16]], + loopback: [[new IPv4([127, 0, 0, 0]), 8]], + carrierGradeNat: [[new IPv4([100, 64, 0, 0]), 10]], + "private": [[new IPv4([10, 0, 0, 0]), 8], [new IPv4([172, 16, 0, 0]), 12], [new IPv4([192, 168, 0, 0]), 16]], + reserved: [[new IPv4([192, 0, 0, 0]), 24], [new IPv4([192, 0, 2, 0]), 24], [new IPv4([192, 88, 99, 0]), 24], [new IPv4([198, 51, 100, 0]), 24], [new IPv4([203, 0, 113, 0]), 24], [new IPv4([240, 0, 0, 0]), 4]] + }; + IPv4.prototype.range = function() { + return ipaddr.subnetMatch(this, this.SpecialRanges); + }; + IPv4.prototype.toIPv4MappedAddress = function() { + return ipaddr.IPv6.parse("::ffff:" + this.toString()); + }; + IPv4.prototype.prefixLengthFromSubnetMask = function() { + var cidr, i, k, octet, stop, zeros, zerotable; + zerotable = { + 0: 8, + 128: 7, + 192: 6, + 224: 5, + 240: 4, + 248: 3, + 252: 2, + 254: 1, + 255: 0 + }; + cidr = 0; + stop = false; + for (i = k = 3; k >= 0; i = k += -1) { + octet = this.octets[i]; + if (octet in zerotable) { + zeros = zerotable[octet]; + if (stop && zeros !== 0) { + return null; + } + if (zeros !== 8) { + stop = true; + } + cidr += zeros; + } else { + return null; + } + } + return 32 - cidr; + }; + return IPv4; + })(); + ipv4Part = "(0?\\d+|0x[a-f0-9]+)"; + ipv4Regexes = { + fourOctet: new RegExp("^" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$", "i"), + longValue: new RegExp("^" + ipv4Part + "$", "i") + }; + ipaddr.IPv4.parser = function(string) { + var match, parseIntAuto, part, shift, value; + parseIntAuto = function(string2) { + if (string2[0] === "0" && string2[1] !== "x") { + return parseInt(string2, 8); + } else { + return parseInt(string2); + } + }; + if (match = string.match(ipv4Regexes.fourOctet)) { + return (function() { + var k, len, ref, results; + ref = match.slice(1, 6); + results = []; + for (k = 0, len = ref.length; k < len; k++) { + part = ref[k]; + results.push(parseIntAuto(part)); + } + return results; + })(); + } else if (match = string.match(ipv4Regexes.longValue)) { + value = parseIntAuto(match[1]); + if (value > 4294967295 || value < 0) { + throw new Error("ipaddr: address outside defined range"); + } + return (function() { + var k, results; + results = []; + for (shift = k = 0; k <= 24; shift = k += 8) { + results.push(value >> shift & 255); + } + return results; + })().reverse(); + } else { + return null; + } + }; + ipaddr.IPv6 = (function() { + function IPv6(parts, zoneId) { + var i, k, l, len, part, ref; + if (parts.length === 16) { + this.parts = []; + for (i = k = 0; k <= 14; i = k += 2) { + this.parts.push(parts[i] << 8 | parts[i + 1]); + } + } else if (parts.length === 8) { + this.parts = parts; + } else { + throw new Error("ipaddr: ipv6 part count should be 8 or 16"); + } + ref = this.parts; + for (l = 0, len = ref.length; l < len; l++) { + part = ref[l]; + if (!(0 <= part && part <= 65535)) { + throw new Error("ipaddr: ipv6 part should fit in 16 bits"); + } + } + if (zoneId) { + this.zoneId = zoneId; + } + } + IPv6.prototype.kind = function() { + return "ipv6"; + }; + IPv6.prototype.toString = function() { + return this.toNormalizedString().replace(/((^|:)(0(:|$))+)/, "::"); + }; + IPv6.prototype.toRFC5952String = function() { + var bestMatchIndex, bestMatchLength, match, regex, string; + regex = /((^|:)(0(:|$)){2,})/g; + string = this.toNormalizedString(); + bestMatchIndex = 0; + bestMatchLength = -1; + while (match = regex.exec(string)) { + if (match[0].length > bestMatchLength) { + bestMatchIndex = match.index; + bestMatchLength = match[0].length; + } + } + if (bestMatchLength < 0) { + return string; + } + return string.substring(0, bestMatchIndex) + "::" + string.substring(bestMatchIndex + bestMatchLength); + }; + IPv6.prototype.toByteArray = function() { + var bytes, k, len, part, ref; + bytes = []; + ref = this.parts; + for (k = 0, len = ref.length; k < len; k++) { + part = ref[k]; + bytes.push(part >> 8); + bytes.push(part & 255); + } + return bytes; + }; + IPv6.prototype.toNormalizedString = function() { + var addr, part, suffix; + addr = (function() { + var k, len, ref, results; + ref = this.parts; + results = []; + for (k = 0, len = ref.length; k < len; k++) { + part = ref[k]; + results.push(part.toString(16)); + } + return results; + }).call(this).join(":"); + suffix = ""; + if (this.zoneId) { + suffix = "%" + this.zoneId; + } + return addr + suffix; + }; + IPv6.prototype.toFixedLengthString = function() { + var addr, part, suffix; + addr = (function() { + var k, len, ref, results; + ref = this.parts; + results = []; + for (k = 0, len = ref.length; k < len; k++) { + part = ref[k]; + results.push(part.toString(16).padStart(4, "0")); + } + return results; + }).call(this).join(":"); + suffix = ""; + if (this.zoneId) { + suffix = "%" + this.zoneId; + } + return addr + suffix; + }; + IPv6.prototype.match = function(other, cidrRange) { + var ref; + if (cidrRange === void 0) { + ref = other, other = ref[0], cidrRange = ref[1]; + } + if (other.kind() !== "ipv6") { + throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one"); + } + return matchCIDR(this.parts, other.parts, 16, cidrRange); + }; + IPv6.prototype.SpecialRanges = { + unspecified: [new IPv6([0, 0, 0, 0, 0, 0, 0, 0]), 128], + linkLocal: [new IPv6([65152, 0, 0, 0, 0, 0, 0, 0]), 10], + multicast: [new IPv6([65280, 0, 0, 0, 0, 0, 0, 0]), 8], + loopback: [new IPv6([0, 0, 0, 0, 0, 0, 0, 1]), 128], + uniqueLocal: [new IPv6([64512, 0, 0, 0, 0, 0, 0, 0]), 7], + ipv4Mapped: [new IPv6([0, 0, 0, 0, 0, 65535, 0, 0]), 96], + rfc6145: [new IPv6([0, 0, 0, 0, 65535, 0, 0, 0]), 96], + rfc6052: [new IPv6([100, 65435, 0, 0, 0, 0, 0, 0]), 96], + "6to4": [new IPv6([8194, 0, 0, 0, 0, 0, 0, 0]), 16], + teredo: [new IPv6([8193, 0, 0, 0, 0, 0, 0, 0]), 32], + reserved: [[new IPv6([8193, 3512, 0, 0, 0, 0, 0, 0]), 32]] + }; + IPv6.prototype.range = function() { + return ipaddr.subnetMatch(this, this.SpecialRanges); + }; + IPv6.prototype.isIPv4MappedAddress = function() { + return this.range() === "ipv4Mapped"; + }; + IPv6.prototype.toIPv4Address = function() { + var high, low, ref; + if (!this.isIPv4MappedAddress()) { + throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4"); + } + ref = this.parts.slice(-2), high = ref[0], low = ref[1]; + return new ipaddr.IPv4([high >> 8, high & 255, low >> 8, low & 255]); + }; + IPv6.prototype.prefixLengthFromSubnetMask = function() { + var cidr, i, k, part, stop, zeros, zerotable; + zerotable = { + 0: 16, + 32768: 15, + 49152: 14, + 57344: 13, + 61440: 12, + 63488: 11, + 64512: 10, + 65024: 9, + 65280: 8, + 65408: 7, + 65472: 6, + 65504: 5, + 65520: 4, + 65528: 3, + 65532: 2, + 65534: 1, + 65535: 0 + }; + cidr = 0; + stop = false; + for (i = k = 7; k >= 0; i = k += -1) { + part = this.parts[i]; + if (part in zerotable) { + zeros = zerotable[part]; + if (stop && zeros !== 0) { + return null; + } + if (zeros !== 16) { + stop = true; + } + cidr += zeros; + } else { + return null; + } + } + return 128 - cidr; + }; + return IPv6; + })(); + ipv6Part = "(?:[0-9a-f]+::?)+"; + zoneIndex = "%[0-9a-z]{1,}"; + ipv6Regexes = { + zoneIndex: new RegExp(zoneIndex, "i"), + "native": new RegExp("^(::)?(" + ipv6Part + ")?([0-9a-f]+)?(::)?(" + zoneIndex + ")?$", "i"), + transitional: new RegExp("^((?:" + ipv6Part + ")|(?:::)(?:" + ipv6Part + ")?)" + (ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part) + ("(" + zoneIndex + ")?$"), "i") + }; + expandIPv6 = function(string, parts) { + var colonCount, lastColon, part, replacement, replacementCount, zoneId; + if (string.indexOf("::") !== string.lastIndexOf("::")) { + return null; + } + zoneId = (string.match(ipv6Regexes["zoneIndex"]) || [])[0]; + if (zoneId) { + zoneId = zoneId.substring(1); + string = string.replace(/%.+$/, ""); + } + colonCount = 0; + lastColon = -1; + while ((lastColon = string.indexOf(":", lastColon + 1)) >= 0) { + colonCount++; + } + if (string.substr(0, 2) === "::") { + colonCount--; + } + if (string.substr(-2, 2) === "::") { + colonCount--; + } + if (colonCount > parts) { + return null; + } + replacementCount = parts - colonCount; + replacement = ":"; + while (replacementCount--) { + replacement += "0:"; + } + string = string.replace("::", replacement); + if (string[0] === ":") { + string = string.slice(1); + } + if (string[string.length - 1] === ":") { + string = string.slice(0, -1); + } + parts = (function() { + var k, len, ref, results; + ref = string.split(":"); + results = []; + for (k = 0, len = ref.length; k < len; k++) { + part = ref[k]; + results.push(parseInt(part, 16)); + } + return results; + })(); + return { + parts, + zoneId + }; + }; + ipaddr.IPv6.parser = function(string) { + var addr, k, len, match, octet, octets, zoneId; + if (ipv6Regexes["native"].test(string)) { + return expandIPv6(string, 8); + } else if (match = string.match(ipv6Regexes["transitional"])) { + zoneId = match[6] || ""; + addr = expandIPv6(match[1].slice(0, -1) + zoneId, 6); + if (addr.parts) { + octets = [parseInt(match[2]), parseInt(match[3]), parseInt(match[4]), parseInt(match[5])]; + for (k = 0, len = octets.length; k < len; k++) { + octet = octets[k]; + if (!(0 <= octet && octet <= 255)) { + return null; + } + } + addr.parts.push(octets[0] << 8 | octets[1]); + addr.parts.push(octets[2] << 8 | octets[3]); + return { + parts: addr.parts, + zoneId: addr.zoneId + }; + } + } + return null; + }; + ipaddr.IPv4.isIPv4 = ipaddr.IPv6.isIPv6 = function(string) { + return this.parser(string) !== null; + }; + ipaddr.IPv4.isValid = function(string) { + var e; + try { + new this(this.parser(string)); + return true; + } catch (error1) { + e = error1; + return false; + } + }; + ipaddr.IPv4.isValidFourPartDecimal = function(string) { + if (ipaddr.IPv4.isValid(string) && string.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/)) { + return true; + } else { + return false; + } + }; + ipaddr.IPv6.isValid = function(string) { + var addr, e; + if (typeof string === "string" && string.indexOf(":") === -1) { + return false; + } + try { + addr = this.parser(string); + new this(addr.parts, addr.zoneId); + return true; + } catch (error1) { + e = error1; + return false; + } + }; + ipaddr.IPv4.parse = function(string) { + var parts; + parts = this.parser(string); + if (parts === null) { + throw new Error("ipaddr: string is not formatted like ip address"); + } + return new this(parts); + }; + ipaddr.IPv6.parse = function(string) { + var addr; + addr = this.parser(string); + if (addr.parts === null) { + throw new Error("ipaddr: string is not formatted like ip address"); + } + return new this(addr.parts, addr.zoneId); + }; + ipaddr.IPv4.parseCIDR = function(string) { + var maskLength, match, parsed; + if (match = string.match(/^(.+)\/(\d+)$/)) { + maskLength = parseInt(match[2]); + if (maskLength >= 0 && maskLength <= 32) { + parsed = [this.parse(match[1]), maskLength]; + Object.defineProperty(parsed, "toString", { + value: function() { + return this.join("/"); + } + }); + return parsed; + } + } + throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range"); + }; + ipaddr.IPv4.subnetMaskFromPrefixLength = function(prefix) { + var filledOctetCount, j, octets; + prefix = parseInt(prefix); + if (prefix < 0 || prefix > 32) { + throw new Error("ipaddr: invalid IPv4 prefix length"); + } + octets = [0, 0, 0, 0]; + j = 0; + filledOctetCount = Math.floor(prefix / 8); + while (j < filledOctetCount) { + octets[j] = 255; + j++; + } + if (filledOctetCount < 4) { + octets[filledOctetCount] = Math.pow(2, prefix % 8) - 1 << 8 - prefix % 8; + } + return new this(octets); + }; + ipaddr.IPv4.broadcastAddressFromCIDR = function(string) { + var cidr, error, i, ipInterfaceOctets, octets, subnetMaskOctets; + try { + cidr = this.parseCIDR(string); + ipInterfaceOctets = cidr[0].toByteArray(); + subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray(); + octets = []; + i = 0; + while (i < 4) { + octets.push(parseInt(ipInterfaceOctets[i], 10) | parseInt(subnetMaskOctets[i], 10) ^ 255); + i++; + } + return new this(octets); + } catch (error1) { + error = error1; + throw new Error("ipaddr: the address does not have IPv4 CIDR format"); + } + }; + ipaddr.IPv4.networkAddressFromCIDR = function(string) { + var cidr, error, i, ipInterfaceOctets, octets, subnetMaskOctets; + try { + cidr = this.parseCIDR(string); + ipInterfaceOctets = cidr[0].toByteArray(); + subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray(); + octets = []; + i = 0; + while (i < 4) { + octets.push(parseInt(ipInterfaceOctets[i], 10) & parseInt(subnetMaskOctets[i], 10)); + i++; + } + return new this(octets); + } catch (error1) { + error = error1; + throw new Error("ipaddr: the address does not have IPv4 CIDR format"); + } + }; + ipaddr.IPv6.parseCIDR = function(string) { + var maskLength, match, parsed; + if (match = string.match(/^(.+)\/(\d+)$/)) { + maskLength = parseInt(match[2]); + if (maskLength >= 0 && maskLength <= 128) { + parsed = [this.parse(match[1]), maskLength]; + Object.defineProperty(parsed, "toString", { + value: function() { + return this.join("/"); + } + }); + return parsed; + } + } + throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range"); + }; + ipaddr.isValid = function(string) { + return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string); + }; + ipaddr.parse = function(string) { + if (ipaddr.IPv6.isValid(string)) { + return ipaddr.IPv6.parse(string); + } else if (ipaddr.IPv4.isValid(string)) { + return ipaddr.IPv4.parse(string); + } else { + throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format"); + } + }; + ipaddr.parseCIDR = function(string) { + var e; + try { + return ipaddr.IPv6.parseCIDR(string); + } catch (error1) { + e = error1; + try { + return ipaddr.IPv4.parseCIDR(string); + } catch (error12) { + e = error12; + throw new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format"); + } + } + }; + ipaddr.fromByteArray = function(bytes) { + var length; + length = bytes.length; + if (length === 4) { + return new ipaddr.IPv4(bytes); + } else if (length === 16) { + return new ipaddr.IPv6(bytes); + } else { + throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address"); + } + }; + ipaddr.process = function(string) { + var addr; + addr = this.parse(string); + if (addr.kind() === "ipv6" && addr.isIPv4MappedAddress()) { + return addr.toIPv4Address(); + } else { + return addr; + } + }; + }).call(exports2); + } +}); + +// node_modules/proxy-addr/index.js +var require_proxy_addr = __commonJS({ + "node_modules/proxy-addr/index.js"(exports2, module2) { + "use strict"; + module2.exports = proxyaddr; + module2.exports.all = alladdrs; + module2.exports.compile = compile; + var forwarded = require_forwarded(); + var ipaddr = require_ipaddr(); + var DIGIT_REGEXP = /^[0-9]+$/; + var isip = ipaddr.isValid; + var parseip = ipaddr.parse; + var IP_RANGES = { + linklocal: ["169.254.0.0/16", "fe80::/10"], + loopback: ["127.0.0.1/8", "::1/128"], + uniquelocal: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fc00::/7"] + }; + function alladdrs(req, trust) { + var addrs = forwarded(req); + if (!trust) { + return addrs; + } + if (typeof trust !== "function") { + trust = compile(trust); + } + for (var i = 0; i < addrs.length - 1; i++) { + if (trust(addrs[i], i)) continue; + addrs.length = i + 1; + } + return addrs; + } + function compile(val) { + if (!val) { + throw new TypeError("argument is required"); + } + var trust; + if (typeof val === "string") { + trust = [val]; + } else if (Array.isArray(val)) { + trust = val.slice(); + } else { + throw new TypeError("unsupported trust argument"); + } + for (var i = 0; i < trust.length; i++) { + val = trust[i]; + if (!Object.prototype.hasOwnProperty.call(IP_RANGES, val)) { + continue; + } + val = IP_RANGES[val]; + trust.splice.apply(trust, [i, 1].concat(val)); + i += val.length - 1; + } + return compileTrust(compileRangeSubnets(trust)); + } + function compileRangeSubnets(arr) { + var rangeSubnets = new Array(arr.length); + for (var i = 0; i < arr.length; i++) { + rangeSubnets[i] = parseipNotation(arr[i]); + } + return rangeSubnets; + } + function compileTrust(rangeSubnets) { + var len = rangeSubnets.length; + return len === 0 ? trustNone : len === 1 ? trustSingle(rangeSubnets[0]) : trustMulti(rangeSubnets); + } + function parseipNotation(note) { + var pos = note.lastIndexOf("/"); + var str = pos !== -1 ? note.substring(0, pos) : note; + if (!isip(str)) { + throw new TypeError("invalid IP address: " + str); + } + var ip = parseip(str); + if (pos === -1 && ip.kind() === "ipv6" && ip.isIPv4MappedAddress()) { + ip = ip.toIPv4Address(); + } + var max = ip.kind() === "ipv6" ? 128 : 32; + var range = pos !== -1 ? note.substring(pos + 1, note.length) : null; + if (range === null) { + range = max; + } else if (DIGIT_REGEXP.test(range)) { + range = parseInt(range, 10); + } else if (ip.kind() === "ipv4" && isip(range)) { + range = parseNetmask(range); + } else { + range = null; + } + if (range <= 0 || range > max) { + throw new TypeError("invalid range on address: " + note); + } + return [ip, range]; + } + function parseNetmask(netmask) { + var ip = parseip(netmask); + var kind = ip.kind(); + return kind === "ipv4" ? ip.prefixLengthFromSubnetMask() : null; + } + function proxyaddr(req, trust) { + if (!req) { + throw new TypeError("req argument is required"); + } + if (!trust) { + throw new TypeError("trust argument is required"); + } + var addrs = alladdrs(req, trust); + var addr = addrs[addrs.length - 1]; + return addr; + } + function trustNone() { + return false; + } + function trustMulti(subnets) { + return function trust(addr) { + if (!isip(addr)) return false; + var ip = parseip(addr); + var ipconv; + var kind = ip.kind(); + for (var i = 0; i < subnets.length; i++) { + var subnet = subnets[i]; + var subnetip = subnet[0]; + var subnetkind = subnetip.kind(); + var subnetrange = subnet[1]; + var trusted = ip; + if (kind !== subnetkind) { + if (subnetkind === "ipv4" && !ip.isIPv4MappedAddress()) { + continue; + } + if (!ipconv) { + ipconv = subnetkind === "ipv4" ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); + } + trusted = ipconv; + } + if (trusted.match(subnetip, subnetrange)) { + return true; + } + } + return false; + }; + } + function trustSingle(subnet) { + var subnetip = subnet[0]; + var subnetkind = subnetip.kind(); + var subnetisipv4 = subnetkind === "ipv4"; + var subnetrange = subnet[1]; + return function trust(addr) { + if (!isip(addr)) return false; + var ip = parseip(addr); + var kind = ip.kind(); + if (kind !== subnetkind) { + if (subnetisipv4 && !ip.isIPv4MappedAddress()) { + return false; + } + ip = subnetisipv4 ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); + } + return ip.match(subnetip, subnetrange); + }; + } + } +}); + +// node_modules/express/lib/utils.js +var require_utils2 = __commonJS({ + "node_modules/express/lib/utils.js"(exports2) { + "use strict"; + var Buffer3 = require_safe_buffer().Buffer; + var contentDisposition = require_content_disposition(); + var contentType = require_content_type(); + var deprecate = require_depd()("express"); + var flatten = require_array_flatten(); + var mime = require_send().mime; + var etag = require_etag(); + var proxyaddr = require_proxy_addr(); + var qs = require_lib2(); + var querystring = require("querystring"); + exports2.etag = createETagGenerator({ weak: false }); + exports2.wetag = createETagGenerator({ weak: true }); + exports2.isAbsolute = function(path3) { + if ("/" === path3[0]) return true; + if (":" === path3[1] && ("\\" === path3[2] || "/" === path3[2])) return true; + if ("\\\\" === path3.substring(0, 2)) return true; + }; + exports2.flatten = deprecate.function( + flatten, + "utils.flatten: use array-flatten npm module instead" + ); + exports2.normalizeType = function(type) { + return ~type.indexOf("/") ? acceptParams(type) : { value: mime.lookup(type), params: {} }; + }; + exports2.normalizeTypes = function(types) { + var ret = []; + for (var i = 0; i < types.length; ++i) { + ret.push(exports2.normalizeType(types[i])); + } + return ret; + }; + exports2.contentDisposition = deprecate.function( + contentDisposition, + "utils.contentDisposition: use content-disposition npm module instead" + ); + function acceptParams(str) { + var parts = str.split(/ *; */); + var ret = { value: parts[0], quality: 1, params: {} }; + for (var i = 1; i < parts.length; ++i) { + var pms = parts[i].split(/ *= */); + if ("q" === pms[0]) { + ret.quality = parseFloat(pms[1]); + } else { + ret.params[pms[0]] = pms[1]; + } + } + return ret; + } + exports2.compileETag = function(val) { + var fn; + if (typeof val === "function") { + return val; + } + switch (val) { + case true: + case "weak": + fn = exports2.wetag; + break; + case false: + break; + case "strong": + fn = exports2.etag; + break; + default: + throw new TypeError("unknown value for etag function: " + val); + } + return fn; + }; + exports2.compileQueryParser = function compileQueryParser(val) { + var fn; + if (typeof val === "function") { + return val; + } + switch (val) { + case true: + case "simple": + fn = querystring.parse; + break; + case false: + fn = newObject; + break; + case "extended": + fn = parseExtendedQueryString; + break; + default: + throw new TypeError("unknown value for query parser function: " + val); + } + return fn; + }; + exports2.compileTrust = function(val) { + if (typeof val === "function") return val; + if (val === true) { + return function() { + return true; + }; + } + if (typeof val === "number") { + return function(a, i) { + return i < val; + }; + } + if (typeof val === "string") { + val = val.split(",").map(function(v) { + return v.trim(); + }); + } + return proxyaddr.compile(val || []); + }; + exports2.setCharset = function setCharset(type, charset) { + if (!type || !charset) { + return type; + } + var parsed = contentType.parse(type); + parsed.parameters.charset = charset; + return contentType.format(parsed); + }; + function createETagGenerator(options) { + return function generateETag(body, encoding) { + var buf = !Buffer3.isBuffer(body) ? Buffer3.from(body, encoding) : body; + return etag(buf, options); + }; + } + function parseExtendedQueryString(str) { + return qs.parse(str, { + allowPrototypes: true + }); + } + function newObject() { + return {}; + } + } +}); + +// node_modules/express/lib/application.js +var require_application = __commonJS({ + "node_modules/express/lib/application.js"(exports2, module2) { + "use strict"; + var finalhandler = require_finalhandler(); + var Router = require_router(); + var methods = require_methods(); + var middleware = require_init(); + var query = require_query(); + var debug = require_src3()("express:application"); + var View = require_view(); + var http = require("http"); + var compileETag = require_utils2().compileETag; + var compileQueryParser = require_utils2().compileQueryParser; + var compileTrust = require_utils2().compileTrust; + var deprecate = require_depd()("express"); + var flatten = require_array_flatten(); + var merge = require_utils_merge(); + var resolve = require("path").resolve; + var setPrototypeOf = require_setprototypeof(); + var hasOwnProperty = Object.prototype.hasOwnProperty; + var slice = Array.prototype.slice; + var app = exports2 = module2.exports = {}; + var trustProxyDefaultSymbol = "@@symbol:trust_proxy_default"; + app.init = function init() { + this.cache = {}; + this.engines = {}; + this.settings = {}; + this.defaultConfiguration(); + }; + app.defaultConfiguration = function defaultConfiguration() { + var env = process.env.NODE_ENV || "development"; + this.enable("x-powered-by"); + this.set("etag", "weak"); + this.set("env", env); + this.set("query parser", "extended"); + this.set("subdomain offset", 2); + this.set("trust proxy", false); + Object.defineProperty(this.settings, trustProxyDefaultSymbol, { + configurable: true, + value: true + }); + debug("booting in %s mode", env); + this.on("mount", function onmount(parent) { + if (this.settings[trustProxyDefaultSymbol] === true && typeof parent.settings["trust proxy fn"] === "function") { + delete this.settings["trust proxy"]; + delete this.settings["trust proxy fn"]; + } + setPrototypeOf(this.request, parent.request); + setPrototypeOf(this.response, parent.response); + setPrototypeOf(this.engines, parent.engines); + setPrototypeOf(this.settings, parent.settings); + }); + this.locals = /* @__PURE__ */ Object.create(null); + this.mountpath = "/"; + this.locals.settings = this.settings; + this.set("view", View); + this.set("views", resolve("views")); + this.set("jsonp callback name", "callback"); + if (env === "production") { + this.enable("view cache"); + } + Object.defineProperty(this, "router", { + get: function() { + throw new Error("'app.router' is deprecated!\nPlease see the 3.x to 4.x migration guide for details on how to update your app."); + } + }); + }; + app.lazyrouter = function lazyrouter() { + if (!this._router) { + this._router = new Router({ + caseSensitive: this.enabled("case sensitive routing"), + strict: this.enabled("strict routing") + }); + this._router.use(query(this.get("query parser fn"))); + this._router.use(middleware.init(this)); + } + }; + app.handle = function handle(req, res, callback) { + var router = this._router; + var done = callback || finalhandler(req, res, { + env: this.get("env"), + onerror: logerror.bind(this) + }); + if (!router) { + debug("no routes defined on app"); + done(); + return; + } + router.handle(req, res, done); + }; + app.use = function use(fn) { + var offset = 0; + var path3 = "/"; + if (typeof fn !== "function") { + var arg = fn; + while (Array.isArray(arg) && arg.length !== 0) { + arg = arg[0]; + } + if (typeof arg !== "function") { + offset = 1; + path3 = fn; + } + } + var fns = flatten(slice.call(arguments, offset)); + if (fns.length === 0) { + throw new TypeError("app.use() requires a middleware function"); + } + this.lazyrouter(); + var router = this._router; + fns.forEach(function(fn2) { + if (!fn2 || !fn2.handle || !fn2.set) { + return router.use(path3, fn2); + } + debug(".use app under %s", path3); + fn2.mountpath = path3; + fn2.parent = this; + router.use(path3, function mounted_app(req, res, next) { + var orig = req.app; + fn2.handle(req, res, function(err) { + setPrototypeOf(req, orig.request); + setPrototypeOf(res, orig.response); + next(err); + }); + }); + fn2.emit("mount", this); + }, this); + return this; + }; + app.route = function route(path3) { + this.lazyrouter(); + return this._router.route(path3); + }; + app.engine = function engine(ext, fn) { + if (typeof fn !== "function") { + throw new Error("callback function required"); + } + var extension = ext[0] !== "." ? "." + ext : ext; + this.engines[extension] = fn; + return this; + }; + app.param = function param(name, fn) { + this.lazyrouter(); + if (Array.isArray(name)) { + for (var i = 0; i < name.length; i++) { + this.param(name[i], fn); + } + return this; + } + this._router.param(name, fn); + return this; + }; + app.set = function set(setting, val) { + if (arguments.length === 1) { + var settings = this.settings; + while (settings && settings !== Object.prototype) { + if (hasOwnProperty.call(settings, setting)) { + return settings[setting]; + } + settings = Object.getPrototypeOf(settings); + } + return void 0; + } + debug('set "%s" to %o', setting, val); + this.settings[setting] = val; + switch (setting) { + case "etag": + this.set("etag fn", compileETag(val)); + break; + case "query parser": + this.set("query parser fn", compileQueryParser(val)); + break; + case "trust proxy": + this.set("trust proxy fn", compileTrust(val)); + Object.defineProperty(this.settings, trustProxyDefaultSymbol, { + configurable: true, + value: false + }); + break; + } + return this; + }; + app.path = function path3() { + return this.parent ? this.parent.path() + this.mountpath : ""; + }; + app.enabled = function enabled(setting) { + return Boolean(this.set(setting)); + }; + app.disabled = function disabled(setting) { + return !this.set(setting); + }; + app.enable = function enable(setting) { + return this.set(setting, true); + }; + app.disable = function disable(setting) { + return this.set(setting, false); + }; + methods.forEach(function(method) { + app[method] = function(path3) { + if (method === "get" && arguments.length === 1) { + return this.set(path3); + } + this.lazyrouter(); + var route = this._router.route(path3); + route[method].apply(route, slice.call(arguments, 1)); + return this; + }; + }); + app.all = function all(path3) { + this.lazyrouter(); + var route = this._router.route(path3); + var args = slice.call(arguments, 1); + for (var i = 0; i < methods.length; i++) { + route[methods[i]].apply(route, args); + } + return this; + }; + app.del = deprecate.function(app.delete, "app.del: Use app.delete instead"); + app.render = function render(name, options, callback) { + var cache = this.cache; + var done = callback; + var engines = this.engines; + var opts = options; + var renderOptions = {}; + var view; + if (typeof options === "function") { + done = options; + opts = {}; + } + merge(renderOptions, this.locals); + if (opts._locals) { + merge(renderOptions, opts._locals); + } + merge(renderOptions, opts); + if (renderOptions.cache == null) { + renderOptions.cache = this.enabled("view cache"); + } + if (renderOptions.cache) { + view = cache[name]; + } + if (!view) { + var View2 = this.get("view"); + view = new View2(name, { + defaultEngine: this.get("view engine"), + root: this.get("views"), + engines + }); + if (!view.path) { + var dirs = Array.isArray(view.root) && view.root.length > 1 ? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"' : 'directory "' + view.root + '"'; + var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs); + err.view = view; + return done(err); + } + if (renderOptions.cache) { + cache[name] = view; + } + } + tryRender(view, renderOptions, done); + }; + app.listen = function listen() { + var server2 = http.createServer(this); + return server2.listen.apply(server2, arguments); + }; + function logerror(err) { + if (this.get("env") !== "test") console.error(err.stack || err.toString()); + } + function tryRender(view, options, callback) { + try { + view.render(options, callback); + } catch (err) { + callback(err); + } + } + } +}); + +// node_modules/negotiator/lib/charset.js +var require_charset = __commonJS({ + "node_modules/negotiator/lib/charset.js"(exports2, module2) { + "use strict"; + module2.exports = preferredCharsets; + module2.exports.preferredCharsets = preferredCharsets; + var simpleCharsetRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/; + function parseAcceptCharset(accept) { + var accepts = accept.split(","); + for (var i = 0, j = 0; i < accepts.length; i++) { + var charset = parseCharset(accepts[i].trim(), i); + if (charset) { + accepts[j++] = charset; + } + } + accepts.length = j; + return accepts; + } + function parseCharset(str, i) { + var match = simpleCharsetRegExp.exec(str); + if (!match) return null; + var charset = match[1]; + var q = 1; + if (match[2]) { + var params = match[2].split(";"); + for (var j = 0; j < params.length; j++) { + var p = params[j].trim().split("="); + if (p[0] === "q") { + q = parseFloat(p[1]); + break; + } + } + } + return { + charset, + q, + i + }; + } + function getCharsetPriority(charset, accepted, index) { + var priority = { o: -1, q: 0, s: 0 }; + for (var i = 0; i < accepted.length; i++) { + var spec = specify(charset, accepted[i], index); + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + return priority; + } + function specify(charset, spec, index) { + var s = 0; + if (spec.charset.toLowerCase() === charset.toLowerCase()) { + s |= 1; + } else if (spec.charset !== "*") { + return null; + } + return { + i: index, + o: spec.i, + q: spec.q, + s + }; + } + function preferredCharsets(accept, provided) { + var accepts = parseAcceptCharset(accept === void 0 ? "*" : accept || ""); + if (!provided) { + return accepts.filter(isQuality).sort(compareSpecs).map(getFullCharset); + } + var priorities = provided.map(function getPriority(type, index) { + return getCharsetPriority(type, accepts, index); + }); + return priorities.filter(isQuality).sort(compareSpecs).map(function getCharset(priority) { + return provided[priorities.indexOf(priority)]; + }); + } + function compareSpecs(a, b) { + return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0; + } + function getFullCharset(spec) { + return spec.charset; + } + function isQuality(spec) { + return spec.q > 0; + } + } +}); + +// node_modules/negotiator/lib/encoding.js +var require_encoding = __commonJS({ + "node_modules/negotiator/lib/encoding.js"(exports2, module2) { + "use strict"; + module2.exports = preferredEncodings; + module2.exports.preferredEncodings = preferredEncodings; + var simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/; + function parseAcceptEncoding(accept) { + var accepts = accept.split(","); + var hasIdentity = false; + var minQuality = 1; + for (var i = 0, j = 0; i < accepts.length; i++) { + var encoding = parseEncoding(accepts[i].trim(), i); + if (encoding) { + accepts[j++] = encoding; + hasIdentity = hasIdentity || specify("identity", encoding); + minQuality = Math.min(minQuality, encoding.q || 1); + } + } + if (!hasIdentity) { + accepts[j++] = { + encoding: "identity", + q: minQuality, + i + }; + } + accepts.length = j; + return accepts; + } + function parseEncoding(str, i) { + var match = simpleEncodingRegExp.exec(str); + if (!match) return null; + var encoding = match[1]; + var q = 1; + if (match[2]) { + var params = match[2].split(";"); + for (var j = 0; j < params.length; j++) { + var p = params[j].trim().split("="); + if (p[0] === "q") { + q = parseFloat(p[1]); + break; + } + } + } + return { + encoding, + q, + i + }; + } + function getEncodingPriority(encoding, accepted, index) { + var priority = { o: -1, q: 0, s: 0 }; + for (var i = 0; i < accepted.length; i++) { + var spec = specify(encoding, accepted[i], index); + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + return priority; + } + function specify(encoding, spec, index) { + var s = 0; + if (spec.encoding.toLowerCase() === encoding.toLowerCase()) { + s |= 1; + } else if (spec.encoding !== "*") { + return null; + } + return { + i: index, + o: spec.i, + q: spec.q, + s + }; + } + function preferredEncodings(accept, provided) { + var accepts = parseAcceptEncoding(accept || ""); + if (!provided) { + return accepts.filter(isQuality).sort(compareSpecs).map(getFullEncoding); + } + var priorities = provided.map(function getPriority(type, index) { + return getEncodingPriority(type, accepts, index); + }); + return priorities.filter(isQuality).sort(compareSpecs).map(function getEncoding(priority) { + return provided[priorities.indexOf(priority)]; + }); + } + function compareSpecs(a, b) { + return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0; + } + function getFullEncoding(spec) { + return spec.encoding; + } + function isQuality(spec) { + return spec.q > 0; + } + } +}); + +// node_modules/negotiator/lib/language.js +var require_language = __commonJS({ + "node_modules/negotiator/lib/language.js"(exports2, module2) { + "use strict"; + module2.exports = preferredLanguages; + module2.exports.preferredLanguages = preferredLanguages; + var simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/; + function parseAcceptLanguage(accept) { + var accepts = accept.split(","); + for (var i = 0, j = 0; i < accepts.length; i++) { + var language = parseLanguage(accepts[i].trim(), i); + if (language) { + accepts[j++] = language; + } + } + accepts.length = j; + return accepts; + } + function parseLanguage(str, i) { + var match = simpleLanguageRegExp.exec(str); + if (!match) return null; + var prefix = match[1]; + var suffix = match[2]; + var full = prefix; + if (suffix) full += "-" + suffix; + var q = 1; + if (match[3]) { + var params = match[3].split(";"); + for (var j = 0; j < params.length; j++) { + var p = params[j].split("="); + if (p[0] === "q") q = parseFloat(p[1]); + } + } + return { + prefix, + suffix, + q, + i, + full + }; + } + function getLanguagePriority(language, accepted, index) { + var priority = { o: -1, q: 0, s: 0 }; + for (var i = 0; i < accepted.length; i++) { + var spec = specify(language, accepted[i], index); + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + return priority; + } + function specify(language, spec, index) { + var p = parseLanguage(language); + if (!p) return null; + var s = 0; + if (spec.full.toLowerCase() === p.full.toLowerCase()) { + s |= 4; + } else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) { + s |= 2; + } else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) { + s |= 1; + } else if (spec.full !== "*") { + return null; + } + return { + i: index, + o: spec.i, + q: spec.q, + s + }; + } + function preferredLanguages(accept, provided) { + var accepts = parseAcceptLanguage(accept === void 0 ? "*" : accept || ""); + if (!provided) { + return accepts.filter(isQuality).sort(compareSpecs).map(getFullLanguage); + } + var priorities = provided.map(function getPriority(type, index) { + return getLanguagePriority(type, accepts, index); + }); + return priorities.filter(isQuality).sort(compareSpecs).map(function getLanguage(priority) { + return provided[priorities.indexOf(priority)]; + }); + } + function compareSpecs(a, b) { + return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0; + } + function getFullLanguage(spec) { + return spec.full; + } + function isQuality(spec) { + return spec.q > 0; + } + } +}); + +// node_modules/negotiator/lib/mediaType.js +var require_mediaType = __commonJS({ + "node_modules/negotiator/lib/mediaType.js"(exports2, module2) { + "use strict"; + module2.exports = preferredMediaTypes; + module2.exports.preferredMediaTypes = preferredMediaTypes; + var simpleMediaTypeRegExp = /^\s*([^\s\/;]+)\/([^;\s]+)\s*(?:;(.*))?$/; + function parseAccept(accept) { + var accepts = splitMediaTypes(accept); + for (var i = 0, j = 0; i < accepts.length; i++) { + var mediaType = parseMediaType(accepts[i].trim(), i); + if (mediaType) { + accepts[j++] = mediaType; + } + } + accepts.length = j; + return accepts; + } + function parseMediaType(str, i) { + var match = simpleMediaTypeRegExp.exec(str); + if (!match) return null; + var params = /* @__PURE__ */ Object.create(null); + var q = 1; + var subtype = match[2]; + var type = match[1]; + if (match[3]) { + var kvps = splitParameters(match[3]).map(splitKeyValuePair); + for (var j = 0; j < kvps.length; j++) { + var pair = kvps[j]; + var key = pair[0].toLowerCase(); + var val = pair[1]; + var value = val && val[0] === '"' && val[val.length - 1] === '"' ? val.substr(1, val.length - 2) : val; + if (key === "q") { + q = parseFloat(value); + break; + } + params[key] = value; + } + } + return { + type, + subtype, + params, + q, + i + }; + } + function getMediaTypePriority(type, accepted, index) { + var priority = { o: -1, q: 0, s: 0 }; + for (var i = 0; i < accepted.length; i++) { + var spec = specify(type, accepted[i], index); + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + return priority; + } + function specify(type, spec, index) { + var p = parseMediaType(type); + var s = 0; + if (!p) { + return null; + } + if (spec.type.toLowerCase() == p.type.toLowerCase()) { + s |= 4; + } else if (spec.type != "*") { + return null; + } + if (spec.subtype.toLowerCase() == p.subtype.toLowerCase()) { + s |= 2; + } else if (spec.subtype != "*") { + return null; + } + var keys = Object.keys(spec.params); + if (keys.length > 0) { + if (keys.every(function(k) { + return spec.params[k] == "*" || (spec.params[k] || "").toLowerCase() == (p.params[k] || "").toLowerCase(); + })) { + s |= 1; + } else { + return null; + } + } + return { + i: index, + o: spec.i, + q: spec.q, + s + }; + } + function preferredMediaTypes(accept, provided) { + var accepts = parseAccept(accept === void 0 ? "*/*" : accept || ""); + if (!provided) { + return accepts.filter(isQuality).sort(compareSpecs).map(getFullType); + } + var priorities = provided.map(function getPriority(type, index) { + return getMediaTypePriority(type, accepts, index); + }); + return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) { + return provided[priorities.indexOf(priority)]; + }); + } + function compareSpecs(a, b) { + return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0; + } + function getFullType(spec) { + return spec.type + "/" + spec.subtype; + } + function isQuality(spec) { + return spec.q > 0; + } + function quoteCount(string) { + var count = 0; + var index = 0; + while ((index = string.indexOf('"', index)) !== -1) { + count++; + index++; + } + return count; + } + function splitKeyValuePair(str) { + var index = str.indexOf("="); + var key; + var val; + if (index === -1) { + key = str; + } else { + key = str.substr(0, index); + val = str.substr(index + 1); + } + return [key, val]; + } + function splitMediaTypes(accept) { + var accepts = accept.split(","); + for (var i = 1, j = 0; i < accepts.length; i++) { + if (quoteCount(accepts[j]) % 2 == 0) { + accepts[++j] = accepts[i]; + } else { + accepts[j] += "," + accepts[i]; + } + } + accepts.length = j + 1; + return accepts; + } + function splitParameters(str) { + var parameters = str.split(";"); + for (var i = 1, j = 0; i < parameters.length; i++) { + if (quoteCount(parameters[j]) % 2 == 0) { + parameters[++j] = parameters[i]; + } else { + parameters[j] += ";" + parameters[i]; + } + } + parameters.length = j + 1; + for (var i = 0; i < parameters.length; i++) { + parameters[i] = parameters[i].trim(); + } + return parameters; + } + } +}); + +// node_modules/negotiator/index.js +var require_negotiator = __commonJS({ + "node_modules/negotiator/index.js"(exports2, module2) { + "use strict"; + var preferredCharsets = require_charset(); + var preferredEncodings = require_encoding(); + var preferredLanguages = require_language(); + var preferredMediaTypes = require_mediaType(); + module2.exports = Negotiator; + module2.exports.Negotiator = Negotiator; + function Negotiator(request) { + if (!(this instanceof Negotiator)) { + return new Negotiator(request); + } + this.request = request; + } + Negotiator.prototype.charset = function charset(available) { + var set = this.charsets(available); + return set && set[0]; + }; + Negotiator.prototype.charsets = function charsets(available) { + return preferredCharsets(this.request.headers["accept-charset"], available); + }; + Negotiator.prototype.encoding = function encoding(available) { + var set = this.encodings(available); + return set && set[0]; + }; + Negotiator.prototype.encodings = function encodings(available) { + return preferredEncodings(this.request.headers["accept-encoding"], available); + }; + Negotiator.prototype.language = function language(available) { + var set = this.languages(available); + return set && set[0]; + }; + Negotiator.prototype.languages = function languages(available) { + return preferredLanguages(this.request.headers["accept-language"], available); + }; + Negotiator.prototype.mediaType = function mediaType(available) { + var set = this.mediaTypes(available); + return set && set[0]; + }; + Negotiator.prototype.mediaTypes = function mediaTypes(available) { + return preferredMediaTypes(this.request.headers.accept, available); + }; + Negotiator.prototype.preferredCharset = Negotiator.prototype.charset; + Negotiator.prototype.preferredCharsets = Negotiator.prototype.charsets; + Negotiator.prototype.preferredEncoding = Negotiator.prototype.encoding; + Negotiator.prototype.preferredEncodings = Negotiator.prototype.encodings; + Negotiator.prototype.preferredLanguage = Negotiator.prototype.language; + Negotiator.prototype.preferredLanguages = Negotiator.prototype.languages; + Negotiator.prototype.preferredMediaType = Negotiator.prototype.mediaType; + Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes; + } +}); + +// node_modules/accepts/index.js +var require_accepts = __commonJS({ + "node_modules/accepts/index.js"(exports2, module2) { + "use strict"; + var Negotiator = require_negotiator(); + var mime = require_mime_types(); + module2.exports = Accepts; + function Accepts(req) { + if (!(this instanceof Accepts)) { + return new Accepts(req); + } + this.headers = req.headers; + this.negotiator = new Negotiator(req); + } + Accepts.prototype.type = Accepts.prototype.types = function(types_) { + var types = types_; + if (types && !Array.isArray(types)) { + types = new Array(arguments.length); + for (var i = 0; i < types.length; i++) { + types[i] = arguments[i]; + } + } + if (!types || types.length === 0) { + return this.negotiator.mediaTypes(); + } + if (!this.headers.accept) { + return types[0]; + } + var mimes = types.map(extToMime); + var accepts = this.negotiator.mediaTypes(mimes.filter(validMime)); + var first = accepts[0]; + return first ? types[mimes.indexOf(first)] : false; + }; + Accepts.prototype.encoding = Accepts.prototype.encodings = function(encodings_) { + var encodings = encodings_; + if (encodings && !Array.isArray(encodings)) { + encodings = new Array(arguments.length); + for (var i = 0; i < encodings.length; i++) { + encodings[i] = arguments[i]; + } + } + if (!encodings || encodings.length === 0) { + return this.negotiator.encodings(); + } + return this.negotiator.encodings(encodings)[0] || false; + }; + Accepts.prototype.charset = Accepts.prototype.charsets = function(charsets_) { + var charsets = charsets_; + if (charsets && !Array.isArray(charsets)) { + charsets = new Array(arguments.length); + for (var i = 0; i < charsets.length; i++) { + charsets[i] = arguments[i]; + } + } + if (!charsets || charsets.length === 0) { + return this.negotiator.charsets(); + } + return this.negotiator.charsets(charsets)[0] || false; + }; + Accepts.prototype.lang = Accepts.prototype.langs = Accepts.prototype.language = Accepts.prototype.languages = function(languages_) { + var languages = languages_; + if (languages && !Array.isArray(languages)) { + languages = new Array(arguments.length); + for (var i = 0; i < languages.length; i++) { + languages[i] = arguments[i]; + } + } + if (!languages || languages.length === 0) { + return this.negotiator.languages(); + } + return this.negotiator.languages(languages)[0] || false; + }; + function extToMime(type) { + return type.indexOf("/") === -1 ? mime.lookup(type) : type; + } + function validMime(type) { + return typeof type === "string"; + } + } +}); + +// node_modules/express/lib/request.js +var require_request = __commonJS({ + "node_modules/express/lib/request.js"(exports2, module2) { + "use strict"; + var accepts = require_accepts(); + var deprecate = require_depd()("express"); + var isIP = require("net").isIP; + var typeis = require_type_is(); + var http = require("http"); + var fresh = require_fresh(); + var parseRange = require_range_parser(); + var parse4 = require_parseurl(); + var proxyaddr = require_proxy_addr(); + var req = Object.create(http.IncomingMessage.prototype); + module2.exports = req; + req.get = req.header = function header(name) { + if (!name) { + throw new TypeError("name argument is required to req.get"); + } + if (typeof name !== "string") { + throw new TypeError("name must be a string to req.get"); + } + var lc = name.toLowerCase(); + switch (lc) { + case "referer": + case "referrer": + return this.headers.referrer || this.headers.referer; + default: + return this.headers[lc]; + } + }; + req.accepts = function() { + var accept = accepts(this); + return accept.types.apply(accept, arguments); + }; + req.acceptsEncodings = function() { + var accept = accepts(this); + return accept.encodings.apply(accept, arguments); + }; + req.acceptsEncoding = deprecate.function( + req.acceptsEncodings, + "req.acceptsEncoding: Use acceptsEncodings instead" + ); + req.acceptsCharsets = function() { + var accept = accepts(this); + return accept.charsets.apply(accept, arguments); + }; + req.acceptsCharset = deprecate.function( + req.acceptsCharsets, + "req.acceptsCharset: Use acceptsCharsets instead" + ); + req.acceptsLanguages = function() { + var accept = accepts(this); + return accept.languages.apply(accept, arguments); + }; + req.acceptsLanguage = deprecate.function( + req.acceptsLanguages, + "req.acceptsLanguage: Use acceptsLanguages instead" + ); + req.range = function range(size, options) { + var range2 = this.get("Range"); + if (!range2) return; + return parseRange(size, range2, options); + }; + req.param = function param(name, defaultValue) { + var params = this.params || {}; + var body = this.body || {}; + var query = this.query || {}; + var args = arguments.length === 1 ? "name" : "name, default"; + deprecate("req.param(" + args + "): Use req.params, req.body, or req.query instead"); + if (null != params[name] && params.hasOwnProperty(name)) return params[name]; + if (null != body[name]) return body[name]; + if (null != query[name]) return query[name]; + return defaultValue; + }; + req.is = function is(types) { + var arr = types; + if (!Array.isArray(types)) { + arr = new Array(arguments.length); + for (var i = 0; i < arr.length; i++) { + arr[i] = arguments[i]; + } + } + return typeis(this, arr); + }; + defineGetter(req, "protocol", function protocol() { + var proto = this.connection.encrypted ? "https" : "http"; + var trust = this.app.get("trust proxy fn"); + if (!trust(this.connection.remoteAddress, 0)) { + return proto; + } + var header = this.get("X-Forwarded-Proto") || proto; + var index = header.indexOf(","); + return index !== -1 ? header.substring(0, index).trim() : header.trim(); + }); + defineGetter(req, "secure", function secure() { + return this.protocol === "https"; + }); + defineGetter(req, "ip", function ip() { + var trust = this.app.get("trust proxy fn"); + return proxyaddr(this, trust); + }); + defineGetter(req, "ips", function ips() { + var trust = this.app.get("trust proxy fn"); + var addrs = proxyaddr.all(this, trust); + addrs.reverse().pop(); + return addrs; + }); + defineGetter(req, "subdomains", function subdomains() { + var hostname = this.hostname; + if (!hostname) return []; + var offset = this.app.get("subdomain offset"); + var subdomains2 = !isIP(hostname) ? hostname.split(".").reverse() : [hostname]; + return subdomains2.slice(offset); + }); + defineGetter(req, "path", function path3() { + return parse4(this).pathname; + }); + defineGetter(req, "hostname", function hostname() { + var trust = this.app.get("trust proxy fn"); + var host = this.get("X-Forwarded-Host"); + if (!host || !trust(this.connection.remoteAddress, 0)) { + host = this.get("Host"); + } else if (host.indexOf(",") !== -1) { + host = host.substring(0, host.indexOf(",")).trimRight(); + } + if (!host) return; + var offset = host[0] === "[" ? host.indexOf("]") + 1 : 0; + var index = host.indexOf(":", offset); + return index !== -1 ? host.substring(0, index) : host; + }); + defineGetter(req, "host", deprecate.function(function host() { + return this.hostname; + }, "req.host: Use req.hostname instead")); + defineGetter(req, "fresh", function() { + var method = this.method; + var res = this.res; + var status = res.statusCode; + if ("GET" !== method && "HEAD" !== method) return false; + if (status >= 200 && status < 300 || 304 === status) { + return fresh(this.headers, { + "etag": res.get("ETag"), + "last-modified": res.get("Last-Modified") + }); + } + return false; + }); + defineGetter(req, "stale", function stale() { + return !this.fresh; + }); + defineGetter(req, "xhr", function xhr() { + var val = this.get("X-Requested-With") || ""; + return val.toLowerCase() === "xmlhttprequest"; + }); + function defineGetter(obj, name, getter) { + Object.defineProperty(obj, name, { + configurable: true, + enumerable: true, + get: getter + }); + } + } +}); + +// node_modules/cookie-signature/index.js +var require_cookie_signature = __commonJS({ + "node_modules/cookie-signature/index.js"(exports2) { + var crypto12 = require("crypto"); + exports2.sign = function(val, secret) { + if ("string" !== typeof val) throw new TypeError("Cookie value must be provided as a string."); + if (null == secret) throw new TypeError("Secret key must be provided."); + return val + "." + crypto12.createHmac("sha256", secret).update(val).digest("base64").replace(/\=+$/, ""); + }; + exports2.unsign = function(val, secret) { + if ("string" !== typeof val) throw new TypeError("Signed cookie string must be provided."); + if (null == secret) throw new TypeError("Secret key must be provided."); + var str = val.slice(0, val.lastIndexOf(".")), mac = exports2.sign(str, secret); + return sha14(mac) == sha14(val) ? str : false; + }; + function sha14(str) { + return crypto12.createHash("sha1").update(str).digest("hex"); + } + } +}); + +// node_modules/cookie/index.js +var require_cookie = __commonJS({ + "node_modules/cookie/index.js"(exports2) { + "use strict"; + exports2.parse = parse4; + exports2.serialize = serialize; + var __toString = Object.prototype.toString; + var __hasOwnProperty = Object.prototype.hasOwnProperty; + var cookieNameRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; + var cookieValueRegExp = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/; + var domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i; + var pathValueRegExp = /^[\u0020-\u003A\u003D-\u007E]*$/; + function parse4(str, opt) { + if (typeof str !== "string") { + throw new TypeError("argument str must be a string"); + } + var obj = {}; + var len = str.length; + if (len < 2) return obj; + var dec = opt && opt.decode || decode; + var index = 0; + var eqIdx = 0; + var endIdx = 0; + do { + eqIdx = str.indexOf("=", index); + if (eqIdx === -1) break; + endIdx = str.indexOf(";", index); + if (endIdx === -1) { + endIdx = len; + } else if (eqIdx > endIdx) { + index = str.lastIndexOf(";", eqIdx - 1) + 1; + continue; + } + var keyStartIdx = startIndex(str, index, eqIdx); + var keyEndIdx = endIndex(str, eqIdx, keyStartIdx); + var key = str.slice(keyStartIdx, keyEndIdx); + if (!__hasOwnProperty.call(obj, key)) { + var valStartIdx = startIndex(str, eqIdx + 1, endIdx); + var valEndIdx = endIndex(str, endIdx, valStartIdx); + if (str.charCodeAt(valStartIdx) === 34 && str.charCodeAt(valEndIdx - 1) === 34) { + valStartIdx++; + valEndIdx--; + } + var val = str.slice(valStartIdx, valEndIdx); + obj[key] = tryDecode(val, dec); + } + index = endIdx + 1; + } while (index < len); + return obj; + } + function startIndex(str, index, max) { + do { + var code = str.charCodeAt(index); + if (code !== 32 && code !== 9) return index; + } while (++index < max); + return max; + } + function endIndex(str, index, min) { + while (index > min) { + var code = str.charCodeAt(--index); + if (code !== 32 && code !== 9) return index + 1; + } + return min; + } + function serialize(name, val, opt) { + var enc = opt && opt.encode || encodeURIComponent; + if (typeof enc !== "function") { + throw new TypeError("option encode is invalid"); + } + if (!cookieNameRegExp.test(name)) { + throw new TypeError("argument name is invalid"); + } + var value = enc(val); + if (!cookieValueRegExp.test(value)) { + throw new TypeError("argument val is invalid"); + } + var str = name + "=" + value; + if (!opt) return str; + if (null != opt.maxAge) { + var maxAge = Math.floor(opt.maxAge); + if (!isFinite(maxAge)) { + throw new TypeError("option maxAge is invalid"); + } + str += "; Max-Age=" + maxAge; + } + if (opt.domain) { + if (!domainValueRegExp.test(opt.domain)) { + throw new TypeError("option domain is invalid"); + } + str += "; Domain=" + opt.domain; + } + if (opt.path) { + if (!pathValueRegExp.test(opt.path)) { + throw new TypeError("option path is invalid"); + } + str += "; Path=" + opt.path; + } + if (opt.expires) { + var expires = opt.expires; + if (!isDate(expires) || isNaN(expires.valueOf())) { + throw new TypeError("option expires is invalid"); + } + str += "; Expires=" + expires.toUTCString(); + } + if (opt.httpOnly) { + str += "; HttpOnly"; + } + if (opt.secure) { + str += "; Secure"; + } + if (opt.partitioned) { + str += "; Partitioned"; + } + if (opt.priority) { + var priority = typeof opt.priority === "string" ? opt.priority.toLowerCase() : opt.priority; + switch (priority) { + case "low": + str += "; Priority=Low"; + break; + case "medium": + str += "; Priority=Medium"; + break; + case "high": + str += "; Priority=High"; + break; + default: + throw new TypeError("option priority is invalid"); + } + } + if (opt.sameSite) { + var sameSite = typeof opt.sameSite === "string" ? opt.sameSite.toLowerCase() : opt.sameSite; + switch (sameSite) { + case true: + str += "; SameSite=Strict"; + break; + case "lax": + str += "; SameSite=Lax"; + break; + case "strict": + str += "; SameSite=Strict"; + break; + case "none": + str += "; SameSite=None"; + break; + default: + throw new TypeError("option sameSite is invalid"); + } + } + return str; + } + function decode(str) { + return str.indexOf("%") !== -1 ? decodeURIComponent(str) : str; + } + function isDate(val) { + return __toString.call(val) === "[object Date]"; + } + function tryDecode(str, decode2) { + try { + return decode2(str); + } catch (e) { + return str; + } + } + } +}); + +// node_modules/vary/index.js +var require_vary = __commonJS({ + "node_modules/vary/index.js"(exports2, module2) { + "use strict"; + module2.exports = vary; + module2.exports.append = append; + var FIELD_NAME_REGEXP = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; + function append(header, field) { + if (typeof header !== "string") { + throw new TypeError("header argument is required"); + } + if (!field) { + throw new TypeError("field argument is required"); + } + var fields = !Array.isArray(field) ? parse4(String(field)) : field; + for (var j = 0; j < fields.length; j++) { + if (!FIELD_NAME_REGEXP.test(fields[j])) { + throw new TypeError("field argument contains an invalid header name"); + } + } + if (header === "*") { + return header; + } + var val = header; + var vals = parse4(header.toLowerCase()); + if (fields.indexOf("*") !== -1 || vals.indexOf("*") !== -1) { + return "*"; + } + for (var i = 0; i < fields.length; i++) { + var fld = fields[i].toLowerCase(); + if (vals.indexOf(fld) === -1) { + vals.push(fld); + val = val ? val + ", " + fields[i] : fields[i]; + } + } + return val; + } + function parse4(header) { + var end = 0; + var list = []; + var start = 0; + for (var i = 0, len = header.length; i < len; i++) { + switch (header.charCodeAt(i)) { + case 32: + if (start === end) { + start = end = i + 1; + } + break; + case 44: + list.push(header.substring(start, end)); + start = end = i + 1; + break; + default: + end = i + 1; + break; + } + } + list.push(header.substring(start, end)); + return list; + } + function vary(res, field) { + if (!res || !res.getHeader || !res.setHeader) { + throw new TypeError("res argument is required"); + } + var val = res.getHeader("Vary") || ""; + var header = Array.isArray(val) ? val.join(", ") : String(val); + if (val = append(header, field)) { + res.setHeader("Vary", val); + } + } + } +}); + +// node_modules/express/lib/response.js +var require_response = __commonJS({ + "node_modules/express/lib/response.js"(exports2, module2) { + "use strict"; + var Buffer3 = require_safe_buffer().Buffer; + var contentDisposition = require_content_disposition(); + var createError = require_http_errors(); + var deprecate = require_depd()("express"); + var encodeUrl = require_encodeurl(); + var escapeHtml = require_escape_html(); + var http = require("http"); + var isAbsolute = require_utils2().isAbsolute; + var onFinished = require_on_finished(); + var path3 = require("path"); + var statuses = require_statuses(); + var merge = require_utils_merge(); + var sign = require_cookie_signature().sign; + var normalizeType = require_utils2().normalizeType; + var normalizeTypes = require_utils2().normalizeTypes; + var setCharset = require_utils2().setCharset; + var cookie = require_cookie(); + var send = require_send(); + var extname = path3.extname; + var mime = send.mime; + var resolve = path3.resolve; + var vary = require_vary(); + var res = Object.create(http.ServerResponse.prototype); + module2.exports = res; + var charsetRegExp = /;\s*charset\s*=/; + res.status = function status(code) { + if ((typeof code === "string" || Math.floor(code) !== code) && code > 99 && code < 1e3) { + deprecate("res.status(" + JSON.stringify(code) + "): use res.status(" + Math.floor(code) + ") instead"); + } + this.statusCode = code; + return this; + }; + res.links = function(links) { + var link = this.get("Link") || ""; + if (link) link += ", "; + return this.set("Link", link + Object.keys(links).map(function(rel) { + return "<" + links[rel] + '>; rel="' + rel + '"'; + }).join(", ")); + }; + res.send = function send2(body) { + var chunk = body; + var encoding; + var req = this.req; + var type; + var app = this.app; + if (arguments.length === 2) { + if (typeof arguments[0] !== "number" && typeof arguments[1] === "number") { + deprecate("res.send(body, status): Use res.status(status).send(body) instead"); + this.statusCode = arguments[1]; + } else { + deprecate("res.send(status, body): Use res.status(status).send(body) instead"); + this.statusCode = arguments[0]; + chunk = arguments[1]; + } + } + if (typeof chunk === "number" && arguments.length === 1) { + if (!this.get("Content-Type")) { + this.type("txt"); + } + deprecate("res.send(status): Use res.sendStatus(status) instead"); + this.statusCode = chunk; + chunk = statuses.message[chunk]; + } + switch (typeof chunk) { + // string defaulting to html + case "string": + if (!this.get("Content-Type")) { + this.type("html"); + } + break; + case "boolean": + case "number": + case "object": + if (chunk === null) { + chunk = ""; + } else if (Buffer3.isBuffer(chunk)) { + if (!this.get("Content-Type")) { + this.type("bin"); + } + } else { + return this.json(chunk); + } + break; + } + if (typeof chunk === "string") { + encoding = "utf8"; + type = this.get("Content-Type"); + if (typeof type === "string") { + this.set("Content-Type", setCharset(type, "utf-8")); + } + } + var etagFn = app.get("etag fn"); + var generateETag = !this.get("ETag") && typeof etagFn === "function"; + var len; + if (chunk !== void 0) { + if (Buffer3.isBuffer(chunk)) { + len = chunk.length; + } else if (!generateETag && chunk.length < 1e3) { + len = Buffer3.byteLength(chunk, encoding); + } else { + chunk = Buffer3.from(chunk, encoding); + encoding = void 0; + len = chunk.length; + } + this.set("Content-Length", len); + } + var etag; + if (generateETag && len !== void 0) { + if (etag = etagFn(chunk, encoding)) { + this.set("ETag", etag); + } + } + if (req.fresh) this.statusCode = 304; + if (204 === this.statusCode || 304 === this.statusCode) { + this.removeHeader("Content-Type"); + this.removeHeader("Content-Length"); + this.removeHeader("Transfer-Encoding"); + chunk = ""; + } + if (this.statusCode === 205) { + this.set("Content-Length", "0"); + this.removeHeader("Transfer-Encoding"); + chunk = ""; + } + if (req.method === "HEAD") { + this.end(); + } else { + this.end(chunk, encoding); + } + return this; + }; + res.json = function json(obj) { + var val = obj; + if (arguments.length === 2) { + if (typeof arguments[1] === "number") { + deprecate("res.json(obj, status): Use res.status(status).json(obj) instead"); + this.statusCode = arguments[1]; + } else { + deprecate("res.json(status, obj): Use res.status(status).json(obj) instead"); + this.statusCode = arguments[0]; + val = arguments[1]; + } + } + var app = this.app; + var escape2 = app.get("json escape"); + var replacer = app.get("json replacer"); + var spaces = app.get("json spaces"); + var body = stringify4(val, replacer, spaces, escape2); + if (!this.get("Content-Type")) { + this.set("Content-Type", "application/json"); + } + return this.send(body); + }; + res.jsonp = function jsonp(obj) { + var val = obj; + if (arguments.length === 2) { + if (typeof arguments[1] === "number") { + deprecate("res.jsonp(obj, status): Use res.status(status).jsonp(obj) instead"); + this.statusCode = arguments[1]; + } else { + deprecate("res.jsonp(status, obj): Use res.status(status).jsonp(obj) instead"); + this.statusCode = arguments[0]; + val = arguments[1]; + } + } + var app = this.app; + var escape2 = app.get("json escape"); + var replacer = app.get("json replacer"); + var spaces = app.get("json spaces"); + var body = stringify4(val, replacer, spaces, escape2); + var callback = this.req.query[app.get("jsonp callback name")]; + if (!this.get("Content-Type")) { + this.set("X-Content-Type-Options", "nosniff"); + this.set("Content-Type", "application/json"); + } + if (Array.isArray(callback)) { + callback = callback[0]; + } + if (typeof callback === "string" && callback.length !== 0) { + this.set("X-Content-Type-Options", "nosniff"); + this.set("Content-Type", "text/javascript"); + callback = callback.replace(/[^\[\]\w$.]/g, ""); + if (body === void 0) { + body = ""; + } else if (typeof body === "string") { + body = body.replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029"); + } + body = "/**/ typeof " + callback + " === 'function' && " + callback + "(" + body + ");"; + } + return this.send(body); + }; + res.sendStatus = function sendStatus(statusCode) { + var body = statuses.message[statusCode] || String(statusCode); + this.statusCode = statusCode; + this.type("txt"); + return this.send(body); + }; + res.sendFile = function sendFile(path4, options, callback) { + var done = callback; + var req = this.req; + var res2 = this; + var next = req.next; + var opts = options || {}; + if (!path4) { + throw new TypeError("path argument is required to res.sendFile"); + } + if (typeof path4 !== "string") { + throw new TypeError("path must be a string to res.sendFile"); + } + if (typeof options === "function") { + done = options; + opts = {}; + } + if (!opts.root && !isAbsolute(path4)) { + throw new TypeError("path must be absolute or specify root to res.sendFile"); + } + var pathname = encodeURI(path4); + var file = send(req, pathname, opts); + sendfile(res2, file, opts, function(err) { + if (done) return done(err); + if (err && err.code === "EISDIR") return next(); + if (err && err.code !== "ECONNABORTED" && err.syscall !== "write") { + next(err); + } + }); + }; + res.sendfile = function(path4, options, callback) { + var done = callback; + var req = this.req; + var res2 = this; + var next = req.next; + var opts = options || {}; + if (typeof options === "function") { + done = options; + opts = {}; + } + var file = send(req, path4, opts); + sendfile(res2, file, opts, function(err) { + if (done) return done(err); + if (err && err.code === "EISDIR") return next(); + if (err && err.code !== "ECONNABORTED" && err.syscall !== "write") { + next(err); + } + }); + }; + res.sendfile = deprecate.function( + res.sendfile, + "res.sendfile: Use res.sendFile instead" + ); + res.download = function download(path4, filename, options, callback) { + var done = callback; + var name = filename; + var opts = options || null; + if (typeof filename === "function") { + done = filename; + name = null; + opts = null; + } else if (typeof options === "function") { + done = options; + opts = null; + } + if (typeof filename === "object" && (typeof options === "function" || options === void 0)) { + name = null; + opts = filename; + } + var headers = { + "Content-Disposition": contentDisposition(name || path4) + }; + if (opts && opts.headers) { + var keys = Object.keys(opts.headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (key.toLowerCase() !== "content-disposition") { + headers[key] = opts.headers[key]; + } + } + } + opts = Object.create(opts); + opts.headers = headers; + var fullPath = !opts.root ? resolve(path4) : path4; + return this.sendFile(fullPath, opts, done); + }; + res.contentType = res.type = function contentType(type) { + var ct = type.indexOf("/") === -1 ? mime.lookup(type) : type; + return this.set("Content-Type", ct); + }; + res.format = function(obj) { + var req = this.req; + var next = req.next; + var keys = Object.keys(obj).filter(function(v) { + return v !== "default"; + }); + var key = keys.length > 0 ? req.accepts(keys) : false; + this.vary("Accept"); + if (key) { + this.set("Content-Type", normalizeType(key).value); + obj[key](req, this, next); + } else if (obj.default) { + obj.default(req, this, next); + } else { + next(createError(406, { + types: normalizeTypes(keys).map(function(o) { + return o.value; + }) + })); + } + return this; + }; + res.attachment = function attachment(filename) { + if (filename) { + this.type(extname(filename)); + } + this.set("Content-Disposition", contentDisposition(filename)); + return this; + }; + res.append = function append(field, val) { + var prev = this.get(field); + var value = val; + if (prev) { + value = Array.isArray(prev) ? prev.concat(val) : Array.isArray(val) ? [prev].concat(val) : [prev, val]; + } + return this.set(field, value); + }; + res.set = res.header = function header(field, val) { + if (arguments.length === 2) { + var value = Array.isArray(val) ? val.map(String) : String(val); + if (field.toLowerCase() === "content-type") { + if (Array.isArray(value)) { + throw new TypeError("Content-Type cannot be set to an Array"); + } + if (!charsetRegExp.test(value)) { + var charset = mime.charsets.lookup(value.split(";")[0]); + if (charset) value += "; charset=" + charset.toLowerCase(); + } + } + this.setHeader(field, value); + } else { + for (var key in field) { + this.set(key, field[key]); + } + } + return this; + }; + res.get = function(field) { + return this.getHeader(field); + }; + res.clearCookie = function clearCookie(name, options) { + if (options) { + if (options.maxAge) { + deprecate('res.clearCookie: Passing "options.maxAge" is deprecated. In v5.0.0 of Express, this option will be ignored, as res.clearCookie will automatically set cookies to expire immediately. Please update your code to omit this option.'); + } + if (options.expires) { + deprecate('res.clearCookie: Passing "options.expires" is deprecated. In v5.0.0 of Express, this option will be ignored, as res.clearCookie will automatically set cookies to expire immediately. Please update your code to omit this option.'); + } + } + var opts = merge({ expires: /* @__PURE__ */ new Date(1), path: "/" }, options); + return this.cookie(name, "", opts); + }; + res.cookie = function(name, value, options) { + var opts = merge({}, options); + var secret = this.req.secret; + var signed = opts.signed; + if (signed && !secret) { + throw new Error('cookieParser("secret") required for signed cookies'); + } + var val = typeof value === "object" ? "j:" + JSON.stringify(value) : String(value); + if (signed) { + val = "s:" + sign(val, secret); + } + if (opts.maxAge != null) { + var maxAge = opts.maxAge - 0; + if (!isNaN(maxAge)) { + opts.expires = new Date(Date.now() + maxAge); + opts.maxAge = Math.floor(maxAge / 1e3); + } + } + if (opts.path == null) { + opts.path = "/"; + } + this.append("Set-Cookie", cookie.serialize(name, String(val), opts)); + return this; + }; + res.location = function location(url) { + var loc; + if (url === "back") { + deprecate('res.location("back"): use res.location(req.get("Referrer") || "/") and refer to https://dub.sh/security-redirect for best practices'); + loc = this.req.get("Referrer") || "/"; + } else { + loc = String(url); + } + return this.set("Location", encodeUrl(loc)); + }; + res.redirect = function redirect(url) { + var address = url; + var body; + var status = 302; + if (arguments.length === 2) { + if (typeof arguments[0] === "number") { + status = arguments[0]; + address = arguments[1]; + } else { + deprecate("res.redirect(url, status): Use res.redirect(status, url) instead"); + status = arguments[1]; + } + } + address = this.location(address).get("Location"); + this.format({ + text: function() { + body = statuses.message[status] + ". Redirecting to " + address; + }, + html: function() { + var u = escapeHtml(address); + body = "

" + statuses.message[status] + ". Redirecting to " + u + "

"; + }, + default: function() { + body = ""; + } + }); + this.statusCode = status; + this.set("Content-Length", Buffer3.byteLength(body)); + if (this.req.method === "HEAD") { + this.end(); + } else { + this.end(body); + } + }; + res.vary = function(field) { + if (!field || Array.isArray(field) && !field.length) { + deprecate("res.vary(): Provide a field name"); + return this; + } + vary(this, field); + return this; + }; + res.render = function render(view, options, callback) { + var app = this.req.app; + var done = callback; + var opts = options || {}; + var req = this.req; + var self2 = this; + if (typeof options === "function") { + done = options; + opts = {}; + } + opts._locals = self2.locals; + done = done || function(err, str) { + if (err) return req.next(err); + self2.send(str); + }; + app.render(view, opts, done); + }; + function sendfile(res2, file, options, callback) { + var done = false; + var streaming; + function onaborted() { + if (done) return; + done = true; + var err = new Error("Request aborted"); + err.code = "ECONNABORTED"; + callback(err); + } + function ondirectory() { + if (done) return; + done = true; + var err = new Error("EISDIR, read"); + err.code = "EISDIR"; + callback(err); + } + function onerror(err) { + if (done) return; + done = true; + callback(err); + } + function onend() { + if (done) return; + done = true; + callback(); + } + function onfile() { + streaming = false; + } + function onfinish(err) { + if (err && err.code === "ECONNRESET") return onaborted(); + if (err) return onerror(err); + if (done) return; + setImmediate(function() { + if (streaming !== false && !done) { + onaborted(); + return; + } + if (done) return; + done = true; + callback(); + }); + } + function onstream() { + streaming = true; + } + file.on("directory", ondirectory); + file.on("end", onend); + file.on("error", onerror); + file.on("file", onfile); + file.on("stream", onstream); + onFinished(res2, onfinish); + if (options.headers) { + file.on("headers", function headers(res3) { + var obj = options.headers; + var keys = Object.keys(obj); + for (var i = 0; i < keys.length; i++) { + var k = keys[i]; + res3.setHeader(k, obj[k]); + } + }); + } + file.pipe(res2); + } + function stringify4(value, replacer, spaces, escape2) { + var json = replacer || spaces ? JSON.stringify(value, replacer, spaces) : JSON.stringify(value); + if (escape2 && typeof json === "string") { + json = json.replace(/[<>&]/g, function(c) { + switch (c.charCodeAt(0)) { + case 60: + return "\\u003c"; + case 62: + return "\\u003e"; + case 38: + return "\\u0026"; + /* istanbul ignore next: unreachable default */ + default: + return c; + } + }); + } + return json; + } + } +}); + +// node_modules/serve-static/index.js +var require_serve_static = __commonJS({ + "node_modules/serve-static/index.js"(exports2, module2) { + "use strict"; + var encodeUrl = require_encodeurl(); + var escapeHtml = require_escape_html(); + var parseUrl = require_parseurl(); + var resolve = require("path").resolve; + var send = require_send(); + var url = require("url"); + module2.exports = serveStatic; + module2.exports.mime = send.mime; + function serveStatic(root, options) { + if (!root) { + throw new TypeError("root path required"); + } + if (typeof root !== "string") { + throw new TypeError("root path must be a string"); + } + var opts = Object.create(options || null); + var fallthrough = opts.fallthrough !== false; + var redirect = opts.redirect !== false; + var setHeaders = opts.setHeaders; + if (setHeaders && typeof setHeaders !== "function") { + throw new TypeError("option setHeaders must be function"); + } + opts.maxage = opts.maxage || opts.maxAge || 0; + opts.root = resolve(root); + var onDirectory = redirect ? createRedirectDirectoryListener() : createNotFoundDirectoryListener(); + return function serveStatic2(req, res, next) { + if (req.method !== "GET" && req.method !== "HEAD") { + if (fallthrough) { + return next(); + } + res.statusCode = 405; + res.setHeader("Allow", "GET, HEAD"); + res.setHeader("Content-Length", "0"); + res.end(); + return; + } + var forwardError = !fallthrough; + var originalUrl = parseUrl.original(req); + var path3 = parseUrl(req).pathname; + if (path3 === "/" && originalUrl.pathname.substr(-1) !== "/") { + path3 = ""; + } + var stream = send(req, path3, opts); + stream.on("directory", onDirectory); + if (setHeaders) { + stream.on("headers", setHeaders); + } + if (fallthrough) { + stream.on("file", function onFile() { + forwardError = true; + }); + } + stream.on("error", function error(err) { + if (forwardError || !(err.statusCode < 500)) { + next(err); + return; + } + next(); + }); + stream.pipe(res); + }; + } + function collapseLeadingSlashes(str) { + for (var i = 0; i < str.length; i++) { + if (str.charCodeAt(i) !== 47) { + break; + } + } + return i > 1 ? "/" + str.substr(i) : str; + } + function createHtmlDocument(title, body) { + return '\n\n\n\n' + title + "\n\n\n
" + body + "
\n\n\n"; + } + function createNotFoundDirectoryListener() { + return function notFound() { + this.error(404); + }; + } + function createRedirectDirectoryListener() { + return function redirect(res) { + if (this.hasTrailingSlash()) { + this.error(404); + return; + } + var originalUrl = parseUrl.original(this.req); + originalUrl.path = null; + originalUrl.pathname = collapseLeadingSlashes(originalUrl.pathname + "/"); + var loc = encodeUrl(url.format(originalUrl)); + var doc = createHtmlDocument("Redirecting", "Redirecting to " + escapeHtml(loc)); + res.statusCode = 301; + res.setHeader("Content-Type", "text/html; charset=UTF-8"); + res.setHeader("Content-Length", Buffer.byteLength(doc)); + res.setHeader("Content-Security-Policy", "default-src 'none'"); + res.setHeader("X-Content-Type-Options", "nosniff"); + res.setHeader("Location", loc); + res.end(doc); + }; + } + } +}); + +// node_modules/express/lib/express.js +var require_express = __commonJS({ + "node_modules/express/lib/express.js"(exports2, module2) { + "use strict"; + var bodyParser = require_body_parser(); + var EventEmitter = require("events").EventEmitter; + var mixin = require_merge_descriptors(); + var proto = require_application(); + var Route = require_route(); + var Router = require_router(); + var req = require_request(); + var res = require_response(); + exports2 = module2.exports = createApplication; + function createApplication() { + var app = function(req2, res2, next) { + app.handle(req2, res2, next); + }; + mixin(app, EventEmitter.prototype, false); + mixin(app, proto, false); + app.request = Object.create(req, { + app: { configurable: true, enumerable: true, writable: true, value: app } + }); + app.response = Object.create(res, { + app: { configurable: true, enumerable: true, writable: true, value: app } + }); + app.init(); + return app; + } + exports2.application = proto; + exports2.request = req; + exports2.response = res; + exports2.Route = Route; + exports2.Router = Router; + exports2.json = bodyParser.json; + exports2.query = require_query(); + exports2.raw = bodyParser.raw; + exports2.static = require_serve_static(); + exports2.text = bodyParser.text; + exports2.urlencoded = bodyParser.urlencoded; + var removedMiddlewares = [ + "bodyParser", + "compress", + "cookieSession", + "session", + "logger", + "cookieParser", + "favicon", + "responseTime", + "errorHandler", + "timeout", + "methodOverride", + "vhost", + "csrf", + "directory", + "limit", + "multipart", + "staticCache" + ]; + removedMiddlewares.forEach(function(name) { + Object.defineProperty(exports2, name, { + get: function() { + throw new Error("Most middleware (like " + name + ") is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware."); + }, + configurable: true + }); + }); + } +}); + +// node_modules/express/index.js +var require_express2 = __commonJS({ + "node_modules/express/index.js"(exports2, module2) { + "use strict"; + module2.exports = require_express(); + } +}); + +// node_modules/object-assign/index.js +var require_object_assign = __commonJS({ + "node_modules/object-assign/index.js"(exports2, module2) { + "use strict"; + var getOwnPropertySymbols = Object.getOwnPropertySymbols; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var propIsEnumerable = Object.prototype.propertyIsEnumerable; + function toObject(val) { + if (val === null || val === void 0) { + throw new TypeError("Object.assign cannot be called with null or undefined"); + } + return Object(val); + } + function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + var test1 = new String("abc"); + test1[5] = "de"; + if (Object.getOwnPropertyNames(test1)[0] === "5") { + return false; + } + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2["_" + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function(n) { + return test2[n]; + }); + if (order2.join("") !== "0123456789") { + return false; + } + var test3 = {}; + "abcdefghijklmnopqrst".split("").forEach(function(letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join("") !== "abcdefghijklmnopqrst") { + return false; + } + return true; + } catch (err) { + return false; + } + } + module2.exports = shouldUseNative() ? Object.assign : function(target, source) { + var from; + var to = toObject(target); + var symbols; + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + return to; + }; + } +}); + +// node_modules/cors/lib/index.js +var require_lib3 = __commonJS({ + "node_modules/cors/lib/index.js"(exports2, module2) { + (function() { + "use strict"; + var assign = require_object_assign(); + var vary = require_vary(); + var defaults = { + origin: "*", + methods: "GET,HEAD,PUT,PATCH,POST,DELETE", + preflightContinue: false, + optionsSuccessStatus: 204 + }; + function isString(s) { + return typeof s === "string" || s instanceof String; + } + function isOriginAllowed(origin, allowedOrigin) { + if (Array.isArray(allowedOrigin)) { + for (var i = 0; i < allowedOrigin.length; ++i) { + if (isOriginAllowed(origin, allowedOrigin[i])) { + return true; + } + } + return false; + } else if (isString(allowedOrigin)) { + return origin === allowedOrigin; + } else if (allowedOrigin instanceof RegExp) { + return allowedOrigin.test(origin); + } else { + return !!allowedOrigin; + } + } + function configureOrigin(options, req) { + var requestOrigin = req.headers.origin, headers = [], isAllowed; + if (!options.origin || options.origin === "*") { + headers.push([{ + key: "Access-Control-Allow-Origin", + value: "*" + }]); + } else if (isString(options.origin)) { + headers.push([{ + key: "Access-Control-Allow-Origin", + value: options.origin + }]); + headers.push([{ + key: "Vary", + value: "Origin" + }]); + } else { + isAllowed = isOriginAllowed(requestOrigin, options.origin); + headers.push([{ + key: "Access-Control-Allow-Origin", + value: isAllowed ? requestOrigin : false + }]); + headers.push([{ + key: "Vary", + value: "Origin" + }]); + } + return headers; + } + function configureMethods(options) { + var methods = options.methods; + if (methods.join) { + methods = options.methods.join(","); + } + return { + key: "Access-Control-Allow-Methods", + value: methods + }; + } + function configureCredentials(options) { + if (options.credentials === true) { + return { + key: "Access-Control-Allow-Credentials", + value: "true" + }; + } + return null; + } + function configureAllowedHeaders(options, req) { + var allowedHeaders = options.allowedHeaders || options.headers; + var headers = []; + if (!allowedHeaders) { + allowedHeaders = req.headers["access-control-request-headers"]; + headers.push([{ + key: "Vary", + value: "Access-Control-Request-Headers" + }]); + } else if (allowedHeaders.join) { + allowedHeaders = allowedHeaders.join(","); + } + if (allowedHeaders && allowedHeaders.length) { + headers.push([{ + key: "Access-Control-Allow-Headers", + value: allowedHeaders + }]); + } + return headers; + } + function configureExposedHeaders(options) { + var headers = options.exposedHeaders; + if (!headers) { + return null; + } else if (headers.join) { + headers = headers.join(","); + } + if (headers && headers.length) { + return { + key: "Access-Control-Expose-Headers", + value: headers + }; + } + return null; + } + function configureMaxAge(options) { + var maxAge = (typeof options.maxAge === "number" || options.maxAge) && options.maxAge.toString(); + if (maxAge && maxAge.length) { + return { + key: "Access-Control-Max-Age", + value: maxAge + }; + } + return null; + } + function applyHeaders(headers, res) { + for (var i = 0, n = headers.length; i < n; i++) { + var header = headers[i]; + if (header) { + if (Array.isArray(header)) { + applyHeaders(header, res); + } else if (header.key === "Vary" && header.value) { + vary(res, header.value); + } else if (header.value) { + res.setHeader(header.key, header.value); + } + } + } + } + function cors2(options, req, res, next) { + var headers = [], method = req.method && req.method.toUpperCase && req.method.toUpperCase(); + if (method === "OPTIONS") { + headers.push(configureOrigin(options, req)); + headers.push(configureCredentials(options)); + headers.push(configureMethods(options)); + headers.push(configureAllowedHeaders(options, req)); + headers.push(configureMaxAge(options)); + headers.push(configureExposedHeaders(options)); + applyHeaders(headers, res); + if (options.preflightContinue) { + next(); + } else { + res.statusCode = options.optionsSuccessStatus; + res.setHeader("Content-Length", "0"); + res.end(); + } + } else { + headers.push(configureOrigin(options, req)); + headers.push(configureCredentials(options)); + headers.push(configureExposedHeaders(options)); + applyHeaders(headers, res); + next(); + } + } + function middlewareWrapper(o) { + var optionsCallback = null; + if (typeof o === "function") { + optionsCallback = o; + } else { + optionsCallback = function(req, cb) { + cb(null, o); + }; + } + return function corsMiddleware(req, res, next) { + optionsCallback(req, function(err, options) { + if (err) { + next(err); + } else { + var corsOptions = assign({}, defaults, options); + var originCallback = null; + if (corsOptions.origin && typeof corsOptions.origin === "function") { + originCallback = corsOptions.origin; + } else if (corsOptions.origin) { + originCallback = function(origin, cb) { + cb(null, corsOptions.origin); + }; + } + if (originCallback) { + originCallback(req.headers.origin, function(err2, origin) { + if (err2 || !origin) { + next(err2); + } else { + corsOptions.origin = origin; + cors2(corsOptions, req, res, next); + } + }); + } else { + next(); + } + } + }); + }; + } + module2.exports = middlewareWrapper; + })(); + } +}); + +// node_modules/dotenv/package.json +var require_package = __commonJS({ + "node_modules/dotenv/package.json"(exports2, module2) { + module2.exports = { + name: "dotenv", + version: "16.6.1", + description: "Loads environment variables from .env file", + main: "lib/main.js", + types: "lib/main.d.ts", + exports: { + ".": { + types: "./lib/main.d.ts", + require: "./lib/main.js", + default: "./lib/main.js" + }, + "./config": "./config.js", + "./config.js": "./config.js", + "./lib/env-options": "./lib/env-options.js", + "./lib/env-options.js": "./lib/env-options.js", + "./lib/cli-options": "./lib/cli-options.js", + "./lib/cli-options.js": "./lib/cli-options.js", + "./package.json": "./package.json" + }, + scripts: { + "dts-check": "tsc --project tests/types/tsconfig.json", + lint: "standard", + pretest: "npm run lint && npm run dts-check", + test: "tap run --allow-empty-coverage --disable-coverage --timeout=60000", + "test:coverage": "tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov", + prerelease: "npm test", + release: "standard-version" + }, + repository: { + type: "git", + url: "git://github.com/motdotla/dotenv.git" + }, + homepage: "https://github.com/motdotla/dotenv#readme", + funding: "https://dotenvx.com", + keywords: [ + "dotenv", + "env", + ".env", + "environment", + "variables", + "config", + "settings" + ], + readmeFilename: "README.md", + license: "BSD-2-Clause", + devDependencies: { + "@types/node": "^18.11.3", + decache: "^4.6.2", + sinon: "^14.0.1", + standard: "^17.0.0", + "standard-version": "^9.5.0", + tap: "^19.2.0", + typescript: "^4.8.4" + }, + engines: { + node: ">=12" + }, + browser: { + fs: false + } + }; + } +}); + +// node_modules/dotenv/lib/main.js +var require_main = __commonJS({ + "node_modules/dotenv/lib/main.js"(exports2, module2) { + var fs6 = require("fs"); + var path3 = require("path"); + var os2 = require("os"); + var crypto12 = require("crypto"); + var packageJson = require_package(); + var version4 = packageJson.version; + var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg; + function parse4(src) { + const obj = {}; + let lines = src.toString(); + lines = lines.replace(/\r\n?/mg, "\n"); + let match; + while ((match = LINE.exec(lines)) != null) { + const key = match[1]; + let value = match[2] || ""; + value = value.trim(); + const maybeQuote = value[0]; + value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2"); + if (maybeQuote === '"') { + value = value.replace(/\\n/g, "\n"); + value = value.replace(/\\r/g, "\r"); + } + obj[key] = value; + } + return obj; + } + function _parseVault(options) { + options = options || {}; + const vaultPath = _vaultPath(options); + options.path = vaultPath; + const result = DotenvModule.configDotenv(options); + if (!result.parsed) { + const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`); + err.code = "MISSING_DATA"; + throw err; + } + const keys = _dotenvKey(options).split(","); + const length = keys.length; + let decrypted; + for (let i = 0; i < length; i++) { + try { + const key = keys[i].trim(); + const attrs = _instructions(result, key); + decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key); + break; + } catch (error) { + if (i + 1 >= length) { + throw error; + } + } + } + return DotenvModule.parse(decrypted); + } + function _warn(message) { + console.log(`[dotenv@${version4}][WARN] ${message}`); + } + function _debug(message) { + console.log(`[dotenv@${version4}][DEBUG] ${message}`); + } + function _log(message) { + console.log(`[dotenv@${version4}] ${message}`); + } + function _dotenvKey(options) { + if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) { + return options.DOTENV_KEY; + } + if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) { + return process.env.DOTENV_KEY; + } + return ""; + } + function _instructions(result, dotenvKey) { + let uri; + try { + uri = new URL(dotenvKey); + } catch (error) { + if (error.code === "ERR_INVALID_URL") { + const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development"); + err.code = "INVALID_DOTENV_KEY"; + throw err; + } + throw error; + } + const key = uri.password; + if (!key) { + const err = new Error("INVALID_DOTENV_KEY: Missing key part"); + err.code = "INVALID_DOTENV_KEY"; + throw err; + } + const environment = uri.searchParams.get("environment"); + if (!environment) { + const err = new Error("INVALID_DOTENV_KEY: Missing environment part"); + err.code = "INVALID_DOTENV_KEY"; + throw err; + } + const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`; + const ciphertext = result.parsed[environmentKey]; + if (!ciphertext) { + const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`); + err.code = "NOT_FOUND_DOTENV_ENVIRONMENT"; + throw err; + } + return { ciphertext, key }; + } + function _vaultPath(options) { + let possibleVaultPath = null; + if (options && options.path && options.path.length > 0) { + if (Array.isArray(options.path)) { + for (const filepath of options.path) { + if (fs6.existsSync(filepath)) { + possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`; + } + } + } else { + possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`; + } + } else { + possibleVaultPath = path3.resolve(process.cwd(), ".env.vault"); + } + if (fs6.existsSync(possibleVaultPath)) { + return possibleVaultPath; + } + return null; + } + function _resolveHome(envPath) { + return envPath[0] === "~" ? path3.join(os2.homedir(), envPath.slice(1)) : envPath; + } + function _configVault(options) { + const debug = Boolean(options && options.debug); + const quiet = options && "quiet" in options ? options.quiet : true; + if (debug || !quiet) { + _log("Loading env from encrypted .env.vault"); + } + const parsed = DotenvModule._parseVault(options); + let processEnv = process.env; + if (options && options.processEnv != null) { + processEnv = options.processEnv; + } + DotenvModule.populate(processEnv, parsed, options); + return { parsed }; + } + function configDotenv(options) { + const dotenvPath = path3.resolve(process.cwd(), ".env"); + let encoding = "utf8"; + const debug = Boolean(options && options.debug); + const quiet = options && "quiet" in options ? options.quiet : true; + if (options && options.encoding) { + encoding = options.encoding; + } else { + if (debug) { + _debug("No encoding is specified. UTF-8 is used by default"); + } + } + let optionPaths = [dotenvPath]; + if (options && options.path) { + if (!Array.isArray(options.path)) { + optionPaths = [_resolveHome(options.path)]; + } else { + optionPaths = []; + for (const filepath of options.path) { + optionPaths.push(_resolveHome(filepath)); + } + } + } + let lastError; + const parsedAll = {}; + for (const path4 of optionPaths) { + try { + const parsed = DotenvModule.parse(fs6.readFileSync(path4, { encoding })); + DotenvModule.populate(parsedAll, parsed, options); + } catch (e) { + if (debug) { + _debug(`Failed to load ${path4} ${e.message}`); + } + lastError = e; + } + } + let processEnv = process.env; + if (options && options.processEnv != null) { + processEnv = options.processEnv; + } + DotenvModule.populate(processEnv, parsedAll, options); + if (debug || !quiet) { + const keysCount = Object.keys(parsedAll).length; + const shortPaths = []; + for (const filePath of optionPaths) { + try { + const relative = path3.relative(process.cwd(), filePath); + shortPaths.push(relative); + } catch (e) { + if (debug) { + _debug(`Failed to load ${filePath} ${e.message}`); + } + lastError = e; + } + } + _log(`injecting env (${keysCount}) from ${shortPaths.join(",")}`); + } + if (lastError) { + return { parsed: parsedAll, error: lastError }; + } else { + return { parsed: parsedAll }; + } + } + function config(options) { + if (_dotenvKey(options).length === 0) { + return DotenvModule.configDotenv(options); + } + const vaultPath = _vaultPath(options); + if (!vaultPath) { + _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`); + return DotenvModule.configDotenv(options); + } + return DotenvModule._configVault(options); + } + function decrypt(encrypted, keyStr) { + const key = Buffer.from(keyStr.slice(-64), "hex"); + let ciphertext = Buffer.from(encrypted, "base64"); + const nonce = ciphertext.subarray(0, 12); + const authTag = ciphertext.subarray(-16); + ciphertext = ciphertext.subarray(12, -16); + try { + const aesgcm = crypto12.createDecipheriv("aes-256-gcm", key, nonce); + aesgcm.setAuthTag(authTag); + return `${aesgcm.update(ciphertext)}${aesgcm.final()}`; + } catch (error) { + const isRange = error instanceof RangeError; + const invalidKeyLength = error.message === "Invalid key length"; + const decryptionFailed = error.message === "Unsupported state or unable to authenticate data"; + if (isRange || invalidKeyLength) { + const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)"); + err.code = "INVALID_DOTENV_KEY"; + throw err; + } else if (decryptionFailed) { + const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY"); + err.code = "DECRYPTION_FAILED"; + throw err; + } else { + throw error; + } + } + } + function populate(processEnv, parsed, options = {}) { + const debug = Boolean(options && options.debug); + const override = Boolean(options && options.override); + if (typeof parsed !== "object") { + const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate"); + err.code = "OBJECT_REQUIRED"; + throw err; + } + for (const key of Object.keys(parsed)) { + if (Object.prototype.hasOwnProperty.call(processEnv, key)) { + if (override === true) { + processEnv[key] = parsed[key]; + } + if (debug) { + if (override === true) { + _debug(`"${key}" is already defined and WAS overwritten`); + } else { + _debug(`"${key}" is already defined and was NOT overwritten`); + } + } + } else { + processEnv[key] = parsed[key]; + } + } + } + var DotenvModule = { + configDotenv, + _configVault, + _parseVault, + config, + decrypt, + parse: parse4, + populate + }; + module2.exports.configDotenv = DotenvModule.configDotenv; + module2.exports._configVault = DotenvModule._configVault; + module2.exports._parseVault = DotenvModule._parseVault; + module2.exports.config = DotenvModule.config; + module2.exports.decrypt = DotenvModule.decrypt; + module2.exports.parse = DotenvModule.parse; + module2.exports.populate = DotenvModule.populate; + module2.exports = DotenvModule; + } +}); + +// node_modules/ejs/lib/utils.js +var require_utils3 = __commonJS({ + "node_modules/ejs/lib/utils.js"(exports2) { + "use strict"; + var regExpChars = /[|\\{}()[\]^$+*?.]/g; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var hasOwn = function(obj, key) { + return hasOwnProperty.apply(obj, [key]); + }; + exports2.escapeRegExpChars = function(string) { + if (!string) { + return ""; + } + return String(string).replace(regExpChars, "\\$&"); + }; + var _ENCODE_HTML_RULES = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'" + }; + var _MATCH_HTML = /[&<>'"]/g; + function encode_char(c) { + return _ENCODE_HTML_RULES[c] || c; + } + var escapeFuncStr = `var _ENCODE_HTML_RULES = { + "&": "&" + , "<": "<" + , ">": ">" + , '"': """ + , "'": "'" + } + , _MATCH_HTML = /[&<>'"]/g; +function encode_char(c) { + return _ENCODE_HTML_RULES[c] || c; +}; +`; + exports2.escapeXML = function(markup) { + return markup == void 0 ? "" : String(markup).replace(_MATCH_HTML, encode_char); + }; + function escapeXMLToString() { + return Function.prototype.toString.call(this) + ";\n" + escapeFuncStr; + } + try { + if (typeof Object.defineProperty === "function") { + Object.defineProperty(exports2.escapeXML, "toString", { value: escapeXMLToString }); + } else { + exports2.escapeXML.toString = escapeXMLToString; + } + } catch (err) { + console.warn("Unable to set escapeXML.toString (is the Function prototype frozen?)"); + } + exports2.shallowCopy = function(to, from) { + from = from || {}; + if (to !== null && to !== void 0) { + for (var p in from) { + if (!hasOwn(from, p)) { + continue; + } + if (p === "__proto__" || p === "constructor") { + continue; + } + to[p] = from[p]; + } + } + return to; + }; + exports2.shallowCopyFromList = function(to, from, list) { + list = list || []; + from = from || {}; + if (to !== null && to !== void 0) { + for (var i = 0; i < list.length; i++) { + var p = list[i]; + if (typeof from[p] != "undefined") { + if (!hasOwn(from, p)) { + continue; + } + if (p === "__proto__" || p === "constructor") { + continue; + } + to[p] = from[p]; + } + } + } + return to; + }; + exports2.cache = { + _data: {}, + set: function(key, val) { + this._data[key] = val; + }, + get: function(key) { + return this._data[key]; + }, + remove: function(key) { + delete this._data[key]; + }, + reset: function() { + this._data = {}; + } + }; + exports2.hyphenToCamel = function(str) { + return str.replace(/-[a-z]/g, function(match) { + return match[1].toUpperCase(); + }); + }; + exports2.createNullProtoObjWherePossible = (function() { + if (typeof Object.create == "function") { + return function() { + return /* @__PURE__ */ Object.create(null); + }; + } + if (!({ __proto__: null } instanceof Object)) { + return function() { + return { __proto__: null }; + }; + } + return function() { + return {}; + }; + })(); + exports2.hasOwnOnlyObject = function(obj) { + var o = exports2.createNullProtoObjWherePossible(); + for (var p in obj) { + if (hasOwn(obj, p)) { + o[p] = obj[p]; + } + } + return o; + }; + } +}); + +// node_modules/ejs/package.json +var require_package2 = __commonJS({ + "node_modules/ejs/package.json"(exports2, module2) { + module2.exports = { + name: "ejs", + description: "Embedded JavaScript templates", + keywords: [ + "template", + "engine", + "ejs" + ], + version: "3.1.10", + author: "Matthew Eernisse (http://fleegix.org)", + license: "Apache-2.0", + bin: { + ejs: "./bin/cli.js" + }, + main: "./lib/ejs.js", + jsdelivr: "ejs.min.js", + unpkg: "ejs.min.js", + repository: { + type: "git", + url: "git://github.com/mde/ejs.git" + }, + bugs: "https://github.com/mde/ejs/issues", + homepage: "https://github.com/mde/ejs", + dependencies: { + jake: "^10.8.5" + }, + devDependencies: { + browserify: "^16.5.1", + eslint: "^6.8.0", + "git-directory-deploy": "^1.5.1", + jsdoc: "^4.0.2", + "lru-cache": "^4.0.1", + mocha: "^10.2.0", + "uglify-js": "^3.3.16" + }, + engines: { + node: ">=0.10.0" + }, + scripts: { + test: "npx jake test" + } + }; + } +}); + +// node_modules/ejs/lib/ejs.js +var require_ejs = __commonJS({ + "node_modules/ejs/lib/ejs.js"(exports2) { + "use strict"; + var fs6 = require("fs"); + var path3 = require("path"); + var utils = require_utils3(); + var scopeOptionWarned = false; + var _VERSION_STRING = require_package2().version; + var _DEFAULT_OPEN_DELIMITER = "<"; + var _DEFAULT_CLOSE_DELIMITER = ">"; + var _DEFAULT_DELIMITER = "%"; + var _DEFAULT_LOCALS_NAME = "locals"; + var _NAME = "ejs"; + var _REGEX_STRING = "(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)"; + var _OPTS_PASSABLE_WITH_DATA = [ + "delimiter", + "scope", + "context", + "debug", + "compileDebug", + "client", + "_with", + "rmWhitespace", + "strict", + "filename", + "async" + ]; + var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat("cache"); + var _BOM = /^\uFEFF/; + var _JS_IDENTIFIER = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/; + exports2.cache = utils.cache; + exports2.fileLoader = fs6.readFileSync; + exports2.localsName = _DEFAULT_LOCALS_NAME; + exports2.promiseImpl = new Function("return this;")().Promise; + exports2.resolveInclude = function(name, filename, isDir) { + var dirname = path3.dirname; + var extname = path3.extname; + var resolve = path3.resolve; + var includePath = resolve(isDir ? filename : dirname(filename), name); + var ext = extname(name); + if (!ext) { + includePath += ".ejs"; + } + return includePath; + }; + function resolvePaths(name, paths) { + var filePath; + if (paths.some(function(v) { + filePath = exports2.resolveInclude(name, v, true); + return fs6.existsSync(filePath); + })) { + return filePath; + } + } + function getIncludePath(path4, options) { + var includePath; + var filePath; + var views = options.views; + var match = /^[A-Za-z]+:\\|^\//.exec(path4); + if (match && match.length) { + path4 = path4.replace(/^\/*/, ""); + if (Array.isArray(options.root)) { + includePath = resolvePaths(path4, options.root); + } else { + includePath = exports2.resolveInclude(path4, options.root || "/", true); + } + } else { + if (options.filename) { + filePath = exports2.resolveInclude(path4, options.filename); + if (fs6.existsSync(filePath)) { + includePath = filePath; + } + } + if (!includePath && Array.isArray(views)) { + includePath = resolvePaths(path4, views); + } + if (!includePath && typeof options.includer !== "function") { + throw new Error('Could not find the include file "' + options.escapeFunction(path4) + '"'); + } + } + return includePath; + } + function handleCache(options, template) { + var func; + var filename = options.filename; + var hasTemplate = arguments.length > 1; + if (options.cache) { + if (!filename) { + throw new Error("cache option requires a filename"); + } + func = exports2.cache.get(filename); + if (func) { + return func; + } + if (!hasTemplate) { + template = fileLoader(filename).toString().replace(_BOM, ""); + } + } else if (!hasTemplate) { + if (!filename) { + throw new Error("Internal EJS error: no file name or template provided"); + } + template = fileLoader(filename).toString().replace(_BOM, ""); + } + func = exports2.compile(template, options); + if (options.cache) { + exports2.cache.set(filename, func); + } + return func; + } + function tryHandleCache(options, data, cb) { + var result; + if (!cb) { + if (typeof exports2.promiseImpl == "function") { + return new exports2.promiseImpl(function(resolve, reject) { + try { + result = handleCache(options)(data); + resolve(result); + } catch (err) { + reject(err); + } + }); + } else { + throw new Error("Please provide a callback function"); + } + } else { + try { + result = handleCache(options)(data); + } catch (err) { + return cb(err); + } + cb(null, result); + } + } + function fileLoader(filePath) { + return exports2.fileLoader(filePath); + } + function includeFile(path4, options) { + var opts = utils.shallowCopy(utils.createNullProtoObjWherePossible(), options); + opts.filename = getIncludePath(path4, opts); + if (typeof options.includer === "function") { + var includerResult = options.includer(path4, opts.filename); + if (includerResult) { + if (includerResult.filename) { + opts.filename = includerResult.filename; + } + if (includerResult.template) { + return handleCache(opts, includerResult.template); + } + } + } + return handleCache(opts); + } + function rethrow(err, str, flnm, lineno, esc) { + var lines = str.split("\n"); + var start = Math.max(lineno - 3, 0); + var end = Math.min(lines.length, lineno + 3); + var filename = esc(flnm); + var context = lines.slice(start, end).map(function(line, i) { + var curr = i + start + 1; + return (curr == lineno ? " >> " : " ") + curr + "| " + line; + }).join("\n"); + err.path = filename; + err.message = (filename || "ejs") + ":" + lineno + "\n" + context + "\n\n" + err.message; + throw err; + } + function stripSemi(str) { + return str.replace(/;(\s*$)/, "$1"); + } + exports2.compile = function compile(template, opts) { + var templ; + if (opts && opts.scope) { + if (!scopeOptionWarned) { + console.warn("`scope` option is deprecated and will be removed in EJS 3"); + scopeOptionWarned = true; + } + if (!opts.context) { + opts.context = opts.scope; + } + delete opts.scope; + } + templ = new Template(template, opts); + return templ.compile(); + }; + exports2.render = function(template, d, o) { + var data = d || utils.createNullProtoObjWherePossible(); + var opts = o || utils.createNullProtoObjWherePossible(); + if (arguments.length == 2) { + utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA); + } + return handleCache(opts, template)(data); + }; + exports2.renderFile = function() { + var args = Array.prototype.slice.call(arguments); + var filename = args.shift(); + var cb; + var opts = { filename }; + var data; + var viewOpts; + if (typeof arguments[arguments.length - 1] == "function") { + cb = args.pop(); + } + if (args.length) { + data = args.shift(); + if (args.length) { + utils.shallowCopy(opts, args.pop()); + } else { + if (data.settings) { + if (data.settings.views) { + opts.views = data.settings.views; + } + if (data.settings["view cache"]) { + opts.cache = true; + } + viewOpts = data.settings["view options"]; + if (viewOpts) { + utils.shallowCopy(opts, viewOpts); + } + } + utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS); + } + opts.filename = filename; + } else { + data = utils.createNullProtoObjWherePossible(); + } + return tryHandleCache(opts, data, cb); + }; + exports2.Template = Template; + exports2.clearCache = function() { + exports2.cache.reset(); + }; + function Template(text, optsParam) { + var opts = utils.hasOwnOnlyObject(optsParam); + var options = utils.createNullProtoObjWherePossible(); + this.templateText = text; + this.mode = null; + this.truncate = false; + this.currentLine = 1; + this.source = ""; + options.client = opts.client || false; + options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML; + options.compileDebug = opts.compileDebug !== false; + options.debug = !!opts.debug; + options.filename = opts.filename; + options.openDelimiter = opts.openDelimiter || exports2.openDelimiter || _DEFAULT_OPEN_DELIMITER; + options.closeDelimiter = opts.closeDelimiter || exports2.closeDelimiter || _DEFAULT_CLOSE_DELIMITER; + options.delimiter = opts.delimiter || exports2.delimiter || _DEFAULT_DELIMITER; + options.strict = opts.strict || false; + options.context = opts.context; + options.cache = opts.cache || false; + options.rmWhitespace = opts.rmWhitespace; + options.root = opts.root; + options.includer = opts.includer; + options.outputFunctionName = opts.outputFunctionName; + options.localsName = opts.localsName || exports2.localsName || _DEFAULT_LOCALS_NAME; + options.views = opts.views; + options.async = opts.async; + options.destructuredLocals = opts.destructuredLocals; + options.legacyInclude = typeof opts.legacyInclude != "undefined" ? !!opts.legacyInclude : true; + if (options.strict) { + options._with = false; + } else { + options._with = typeof opts._with != "undefined" ? opts._with : true; + } + this.opts = options; + this.regex = this.createRegex(); + } + Template.modes = { + EVAL: "eval", + ESCAPED: "escaped", + RAW: "raw", + COMMENT: "comment", + LITERAL: "literal" + }; + Template.prototype = { + createRegex: function() { + var str = _REGEX_STRING; + var delim = utils.escapeRegExpChars(this.opts.delimiter); + var open2 = utils.escapeRegExpChars(this.opts.openDelimiter); + var close = utils.escapeRegExpChars(this.opts.closeDelimiter); + str = str.replace(/%/g, delim).replace(//g, close); + return new RegExp(str); + }, + compile: function() { + var src; + var fn; + var opts = this.opts; + var prepended = ""; + var appended = ""; + var escapeFn = opts.escapeFunction; + var ctor; + var sanitizedFilename = opts.filename ? JSON.stringify(opts.filename) : "undefined"; + if (!this.source) { + this.generateSource(); + prepended += ' var __output = "";\n function __append(s) { if (s !== undefined && s !== null) __output += s }\n'; + if (opts.outputFunctionName) { + if (!_JS_IDENTIFIER.test(opts.outputFunctionName)) { + throw new Error("outputFunctionName is not a valid JS identifier."); + } + prepended += " var " + opts.outputFunctionName + " = __append;\n"; + } + if (opts.localsName && !_JS_IDENTIFIER.test(opts.localsName)) { + throw new Error("localsName is not a valid JS identifier."); + } + if (opts.destructuredLocals && opts.destructuredLocals.length) { + var destructuring = " var __locals = (" + opts.localsName + " || {}),\n"; + for (var i = 0; i < opts.destructuredLocals.length; i++) { + var name = opts.destructuredLocals[i]; + if (!_JS_IDENTIFIER.test(name)) { + throw new Error("destructuredLocals[" + i + "] is not a valid JS identifier."); + } + if (i > 0) { + destructuring += ",\n "; + } + destructuring += name + " = __locals." + name; + } + prepended += destructuring + ";\n"; + } + if (opts._with !== false) { + prepended += " with (" + opts.localsName + " || {}) {\n"; + appended += " }\n"; + } + appended += " return __output;\n"; + this.source = prepended + this.source + appended; + } + if (opts.compileDebug) { + src = "var __line = 1\n , __lines = " + JSON.stringify(this.templateText) + "\n , __filename = " + sanitizedFilename + ";\ntry {\n" + this.source + "} catch (e) {\n rethrow(e, __lines, __filename, __line, escapeFn);\n}\n"; + } else { + src = this.source; + } + if (opts.client) { + src = "escapeFn = escapeFn || " + escapeFn.toString() + ";\n" + src; + if (opts.compileDebug) { + src = "rethrow = rethrow || " + rethrow.toString() + ";\n" + src; + } + } + if (opts.strict) { + src = '"use strict";\n' + src; + } + if (opts.debug) { + console.log(src); + } + if (opts.compileDebug && opts.filename) { + src = src + "\n//# sourceURL=" + sanitizedFilename + "\n"; + } + try { + if (opts.async) { + try { + ctor = new Function("return (async function(){}).constructor;")(); + } catch (e) { + if (e instanceof SyntaxError) { + throw new Error("This environment does not support async/await"); + } else { + throw e; + } + } + } else { + ctor = Function; + } + fn = new ctor(opts.localsName + ", escapeFn, include, rethrow", src); + } catch (e) { + if (e instanceof SyntaxError) { + if (opts.filename) { + e.message += " in " + opts.filename; + } + e.message += " while compiling ejs\n\n"; + e.message += "If the above error is not helpful, you may want to try EJS-Lint:\n"; + e.message += "https://github.com/RyanZim/EJS-Lint"; + if (!opts.async) { + e.message += "\n"; + e.message += "Or, if you meant to create an async function, pass `async: true` as an option."; + } + } + throw e; + } + var returnedFn = opts.client ? fn : function anonymous(data) { + var include = function(path4, includeData) { + var d = utils.shallowCopy(utils.createNullProtoObjWherePossible(), data); + if (includeData) { + d = utils.shallowCopy(d, includeData); + } + return includeFile(path4, opts)(d); + }; + return fn.apply( + opts.context, + [data || utils.createNullProtoObjWherePossible(), escapeFn, include, rethrow] + ); + }; + if (opts.filename && typeof Object.defineProperty === "function") { + var filename = opts.filename; + var basename = path3.basename(filename, path3.extname(filename)); + try { + Object.defineProperty(returnedFn, "name", { + value: basename, + writable: false, + enumerable: false, + configurable: true + }); + } catch (e) { + } + } + return returnedFn; + }, + generateSource: function() { + var opts = this.opts; + if (opts.rmWhitespace) { + this.templateText = this.templateText.replace(/[\r\n]+/g, "\n").replace(/^\s+|\s+$/gm, ""); + } + this.templateText = this.templateText.replace(/[ \t]*<%_/gm, "<%_").replace(/_%>[ \t]*/gm, "_%>"); + var self2 = this; + var matches = this.parseTemplateText(); + var d = this.opts.delimiter; + var o = this.opts.openDelimiter; + var c = this.opts.closeDelimiter; + if (matches && matches.length) { + matches.forEach(function(line, index) { + var closing; + if (line.indexOf(o + d) === 0 && line.indexOf(o + d + d) !== 0) { + closing = matches[index + 2]; + if (!(closing == d + c || closing == "-" + d + c || closing == "_" + d + c)) { + throw new Error('Could not find matching close tag for "' + line + '".'); + } + } + self2.scanLine(line); + }); + } + }, + parseTemplateText: function() { + var str = this.templateText; + var pat = this.regex; + var result = pat.exec(str); + var arr = []; + var firstPos; + while (result) { + firstPos = result.index; + if (firstPos !== 0) { + arr.push(str.substring(0, firstPos)); + str = str.slice(firstPos); + } + arr.push(result[0]); + str = str.slice(result[0].length); + result = pat.exec(str); + } + if (str) { + arr.push(str); + } + return arr; + }, + _addOutput: function(line) { + if (this.truncate) { + line = line.replace(/^(?:\r\n|\r|\n)/, ""); + this.truncate = false; + } + if (!line) { + return line; + } + line = line.replace(/\\/g, "\\\\"); + line = line.replace(/\n/g, "\\n"); + line = line.replace(/\r/g, "\\r"); + line = line.replace(/"/g, '\\"'); + this.source += ' ; __append("' + line + '")\n'; + }, + scanLine: function(line) { + var self2 = this; + var d = this.opts.delimiter; + var o = this.opts.openDelimiter; + var c = this.opts.closeDelimiter; + var newLineCount = 0; + newLineCount = line.split("\n").length - 1; + switch (line) { + case o + d: + case o + d + "_": + this.mode = Template.modes.EVAL; + break; + case o + d + "=": + this.mode = Template.modes.ESCAPED; + break; + case o + d + "-": + this.mode = Template.modes.RAW; + break; + case o + d + "#": + this.mode = Template.modes.COMMENT; + break; + case o + d + d: + this.mode = Template.modes.LITERAL; + this.source += ' ; __append("' + line.replace(o + d + d, o + d) + '")\n'; + break; + case d + d + c: + this.mode = Template.modes.LITERAL; + this.source += ' ; __append("' + line.replace(d + d + c, d + c) + '")\n'; + break; + case d + c: + case "-" + d + c: + case "_" + d + c: + if (this.mode == Template.modes.LITERAL) { + this._addOutput(line); + } + this.mode = null; + this.truncate = line.indexOf("-") === 0 || line.indexOf("_") === 0; + break; + default: + if (this.mode) { + switch (this.mode) { + case Template.modes.EVAL: + case Template.modes.ESCAPED: + case Template.modes.RAW: + if (line.lastIndexOf("//") > line.lastIndexOf("\n")) { + line += "\n"; + } + } + switch (this.mode) { + // Just executing code + case Template.modes.EVAL: + this.source += " ; " + line + "\n"; + break; + // Exec, esc, and output + case Template.modes.ESCAPED: + this.source += " ; __append(escapeFn(" + stripSemi(line) + "))\n"; + break; + // Exec and output + case Template.modes.RAW: + this.source += " ; __append(" + stripSemi(line) + ")\n"; + break; + case Template.modes.COMMENT: + break; + // Literal <%% mode, append as raw output + case Template.modes.LITERAL: + this._addOutput(line); + break; + } + } else { + this._addOutput(line); + } + } + if (self2.opts.compileDebug && newLineCount) { + this.currentLine += newLineCount; + this.source += " ; __line = " + this.currentLine + "\n"; + } + } + }; + exports2.escapeXML = utils.escapeXML; + exports2.__express = exports2.renderFile; + exports2.VERSION = _VERSION_STRING; + exports2.name = _NAME; + if (typeof window != "undefined") { + window.ejs = exports2; + } + } +}); + +// node_modules/zod/v3/helpers/util.cjs +var require_util = __commonJS({ + "node_modules/zod/v3/helpers/util.cjs"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getParsedType = exports2.ZodParsedType = exports2.objectUtil = exports2.util = void 0; + var util; + (function(util2) { + util2.assertEqual = (_) => { + }; + function assertIs(_arg) { + } + util2.assertIs = assertIs; + function assertNever(_x) { + throw new Error(); + } + util2.assertNever = assertNever; + util2.arrayToEnum = (items) => { + const obj = {}; + for (const item of items) { + obj[item] = item; + } + return obj; + }; + util2.getValidEnumValues = (obj) => { + const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number"); + const filtered = {}; + for (const k of validKeys) { + filtered[k] = obj[k]; + } + return util2.objectValues(filtered); + }; + util2.objectValues = (obj) => { + return util2.objectKeys(obj).map(function(e) { + return obj[e]; + }); + }; + util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => { + const keys = []; + for (const key in object) { + if (Object.prototype.hasOwnProperty.call(object, key)) { + keys.push(key); + } + } + return keys; + }; + util2.find = (arr, checker) => { + for (const item of arr) { + if (checker(item)) + return item; + } + return void 0; + }; + util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val; + function joinValues(array, separator = " | ") { + return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator); + } + util2.joinValues = joinValues; + util2.jsonStringifyReplacer = (_, value) => { + if (typeof value === "bigint") { + return value.toString(); + } + return value; + }; + })(util || (exports2.util = util = {})); + var objectUtil; + (function(objectUtil2) { + objectUtil2.mergeShapes = (first, second) => { + return { + ...first, + ...second + // second overwrites first + }; + }; + })(objectUtil || (exports2.objectUtil = objectUtil = {})); + exports2.ZodParsedType = util.arrayToEnum([ + "string", + "nan", + "number", + "integer", + "float", + "boolean", + "date", + "bigint", + "symbol", + "function", + "undefined", + "null", + "array", + "object", + "unknown", + "promise", + "void", + "never", + "map", + "set" + ]); + var getParsedType = (data) => { + const t = typeof data; + switch (t) { + case "undefined": + return exports2.ZodParsedType.undefined; + case "string": + return exports2.ZodParsedType.string; + case "number": + return Number.isNaN(data) ? exports2.ZodParsedType.nan : exports2.ZodParsedType.number; + case "boolean": + return exports2.ZodParsedType.boolean; + case "function": + return exports2.ZodParsedType.function; + case "bigint": + return exports2.ZodParsedType.bigint; + case "symbol": + return exports2.ZodParsedType.symbol; + case "object": + if (Array.isArray(data)) { + return exports2.ZodParsedType.array; + } + if (data === null) { + return exports2.ZodParsedType.null; + } + if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") { + return exports2.ZodParsedType.promise; + } + if (typeof Map !== "undefined" && data instanceof Map) { + return exports2.ZodParsedType.map; + } + if (typeof Set !== "undefined" && data instanceof Set) { + return exports2.ZodParsedType.set; + } + if (typeof Date !== "undefined" && data instanceof Date) { + return exports2.ZodParsedType.date; + } + return exports2.ZodParsedType.object; + default: + return exports2.ZodParsedType.unknown; + } + }; + exports2.getParsedType = getParsedType; + } +}); + +// node_modules/zod/v3/ZodError.cjs +var require_ZodError = __commonJS({ + "node_modules/zod/v3/ZodError.cjs"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ZodError = exports2.quotelessJson = exports2.ZodIssueCode = void 0; + var util_js_1 = require_util(); + exports2.ZodIssueCode = util_js_1.util.arrayToEnum([ + "invalid_type", + "invalid_literal", + "custom", + "invalid_union", + "invalid_union_discriminator", + "invalid_enum_value", + "unrecognized_keys", + "invalid_arguments", + "invalid_return_type", + "invalid_date", + "invalid_string", + "too_small", + "too_big", + "invalid_intersection_types", + "not_multiple_of", + "not_finite" + ]); + var quotelessJson = (obj) => { + const json = JSON.stringify(obj, null, 2); + return json.replace(/"([^"]+)":/g, "$1:"); + }; + exports2.quotelessJson = quotelessJson; + var ZodError = class _ZodError extends Error { + get errors() { + return this.issues; + } + constructor(issues) { + super(); + this.issues = []; + this.addIssue = (sub) => { + this.issues = [...this.issues, sub]; + }; + this.addIssues = (subs = []) => { + this.issues = [...this.issues, ...subs]; + }; + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + Object.setPrototypeOf(this, actualProto); + } else { + this.__proto__ = actualProto; + } + this.name = "ZodError"; + this.issues = issues; + } + format(_mapper) { + const mapper = _mapper || function(issue) { + return issue.message; + }; + const fieldErrors = { _errors: [] }; + const processError = (error) => { + for (const issue of error.issues) { + if (issue.code === "invalid_union") { + issue.unionErrors.map(processError); + } else if (issue.code === "invalid_return_type") { + processError(issue.returnTypeError); + } else if (issue.code === "invalid_arguments") { + processError(issue.argumentsError); + } else if (issue.path.length === 0) { + fieldErrors._errors.push(mapper(issue)); + } else { + let curr = fieldErrors; + let i = 0; + while (i < issue.path.length) { + const el = issue.path[i]; + const terminal = i === issue.path.length - 1; + if (!terminal) { + curr[el] = curr[el] || { _errors: [] }; + } else { + curr[el] = curr[el] || { _errors: [] }; + curr[el]._errors.push(mapper(issue)); + } + curr = curr[el]; + i++; + } + } + } + }; + processError(this); + return fieldErrors; + } + static assert(value) { + if (!(value instanceof _ZodError)) { + throw new Error(`Not a ZodError: ${value}`); + } + } + toString() { + return this.message; + } + get message() { + return JSON.stringify(this.issues, util_js_1.util.jsonStringifyReplacer, 2); + } + get isEmpty() { + return this.issues.length === 0; + } + flatten(mapper = (issue) => issue.message) { + const fieldErrors = {}; + const formErrors = []; + for (const sub of this.issues) { + if (sub.path.length > 0) { + const firstEl = sub.path[0]; + fieldErrors[firstEl] = fieldErrors[firstEl] || []; + fieldErrors[firstEl].push(mapper(sub)); + } else { + formErrors.push(mapper(sub)); + } + } + return { formErrors, fieldErrors }; + } + get formErrors() { + return this.flatten(); + } + }; + exports2.ZodError = ZodError; + ZodError.create = (issues) => { + const error = new ZodError(issues); + return error; + }; + } +}); + +// node_modules/zod/v3/locales/en.cjs +var require_en = __commonJS({ + "node_modules/zod/v3/locales/en.cjs"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + var ZodError_js_1 = require_ZodError(); + var util_js_1 = require_util(); + var errorMap = (issue, _ctx) => { + let message; + switch (issue.code) { + case ZodError_js_1.ZodIssueCode.invalid_type: + if (issue.received === util_js_1.ZodParsedType.undefined) { + message = "Required"; + } else { + message = `Expected ${issue.expected}, received ${issue.received}`; + } + break; + case ZodError_js_1.ZodIssueCode.invalid_literal: + message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util_js_1.util.jsonStringifyReplacer)}`; + break; + case ZodError_js_1.ZodIssueCode.unrecognized_keys: + message = `Unrecognized key(s) in object: ${util_js_1.util.joinValues(issue.keys, ", ")}`; + break; + case ZodError_js_1.ZodIssueCode.invalid_union: + message = `Invalid input`; + break; + case ZodError_js_1.ZodIssueCode.invalid_union_discriminator: + message = `Invalid discriminator value. Expected ${util_js_1.util.joinValues(issue.options)}`; + break; + case ZodError_js_1.ZodIssueCode.invalid_enum_value: + message = `Invalid enum value. Expected ${util_js_1.util.joinValues(issue.options)}, received '${issue.received}'`; + break; + case ZodError_js_1.ZodIssueCode.invalid_arguments: + message = `Invalid function arguments`; + break; + case ZodError_js_1.ZodIssueCode.invalid_return_type: + message = `Invalid function return type`; + break; + case ZodError_js_1.ZodIssueCode.invalid_date: + message = `Invalid date`; + break; + case ZodError_js_1.ZodIssueCode.invalid_string: + if (typeof issue.validation === "object") { + if ("includes" in issue.validation) { + message = `Invalid input: must include "${issue.validation.includes}"`; + if (typeof issue.validation.position === "number") { + message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`; + } + } else if ("startsWith" in issue.validation) { + message = `Invalid input: must start with "${issue.validation.startsWith}"`; + } else if ("endsWith" in issue.validation) { + message = `Invalid input: must end with "${issue.validation.endsWith}"`; + } else { + util_js_1.util.assertNever(issue.validation); + } + } else if (issue.validation !== "regex") { + message = `Invalid ${issue.validation}`; + } else { + message = "Invalid"; + } + break; + case ZodError_js_1.ZodIssueCode.too_small: + if (issue.type === "array") + message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`; + else if (issue.type === "string") + message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`; + else if (issue.type === "number") + message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`; + else if (issue.type === "bigint") + message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`; + else if (issue.type === "date") + message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`; + else + message = "Invalid input"; + break; + case ZodError_js_1.ZodIssueCode.too_big: + if (issue.type === "array") + message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`; + else if (issue.type === "string") + message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`; + else if (issue.type === "number") + message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`; + else if (issue.type === "bigint") + message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`; + else if (issue.type === "date") + message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`; + else + message = "Invalid input"; + break; + case ZodError_js_1.ZodIssueCode.custom: + message = `Invalid input`; + break; + case ZodError_js_1.ZodIssueCode.invalid_intersection_types: + message = `Intersection results could not be merged`; + break; + case ZodError_js_1.ZodIssueCode.not_multiple_of: + message = `Number must be a multiple of ${issue.multipleOf}`; + break; + case ZodError_js_1.ZodIssueCode.not_finite: + message = "Number must be finite"; + break; + default: + message = _ctx.defaultError; + util_js_1.util.assertNever(issue); + } + return { message }; + }; + exports2.default = errorMap; + } +}); + +// node_modules/zod/v3/errors.cjs +var require_errors = __commonJS({ + "node_modules/zod/v3/errors.cjs"(exports2) { + "use strict"; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.defaultErrorMap = void 0; + exports2.setErrorMap = setErrorMap; + exports2.getErrorMap = getErrorMap; + var en_js_1 = __importDefault2(require_en()); + exports2.defaultErrorMap = en_js_1.default; + var overrideErrorMap = en_js_1.default; + function setErrorMap(map) { + overrideErrorMap = map; + } + function getErrorMap() { + return overrideErrorMap; + } + } +}); + +// node_modules/zod/v3/helpers/parseUtil.cjs +var require_parseUtil = __commonJS({ + "node_modules/zod/v3/helpers/parseUtil.cjs"(exports2) { + "use strict"; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isAsync = exports2.isValid = exports2.isDirty = exports2.isAborted = exports2.OK = exports2.DIRTY = exports2.INVALID = exports2.ParseStatus = exports2.EMPTY_PATH = exports2.makeIssue = void 0; + exports2.addIssueToContext = addIssueToContext; + var errors_js_1 = require_errors(); + var en_js_1 = __importDefault2(require_en()); + var makeIssue = (params) => { + const { data, path: path3, errorMaps, issueData } = params; + const fullPath = [...path3, ...issueData.path || []]; + const fullIssue = { + ...issueData, + path: fullPath + }; + if (issueData.message !== void 0) { + return { + ...issueData, + path: fullPath, + message: issueData.message + }; + } + let errorMessage = ""; + const maps = errorMaps.filter((m) => !!m).slice().reverse(); + for (const map of maps) { + errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message; + } + return { + ...issueData, + path: fullPath, + message: errorMessage + }; + }; + exports2.makeIssue = makeIssue; + exports2.EMPTY_PATH = []; + function addIssueToContext(ctx, issueData) { + const overrideMap = (0, errors_js_1.getErrorMap)(); + const issue = (0, exports2.makeIssue)({ + issueData, + data: ctx.data, + path: ctx.path, + errorMaps: [ + ctx.common.contextualErrorMap, + // contextual error map is first priority + ctx.schemaErrorMap, + // then schema-bound map if available + overrideMap, + // then global override map + overrideMap === en_js_1.default ? void 0 : en_js_1.default + // then global default map + ].filter((x) => !!x) + }); + ctx.common.issues.push(issue); + } + var ParseStatus = class _ParseStatus { + constructor() { + this.value = "valid"; + } + dirty() { + if (this.value === "valid") + this.value = "dirty"; + } + abort() { + if (this.value !== "aborted") + this.value = "aborted"; + } + static mergeArray(status, results) { + const arrayValue = []; + for (const s of results) { + if (s.status === "aborted") + return exports2.INVALID; + if (s.status === "dirty") + status.dirty(); + arrayValue.push(s.value); + } + return { status: status.value, value: arrayValue }; + } + static async mergeObjectAsync(status, pairs) { + const syncPairs = []; + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + syncPairs.push({ + key, + value + }); + } + return _ParseStatus.mergeObjectSync(status, syncPairs); + } + static mergeObjectSync(status, pairs) { + const finalObject = {}; + for (const pair of pairs) { + const { key, value } = pair; + if (key.status === "aborted") + return exports2.INVALID; + if (value.status === "aborted") + return exports2.INVALID; + if (key.status === "dirty") + status.dirty(); + if (value.status === "dirty") + status.dirty(); + if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) { + finalObject[key.value] = value.value; + } + } + return { status: status.value, value: finalObject }; + } + }; + exports2.ParseStatus = ParseStatus; + exports2.INVALID = Object.freeze({ + status: "aborted" + }); + var DIRTY = (value) => ({ status: "dirty", value }); + exports2.DIRTY = DIRTY; + var OK = (value) => ({ status: "valid", value }); + exports2.OK = OK; + var isAborted = (x) => x.status === "aborted"; + exports2.isAborted = isAborted; + var isDirty = (x) => x.status === "dirty"; + exports2.isDirty = isDirty; + var isValid = (x) => x.status === "valid"; + exports2.isValid = isValid; + var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise; + exports2.isAsync = isAsync; + } +}); + +// node_modules/zod/v3/helpers/typeAliases.cjs +var require_typeAliases = __commonJS({ + "node_modules/zod/v3/helpers/typeAliases.cjs"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/zod/v3/helpers/errorUtil.cjs +var require_errorUtil = __commonJS({ + "node_modules/zod/v3/helpers/errorUtil.cjs"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.errorUtil = void 0; + var errorUtil; + (function(errorUtil2) { + errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {}; + errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message; + })(errorUtil || (exports2.errorUtil = errorUtil = {})); + } +}); + +// node_modules/zod/v3/types.cjs +var require_types2 = __commonJS({ + "node_modules/zod/v3/types.cjs"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.discriminatedUnion = exports2.date = exports2.boolean = exports2.bigint = exports2.array = exports2.any = exports2.coerce = exports2.ZodFirstPartyTypeKind = exports2.late = exports2.ZodSchema = exports2.Schema = exports2.ZodReadonly = exports2.ZodPipeline = exports2.ZodBranded = exports2.BRAND = exports2.ZodNaN = exports2.ZodCatch = exports2.ZodDefault = exports2.ZodNullable = exports2.ZodOptional = exports2.ZodTransformer = exports2.ZodEffects = exports2.ZodPromise = exports2.ZodNativeEnum = exports2.ZodEnum = exports2.ZodLiteral = exports2.ZodLazy = exports2.ZodFunction = exports2.ZodSet = exports2.ZodMap = exports2.ZodRecord = exports2.ZodTuple = exports2.ZodIntersection = exports2.ZodDiscriminatedUnion = exports2.ZodUnion = exports2.ZodObject = exports2.ZodArray = exports2.ZodVoid = exports2.ZodNever = exports2.ZodUnknown = exports2.ZodAny = exports2.ZodNull = exports2.ZodUndefined = exports2.ZodSymbol = exports2.ZodDate = exports2.ZodBoolean = exports2.ZodBigInt = exports2.ZodNumber = exports2.ZodString = exports2.ZodType = void 0; + exports2.NEVER = exports2.void = exports2.unknown = exports2.union = exports2.undefined = exports2.tuple = exports2.transformer = exports2.symbol = exports2.string = exports2.strictObject = exports2.set = exports2.record = exports2.promise = exports2.preprocess = exports2.pipeline = exports2.ostring = exports2.optional = exports2.onumber = exports2.oboolean = exports2.object = exports2.number = exports2.nullable = exports2.null = exports2.never = exports2.nativeEnum = exports2.nan = exports2.map = exports2.literal = exports2.lazy = exports2.intersection = exports2.instanceof = exports2.function = exports2.enum = exports2.effect = void 0; + exports2.datetimeRegex = datetimeRegex; + exports2.custom = custom; + var ZodError_js_1 = require_ZodError(); + var errors_js_1 = require_errors(); + var errorUtil_js_1 = require_errorUtil(); + var parseUtil_js_1 = require_parseUtil(); + var util_js_1 = require_util(); + var ParseInputLazyPath = class { + constructor(parent, value, path3, key) { + this._cachedPath = []; + this.parent = parent; + this.data = value; + this._path = path3; + this._key = key; + } + get path() { + if (!this._cachedPath.length) { + if (Array.isArray(this._key)) { + this._cachedPath.push(...this._path, ...this._key); + } else { + this._cachedPath.push(...this._path, this._key); + } + } + return this._cachedPath; + } + }; + var handleResult = (ctx, result) => { + if ((0, parseUtil_js_1.isValid)(result)) { + return { success: true, data: result.value }; + } else { + if (!ctx.common.issues.length) { + throw new Error("Validation failed but no issues detected."); + } + return { + success: false, + get error() { + if (this._error) + return this._error; + const error = new ZodError_js_1.ZodError(ctx.common.issues); + this._error = error; + return this._error; + } + }; + } + }; + function processCreateParams(params) { + if (!params) + return {}; + const { errorMap, invalid_type_error, required_error, description } = params; + if (errorMap && (invalid_type_error || required_error)) { + throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`); + } + if (errorMap) + return { errorMap, description }; + const customMap = (iss, ctx) => { + const { message } = params; + if (iss.code === "invalid_enum_value") { + return { message: message ?? ctx.defaultError }; + } + if (typeof ctx.data === "undefined") { + return { message: message ?? required_error ?? ctx.defaultError }; + } + if (iss.code !== "invalid_type") + return { message: ctx.defaultError }; + return { message: message ?? invalid_type_error ?? ctx.defaultError }; + }; + return { errorMap: customMap, description }; + } + var ZodType = class { + get description() { + return this._def.description; + } + _getType(input) { + return (0, util_js_1.getParsedType)(input.data); + } + _getOrReturnCtx(input, ctx) { + return ctx || { + common: input.parent.common, + data: input.data, + parsedType: (0, util_js_1.getParsedType)(input.data), + schemaErrorMap: this._def.errorMap, + path: input.path, + parent: input.parent + }; + } + _processInputParams(input) { + return { + status: new parseUtil_js_1.ParseStatus(), + ctx: { + common: input.parent.common, + data: input.data, + parsedType: (0, util_js_1.getParsedType)(input.data), + schemaErrorMap: this._def.errorMap, + path: input.path, + parent: input.parent + } + }; + } + _parseSync(input) { + const result = this._parse(input); + if ((0, parseUtil_js_1.isAsync)(result)) { + throw new Error("Synchronous parse encountered promise."); + } + return result; + } + _parseAsync(input) { + const result = this._parse(input); + return Promise.resolve(result); + } + parse(data, params) { + const result = this.safeParse(data, params); + if (result.success) + return result.data; + throw result.error; + } + safeParse(data, params) { + const ctx = { + common: { + issues: [], + async: params?.async ?? false, + contextualErrorMap: params?.errorMap + }, + path: params?.path || [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: (0, util_js_1.getParsedType)(data) + }; + const result = this._parseSync({ data, path: ctx.path, parent: ctx }); + return handleResult(ctx, result); + } + "~validate"(data) { + const ctx = { + common: { + issues: [], + async: !!this["~standard"].async + }, + path: [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: (0, util_js_1.getParsedType)(data) + }; + if (!this["~standard"].async) { + try { + const result = this._parseSync({ data, path: [], parent: ctx }); + return (0, parseUtil_js_1.isValid)(result) ? { + value: result.value + } : { + issues: ctx.common.issues + }; + } catch (err) { + if (err?.message?.toLowerCase()?.includes("encountered")) { + this["~standard"].async = true; + } + ctx.common = { + issues: [], + async: true + }; + } + } + return this._parseAsync({ data, path: [], parent: ctx }).then((result) => (0, parseUtil_js_1.isValid)(result) ? { + value: result.value + } : { + issues: ctx.common.issues + }); + } + async parseAsync(data, params) { + const result = await this.safeParseAsync(data, params); + if (result.success) + return result.data; + throw result.error; + } + async safeParseAsync(data, params) { + const ctx = { + common: { + issues: [], + contextualErrorMap: params?.errorMap, + async: true + }, + path: params?.path || [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: (0, util_js_1.getParsedType)(data) + }; + const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx }); + const result = await ((0, parseUtil_js_1.isAsync)(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult)); + return handleResult(ctx, result); + } + refine(check, message) { + const getIssueProperties = (val) => { + if (typeof message === "string" || typeof message === "undefined") { + return { message }; + } else if (typeof message === "function") { + return message(val); + } else { + return message; + } + }; + return this._refinement((val, ctx) => { + const result = check(val); + const setError = () => ctx.addIssue({ + code: ZodError_js_1.ZodIssueCode.custom, + ...getIssueProperties(val) + }); + if (typeof Promise !== "undefined" && result instanceof Promise) { + return result.then((data) => { + if (!data) { + setError(); + return false; + } else { + return true; + } + }); + } + if (!result) { + setError(); + return false; + } else { + return true; + } + }); + } + refinement(check, refinementData) { + return this._refinement((val, ctx) => { + if (!check(val)) { + ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData); + return false; + } else { + return true; + } + }); + } + _refinement(refinement) { + return new ZodEffects({ + schema: this, + typeName: ZodFirstPartyTypeKind.ZodEffects, + effect: { type: "refinement", refinement } + }); + } + superRefine(refinement) { + return this._refinement(refinement); + } + constructor(def) { + this.spa = this.safeParseAsync; + this._def = def; + this.parse = this.parse.bind(this); + this.safeParse = this.safeParse.bind(this); + this.parseAsync = this.parseAsync.bind(this); + this.safeParseAsync = this.safeParseAsync.bind(this); + this.spa = this.spa.bind(this); + this.refine = this.refine.bind(this); + this.refinement = this.refinement.bind(this); + this.superRefine = this.superRefine.bind(this); + this.optional = this.optional.bind(this); + this.nullable = this.nullable.bind(this); + this.nullish = this.nullish.bind(this); + this.array = this.array.bind(this); + this.promise = this.promise.bind(this); + this.or = this.or.bind(this); + this.and = this.and.bind(this); + this.transform = this.transform.bind(this); + this.brand = this.brand.bind(this); + this.default = this.default.bind(this); + this.catch = this.catch.bind(this); + this.describe = this.describe.bind(this); + this.pipe = this.pipe.bind(this); + this.readonly = this.readonly.bind(this); + this.isNullable = this.isNullable.bind(this); + this.isOptional = this.isOptional.bind(this); + this["~standard"] = { + version: 1, + vendor: "zod", + validate: (data) => this["~validate"](data) + }; + } + optional() { + return ZodOptional.create(this, this._def); + } + nullable() { + return ZodNullable.create(this, this._def); + } + nullish() { + return this.nullable().optional(); + } + array() { + return ZodArray.create(this); + } + promise() { + return ZodPromise.create(this, this._def); + } + or(option) { + return ZodUnion.create([this, option], this._def); + } + and(incoming) { + return ZodIntersection.create(this, incoming, this._def); + } + transform(transform) { + return new ZodEffects({ + ...processCreateParams(this._def), + schema: this, + typeName: ZodFirstPartyTypeKind.ZodEffects, + effect: { type: "transform", transform } + }); + } + default(def) { + const defaultValueFunc = typeof def === "function" ? def : () => def; + return new ZodDefault({ + ...processCreateParams(this._def), + innerType: this, + defaultValue: defaultValueFunc, + typeName: ZodFirstPartyTypeKind.ZodDefault + }); + } + brand() { + return new ZodBranded({ + typeName: ZodFirstPartyTypeKind.ZodBranded, + type: this, + ...processCreateParams(this._def) + }); + } + catch(def) { + const catchValueFunc = typeof def === "function" ? def : () => def; + return new ZodCatch({ + ...processCreateParams(this._def), + innerType: this, + catchValue: catchValueFunc, + typeName: ZodFirstPartyTypeKind.ZodCatch + }); + } + describe(description) { + const This = this.constructor; + return new This({ + ...this._def, + description + }); + } + pipe(target) { + return ZodPipeline.create(this, target); + } + readonly() { + return ZodReadonly.create(this); + } + isOptional() { + return this.safeParse(void 0).success; + } + isNullable() { + return this.safeParse(null).success; + } + }; + exports2.ZodType = ZodType; + exports2.Schema = ZodType; + exports2.ZodSchema = ZodType; + var cuidRegex = /^c[^\s-]{8,}$/i; + var cuid2Regex = /^[0-9a-z]+$/; + var ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i; + var uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i; + var nanoidRegex = /^[a-z0-9_-]{21}$/i; + var jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/; + var durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/; + var emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; + var _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`; + var emojiRegex; + var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/; + var ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/; + var ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/; + var ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/; + var base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; + var base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/; + var dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`; + var dateRegex = new RegExp(`^${dateRegexSource}$`); + function timeRegexSource(args) { + let secondsRegexSource = `[0-5]\\d`; + if (args.precision) { + secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`; + } else if (args.precision == null) { + secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`; + } + const secondsQuantifier = args.precision ? "+" : "?"; + return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`; + } + function timeRegex(args) { + return new RegExp(`^${timeRegexSource(args)}$`); + } + function datetimeRegex(args) { + let regex = `${dateRegexSource}T${timeRegexSource(args)}`; + const opts = []; + opts.push(args.local ? `Z?` : `Z`); + if (args.offset) + opts.push(`([+-]\\d{2}:?\\d{2})`); + regex = `${regex}(${opts.join("|")})`; + return new RegExp(`^${regex}$`); + } + function isValidIP(ip, version4) { + if ((version4 === "v4" || !version4) && ipv4Regex.test(ip)) { + return true; + } + if ((version4 === "v6" || !version4) && ipv6Regex.test(ip)) { + return true; + } + return false; + } + function isValidJWT(jwt, alg) { + if (!jwtRegex.test(jwt)) + return false; + try { + const [header] = jwt.split("."); + if (!header) + return false; + const base64 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "="); + const decoded = JSON.parse(atob(base64)); + if (typeof decoded !== "object" || decoded === null) + return false; + if ("typ" in decoded && decoded?.typ !== "JWT") + return false; + if (!decoded.alg) + return false; + if (alg && decoded.alg !== alg) + return false; + return true; + } catch { + return false; + } + } + function isValidCidr(ip, version4) { + if ((version4 === "v4" || !version4) && ipv4CidrRegex.test(ip)) { + return true; + } + if ((version4 === "v6" || !version4) && ipv6CidrRegex.test(ip)) { + return true; + } + return false; + } + var ZodString = class _ZodString extends ZodType { + _parse(input) { + if (this._def.coerce) { + input.data = String(input.data); + } + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.string) { + const ctx2 = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx2, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.string, + received: ctx2.parsedType + }); + return parseUtil_js_1.INVALID; + } + const status = new parseUtil_js_1.ParseStatus(); + let ctx = void 0; + for (const check of this._def.checks) { + if (check.kind === "min") { + if (input.data.length < check.value) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_small, + minimum: check.value, + type: "string", + inclusive: true, + exact: false, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "max") { + if (input.data.length > check.value) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_big, + maximum: check.value, + type: "string", + inclusive: true, + exact: false, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "length") { + const tooBig = input.data.length > check.value; + const tooSmall = input.data.length < check.value; + if (tooBig || tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + if (tooBig) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_big, + maximum: check.value, + type: "string", + inclusive: true, + exact: true, + message: check.message + }); + } else if (tooSmall) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_small, + minimum: check.value, + type: "string", + inclusive: true, + exact: true, + message: check.message + }); + } + status.dirty(); + } + } else if (check.kind === "email") { + if (!emailRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "email", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "emoji") { + if (!emojiRegex) { + emojiRegex = new RegExp(_emojiRegex, "u"); + } + if (!emojiRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "emoji", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "uuid") { + if (!uuidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "uuid", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "nanoid") { + if (!nanoidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "nanoid", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "cuid") { + if (!cuidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "cuid", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "cuid2") { + if (!cuid2Regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "cuid2", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "ulid") { + if (!ulidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "ulid", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "url") { + try { + new URL(input.data); + } catch { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "url", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "regex") { + check.regex.lastIndex = 0; + const testResult = check.regex.test(input.data); + if (!testResult) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "regex", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "trim") { + input.data = input.data.trim(); + } else if (check.kind === "includes") { + if (!input.data.includes(check.value, check.position)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_string, + validation: { includes: check.value, position: check.position }, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "toLowerCase") { + input.data = input.data.toLowerCase(); + } else if (check.kind === "toUpperCase") { + input.data = input.data.toUpperCase(); + } else if (check.kind === "startsWith") { + if (!input.data.startsWith(check.value)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_string, + validation: { startsWith: check.value }, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "endsWith") { + if (!input.data.endsWith(check.value)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_string, + validation: { endsWith: check.value }, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "datetime") { + const regex = datetimeRegex(check); + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_string, + validation: "datetime", + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "date") { + const regex = dateRegex; + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_string, + validation: "date", + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "time") { + const regex = timeRegex(check); + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_string, + validation: "time", + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "duration") { + if (!durationRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "duration", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "ip") { + if (!isValidIP(input.data, check.version)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "ip", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "jwt") { + if (!isValidJWT(input.data, check.alg)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "jwt", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "cidr") { + if (!isValidCidr(input.data, check.version)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "cidr", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "base64") { + if (!base64Regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "base64", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "base64url") { + if (!base64urlRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + validation: "base64url", + code: ZodError_js_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } + } else { + util_js_1.util.assertNever(check); + } + } + return { status: status.value, value: input.data }; + } + _regex(regex, validation, message) { + return this.refinement((data) => regex.test(data), { + validation, + code: ZodError_js_1.ZodIssueCode.invalid_string, + ...errorUtil_js_1.errorUtil.errToObj(message) + }); + } + _addCheck(check) { + return new _ZodString({ + ...this._def, + checks: [...this._def.checks, check] + }); + } + email(message) { + return this._addCheck({ kind: "email", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + url(message) { + return this._addCheck({ kind: "url", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + emoji(message) { + return this._addCheck({ kind: "emoji", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + uuid(message) { + return this._addCheck({ kind: "uuid", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + nanoid(message) { + return this._addCheck({ kind: "nanoid", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + cuid(message) { + return this._addCheck({ kind: "cuid", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + cuid2(message) { + return this._addCheck({ kind: "cuid2", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + ulid(message) { + return this._addCheck({ kind: "ulid", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + base64(message) { + return this._addCheck({ kind: "base64", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + base64url(message) { + return this._addCheck({ + kind: "base64url", + ...errorUtil_js_1.errorUtil.errToObj(message) + }); + } + jwt(options) { + return this._addCheck({ kind: "jwt", ...errorUtil_js_1.errorUtil.errToObj(options) }); + } + ip(options) { + return this._addCheck({ kind: "ip", ...errorUtil_js_1.errorUtil.errToObj(options) }); + } + cidr(options) { + return this._addCheck({ kind: "cidr", ...errorUtil_js_1.errorUtil.errToObj(options) }); + } + datetime(options) { + if (typeof options === "string") { + return this._addCheck({ + kind: "datetime", + precision: null, + offset: false, + local: false, + message: options + }); + } + return this._addCheck({ + kind: "datetime", + precision: typeof options?.precision === "undefined" ? null : options?.precision, + offset: options?.offset ?? false, + local: options?.local ?? false, + ...errorUtil_js_1.errorUtil.errToObj(options?.message) + }); + } + date(message) { + return this._addCheck({ kind: "date", message }); + } + time(options) { + if (typeof options === "string") { + return this._addCheck({ + kind: "time", + precision: null, + message: options + }); + } + return this._addCheck({ + kind: "time", + precision: typeof options?.precision === "undefined" ? null : options?.precision, + ...errorUtil_js_1.errorUtil.errToObj(options?.message) + }); + } + duration(message) { + return this._addCheck({ kind: "duration", ...errorUtil_js_1.errorUtil.errToObj(message) }); + } + regex(regex, message) { + return this._addCheck({ + kind: "regex", + regex, + ...errorUtil_js_1.errorUtil.errToObj(message) + }); + } + includes(value, options) { + return this._addCheck({ + kind: "includes", + value, + position: options?.position, + ...errorUtil_js_1.errorUtil.errToObj(options?.message) + }); + } + startsWith(value, message) { + return this._addCheck({ + kind: "startsWith", + value, + ...errorUtil_js_1.errorUtil.errToObj(message) + }); + } + endsWith(value, message) { + return this._addCheck({ + kind: "endsWith", + value, + ...errorUtil_js_1.errorUtil.errToObj(message) + }); + } + min(minLength, message) { + return this._addCheck({ + kind: "min", + value: minLength, + ...errorUtil_js_1.errorUtil.errToObj(message) + }); + } + max(maxLength, message) { + return this._addCheck({ + kind: "max", + value: maxLength, + ...errorUtil_js_1.errorUtil.errToObj(message) + }); + } + length(len, message) { + return this._addCheck({ + kind: "length", + value: len, + ...errorUtil_js_1.errorUtil.errToObj(message) + }); + } + /** + * Equivalent to `.min(1)` + */ + nonempty(message) { + return this.min(1, errorUtil_js_1.errorUtil.errToObj(message)); + } + trim() { + return new _ZodString({ + ...this._def, + checks: [...this._def.checks, { kind: "trim" }] + }); + } + toLowerCase() { + return new _ZodString({ + ...this._def, + checks: [...this._def.checks, { kind: "toLowerCase" }] + }); + } + toUpperCase() { + return new _ZodString({ + ...this._def, + checks: [...this._def.checks, { kind: "toUpperCase" }] + }); + } + get isDatetime() { + return !!this._def.checks.find((ch) => ch.kind === "datetime"); + } + get isDate() { + return !!this._def.checks.find((ch) => ch.kind === "date"); + } + get isTime() { + return !!this._def.checks.find((ch) => ch.kind === "time"); + } + get isDuration() { + return !!this._def.checks.find((ch) => ch.kind === "duration"); + } + get isEmail() { + return !!this._def.checks.find((ch) => ch.kind === "email"); + } + get isURL() { + return !!this._def.checks.find((ch) => ch.kind === "url"); + } + get isEmoji() { + return !!this._def.checks.find((ch) => ch.kind === "emoji"); + } + get isUUID() { + return !!this._def.checks.find((ch) => ch.kind === "uuid"); + } + get isNANOID() { + return !!this._def.checks.find((ch) => ch.kind === "nanoid"); + } + get isCUID() { + return !!this._def.checks.find((ch) => ch.kind === "cuid"); + } + get isCUID2() { + return !!this._def.checks.find((ch) => ch.kind === "cuid2"); + } + get isULID() { + return !!this._def.checks.find((ch) => ch.kind === "ulid"); + } + get isIP() { + return !!this._def.checks.find((ch) => ch.kind === "ip"); + } + get isCIDR() { + return !!this._def.checks.find((ch) => ch.kind === "cidr"); + } + get isBase64() { + return !!this._def.checks.find((ch) => ch.kind === "base64"); + } + get isBase64url() { + return !!this._def.checks.find((ch) => ch.kind === "base64url"); + } + get minLength() { + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) + min = ch.value; + } + } + return min; + } + get maxLength() { + let max = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) + max = ch.value; + } + } + return max; + } + }; + exports2.ZodString = ZodString; + ZodString.create = (params) => { + return new ZodString({ + checks: [], + typeName: ZodFirstPartyTypeKind.ZodString, + coerce: params?.coerce ?? false, + ...processCreateParams(params) + }); + }; + function floatSafeRemainder(val, step) { + const valDecCount = (val.toString().split(".")[1] || "").length; + const stepDecCount = (step.toString().split(".")[1] || "").length; + const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount; + const valInt = Number.parseInt(val.toFixed(decCount).replace(".", "")); + const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", "")); + return valInt % stepInt / 10 ** decCount; + } + var ZodNumber = class _ZodNumber extends ZodType { + constructor() { + super(...arguments); + this.min = this.gte; + this.max = this.lte; + this.step = this.multipleOf; + } + _parse(input) { + if (this._def.coerce) { + input.data = Number(input.data); + } + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.number) { + const ctx2 = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx2, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.number, + received: ctx2.parsedType + }); + return parseUtil_js_1.INVALID; + } + let ctx = void 0; + const status = new parseUtil_js_1.ParseStatus(); + for (const check of this._def.checks) { + if (check.kind === "int") { + if (!util_js_1.util.isInteger(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: "integer", + received: "float", + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "min") { + const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value; + if (tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_small, + minimum: check.value, + type: "number", + inclusive: check.inclusive, + exact: false, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "max") { + const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value; + if (tooBig) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_big, + maximum: check.value, + type: "number", + inclusive: check.inclusive, + exact: false, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "multipleOf") { + if (floatSafeRemainder(input.data, check.value) !== 0) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.not_multiple_of, + multipleOf: check.value, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "finite") { + if (!Number.isFinite(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.not_finite, + message: check.message + }); + status.dirty(); + } + } else { + util_js_1.util.assertNever(check); + } + } + return { status: status.value, value: input.data }; + } + gte(value, message) { + return this.setLimit("min", value, true, errorUtil_js_1.errorUtil.toString(message)); + } + gt(value, message) { + return this.setLimit("min", value, false, errorUtil_js_1.errorUtil.toString(message)); + } + lte(value, message) { + return this.setLimit("max", value, true, errorUtil_js_1.errorUtil.toString(message)); + } + lt(value, message) { + return this.setLimit("max", value, false, errorUtil_js_1.errorUtil.toString(message)); + } + setLimit(kind, value, inclusive, message) { + return new _ZodNumber({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind, + value, + inclusive, + message: errorUtil_js_1.errorUtil.toString(message) + } + ] + }); + } + _addCheck(check) { + return new _ZodNumber({ + ...this._def, + checks: [...this._def.checks, check] + }); + } + int(message) { + return this._addCheck({ + kind: "int", + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + positive(message) { + return this._addCheck({ + kind: "min", + value: 0, + inclusive: false, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + negative(message) { + return this._addCheck({ + kind: "max", + value: 0, + inclusive: false, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + nonpositive(message) { + return this._addCheck({ + kind: "max", + value: 0, + inclusive: true, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + nonnegative(message) { + return this._addCheck({ + kind: "min", + value: 0, + inclusive: true, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + multipleOf(value, message) { + return this._addCheck({ + kind: "multipleOf", + value, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + finite(message) { + return this._addCheck({ + kind: "finite", + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + safe(message) { + return this._addCheck({ + kind: "min", + inclusive: true, + value: Number.MIN_SAFE_INTEGER, + message: errorUtil_js_1.errorUtil.toString(message) + })._addCheck({ + kind: "max", + inclusive: true, + value: Number.MAX_SAFE_INTEGER, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + get minValue() { + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) + min = ch.value; + } + } + return min; + } + get maxValue() { + let max = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) + max = ch.value; + } + } + return max; + } + get isInt() { + return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util_js_1.util.isInteger(ch.value)); + } + get isFinite() { + let max = null; + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") { + return true; + } else if (ch.kind === "min") { + if (min === null || ch.value > min) + min = ch.value; + } else if (ch.kind === "max") { + if (max === null || ch.value < max) + max = ch.value; + } + } + return Number.isFinite(min) && Number.isFinite(max); + } + }; + exports2.ZodNumber = ZodNumber; + ZodNumber.create = (params) => { + return new ZodNumber({ + checks: [], + typeName: ZodFirstPartyTypeKind.ZodNumber, + coerce: params?.coerce || false, + ...processCreateParams(params) + }); + }; + var ZodBigInt = class _ZodBigInt extends ZodType { + constructor() { + super(...arguments); + this.min = this.gte; + this.max = this.lte; + } + _parse(input) { + if (this._def.coerce) { + try { + input.data = BigInt(input.data); + } catch { + return this._getInvalidInput(input); + } + } + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.bigint) { + return this._getInvalidInput(input); + } + let ctx = void 0; + const status = new parseUtil_js_1.ParseStatus(); + for (const check of this._def.checks) { + if (check.kind === "min") { + const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value; + if (tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_small, + type: "bigint", + minimum: check.value, + inclusive: check.inclusive, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "max") { + const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value; + if (tooBig) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_big, + type: "bigint", + maximum: check.value, + inclusive: check.inclusive, + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "multipleOf") { + if (input.data % check.value !== BigInt(0)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.not_multiple_of, + multipleOf: check.value, + message: check.message + }); + status.dirty(); + } + } else { + util_js_1.util.assertNever(check); + } + } + return { status: status.value, value: input.data }; + } + _getInvalidInput(input) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.bigint, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + gte(value, message) { + return this.setLimit("min", value, true, errorUtil_js_1.errorUtil.toString(message)); + } + gt(value, message) { + return this.setLimit("min", value, false, errorUtil_js_1.errorUtil.toString(message)); + } + lte(value, message) { + return this.setLimit("max", value, true, errorUtil_js_1.errorUtil.toString(message)); + } + lt(value, message) { + return this.setLimit("max", value, false, errorUtil_js_1.errorUtil.toString(message)); + } + setLimit(kind, value, inclusive, message) { + return new _ZodBigInt({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind, + value, + inclusive, + message: errorUtil_js_1.errorUtil.toString(message) + } + ] + }); + } + _addCheck(check) { + return new _ZodBigInt({ + ...this._def, + checks: [...this._def.checks, check] + }); + } + positive(message) { + return this._addCheck({ + kind: "min", + value: BigInt(0), + inclusive: false, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + negative(message) { + return this._addCheck({ + kind: "max", + value: BigInt(0), + inclusive: false, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + nonpositive(message) { + return this._addCheck({ + kind: "max", + value: BigInt(0), + inclusive: true, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + nonnegative(message) { + return this._addCheck({ + kind: "min", + value: BigInt(0), + inclusive: true, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + multipleOf(value, message) { + return this._addCheck({ + kind: "multipleOf", + value, + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + get minValue() { + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) + min = ch.value; + } + } + return min; + } + get maxValue() { + let max = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) + max = ch.value; + } + } + return max; + } + }; + exports2.ZodBigInt = ZodBigInt; + ZodBigInt.create = (params) => { + return new ZodBigInt({ + checks: [], + typeName: ZodFirstPartyTypeKind.ZodBigInt, + coerce: params?.coerce ?? false, + ...processCreateParams(params) + }); + }; + var ZodBoolean = class extends ZodType { + _parse(input) { + if (this._def.coerce) { + input.data = Boolean(input.data); + } + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.boolean) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.boolean, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + return (0, parseUtil_js_1.OK)(input.data); + } + }; + exports2.ZodBoolean = ZodBoolean; + ZodBoolean.create = (params) => { + return new ZodBoolean({ + typeName: ZodFirstPartyTypeKind.ZodBoolean, + coerce: params?.coerce || false, + ...processCreateParams(params) + }); + }; + var ZodDate = class _ZodDate extends ZodType { + _parse(input) { + if (this._def.coerce) { + input.data = new Date(input.data); + } + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.date) { + const ctx2 = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx2, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.date, + received: ctx2.parsedType + }); + return parseUtil_js_1.INVALID; + } + if (Number.isNaN(input.data.getTime())) { + const ctx2 = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx2, { + code: ZodError_js_1.ZodIssueCode.invalid_date + }); + return parseUtil_js_1.INVALID; + } + const status = new parseUtil_js_1.ParseStatus(); + let ctx = void 0; + for (const check of this._def.checks) { + if (check.kind === "min") { + if (input.data.getTime() < check.value) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_small, + message: check.message, + inclusive: true, + exact: false, + minimum: check.value, + type: "date" + }); + status.dirty(); + } + } else if (check.kind === "max") { + if (input.data.getTime() > check.value) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_big, + message: check.message, + inclusive: true, + exact: false, + maximum: check.value, + type: "date" + }); + status.dirty(); + } + } else { + util_js_1.util.assertNever(check); + } + } + return { + status: status.value, + value: new Date(input.data.getTime()) + }; + } + _addCheck(check) { + return new _ZodDate({ + ...this._def, + checks: [...this._def.checks, check] + }); + } + min(minDate, message) { + return this._addCheck({ + kind: "min", + value: minDate.getTime(), + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + max(maxDate, message) { + return this._addCheck({ + kind: "max", + value: maxDate.getTime(), + message: errorUtil_js_1.errorUtil.toString(message) + }); + } + get minDate() { + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) + min = ch.value; + } + } + return min != null ? new Date(min) : null; + } + get maxDate() { + let max = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) + max = ch.value; + } + } + return max != null ? new Date(max) : null; + } + }; + exports2.ZodDate = ZodDate; + ZodDate.create = (params) => { + return new ZodDate({ + checks: [], + coerce: params?.coerce || false, + typeName: ZodFirstPartyTypeKind.ZodDate, + ...processCreateParams(params) + }); + }; + var ZodSymbol = class extends ZodType { + _parse(input) { + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.symbol) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.symbol, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + return (0, parseUtil_js_1.OK)(input.data); + } + }; + exports2.ZodSymbol = ZodSymbol; + ZodSymbol.create = (params) => { + return new ZodSymbol({ + typeName: ZodFirstPartyTypeKind.ZodSymbol, + ...processCreateParams(params) + }); + }; + var ZodUndefined = class extends ZodType { + _parse(input) { + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.undefined) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.undefined, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + return (0, parseUtil_js_1.OK)(input.data); + } + }; + exports2.ZodUndefined = ZodUndefined; + ZodUndefined.create = (params) => { + return new ZodUndefined({ + typeName: ZodFirstPartyTypeKind.ZodUndefined, + ...processCreateParams(params) + }); + }; + var ZodNull = class extends ZodType { + _parse(input) { + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.null) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.null, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + return (0, parseUtil_js_1.OK)(input.data); + } + }; + exports2.ZodNull = ZodNull; + ZodNull.create = (params) => { + return new ZodNull({ + typeName: ZodFirstPartyTypeKind.ZodNull, + ...processCreateParams(params) + }); + }; + var ZodAny = class extends ZodType { + constructor() { + super(...arguments); + this._any = true; + } + _parse(input) { + return (0, parseUtil_js_1.OK)(input.data); + } + }; + exports2.ZodAny = ZodAny; + ZodAny.create = (params) => { + return new ZodAny({ + typeName: ZodFirstPartyTypeKind.ZodAny, + ...processCreateParams(params) + }); + }; + var ZodUnknown = class extends ZodType { + constructor() { + super(...arguments); + this._unknown = true; + } + _parse(input) { + return (0, parseUtil_js_1.OK)(input.data); + } + }; + exports2.ZodUnknown = ZodUnknown; + ZodUnknown.create = (params) => { + return new ZodUnknown({ + typeName: ZodFirstPartyTypeKind.ZodUnknown, + ...processCreateParams(params) + }); + }; + var ZodNever = class extends ZodType { + _parse(input) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.never, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + }; + exports2.ZodNever = ZodNever; + ZodNever.create = (params) => { + return new ZodNever({ + typeName: ZodFirstPartyTypeKind.ZodNever, + ...processCreateParams(params) + }); + }; + var ZodVoid = class extends ZodType { + _parse(input) { + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.undefined) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.void, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + return (0, parseUtil_js_1.OK)(input.data); + } + }; + exports2.ZodVoid = ZodVoid; + ZodVoid.create = (params) => { + return new ZodVoid({ + typeName: ZodFirstPartyTypeKind.ZodVoid, + ...processCreateParams(params) + }); + }; + var ZodArray = class _ZodArray extends ZodType { + _parse(input) { + const { ctx, status } = this._processInputParams(input); + const def = this._def; + if (ctx.parsedType !== util_js_1.ZodParsedType.array) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.array, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + if (def.exactLength !== null) { + const tooBig = ctx.data.length > def.exactLength.value; + const tooSmall = ctx.data.length < def.exactLength.value; + if (tooBig || tooSmall) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: tooBig ? ZodError_js_1.ZodIssueCode.too_big : ZodError_js_1.ZodIssueCode.too_small, + minimum: tooSmall ? def.exactLength.value : void 0, + maximum: tooBig ? def.exactLength.value : void 0, + type: "array", + inclusive: true, + exact: true, + message: def.exactLength.message + }); + status.dirty(); + } + } + if (def.minLength !== null) { + if (ctx.data.length < def.minLength.value) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_small, + minimum: def.minLength.value, + type: "array", + inclusive: true, + exact: false, + message: def.minLength.message + }); + status.dirty(); + } + } + if (def.maxLength !== null) { + if (ctx.data.length > def.maxLength.value) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_big, + maximum: def.maxLength.value, + type: "array", + inclusive: true, + exact: false, + message: def.maxLength.message + }); + status.dirty(); + } + } + if (ctx.common.async) { + return Promise.all([...ctx.data].map((item, i) => { + return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i)); + })).then((result2) => { + return parseUtil_js_1.ParseStatus.mergeArray(status, result2); + }); + } + const result = [...ctx.data].map((item, i) => { + return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i)); + }); + return parseUtil_js_1.ParseStatus.mergeArray(status, result); + } + get element() { + return this._def.type; + } + min(minLength, message) { + return new _ZodArray({ + ...this._def, + minLength: { value: minLength, message: errorUtil_js_1.errorUtil.toString(message) } + }); + } + max(maxLength, message) { + return new _ZodArray({ + ...this._def, + maxLength: { value: maxLength, message: errorUtil_js_1.errorUtil.toString(message) } + }); + } + length(len, message) { + return new _ZodArray({ + ...this._def, + exactLength: { value: len, message: errorUtil_js_1.errorUtil.toString(message) } + }); + } + nonempty(message) { + return this.min(1, message); + } + }; + exports2.ZodArray = ZodArray; + ZodArray.create = (schema, params) => { + return new ZodArray({ + type: schema, + minLength: null, + maxLength: null, + exactLength: null, + typeName: ZodFirstPartyTypeKind.ZodArray, + ...processCreateParams(params) + }); + }; + function deepPartialify(schema) { + if (schema instanceof ZodObject) { + const newShape = {}; + for (const key in schema.shape) { + const fieldSchema = schema.shape[key]; + newShape[key] = ZodOptional.create(deepPartialify(fieldSchema)); + } + return new ZodObject({ + ...schema._def, + shape: () => newShape + }); + } else if (schema instanceof ZodArray) { + return new ZodArray({ + ...schema._def, + type: deepPartialify(schema.element) + }); + } else if (schema instanceof ZodOptional) { + return ZodOptional.create(deepPartialify(schema.unwrap())); + } else if (schema instanceof ZodNullable) { + return ZodNullable.create(deepPartialify(schema.unwrap())); + } else if (schema instanceof ZodTuple) { + return ZodTuple.create(schema.items.map((item) => deepPartialify(item))); + } else { + return schema; + } + } + var ZodObject = class _ZodObject extends ZodType { + constructor() { + super(...arguments); + this._cached = null; + this.nonstrict = this.passthrough; + this.augment = this.extend; + } + _getCached() { + if (this._cached !== null) + return this._cached; + const shape = this._def.shape(); + const keys = util_js_1.util.objectKeys(shape); + this._cached = { shape, keys }; + return this._cached; + } + _parse(input) { + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.object) { + const ctx2 = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx2, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.object, + received: ctx2.parsedType + }); + return parseUtil_js_1.INVALID; + } + const { status, ctx } = this._processInputParams(input); + const { shape, keys: shapeKeys } = this._getCached(); + const extraKeys = []; + if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) { + for (const key in ctx.data) { + if (!shapeKeys.includes(key)) { + extraKeys.push(key); + } + } + } + const pairs = []; + for (const key of shapeKeys) { + const keyValidator = shape[key]; + const value = ctx.data[key]; + pairs.push({ + key: { status: "valid", value: key }, + value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)), + alwaysSet: key in ctx.data + }); + } + if (this._def.catchall instanceof ZodNever) { + const unknownKeys = this._def.unknownKeys; + if (unknownKeys === "passthrough") { + for (const key of extraKeys) { + pairs.push({ + key: { status: "valid", value: key }, + value: { status: "valid", value: ctx.data[key] } + }); + } + } else if (unknownKeys === "strict") { + if (extraKeys.length > 0) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.unrecognized_keys, + keys: extraKeys + }); + status.dirty(); + } + } else if (unknownKeys === "strip") { + } else { + throw new Error(`Internal ZodObject error: invalid unknownKeys value.`); + } + } else { + const catchall = this._def.catchall; + for (const key of extraKeys) { + const value = ctx.data[key]; + pairs.push({ + key: { status: "valid", value: key }, + value: catchall._parse( + new ParseInputLazyPath(ctx, value, ctx.path, key) + //, ctx.child(key), value, getParsedType(value) + ), + alwaysSet: key in ctx.data + }); + } + } + if (ctx.common.async) { + return Promise.resolve().then(async () => { + const syncPairs = []; + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + syncPairs.push({ + key, + value, + alwaysSet: pair.alwaysSet + }); + } + return syncPairs; + }).then((syncPairs) => { + return parseUtil_js_1.ParseStatus.mergeObjectSync(status, syncPairs); + }); + } else { + return parseUtil_js_1.ParseStatus.mergeObjectSync(status, pairs); + } + } + get shape() { + return this._def.shape(); + } + strict(message) { + errorUtil_js_1.errorUtil.errToObj; + return new _ZodObject({ + ...this._def, + unknownKeys: "strict", + ...message !== void 0 ? { + errorMap: (issue, ctx) => { + const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError; + if (issue.code === "unrecognized_keys") + return { + message: errorUtil_js_1.errorUtil.errToObj(message).message ?? defaultError + }; + return { + message: defaultError + }; + } + } : {} + }); + } + strip() { + return new _ZodObject({ + ...this._def, + unknownKeys: "strip" + }); + } + passthrough() { + return new _ZodObject({ + ...this._def, + unknownKeys: "passthrough" + }); + } + // const AugmentFactory = + // (def: Def) => + // ( + // augmentation: Augmentation + // ): ZodObject< + // extendShape, Augmentation>, + // Def["unknownKeys"], + // Def["catchall"] + // > => { + // return new ZodObject({ + // ...def, + // shape: () => ({ + // ...def.shape(), + // ...augmentation, + // }), + // }) as any; + // }; + extend(augmentation) { + return new _ZodObject({ + ...this._def, + shape: () => ({ + ...this._def.shape(), + ...augmentation + }) + }); + } + /** + * Prior to zod@1.0.12 there was a bug in the + * inferred type of merged objects. Please + * upgrade if you are experiencing issues. + */ + merge(merging) { + const merged = new _ZodObject({ + unknownKeys: merging._def.unknownKeys, + catchall: merging._def.catchall, + shape: () => ({ + ...this._def.shape(), + ...merging._def.shape() + }), + typeName: ZodFirstPartyTypeKind.ZodObject + }); + return merged; + } + // merge< + // Incoming extends AnyZodObject, + // Augmentation extends Incoming["shape"], + // NewOutput extends { + // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation + // ? Augmentation[k]["_output"] + // : k extends keyof Output + // ? Output[k] + // : never; + // }, + // NewInput extends { + // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation + // ? Augmentation[k]["_input"] + // : k extends keyof Input + // ? Input[k] + // : never; + // } + // >( + // merging: Incoming + // ): ZodObject< + // extendShape>, + // Incoming["_def"]["unknownKeys"], + // Incoming["_def"]["catchall"], + // NewOutput, + // NewInput + // > { + // const merged: any = new ZodObject({ + // unknownKeys: merging._def.unknownKeys, + // catchall: merging._def.catchall, + // shape: () => + // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), + // typeName: ZodFirstPartyTypeKind.ZodObject, + // }) as any; + // return merged; + // } + setKey(key, schema) { + return this.augment({ [key]: schema }); + } + // merge( + // merging: Incoming + // ): //ZodObject = (merging) => { + // ZodObject< + // extendShape>, + // Incoming["_def"]["unknownKeys"], + // Incoming["_def"]["catchall"] + // > { + // // const mergedShape = objectUtil.mergeShapes( + // // this._def.shape(), + // // merging._def.shape() + // // ); + // const merged: any = new ZodObject({ + // unknownKeys: merging._def.unknownKeys, + // catchall: merging._def.catchall, + // shape: () => + // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), + // typeName: ZodFirstPartyTypeKind.ZodObject, + // }) as any; + // return merged; + // } + catchall(index) { + return new _ZodObject({ + ...this._def, + catchall: index + }); + } + pick(mask) { + const shape = {}; + for (const key of util_js_1.util.objectKeys(mask)) { + if (mask[key] && this.shape[key]) { + shape[key] = this.shape[key]; + } + } + return new _ZodObject({ + ...this._def, + shape: () => shape + }); + } + omit(mask) { + const shape = {}; + for (const key of util_js_1.util.objectKeys(this.shape)) { + if (!mask[key]) { + shape[key] = this.shape[key]; + } + } + return new _ZodObject({ + ...this._def, + shape: () => shape + }); + } + /** + * @deprecated + */ + deepPartial() { + return deepPartialify(this); + } + partial(mask) { + const newShape = {}; + for (const key of util_js_1.util.objectKeys(this.shape)) { + const fieldSchema = this.shape[key]; + if (mask && !mask[key]) { + newShape[key] = fieldSchema; + } else { + newShape[key] = fieldSchema.optional(); + } + } + return new _ZodObject({ + ...this._def, + shape: () => newShape + }); + } + required(mask) { + const newShape = {}; + for (const key of util_js_1.util.objectKeys(this.shape)) { + if (mask && !mask[key]) { + newShape[key] = this.shape[key]; + } else { + const fieldSchema = this.shape[key]; + let newField = fieldSchema; + while (newField instanceof ZodOptional) { + newField = newField._def.innerType; + } + newShape[key] = newField; + } + } + return new _ZodObject({ + ...this._def, + shape: () => newShape + }); + } + keyof() { + return createZodEnum(util_js_1.util.objectKeys(this.shape)); + } + }; + exports2.ZodObject = ZodObject; + ZodObject.create = (shape, params) => { + return new ZodObject({ + shape: () => shape, + unknownKeys: "strip", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params) + }); + }; + ZodObject.strictCreate = (shape, params) => { + return new ZodObject({ + shape: () => shape, + unknownKeys: "strict", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params) + }); + }; + ZodObject.lazycreate = (shape, params) => { + return new ZodObject({ + shape, + unknownKeys: "strip", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params) + }); + }; + var ZodUnion = class extends ZodType { + _parse(input) { + const { ctx } = this._processInputParams(input); + const options = this._def.options; + function handleResults(results) { + for (const result of results) { + if (result.result.status === "valid") { + return result.result; + } + } + for (const result of results) { + if (result.result.status === "dirty") { + ctx.common.issues.push(...result.ctx.common.issues); + return result.result; + } + } + const unionErrors = results.map((result) => new ZodError_js_1.ZodError(result.ctx.common.issues)); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_union, + unionErrors + }); + return parseUtil_js_1.INVALID; + } + if (ctx.common.async) { + return Promise.all(options.map(async (option) => { + const childCtx = { + ...ctx, + common: { + ...ctx.common, + issues: [] + }, + parent: null + }; + return { + result: await option._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: childCtx + }), + ctx: childCtx + }; + })).then(handleResults); + } else { + let dirty = void 0; + const issues = []; + for (const option of options) { + const childCtx = { + ...ctx, + common: { + ...ctx.common, + issues: [] + }, + parent: null + }; + const result = option._parseSync({ + data: ctx.data, + path: ctx.path, + parent: childCtx + }); + if (result.status === "valid") { + return result; + } else if (result.status === "dirty" && !dirty) { + dirty = { result, ctx: childCtx }; + } + if (childCtx.common.issues.length) { + issues.push(childCtx.common.issues); + } + } + if (dirty) { + ctx.common.issues.push(...dirty.ctx.common.issues); + return dirty.result; + } + const unionErrors = issues.map((issues2) => new ZodError_js_1.ZodError(issues2)); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_union, + unionErrors + }); + return parseUtil_js_1.INVALID; + } + } + get options() { + return this._def.options; + } + }; + exports2.ZodUnion = ZodUnion; + ZodUnion.create = (types, params) => { + return new ZodUnion({ + options: types, + typeName: ZodFirstPartyTypeKind.ZodUnion, + ...processCreateParams(params) + }); + }; + var getDiscriminator = (type) => { + if (type instanceof ZodLazy) { + return getDiscriminator(type.schema); + } else if (type instanceof ZodEffects) { + return getDiscriminator(type.innerType()); + } else if (type instanceof ZodLiteral) { + return [type.value]; + } else if (type instanceof ZodEnum) { + return type.options; + } else if (type instanceof ZodNativeEnum) { + return util_js_1.util.objectValues(type.enum); + } else if (type instanceof ZodDefault) { + return getDiscriminator(type._def.innerType); + } else if (type instanceof ZodUndefined) { + return [void 0]; + } else if (type instanceof ZodNull) { + return [null]; + } else if (type instanceof ZodOptional) { + return [void 0, ...getDiscriminator(type.unwrap())]; + } else if (type instanceof ZodNullable) { + return [null, ...getDiscriminator(type.unwrap())]; + } else if (type instanceof ZodBranded) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodReadonly) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodCatch) { + return getDiscriminator(type._def.innerType); + } else { + return []; + } + }; + var ZodDiscriminatedUnion = class _ZodDiscriminatedUnion extends ZodType { + _parse(input) { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== util_js_1.ZodParsedType.object) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.object, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + const discriminator = this.discriminator; + const discriminatorValue = ctx.data[discriminator]; + const option = this.optionsMap.get(discriminatorValue); + if (!option) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_union_discriminator, + options: Array.from(this.optionsMap.keys()), + path: [discriminator] + }); + return parseUtil_js_1.INVALID; + } + if (ctx.common.async) { + return option._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + } else { + return option._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + } + } + get discriminator() { + return this._def.discriminator; + } + get options() { + return this._def.options; + } + get optionsMap() { + return this._def.optionsMap; + } + /** + * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor. + * However, it only allows a union of objects, all of which need to share a discriminator property. This property must + * have a different value for each object in the union. + * @param discriminator the name of the discriminator property + * @param types an array of object schemas + * @param params + */ + static create(discriminator, options, params) { + const optionsMap = /* @__PURE__ */ new Map(); + for (const type of options) { + const discriminatorValues = getDiscriminator(type.shape[discriminator]); + if (!discriminatorValues.length) { + throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`); + } + for (const value of discriminatorValues) { + if (optionsMap.has(value)) { + throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`); + } + optionsMap.set(value, type); + } + } + return new _ZodDiscriminatedUnion({ + typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion, + discriminator, + options, + optionsMap, + ...processCreateParams(params) + }); + } + }; + exports2.ZodDiscriminatedUnion = ZodDiscriminatedUnion; + function mergeValues(a, b) { + const aType = (0, util_js_1.getParsedType)(a); + const bType = (0, util_js_1.getParsedType)(b); + if (a === b) { + return { valid: true, data: a }; + } else if (aType === util_js_1.ZodParsedType.object && bType === util_js_1.ZodParsedType.object) { + const bKeys = util_js_1.util.objectKeys(b); + const sharedKeys = util_js_1.util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1); + const newObj = { ...a, ...b }; + for (const key of sharedKeys) { + const sharedValue = mergeValues(a[key], b[key]); + if (!sharedValue.valid) { + return { valid: false }; + } + newObj[key] = sharedValue.data; + } + return { valid: true, data: newObj }; + } else if (aType === util_js_1.ZodParsedType.array && bType === util_js_1.ZodParsedType.array) { + if (a.length !== b.length) { + return { valid: false }; + } + const newArray = []; + for (let index = 0; index < a.length; index++) { + const itemA = a[index]; + const itemB = b[index]; + const sharedValue = mergeValues(itemA, itemB); + if (!sharedValue.valid) { + return { valid: false }; + } + newArray.push(sharedValue.data); + } + return { valid: true, data: newArray }; + } else if (aType === util_js_1.ZodParsedType.date && bType === util_js_1.ZodParsedType.date && +a === +b) { + return { valid: true, data: a }; + } else { + return { valid: false }; + } + } + var ZodIntersection = class extends ZodType { + _parse(input) { + const { status, ctx } = this._processInputParams(input); + const handleParsed = (parsedLeft, parsedRight) => { + if ((0, parseUtil_js_1.isAborted)(parsedLeft) || (0, parseUtil_js_1.isAborted)(parsedRight)) { + return parseUtil_js_1.INVALID; + } + const merged = mergeValues(parsedLeft.value, parsedRight.value); + if (!merged.valid) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_intersection_types + }); + return parseUtil_js_1.INVALID; + } + if ((0, parseUtil_js_1.isDirty)(parsedLeft) || (0, parseUtil_js_1.isDirty)(parsedRight)) { + status.dirty(); + } + return { status: status.value, value: merged.data }; + }; + if (ctx.common.async) { + return Promise.all([ + this._def.left._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }), + this._def.right._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }) + ]).then(([left, right]) => handleParsed(left, right)); + } else { + return handleParsed(this._def.left._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }), this._def.right._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + })); + } + } + }; + exports2.ZodIntersection = ZodIntersection; + ZodIntersection.create = (left, right, params) => { + return new ZodIntersection({ + left, + right, + typeName: ZodFirstPartyTypeKind.ZodIntersection, + ...processCreateParams(params) + }); + }; + var ZodTuple = class _ZodTuple extends ZodType { + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== util_js_1.ZodParsedType.array) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.array, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + if (ctx.data.length < this._def.items.length) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_small, + minimum: this._def.items.length, + inclusive: true, + exact: false, + type: "array" + }); + return parseUtil_js_1.INVALID; + } + const rest = this._def.rest; + if (!rest && ctx.data.length > this._def.items.length) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_big, + maximum: this._def.items.length, + inclusive: true, + exact: false, + type: "array" + }); + status.dirty(); + } + const items = [...ctx.data].map((item, itemIndex) => { + const schema = this._def.items[itemIndex] || this._def.rest; + if (!schema) + return null; + return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)); + }).filter((x) => !!x); + if (ctx.common.async) { + return Promise.all(items).then((results) => { + return parseUtil_js_1.ParseStatus.mergeArray(status, results); + }); + } else { + return parseUtil_js_1.ParseStatus.mergeArray(status, items); + } + } + get items() { + return this._def.items; + } + rest(rest) { + return new _ZodTuple({ + ...this._def, + rest + }); + } + }; + exports2.ZodTuple = ZodTuple; + ZodTuple.create = (schemas, params) => { + if (!Array.isArray(schemas)) { + throw new Error("You must pass an array of schemas to z.tuple([ ... ])"); + } + return new ZodTuple({ + items: schemas, + typeName: ZodFirstPartyTypeKind.ZodTuple, + rest: null, + ...processCreateParams(params) + }); + }; + var ZodRecord = class _ZodRecord extends ZodType { + get keySchema() { + return this._def.keyType; + } + get valueSchema() { + return this._def.valueType; + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== util_js_1.ZodParsedType.object) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.object, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + const pairs = []; + const keyType = this._def.keyType; + const valueType = this._def.valueType; + for (const key in ctx.data) { + pairs.push({ + key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)), + value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)), + alwaysSet: key in ctx.data + }); + } + if (ctx.common.async) { + return parseUtil_js_1.ParseStatus.mergeObjectAsync(status, pairs); + } else { + return parseUtil_js_1.ParseStatus.mergeObjectSync(status, pairs); + } + } + get element() { + return this._def.valueType; + } + static create(first, second, third) { + if (second instanceof ZodType) { + return new _ZodRecord({ + keyType: first, + valueType: second, + typeName: ZodFirstPartyTypeKind.ZodRecord, + ...processCreateParams(third) + }); + } + return new _ZodRecord({ + keyType: ZodString.create(), + valueType: first, + typeName: ZodFirstPartyTypeKind.ZodRecord, + ...processCreateParams(second) + }); + } + }; + exports2.ZodRecord = ZodRecord; + var ZodMap = class extends ZodType { + get keySchema() { + return this._def.keyType; + } + get valueSchema() { + return this._def.valueType; + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== util_js_1.ZodParsedType.map) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.map, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + const keyType = this._def.keyType; + const valueType = this._def.valueType; + const pairs = [...ctx.data.entries()].map(([key, value], index) => { + return { + key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])), + value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"])) + }; + }); + if (ctx.common.async) { + const finalMap = /* @__PURE__ */ new Map(); + return Promise.resolve().then(async () => { + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + if (key.status === "aborted" || value.status === "aborted") { + return parseUtil_js_1.INVALID; + } + if (key.status === "dirty" || value.status === "dirty") { + status.dirty(); + } + finalMap.set(key.value, value.value); + } + return { status: status.value, value: finalMap }; + }); + } else { + const finalMap = /* @__PURE__ */ new Map(); + for (const pair of pairs) { + const key = pair.key; + const value = pair.value; + if (key.status === "aborted" || value.status === "aborted") { + return parseUtil_js_1.INVALID; + } + if (key.status === "dirty" || value.status === "dirty") { + status.dirty(); + } + finalMap.set(key.value, value.value); + } + return { status: status.value, value: finalMap }; + } + } + }; + exports2.ZodMap = ZodMap; + ZodMap.create = (keyType, valueType, params) => { + return new ZodMap({ + valueType, + keyType, + typeName: ZodFirstPartyTypeKind.ZodMap, + ...processCreateParams(params) + }); + }; + var ZodSet = class _ZodSet extends ZodType { + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== util_js_1.ZodParsedType.set) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.set, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + const def = this._def; + if (def.minSize !== null) { + if (ctx.data.size < def.minSize.value) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_small, + minimum: def.minSize.value, + type: "set", + inclusive: true, + exact: false, + message: def.minSize.message + }); + status.dirty(); + } + } + if (def.maxSize !== null) { + if (ctx.data.size > def.maxSize.value) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.too_big, + maximum: def.maxSize.value, + type: "set", + inclusive: true, + exact: false, + message: def.maxSize.message + }); + status.dirty(); + } + } + const valueType = this._def.valueType; + function finalizeSet(elements2) { + const parsedSet = /* @__PURE__ */ new Set(); + for (const element of elements2) { + if (element.status === "aborted") + return parseUtil_js_1.INVALID; + if (element.status === "dirty") + status.dirty(); + parsedSet.add(element.value); + } + return { status: status.value, value: parsedSet }; + } + const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i))); + if (ctx.common.async) { + return Promise.all(elements).then((elements2) => finalizeSet(elements2)); + } else { + return finalizeSet(elements); + } + } + min(minSize, message) { + return new _ZodSet({ + ...this._def, + minSize: { value: minSize, message: errorUtil_js_1.errorUtil.toString(message) } + }); + } + max(maxSize, message) { + return new _ZodSet({ + ...this._def, + maxSize: { value: maxSize, message: errorUtil_js_1.errorUtil.toString(message) } + }); + } + size(size, message) { + return this.min(size, message).max(size, message); + } + nonempty(message) { + return this.min(1, message); + } + }; + exports2.ZodSet = ZodSet; + ZodSet.create = (valueType, params) => { + return new ZodSet({ + valueType, + minSize: null, + maxSize: null, + typeName: ZodFirstPartyTypeKind.ZodSet, + ...processCreateParams(params) + }); + }; + var ZodFunction = class _ZodFunction extends ZodType { + constructor() { + super(...arguments); + this.validate = this.implement; + } + _parse(input) { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== util_js_1.ZodParsedType.function) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.function, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + function makeArgsIssue(args, error) { + return (0, parseUtil_js_1.makeIssue)({ + data: args, + path: ctx.path, + errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, (0, errors_js_1.getErrorMap)(), errors_js_1.defaultErrorMap].filter((x) => !!x), + issueData: { + code: ZodError_js_1.ZodIssueCode.invalid_arguments, + argumentsError: error + } + }); + } + function makeReturnsIssue(returns, error) { + return (0, parseUtil_js_1.makeIssue)({ + data: returns, + path: ctx.path, + errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, (0, errors_js_1.getErrorMap)(), errors_js_1.defaultErrorMap].filter((x) => !!x), + issueData: { + code: ZodError_js_1.ZodIssueCode.invalid_return_type, + returnTypeError: error + } + }); + } + const params = { errorMap: ctx.common.contextualErrorMap }; + const fn = ctx.data; + if (this._def.returns instanceof ZodPromise) { + const me = this; + return (0, parseUtil_js_1.OK)(async function(...args) { + const error = new ZodError_js_1.ZodError([]); + const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => { + error.addIssue(makeArgsIssue(args, e)); + throw error; + }); + const result = await Reflect.apply(fn, this, parsedArgs); + const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => { + error.addIssue(makeReturnsIssue(result, e)); + throw error; + }); + return parsedReturns; + }); + } else { + const me = this; + return (0, parseUtil_js_1.OK)(function(...args) { + const parsedArgs = me._def.args.safeParse(args, params); + if (!parsedArgs.success) { + throw new ZodError_js_1.ZodError([makeArgsIssue(args, parsedArgs.error)]); + } + const result = Reflect.apply(fn, this, parsedArgs.data); + const parsedReturns = me._def.returns.safeParse(result, params); + if (!parsedReturns.success) { + throw new ZodError_js_1.ZodError([makeReturnsIssue(result, parsedReturns.error)]); + } + return parsedReturns.data; + }); + } + } + parameters() { + return this._def.args; + } + returnType() { + return this._def.returns; + } + args(...items) { + return new _ZodFunction({ + ...this._def, + args: ZodTuple.create(items).rest(ZodUnknown.create()) + }); + } + returns(returnType) { + return new _ZodFunction({ + ...this._def, + returns: returnType + }); + } + implement(func) { + const validatedFunc = this.parse(func); + return validatedFunc; + } + strictImplement(func) { + const validatedFunc = this.parse(func); + return validatedFunc; + } + static create(args, returns, params) { + return new _ZodFunction({ + args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()), + returns: returns || ZodUnknown.create(), + typeName: ZodFirstPartyTypeKind.ZodFunction, + ...processCreateParams(params) + }); + } + }; + exports2.ZodFunction = ZodFunction; + var ZodLazy = class extends ZodType { + get schema() { + return this._def.getter(); + } + _parse(input) { + const { ctx } = this._processInputParams(input); + const lazySchema = this._def.getter(); + return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx }); + } + }; + exports2.ZodLazy = ZodLazy; + ZodLazy.create = (getter, params) => { + return new ZodLazy({ + getter, + typeName: ZodFirstPartyTypeKind.ZodLazy, + ...processCreateParams(params) + }); + }; + var ZodLiteral = class extends ZodType { + _parse(input) { + if (input.data !== this._def.value) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + received: ctx.data, + code: ZodError_js_1.ZodIssueCode.invalid_literal, + expected: this._def.value + }); + return parseUtil_js_1.INVALID; + } + return { status: "valid", value: input.data }; + } + get value() { + return this._def.value; + } + }; + exports2.ZodLiteral = ZodLiteral; + ZodLiteral.create = (value, params) => { + return new ZodLiteral({ + value, + typeName: ZodFirstPartyTypeKind.ZodLiteral, + ...processCreateParams(params) + }); + }; + function createZodEnum(values, params) { + return new ZodEnum({ + values, + typeName: ZodFirstPartyTypeKind.ZodEnum, + ...processCreateParams(params) + }); + } + var ZodEnum = class _ZodEnum extends ZodType { + _parse(input) { + if (typeof input.data !== "string") { + const ctx = this._getOrReturnCtx(input); + const expectedValues = this._def.values; + (0, parseUtil_js_1.addIssueToContext)(ctx, { + expected: util_js_1.util.joinValues(expectedValues), + received: ctx.parsedType, + code: ZodError_js_1.ZodIssueCode.invalid_type + }); + return parseUtil_js_1.INVALID; + } + if (!this._cache) { + this._cache = new Set(this._def.values); + } + if (!this._cache.has(input.data)) { + const ctx = this._getOrReturnCtx(input); + const expectedValues = this._def.values; + (0, parseUtil_js_1.addIssueToContext)(ctx, { + received: ctx.data, + code: ZodError_js_1.ZodIssueCode.invalid_enum_value, + options: expectedValues + }); + return parseUtil_js_1.INVALID; + } + return (0, parseUtil_js_1.OK)(input.data); + } + get options() { + return this._def.values; + } + get enum() { + const enumValues = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + get Values() { + const enumValues = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + get Enum() { + const enumValues = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + extract(values, newDef = this._def) { + return _ZodEnum.create(values, { + ...this._def, + ...newDef + }); + } + exclude(values, newDef = this._def) { + return _ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), { + ...this._def, + ...newDef + }); + } + }; + exports2.ZodEnum = ZodEnum; + ZodEnum.create = createZodEnum; + var ZodNativeEnum = class extends ZodType { + _parse(input) { + const nativeEnumValues = util_js_1.util.getValidEnumValues(this._def.values); + const ctx = this._getOrReturnCtx(input); + if (ctx.parsedType !== util_js_1.ZodParsedType.string && ctx.parsedType !== util_js_1.ZodParsedType.number) { + const expectedValues = util_js_1.util.objectValues(nativeEnumValues); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + expected: util_js_1.util.joinValues(expectedValues), + received: ctx.parsedType, + code: ZodError_js_1.ZodIssueCode.invalid_type + }); + return parseUtil_js_1.INVALID; + } + if (!this._cache) { + this._cache = new Set(util_js_1.util.getValidEnumValues(this._def.values)); + } + if (!this._cache.has(input.data)) { + const expectedValues = util_js_1.util.objectValues(nativeEnumValues); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + received: ctx.data, + code: ZodError_js_1.ZodIssueCode.invalid_enum_value, + options: expectedValues + }); + return parseUtil_js_1.INVALID; + } + return (0, parseUtil_js_1.OK)(input.data); + } + get enum() { + return this._def.values; + } + }; + exports2.ZodNativeEnum = ZodNativeEnum; + ZodNativeEnum.create = (values, params) => { + return new ZodNativeEnum({ + values, + typeName: ZodFirstPartyTypeKind.ZodNativeEnum, + ...processCreateParams(params) + }); + }; + var ZodPromise = class extends ZodType { + unwrap() { + return this._def.type; + } + _parse(input) { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== util_js_1.ZodParsedType.promise && ctx.common.async === false) { + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.promise, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + const promisified = ctx.parsedType === util_js_1.ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data); + return (0, parseUtil_js_1.OK)(promisified.then((data) => { + return this._def.type.parseAsync(data, { + path: ctx.path, + errorMap: ctx.common.contextualErrorMap + }); + })); + } + }; + exports2.ZodPromise = ZodPromise; + ZodPromise.create = (schema, params) => { + return new ZodPromise({ + type: schema, + typeName: ZodFirstPartyTypeKind.ZodPromise, + ...processCreateParams(params) + }); + }; + var ZodEffects = class extends ZodType { + innerType() { + return this._def.schema; + } + sourceType() { + return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema; + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + const effect = this._def.effect || null; + const checkCtx = { + addIssue: (arg) => { + (0, parseUtil_js_1.addIssueToContext)(ctx, arg); + if (arg.fatal) { + status.abort(); + } else { + status.dirty(); + } + }, + get path() { + return ctx.path; + } + }; + checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx); + if (effect.type === "preprocess") { + const processed = effect.transform(ctx.data, checkCtx); + if (ctx.common.async) { + return Promise.resolve(processed).then(async (processed2) => { + if (status.value === "aborted") + return parseUtil_js_1.INVALID; + const result = await this._def.schema._parseAsync({ + data: processed2, + path: ctx.path, + parent: ctx + }); + if (result.status === "aborted") + return parseUtil_js_1.INVALID; + if (result.status === "dirty") + return (0, parseUtil_js_1.DIRTY)(result.value); + if (status.value === "dirty") + return (0, parseUtil_js_1.DIRTY)(result.value); + return result; + }); + } else { + if (status.value === "aborted") + return parseUtil_js_1.INVALID; + const result = this._def.schema._parseSync({ + data: processed, + path: ctx.path, + parent: ctx + }); + if (result.status === "aborted") + return parseUtil_js_1.INVALID; + if (result.status === "dirty") + return (0, parseUtil_js_1.DIRTY)(result.value); + if (status.value === "dirty") + return (0, parseUtil_js_1.DIRTY)(result.value); + return result; + } + } + if (effect.type === "refinement") { + const executeRefinement = (acc) => { + const result = effect.refinement(acc, checkCtx); + if (ctx.common.async) { + return Promise.resolve(result); + } + if (result instanceof Promise) { + throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead."); + } + return acc; + }; + if (ctx.common.async === false) { + const inner = this._def.schema._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inner.status === "aborted") + return parseUtil_js_1.INVALID; + if (inner.status === "dirty") + status.dirty(); + executeRefinement(inner.value); + return { status: status.value, value: inner.value }; + } else { + return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => { + if (inner.status === "aborted") + return parseUtil_js_1.INVALID; + if (inner.status === "dirty") + status.dirty(); + return executeRefinement(inner.value).then(() => { + return { status: status.value, value: inner.value }; + }); + }); + } + } + if (effect.type === "transform") { + if (ctx.common.async === false) { + const base = this._def.schema._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (!(0, parseUtil_js_1.isValid)(base)) + return parseUtil_js_1.INVALID; + const result = effect.transform(base.value, checkCtx); + if (result instanceof Promise) { + throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`); + } + return { status: status.value, value: result }; + } else { + return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => { + if (!(0, parseUtil_js_1.isValid)(base)) + return parseUtil_js_1.INVALID; + return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ + status: status.value, + value: result + })); + }); + } + } + util_js_1.util.assertNever(effect); + } + }; + exports2.ZodEffects = ZodEffects; + exports2.ZodTransformer = ZodEffects; + ZodEffects.create = (schema, effect, params) => { + return new ZodEffects({ + schema, + typeName: ZodFirstPartyTypeKind.ZodEffects, + effect, + ...processCreateParams(params) + }); + }; + ZodEffects.createWithPreprocess = (preprocess, schema, params) => { + return new ZodEffects({ + schema, + effect: { type: "preprocess", transform: preprocess }, + typeName: ZodFirstPartyTypeKind.ZodEffects, + ...processCreateParams(params) + }); + }; + var ZodOptional = class extends ZodType { + _parse(input) { + const parsedType = this._getType(input); + if (parsedType === util_js_1.ZodParsedType.undefined) { + return (0, parseUtil_js_1.OK)(void 0); + } + return this._def.innerType._parse(input); + } + unwrap() { + return this._def.innerType; + } + }; + exports2.ZodOptional = ZodOptional; + ZodOptional.create = (type, params) => { + return new ZodOptional({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodOptional, + ...processCreateParams(params) + }); + }; + var ZodNullable = class extends ZodType { + _parse(input) { + const parsedType = this._getType(input); + if (parsedType === util_js_1.ZodParsedType.null) { + return (0, parseUtil_js_1.OK)(null); + } + return this._def.innerType._parse(input); + } + unwrap() { + return this._def.innerType; + } + }; + exports2.ZodNullable = ZodNullable; + ZodNullable.create = (type, params) => { + return new ZodNullable({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodNullable, + ...processCreateParams(params) + }); + }; + var ZodDefault = class extends ZodType { + _parse(input) { + const { ctx } = this._processInputParams(input); + let data = ctx.data; + if (ctx.parsedType === util_js_1.ZodParsedType.undefined) { + data = this._def.defaultValue(); + } + return this._def.innerType._parse({ + data, + path: ctx.path, + parent: ctx + }); + } + removeDefault() { + return this._def.innerType; + } + }; + exports2.ZodDefault = ZodDefault; + ZodDefault.create = (type, params) => { + return new ZodDefault({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodDefault, + defaultValue: typeof params.default === "function" ? params.default : () => params.default, + ...processCreateParams(params) + }); + }; + var ZodCatch = class extends ZodType { + _parse(input) { + const { ctx } = this._processInputParams(input); + const newCtx = { + ...ctx, + common: { + ...ctx.common, + issues: [] + } + }; + const result = this._def.innerType._parse({ + data: newCtx.data, + path: newCtx.path, + parent: { + ...newCtx + } + }); + if ((0, parseUtil_js_1.isAsync)(result)) { + return result.then((result2) => { + return { + status: "valid", + value: result2.status === "valid" ? result2.value : this._def.catchValue({ + get error() { + return new ZodError_js_1.ZodError(newCtx.common.issues); + }, + input: newCtx.data + }) + }; + }); + } else { + return { + status: "valid", + value: result.status === "valid" ? result.value : this._def.catchValue({ + get error() { + return new ZodError_js_1.ZodError(newCtx.common.issues); + }, + input: newCtx.data + }) + }; + } + } + removeCatch() { + return this._def.innerType; + } + }; + exports2.ZodCatch = ZodCatch; + ZodCatch.create = (type, params) => { + return new ZodCatch({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodCatch, + catchValue: typeof params.catch === "function" ? params.catch : () => params.catch, + ...processCreateParams(params) + }); + }; + var ZodNaN = class extends ZodType { + _parse(input) { + const parsedType = this._getType(input); + if (parsedType !== util_js_1.ZodParsedType.nan) { + const ctx = this._getOrReturnCtx(input); + (0, parseUtil_js_1.addIssueToContext)(ctx, { + code: ZodError_js_1.ZodIssueCode.invalid_type, + expected: util_js_1.ZodParsedType.nan, + received: ctx.parsedType + }); + return parseUtil_js_1.INVALID; + } + return { status: "valid", value: input.data }; + } + }; + exports2.ZodNaN = ZodNaN; + ZodNaN.create = (params) => { + return new ZodNaN({ + typeName: ZodFirstPartyTypeKind.ZodNaN, + ...processCreateParams(params) + }); + }; + exports2.BRAND = Symbol("zod_brand"); + var ZodBranded = class extends ZodType { + _parse(input) { + const { ctx } = this._processInputParams(input); + const data = ctx.data; + return this._def.type._parse({ + data, + path: ctx.path, + parent: ctx + }); + } + unwrap() { + return this._def.type; + } + }; + exports2.ZodBranded = ZodBranded; + var ZodPipeline = class _ZodPipeline extends ZodType { + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.common.async) { + const handleAsync = async () => { + const inResult = await this._def.in._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inResult.status === "aborted") + return parseUtil_js_1.INVALID; + if (inResult.status === "dirty") { + status.dirty(); + return (0, parseUtil_js_1.DIRTY)(inResult.value); + } else { + return this._def.out._parseAsync({ + data: inResult.value, + path: ctx.path, + parent: ctx + }); + } + }; + return handleAsync(); + } else { + const inResult = this._def.in._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inResult.status === "aborted") + return parseUtil_js_1.INVALID; + if (inResult.status === "dirty") { + status.dirty(); + return { + status: "dirty", + value: inResult.value + }; + } else { + return this._def.out._parseSync({ + data: inResult.value, + path: ctx.path, + parent: ctx + }); + } + } + } + static create(a, b) { + return new _ZodPipeline({ + in: a, + out: b, + typeName: ZodFirstPartyTypeKind.ZodPipeline + }); + } + }; + exports2.ZodPipeline = ZodPipeline; + var ZodReadonly = class extends ZodType { + _parse(input) { + const result = this._def.innerType._parse(input); + const freeze = (data) => { + if ((0, parseUtil_js_1.isValid)(data)) { + data.value = Object.freeze(data.value); + } + return data; + }; + return (0, parseUtil_js_1.isAsync)(result) ? result.then((data) => freeze(data)) : freeze(result); + } + unwrap() { + return this._def.innerType; + } + }; + exports2.ZodReadonly = ZodReadonly; + ZodReadonly.create = (type, params) => { + return new ZodReadonly({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodReadonly, + ...processCreateParams(params) + }); + }; + function cleanParams(params, data) { + const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params; + const p2 = typeof p === "string" ? { message: p } : p; + return p2; + } + function custom(check, _params = {}, fatal) { + if (check) + return ZodAny.create().superRefine((data, ctx) => { + const r = check(data); + if (r instanceof Promise) { + return r.then((r2) => { + if (!r2) { + const params = cleanParams(_params, data); + const _fatal = params.fatal ?? fatal ?? true; + ctx.addIssue({ code: "custom", ...params, fatal: _fatal }); + } + }); + } + if (!r) { + const params = cleanParams(_params, data); + const _fatal = params.fatal ?? fatal ?? true; + ctx.addIssue({ code: "custom", ...params, fatal: _fatal }); + } + return; + }); + return ZodAny.create(); + } + exports2.late = { + object: ZodObject.lazycreate + }; + var ZodFirstPartyTypeKind; + (function(ZodFirstPartyTypeKind2) { + ZodFirstPartyTypeKind2["ZodString"] = "ZodString"; + ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber"; + ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN"; + ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt"; + ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean"; + ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate"; + ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol"; + ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined"; + ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull"; + ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny"; + ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown"; + ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever"; + ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid"; + ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray"; + ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject"; + ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion"; + ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion"; + ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection"; + ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple"; + ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord"; + ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap"; + ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet"; + ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction"; + ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy"; + ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral"; + ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum"; + ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects"; + ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum"; + ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional"; + ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable"; + ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault"; + ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch"; + ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise"; + ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded"; + ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline"; + ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly"; + })(ZodFirstPartyTypeKind || (exports2.ZodFirstPartyTypeKind = ZodFirstPartyTypeKind = {})); + var instanceOfType = (cls, params = { + message: `Input not instance of ${cls.name}` + }) => custom((data) => data instanceof cls, params); + exports2.instanceof = instanceOfType; + var stringType = ZodString.create; + exports2.string = stringType; + var numberType = ZodNumber.create; + exports2.number = numberType; + var nanType = ZodNaN.create; + exports2.nan = nanType; + var bigIntType = ZodBigInt.create; + exports2.bigint = bigIntType; + var booleanType = ZodBoolean.create; + exports2.boolean = booleanType; + var dateType = ZodDate.create; + exports2.date = dateType; + var symbolType = ZodSymbol.create; + exports2.symbol = symbolType; + var undefinedType = ZodUndefined.create; + exports2.undefined = undefinedType; + var nullType = ZodNull.create; + exports2.null = nullType; + var anyType = ZodAny.create; + exports2.any = anyType; + var unknownType = ZodUnknown.create; + exports2.unknown = unknownType; + var neverType = ZodNever.create; + exports2.never = neverType; + var voidType = ZodVoid.create; + exports2.void = voidType; + var arrayType = ZodArray.create; + exports2.array = arrayType; + var objectType = ZodObject.create; + exports2.object = objectType; + var strictObjectType = ZodObject.strictCreate; + exports2.strictObject = strictObjectType; + var unionType = ZodUnion.create; + exports2.union = unionType; + var discriminatedUnionType = ZodDiscriminatedUnion.create; + exports2.discriminatedUnion = discriminatedUnionType; + var intersectionType = ZodIntersection.create; + exports2.intersection = intersectionType; + var tupleType = ZodTuple.create; + exports2.tuple = tupleType; + var recordType = ZodRecord.create; + exports2.record = recordType; + var mapType = ZodMap.create; + exports2.map = mapType; + var setType = ZodSet.create; + exports2.set = setType; + var functionType = ZodFunction.create; + exports2.function = functionType; + var lazyType = ZodLazy.create; + exports2.lazy = lazyType; + var literalType = ZodLiteral.create; + exports2.literal = literalType; + var enumType = ZodEnum.create; + exports2.enum = enumType; + var nativeEnumType = ZodNativeEnum.create; + exports2.nativeEnum = nativeEnumType; + var promiseType = ZodPromise.create; + exports2.promise = promiseType; + var effectsType = ZodEffects.create; + exports2.effect = effectsType; + exports2.transformer = effectsType; + var optionalType = ZodOptional.create; + exports2.optional = optionalType; + var nullableType = ZodNullable.create; + exports2.nullable = nullableType; + var preprocessType = ZodEffects.createWithPreprocess; + exports2.preprocess = preprocessType; + var pipelineType = ZodPipeline.create; + exports2.pipeline = pipelineType; + var ostring = () => stringType().optional(); + exports2.ostring = ostring; + var onumber = () => numberType().optional(); + exports2.onumber = onumber; + var oboolean = () => booleanType().optional(); + exports2.oboolean = oboolean; + exports2.coerce = { + string: ((arg) => ZodString.create({ ...arg, coerce: true })), + number: ((arg) => ZodNumber.create({ ...arg, coerce: true })), + boolean: ((arg) => ZodBoolean.create({ + ...arg, + coerce: true + })), + bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })), + date: ((arg) => ZodDate.create({ ...arg, coerce: true })) + }; + exports2.NEVER = parseUtil_js_1.INVALID; + } +}); + +// node_modules/zod/v3/external.cjs +var require_external = __commonJS({ + "node_modules/zod/v3/external.cjs"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_errors(), exports2); + __exportStar2(require_parseUtil(), exports2); + __exportStar2(require_typeAliases(), exports2); + __exportStar2(require_util(), exports2); + __exportStar2(require_types2(), exports2); + __exportStar2(require_ZodError(), exports2); + } +}); + +// node_modules/zod/index.cjs +var require_zod = __commonJS({ + "node_modules/zod/index.cjs"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.z = void 0; + var z = __importStar2(require_external()); + exports2.z = z; + __exportStar2(require_external(), exports2); + exports2.default = z; + } +}); + +// node_modules/botframework-schema/lib/activityInterfaces.js +var require_activityInterfaces = __commonJS({ + "node_modules/botframework-schema/lib/activityInterfaces.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/uuid/dist/esm-node/max.js +var max_default; +var init_max = __esm({ + "node_modules/uuid/dist/esm-node/max.js"() { + max_default = "ffffffff-ffff-ffff-ffff-ffffffffffff"; + } +}); + +// node_modules/uuid/dist/esm-node/nil.js +var nil_default; +var init_nil = __esm({ + "node_modules/uuid/dist/esm-node/nil.js"() { + nil_default = "00000000-0000-0000-0000-000000000000"; + } +}); + +// node_modules/uuid/dist/esm-node/regex.js +var regex_default; +var init_regex = __esm({ + "node_modules/uuid/dist/esm-node/regex.js"() { + regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i; + } +}); + +// node_modules/uuid/dist/esm-node/validate.js +function validate(uuid) { + return typeof uuid === "string" && regex_default.test(uuid); +} +var validate_default; +var init_validate = __esm({ + "node_modules/uuid/dist/esm-node/validate.js"() { + init_regex(); + validate_default = validate; + } +}); + +// node_modules/uuid/dist/esm-node/parse.js +function parse(uuid) { + if (!validate_default(uuid)) { + throw TypeError("Invalid UUID"); + } + let v; + const arr = new Uint8Array(16); + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 255; + arr[2] = v >>> 8 & 255; + arr[3] = v & 255; + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 255; + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 255; + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 255; + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255; + arr[11] = v / 4294967296 & 255; + arr[12] = v >>> 24 & 255; + arr[13] = v >>> 16 & 255; + arr[14] = v >>> 8 & 255; + arr[15] = v & 255; + return arr; +} +var parse_default; +var init_parse = __esm({ + "node_modules/uuid/dist/esm-node/parse.js"() { + init_validate(); + parse_default = parse; + } +}); + +// node_modules/uuid/dist/esm-node/stringify.js +function unsafeStringify(arr, offset = 0) { + return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); +} +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); + if (!validate_default(uuid)) { + throw TypeError("Stringified UUID is invalid"); + } + return uuid; +} +var byteToHex, stringify_default; +var init_stringify = __esm({ + "node_modules/uuid/dist/esm-node/stringify.js"() { + init_validate(); + byteToHex = []; + for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 256).toString(16).slice(1)); + } + stringify_default = stringify; + } +}); + +// node_modules/uuid/dist/esm-node/rng.js +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + import_node_crypto.default.randomFillSync(rnds8Pool); + poolPtr = 0; + } + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} +var import_node_crypto, rnds8Pool, poolPtr; +var init_rng = __esm({ + "node_modules/uuid/dist/esm-node/rng.js"() { + import_node_crypto = __toESM(require("node:crypto")); + rnds8Pool = new Uint8Array(256); + poolPtr = rnds8Pool.length; + } +}); + +// node_modules/uuid/dist/esm-node/v1.js +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node; + let clockseq = options.clockseq; + if (!options._v6) { + if (!node) { + node = _nodeId; + } + if (clockseq == null) { + clockseq = _clockseq; + } + } + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || rng)(); + if (node == null) { + node = [seedBytes[0], seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + if (!_nodeId && !options._v6) { + node[0] |= 1; + _nodeId = node; + } + } + if (clockseq == null) { + clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 16383; + if (_clockseq === void 0 && !options._v6) { + _clockseq = clockseq; + } + } + } + let msecs = options.msecs !== void 0 ? options.msecs : Date.now(); + let nsecs = options.nsecs !== void 0 ? options.nsecs : _lastNSecs + 1; + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 1e4; + if (dt < 0 && options.clockseq === void 0) { + clockseq = clockseq + 1 & 16383; + } + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === void 0) { + nsecs = 0; + } + if (nsecs >= 1e4) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + msecs += 122192928e5; + const tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296; + b[i++] = tl >>> 24 & 255; + b[i++] = tl >>> 16 & 255; + b[i++] = tl >>> 8 & 255; + b[i++] = tl & 255; + const tmh = msecs / 4294967296 * 1e4 & 268435455; + b[i++] = tmh >>> 8 & 255; + b[i++] = tmh & 255; + b[i++] = tmh >>> 24 & 15 | 16; + b[i++] = tmh >>> 16 & 255; + b[i++] = clockseq >>> 8 | 128; + b[i++] = clockseq & 255; + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + return buf || unsafeStringify(b); +} +var _nodeId, _clockseq, _lastMSecs, _lastNSecs, v1_default; +var init_v1 = __esm({ + "node_modules/uuid/dist/esm-node/v1.js"() { + init_rng(); + init_stringify(); + _lastMSecs = 0; + _lastNSecs = 0; + v1_default = v1; + } +}); + +// node_modules/uuid/dist/esm-node/v1ToV6.js +function v1ToV6(uuid) { + const v1Bytes = typeof uuid === "string" ? parse_default(uuid) : uuid; + const v6Bytes = _v1ToV6(v1Bytes); + return typeof uuid === "string" ? unsafeStringify(v6Bytes) : v6Bytes; +} +function _v1ToV6(v1Bytes, randomize = false) { + return Uint8Array.of((v1Bytes[6] & 15) << 4 | v1Bytes[7] >> 4 & 15, (v1Bytes[7] & 15) << 4 | (v1Bytes[4] & 240) >> 4, (v1Bytes[4] & 15) << 4 | (v1Bytes[5] & 240) >> 4, (v1Bytes[5] & 15) << 4 | (v1Bytes[0] & 240) >> 4, (v1Bytes[0] & 15) << 4 | (v1Bytes[1] & 240) >> 4, (v1Bytes[1] & 15) << 4 | (v1Bytes[2] & 240) >> 4, 96 | v1Bytes[2] & 15, v1Bytes[3], v1Bytes[8], v1Bytes[9], v1Bytes[10], v1Bytes[11], v1Bytes[12], v1Bytes[13], v1Bytes[14], v1Bytes[15]); +} +var init_v1ToV6 = __esm({ + "node_modules/uuid/dist/esm-node/v1ToV6.js"() { + init_parse(); + init_stringify(); + } +}); + +// node_modules/uuid/dist/esm-node/v35.js +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); + const bytes = []; + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + return bytes; +} +function v35(name, version4, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + var _namespace; + if (typeof value === "string") { + value = stringToBytes(value); + } + if (typeof namespace === "string") { + namespace = parse_default(namespace); + } + if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { + throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)"); + } + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 15 | version4; + bytes[8] = bytes[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + return buf; + } + return unsafeStringify(bytes); + } + try { + generateUUID.name = name; + } catch (err) { + } + generateUUID.DNS = DNS; + generateUUID.URL = URL2; + return generateUUID; +} +var DNS, URL2; +var init_v35 = __esm({ + "node_modules/uuid/dist/esm-node/v35.js"() { + init_stringify(); + init_parse(); + DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; + URL2 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; + } +}); + +// node_modules/uuid/dist/esm-node/md5.js +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return import_node_crypto2.default.createHash("md5").update(bytes).digest(); +} +var import_node_crypto2, md5_default; +var init_md5 = __esm({ + "node_modules/uuid/dist/esm-node/md5.js"() { + import_node_crypto2 = __toESM(require("node:crypto")); + md5_default = md5; + } +}); + +// node_modules/uuid/dist/esm-node/v3.js +var v3, v3_default; +var init_v3 = __esm({ + "node_modules/uuid/dist/esm-node/v3.js"() { + init_v35(); + init_md5(); + v3 = v35("v3", 48, md5_default); + v3_default = v3; + } +}); + +// node_modules/uuid/dist/esm-node/native.js +var import_node_crypto3, native_default; +var init_native = __esm({ + "node_modules/uuid/dist/esm-node/native.js"() { + import_node_crypto3 = __toESM(require("node:crypto")); + native_default = { + randomUUID: import_node_crypto3.default.randomUUID + }; + } +}); + +// node_modules/uuid/dist/esm-node/v4.js +function v4(options, buf, offset) { + if (native_default.randomUUID && !buf && !options) { + return native_default.randomUUID(); + } + options = options || {}; + const rnds = options.random || (options.rng || rng)(); + rnds[6] = rnds[6] & 15 | 64; + rnds[8] = rnds[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + return buf; + } + return unsafeStringify(rnds); +} +var v4_default; +var init_v4 = __esm({ + "node_modules/uuid/dist/esm-node/v4.js"() { + init_native(); + init_rng(); + init_stringify(); + v4_default = v4; + } +}); + +// node_modules/uuid/dist/esm-node/sha1.js +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return import_node_crypto4.default.createHash("sha1").update(bytes).digest(); +} +var import_node_crypto4, sha1_default; +var init_sha1 = __esm({ + "node_modules/uuid/dist/esm-node/sha1.js"() { + import_node_crypto4 = __toESM(require("node:crypto")); + sha1_default = sha1; + } +}); + +// node_modules/uuid/dist/esm-node/v5.js +var v5, v5_default; +var init_v5 = __esm({ + "node_modules/uuid/dist/esm-node/v5.js"() { + init_v35(); + init_sha1(); + v5 = v35("v5", 80, sha1_default); + v5_default = v5; + } +}); + +// node_modules/uuid/dist/esm-node/v6.js +function v6(options = {}, buf, offset = 0) { + let bytes = v1_default({ + ...options, + _v6: true + }, new Uint8Array(16)); + bytes = v1ToV6(bytes); + if (buf) { + for (let i = 0; i < 16; i++) { + buf[offset + i] = bytes[i]; + } + return buf; + } + return unsafeStringify(bytes); +} +var init_v6 = __esm({ + "node_modules/uuid/dist/esm-node/v6.js"() { + init_stringify(); + init_v1(); + init_v1ToV6(); + } +}); + +// node_modules/uuid/dist/esm-node/v6ToV1.js +function v6ToV1(uuid) { + const v6Bytes = typeof uuid === "string" ? parse_default(uuid) : uuid; + const v1Bytes = _v6ToV1(v6Bytes); + return typeof uuid === "string" ? unsafeStringify(v1Bytes) : v1Bytes; +} +function _v6ToV1(v6Bytes) { + return Uint8Array.of((v6Bytes[3] & 15) << 4 | v6Bytes[4] >> 4 & 15, (v6Bytes[4] & 15) << 4 | (v6Bytes[5] & 240) >> 4, (v6Bytes[5] & 15) << 4 | v6Bytes[6] & 15, v6Bytes[7], (v6Bytes[1] & 15) << 4 | (v6Bytes[2] & 240) >> 4, (v6Bytes[2] & 15) << 4 | (v6Bytes[3] & 240) >> 4, 16 | (v6Bytes[0] & 240) >> 4, (v6Bytes[0] & 15) << 4 | (v6Bytes[1] & 240) >> 4, v6Bytes[8], v6Bytes[9], v6Bytes[10], v6Bytes[11], v6Bytes[12], v6Bytes[13], v6Bytes[14], v6Bytes[15]); +} +var init_v6ToV1 = __esm({ + "node_modules/uuid/dist/esm-node/v6ToV1.js"() { + init_parse(); + init_stringify(); + } +}); + +// node_modules/uuid/dist/esm-node/v7.js +function v7(options, buf, offset) { + options = options || {}; + let i = buf && offset || 0; + const b = buf || new Uint8Array(16); + const rnds = options.random || (options.rng || rng)(); + const msecs = options.msecs !== void 0 ? options.msecs : Date.now(); + let seq = options.seq !== void 0 ? options.seq : null; + let seqHigh = _seqHigh; + let seqLow = _seqLow; + if (msecs > _msecs && options.msecs === void 0) { + _msecs = msecs; + if (seq !== null) { + seqHigh = null; + seqLow = null; + } + } + if (seq !== null) { + if (seq > 2147483647) { + seq = 2147483647; + } + seqHigh = seq >>> 19 & 4095; + seqLow = seq & 524287; + } + if (seqHigh === null || seqLow === null) { + seqHigh = rnds[6] & 127; + seqHigh = seqHigh << 8 | rnds[7]; + seqLow = rnds[8] & 63; + seqLow = seqLow << 8 | rnds[9]; + seqLow = seqLow << 5 | rnds[10] >>> 3; + } + if (msecs + 1e4 > _msecs && seq === null) { + if (++seqLow > 524287) { + seqLow = 0; + if (++seqHigh > 4095) { + seqHigh = 0; + _msecs++; + } + } + } else { + _msecs = msecs; + } + _seqHigh = seqHigh; + _seqLow = seqLow; + b[i++] = _msecs / 1099511627776 & 255; + b[i++] = _msecs / 4294967296 & 255; + b[i++] = _msecs / 16777216 & 255; + b[i++] = _msecs / 65536 & 255; + b[i++] = _msecs / 256 & 255; + b[i++] = _msecs & 255; + b[i++] = seqHigh >>> 4 & 15 | 112; + b[i++] = seqHigh & 255; + b[i++] = seqLow >>> 13 & 63 | 128; + b[i++] = seqLow >>> 5 & 255; + b[i++] = seqLow << 3 & 255 | rnds[10] & 7; + b[i++] = rnds[11]; + b[i++] = rnds[12]; + b[i++] = rnds[13]; + b[i++] = rnds[14]; + b[i++] = rnds[15]; + return buf || unsafeStringify(b); +} +var _seqLow, _seqHigh, _msecs, v7_default; +var init_v7 = __esm({ + "node_modules/uuid/dist/esm-node/v7.js"() { + init_rng(); + init_stringify(); + _seqLow = null; + _seqHigh = null; + _msecs = 0; + v7_default = v7; + } +}); + +// node_modules/uuid/dist/esm-node/version.js +function version(uuid) { + if (!validate_default(uuid)) { + throw TypeError("Invalid UUID"); + } + return parseInt(uuid.slice(14, 15), 16); +} +var version_default; +var init_version = __esm({ + "node_modules/uuid/dist/esm-node/version.js"() { + init_validate(); + version_default = version; + } +}); + +// node_modules/uuid/dist/esm-node/index.js +var esm_node_exports = {}; +__export(esm_node_exports, { + MAX: () => max_default, + NIL: () => nil_default, + parse: () => parse_default, + stringify: () => stringify_default, + v1: () => v1_default, + v1ToV6: () => v1ToV6, + v3: () => v3_default, + v4: () => v4_default, + v5: () => v5_default, + v6: () => v6, + v6ToV1: () => v6ToV1, + v7: () => v7_default, + validate: () => validate_default, + version: () => version_default +}); +var init_esm_node = __esm({ + "node_modules/uuid/dist/esm-node/index.js"() { + init_max(); + init_nil(); + init_parse(); + init_stringify(); + init_v1(); + init_v1ToV6(); + init_v3(); + init_v4(); + init_v5(); + init_v6(); + init_v6ToV1(); + init_v7(); + init_validate(); + init_version(); + } +}); + +// node_modules/botframework-schema/lib/activityEx.js +var require_activityEx = __commonJS({ + "node_modules/botframework-schema/lib/activityEx.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ActivityEx = void 0; + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + var index_1 = require_lib4(); + var ActivityEx; + (function(ActivityEx2) { + function createMessageActivity() { + return { type: index_1.ActivityTypes.Message }; + } + ActivityEx2.createMessageActivity = createMessageActivity; + function createContactRelationUpdateActivity() { + return { type: index_1.ActivityTypes.ContactRelationUpdate }; + } + ActivityEx2.createContactRelationUpdateActivity = createContactRelationUpdateActivity; + function createConversationUpdateActivity() { + return { type: index_1.ActivityTypes.ConversationUpdate }; + } + ActivityEx2.createConversationUpdateActivity = createConversationUpdateActivity; + function createTypingActivity() { + return { type: index_1.ActivityTypes.Typing }; + } + ActivityEx2.createTypingActivity = createTypingActivity; + function createHandoffActivity() { + return { type: index_1.ActivityTypes.Handoff }; + } + ActivityEx2.createHandoffActivity = createHandoffActivity; + function createEndOfConversationActivity() { + return { type: index_1.ActivityTypes.EndOfConversation }; + } + ActivityEx2.createEndOfConversationActivity = createEndOfConversationActivity; + function createEventActivity() { + return { type: index_1.ActivityTypes.Event }; + } + ActivityEx2.createEventActivity = createEventActivity; + function createInvokeActivity() { + return { type: index_1.ActivityTypes.Invoke }; + } + ActivityEx2.createInvokeActivity = createInvokeActivity; + function createTraceActivity(name, valueType, value, label) { + return { + type: index_1.ActivityTypes.Trace, + name, + label, + valueType: valueType ? valueType : typeof value, + value + }; + } + ActivityEx2.createTraceActivity = createTraceActivity; + function createReply(source, text, locale) { + return { + type: index_1.ActivityTypes.Message, + timestamp: /* @__PURE__ */ new Date(), + from: { + id: source.recipient ? source.recipient.id : null, + name: source.recipient ? source.recipient.name : null + }, + recipient: { + id: source.from ? source.from.id : null, + name: source.from ? source.from.name : null + }, + replyToId: getAppropriateReplyToId(source), + serviceUrl: source.serviceUrl, + channelId: source.channelId, + conversation: { + isGroup: source.conversation.isGroup, + id: source.conversation.id, + name: source.conversation.name + }, + text: text || "", + locale: locale || source.locale, + label: source.label, + callerId: source.callerId, + valueType: source.valueType, + localTimezone: source.localTimezone, + listenFor: source.listenFor, + semanticAction: source.semanticAction + }; + } + ActivityEx2.createReply = createReply; + function createTrace(source, name, value, valueType, label) { + return { + type: index_1.ActivityTypes.Trace, + timestamp: /* @__PURE__ */ new Date(), + from: { + id: source.recipient ? source.recipient.id : null, + name: source.recipient ? source.recipient.name : null + }, + recipient: { + id: source.from ? source.from.id : null, + name: source.from ? source.from.name : null + }, + replyToId: getAppropriateReplyToId(source), + serviceUrl: source.serviceUrl, + channelId: source.channelId, + conversation: source.conversation, + name, + label, + valueType: valueType ? valueType : typeof value, + value + }; + } + ActivityEx2.createTrace = createTrace; + function asMessageActivity(source) { + return isActivity(source, index_1.ActivityTypes.Message) ? source : null; + } + ActivityEx2.asMessageActivity = asMessageActivity; + function asContactRelationUpdateActivity(source) { + return isActivity(source, index_1.ActivityTypes.ContactRelationUpdate) ? source : null; + } + ActivityEx2.asContactRelationUpdateActivity = asContactRelationUpdateActivity; + function asInstallationUpdateActivity(source) { + return isActivity(source, index_1.ActivityTypes.InstallationUpdate) ? source : null; + } + ActivityEx2.asInstallationUpdateActivity = asInstallationUpdateActivity; + function asConversationUpdateActivity(source) { + return isActivity(source, index_1.ActivityTypes.ConversationUpdate) ? source : null; + } + ActivityEx2.asConversationUpdateActivity = asConversationUpdateActivity; + function asTypingActivity(source) { + return isActivity(source, index_1.ActivityTypes.Typing) ? source : null; + } + ActivityEx2.asTypingActivity = asTypingActivity; + function asEndOfConversationActivity(source) { + return isActivity(source, index_1.ActivityTypes.EndOfConversation) ? source : null; + } + ActivityEx2.asEndOfConversationActivity = asEndOfConversationActivity; + function asEventActivity(source) { + return isActivity(source, index_1.ActivityTypes.Event) ? source : null; + } + ActivityEx2.asEventActivity = asEventActivity; + function asInvokeActivity(source) { + return isActivity(source, index_1.ActivityTypes.Invoke) ? source : null; + } + ActivityEx2.asInvokeActivity = asInvokeActivity; + function asMessageUpdateActivity(source) { + return isActivity(source, index_1.ActivityTypes.MessageUpdate) ? source : null; + } + ActivityEx2.asMessageUpdateActivity = asMessageUpdateActivity; + function asMessageDeleteActivity(source) { + return isActivity(source, index_1.ActivityTypes.MessageDelete) ? source : null; + } + ActivityEx2.asMessageDeleteActivity = asMessageDeleteActivity; + function asMessageReactionActivity(source) { + return isActivity(source, index_1.ActivityTypes.MessageReaction) ? source : null; + } + ActivityEx2.asMessageReactionActivity = asMessageReactionActivity; + function asSuggestionActivity(source) { + return isActivity(source, index_1.ActivityTypes.Suggestion) ? source : null; + } + ActivityEx2.asSuggestionActivity = asSuggestionActivity; + function asTraceActivity(source) { + return isActivity(source, index_1.ActivityTypes.Trace) ? source : null; + } + ActivityEx2.asTraceActivity = asTraceActivity; + function asHandoffActivity(source) { + return isActivity(source, index_1.ActivityTypes.Handoff) ? source : null; + } + ActivityEx2.asHandoffActivity = asHandoffActivity; + function asCommandActivity(source) { + return isActivity(source, index_1.ActivityTypes.Command) ? source : null; + } + ActivityEx2.asCommandActivity = asCommandActivity; + function asCommandResultActivity(source) { + return isActivity(source, index_1.ActivityTypes.CommandResult) ? source : null; + } + ActivityEx2.asCommandResultActivity = asCommandResultActivity; + function hasContent(source) { + if (source.text !== void 0 && source.text.trim().length > 0) { + return true; + } + if (source.summary !== void 0 && source.summary.trim().length > 0) { + return true; + } + if (source.attachments !== void 0 && source.attachments.length > 0) { + return true; + } + if (source.channelData !== void 0) { + return true; + } + return false; + } + ActivityEx2.hasContent = hasContent; + function getMentions(source) { + return source.entities.filter((x) => x.type.toLowerCase() === "mention").map((e) => e); + } + ActivityEx2.getMentions = getMentions; + function getConversationReference(source) { + return { + activityId: getAppropriateReplyToId(source), + bot: source.recipient, + channelId: source.channelId, + conversation: source.conversation, + locale: source.locale, + serviceUrl: source.serviceUrl, + user: source.from + }; + } + ActivityEx2.getConversationReference = getConversationReference; + function getContinuationActivity(reference) { + return { + type: index_1.ActivityTypes.Event, + name: index_1.ActivityEventNames.ContinueConversation, + id: (0, uuid_1.v4)(), + channelId: reference.channelId, + locale: reference.locale, + serviceUrl: reference.serviceUrl, + conversation: reference.conversation, + recipient: reference.bot, + from: reference.user, + relatesTo: reference + }; + } + ActivityEx2.getContinuationActivity = getContinuationActivity; + function isFromStreamingConnection(source) { + if (source.serviceUrl !== void 0) { + const isHttp = source.serviceUrl.toLowerCase().startsWith("http"); + return !isHttp; + } + return false; + } + ActivityEx2.isFromStreamingConnection = isFromStreamingConnection; + function isActivity(source, activityType) { + const type = source.type; + if (type == void 0 || typeof type !== "string") { + return false; + } + let result = type.toUpperCase().startsWith(activityType.toUpperCase()); + if (result) { + result = type.length === activityType.length; + } + if (!result) { + result = type.length > activityType.length && type[activityType.length] === "/"; + } + return result; + } + ActivityEx2.isActivity = isActivity; + })(ActivityEx = exports2.ActivityEx || (exports2.ActivityEx = {})); + function getAppropriateReplyToId(source) { + if (source.type !== index_1.ActivityTypes.ConversationUpdate || source.channelId !== index_1.Channels.Directline && source.channelId !== index_1.Channels.Webchat) { + return source.id; + } + return void 0; + } + } +}); + +// node_modules/botframework-schema/lib/callerIdConstants.js +var require_callerIdConstants = __commonJS({ + "node_modules/botframework-schema/lib/callerIdConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CallerIdConstants = void 0; + var CallerIdConstants = class { + }; + exports2.CallerIdConstants = CallerIdConstants; + CallerIdConstants.PublicAzureChannel = "urn:botframework:azure"; + CallerIdConstants.USGovChannel = "urn:botframework:azureusgov"; + CallerIdConstants.BotToBotPrefix = "urn:botframework:aadappid:"; + } +}); + +// node_modules/botframework-schema/lib/speechConstants.js +var require_speechConstants = __commonJS({ + "node_modules/botframework-schema/lib/speechConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SpeechConstants = void 0; + var SpeechConstants = class { + }; + exports2.SpeechConstants = SpeechConstants; + SpeechConstants.EmptySpeakTag = ''; + } +}); + +// node_modules/botframework-schema/lib/teams/extension/index.js +var require_extension = __commonJS({ + "node_modules/botframework-schema/lib/teams/extension/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/teams/index.js +var require_teams = __commonJS({ + "node_modules/botframework-schema/lib/teams/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_extension(), exports2); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/aceData.js +var require_aceData = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/aceData.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/aceRequest.js +var require_aceRequest = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/aceRequest.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/getPropertyPaneConfigurationResponse.js +var require_getPropertyPaneConfigurationResponse = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/getPropertyPaneConfigurationResponse.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/handleActionResponse.js +var require_handleActionResponse = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/handleActionResponse.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneFieldProperties.js +var require_propertyPaneFieldProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneFieldProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneGroupOrConditionalGroup.js +var require_propertyPaneGroupOrConditionalGroup = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneGroupOrConditionalGroup.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneCheckboxProperties.js +var require_propertyPaneCheckboxProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneCheckboxProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneChoiceGroupIconProperties.js +var require_propertyPaneChoiceGroupIconProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneChoiceGroupIconProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneChoiceGroupImageSize.js +var require_propertyPaneChoiceGroupImageSize = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneChoiceGroupImageSize.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneChoiceGroupOption.js +var require_propertyPaneChoiceGroupOption = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneChoiceGroupOption.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneChoiceGroupProperties.js +var require_propertyPaneChoiceGroupProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneChoiceGroupProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneDropDownOption.js +var require_propertyPaneDropDownOption = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneDropDownOption.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DropDownOptionType = void 0; + var DropDownOptionType; + (function(DropDownOptionType2) { + DropDownOptionType2[DropDownOptionType2["Normal"] = 0] = "Normal"; + DropDownOptionType2[DropDownOptionType2["Divider"] = 1] = "Divider"; + DropDownOptionType2[DropDownOptionType2["Header"] = 2] = "Header"; + })(DropDownOptionType = exports2.DropDownOptionType || (exports2.DropDownOptionType = {})); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneDropDownProperties.js +var require_propertyPaneDropDownProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneDropDownProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneGroupField.js +var require_propertyPaneGroupField = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneGroupField.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.FieldType = void 0; + var FieldType; + (function(FieldType2) { + FieldType2[FieldType2["CheckBox"] = 2] = "CheckBox"; + FieldType2[FieldType2["TextField"] = 3] = "TextField"; + FieldType2[FieldType2["Toggle"] = 5] = "Toggle"; + FieldType2[FieldType2["Dropdown"] = 6] = "Dropdown"; + FieldType2[FieldType2["Label"] = 7] = "Label"; + FieldType2[FieldType2["Slider"] = 8] = "Slider"; + FieldType2[FieldType2["ChoiceGroup"] = 10] = "ChoiceGroup"; + FieldType2[FieldType2["HorizontalRule"] = 12] = "HorizontalRule"; + FieldType2[FieldType2["Link"] = 13] = "Link"; + })(FieldType = exports2.FieldType || (exports2.FieldType = {})); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneGroup.js +var require_propertyPaneGroup = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneGroup.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneLabelProperties.js +var require_propertyPaneLabelProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneLabelProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneLinkPopupWindowProperties.js +var require_propertyPaneLinkPopupWindowProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneLinkPopupWindowProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PopupWindowPosition = void 0; + var PopupWindowPosition; + (function(PopupWindowPosition2) { + PopupWindowPosition2[PopupWindowPosition2["Center"] = 0] = "Center"; + PopupWindowPosition2[PopupWindowPosition2["RightTop"] = 1] = "RightTop"; + PopupWindowPosition2[PopupWindowPosition2["LeftTop"] = 2] = "LeftTop"; + PopupWindowPosition2[PopupWindowPosition2["RightBottom"] = 3] = "RightBottom"; + PopupWindowPosition2[PopupWindowPosition2["LeftBottom"] = 4] = "LeftBottom"; + })(PopupWindowPosition = exports2.PopupWindowPosition || (exports2.PopupWindowPosition = {})); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneLinkProperties.js +var require_propertyPaneLinkProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneLinkProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPanePage.js +var require_propertyPanePage = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPanePage.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPanePageHeader.js +var require_propertyPanePageHeader = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPanePageHeader.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneSliderProperties.js +var require_propertyPaneSliderProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneSliderProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneTextFieldProperties.js +var require_propertyPaneTextFieldProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneTextFieldProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/propertyPaneToggleProperties.js +var require_propertyPaneToggleProperties = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/propertyPaneToggleProperties.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/setPropertyPaneConfigurationResponse.js +var require_setPropertyPaneConfigurationResponse = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/setPropertyPaneConfigurationResponse.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardViewResponse.js +var require_cardViewResponse = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardViewResponse.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/quickViewData.js +var require_quickViewData = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/quickViewData.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/quickViewResponse.js +var require_quickViewResponse = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/quickViewResponse.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/actions/cardAction.js +var require_cardAction = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/actions/cardAction.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MediaType = void 0; + var MediaType; + (function(MediaType2) { + MediaType2[MediaType2["Image"] = 1] = "Image"; + MediaType2[MediaType2["Audio"] = 4] = "Audio"; + MediaType2[MediaType2["Document"] = 8] = "Document"; + })(MediaType = exports2.MediaType || (exports2.MediaType = {})); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/actions/focusParameters.js +var require_focusParameters = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/actions/focusParameters.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/actions/index.js +var require_actions = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/actions/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_cardAction(), exports2); + __exportStar2(require_focusParameters(), exports2); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/baseCardComponent.js +var require_baseCardComponent = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/baseCardComponent.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardBarComponent.js +var require_cardBarComponent = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardBarComponent.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardButtonBase.js +var require_cardButtonBase = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardButtonBase.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardButtonComponent.js +var require_cardButtonComponent = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardButtonComponent.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardImage.js +var require_cardImage = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardImage.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardSearchBoxComponent.js +var require_cardSearchBoxComponent = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardSearchBoxComponent.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardSearchFooterComponent.js +var require_cardSearchFooterComponent = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardSearchFooterComponent.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardTextComponent.js +var require_cardTextComponent = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardTextComponent.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardTextInputComponent.js +var require_cardTextInputComponent = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardTextInputComponent.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/cardViewParameters.js +var require_cardViewParameters = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/cardViewParameters.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SignInCardView = exports2.SearchCardView = exports2.TextInputCardView = exports2.ImageCardView = exports2.PrimaryTextCardView = exports2.BasicCardView = void 0; + function BasicCardView(cardBar, header, footer) { + return { + cardViewType: "text", + body: void 0, + cardBar: [cardBar], + header: [header], + footer + }; + } + exports2.BasicCardView = BasicCardView; + function PrimaryTextCardView(cardBar, header, body, footer) { + return { + cardViewType: "text", + cardBar: [cardBar], + header: [header], + body: [body], + footer + }; + } + exports2.PrimaryTextCardView = PrimaryTextCardView; + function ImageCardView(cardBar, header, image, footer) { + return { + cardViewType: "text", + image, + cardBar: [cardBar], + header: [header], + body: void 0, + footer + }; + } + exports2.ImageCardView = ImageCardView; + function TextInputCardView(cardBar, header, body, footer) { + return { + cardViewType: "textInput", + cardBar: [cardBar], + header: [header], + body: [body], + footer + }; + } + exports2.TextInputCardView = TextInputCardView; + function SearchCardView(cardBar, header, body, footer) { + return { + cardViewType: "search", + cardBar: [cardBar], + header: [header], + body: [body], + footer: [footer] + }; + } + exports2.SearchCardView = SearchCardView; + function SignInCardView(cardBar, header, body, footer) { + return { + cardViewType: "signIn", + cardBar: [cardBar], + header: [header], + body: [body], + footer: [footer] + }; + } + exports2.SignInCardView = SignInCardView; + } +}); + +// node_modules/botframework-schema/lib/sharepoint/cardView/index.js +var require_cardView = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/cardView/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_baseCardComponent(), exports2); + __exportStar2(require_cardBarComponent(), exports2); + __exportStar2(require_cardButtonBase(), exports2); + __exportStar2(require_cardButtonComponent(), exports2); + __exportStar2(require_cardImage(), exports2); + __exportStar2(require_cardSearchBoxComponent(), exports2); + __exportStar2(require_cardSearchFooterComponent(), exports2); + __exportStar2(require_cardTextComponent(), exports2); + __exportStar2(require_cardTextInputComponent(), exports2); + __exportStar2(require_cardViewParameters(), exports2); + } +}); + +// node_modules/botframework-schema/lib/sharepoint/index.js +var require_sharepoint = __commonJS({ + "node_modules/botframework-schema/lib/sharepoint/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_aceData(), exports2); + __exportStar2(require_aceRequest(), exports2); + __exportStar2(require_getPropertyPaneConfigurationResponse(), exports2); + __exportStar2(require_handleActionResponse(), exports2); + __exportStar2(require_propertyPaneFieldProperties(), exports2); + __exportStar2(require_propertyPaneGroupOrConditionalGroup(), exports2); + __exportStar2(require_propertyPaneCheckboxProperties(), exports2); + __exportStar2(require_propertyPaneChoiceGroupIconProperties(), exports2); + __exportStar2(require_propertyPaneChoiceGroupImageSize(), exports2); + __exportStar2(require_propertyPaneChoiceGroupOption(), exports2); + __exportStar2(require_propertyPaneChoiceGroupProperties(), exports2); + __exportStar2(require_propertyPaneDropDownOption(), exports2); + __exportStar2(require_propertyPaneDropDownProperties(), exports2); + __exportStar2(require_propertyPaneGroupField(), exports2); + __exportStar2(require_propertyPaneGroup(), exports2); + __exportStar2(require_propertyPaneLabelProperties(), exports2); + __exportStar2(require_propertyPaneLinkPopupWindowProperties(), exports2); + __exportStar2(require_propertyPaneLinkProperties(), exports2); + __exportStar2(require_propertyPanePage(), exports2); + __exportStar2(require_propertyPanePageHeader(), exports2); + __exportStar2(require_propertyPaneSliderProperties(), exports2); + __exportStar2(require_propertyPaneTextFieldProperties(), exports2); + __exportStar2(require_propertyPaneToggleProperties(), exports2); + __exportStar2(require_setPropertyPaneConfigurationResponse(), exports2); + __exportStar2(require_cardViewResponse(), exports2); + __exportStar2(require_quickViewData(), exports2); + __exportStar2(require_quickViewResponse(), exports2); + __exportStar2(require_actions(), exports2); + __exportStar2(require_cardView(), exports2); + } +}); + +// node_modules/botframework-schema/lib/index.js +var require_lib4 = __commonJS({ + "node_modules/botframework-schema/lib/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.StatusCodes = exports2.Channels = exports2.SemanticActionStateTypes = exports2.InstallationUpdateActionTypes = exports2.ContactRelationUpdateActionTypes = exports2.DeliveryModes = exports2.ActivityImportance = exports2.EndOfConversationCodes = exports2.ActionTypes = exports2.InputHints = exports2.MessageReactionTypes = exports2.AttachmentLayoutTypes = exports2.TextFormatTypes = exports2.ActivityTypes = exports2.ActivityEventNames = exports2.RoleTypes = exports2.conversationParametersObject = exports2.isActivity = exports2.assertActivity = exports2.isSemanticAction = exports2.assertSemanticAction = exports2.isConversationReference = exports2.assertConversationReference = exports2.isEntity = exports2.assertEntity = exports2.isAttachment = exports2.assertAttachment = exports2.isSuggestedActions = exports2.assertSuggestedActions = exports2.isCardAction = exports2.assertCardAction = exports2.isMessageReaction = exports2.assertMessageReaction = exports2.isConversationAccount = exports2.assertConversationAccount = exports2.isChannelAccount = exports2.assertChannelAccount = exports2.isAttachmentInfo = exports2.assertAttachmentInfo = exports2.isAttachmentView = exports2.assertAttachmentView = exports2.SpeechConstants = exports2.CallerIdConstants = void 0; + var z = __importStar2(require_zod()); + __exportStar2(require_activityInterfaces(), exports2); + __exportStar2(require_activityEx(), exports2); + var callerIdConstants_1 = require_callerIdConstants(); + Object.defineProperty(exports2, "CallerIdConstants", { enumerable: true, get: function() { + return callerIdConstants_1.CallerIdConstants; + } }); + var speechConstants_1 = require_speechConstants(); + Object.defineProperty(exports2, "SpeechConstants", { enumerable: true, get: function() { + return speechConstants_1.SpeechConstants; + } }); + __exportStar2(require_teams(), exports2); + __exportStar2(require_sharepoint(), exports2); + var attachmentView = z.object({ + viewId: z.string(), + size: z.number() + }); + function assertAttachmentView(val, ..._args) { + attachmentView.parse(val); + } + exports2.assertAttachmentView = assertAttachmentView; + function isAttachmentView(val) { + return attachmentView.safeParse(val).success; + } + exports2.isAttachmentView = isAttachmentView; + var attachmentInfo = z.object({ + name: z.string(), + type: z.string(), + views: z.array(attachmentView) + }); + function assertAttachmentInfo(val, ..._args) { + attachmentInfo.parse(val); + } + exports2.assertAttachmentInfo = assertAttachmentInfo; + function isAttachmentInfo(val) { + return attachmentInfo.safeParse(val).success; + } + exports2.isAttachmentInfo = isAttachmentInfo; + var channelAccount = z.object({ + id: z.string(), + name: z.string(), + aadObjectId: z.string().optional(), + role: z.string().optional() + }); + function assertChannelAccount(val, ..._args) { + channelAccount.parse(val); + } + exports2.assertChannelAccount = assertChannelAccount; + function isChannelAccount(val) { + return channelAccount.safeParse(val).success; + } + exports2.isChannelAccount = isChannelAccount; + var conversationAccount = z.object({ + isGroup: z.boolean(), + conversationType: z.string(), + tenantId: z.string().optional(), + id: z.string(), + name: z.string(), + aadObjectId: z.string().optional(), + role: z.string().optional(), + properties: z.unknown().optional() + }); + function assertConversationAccount(val, ..._args) { + conversationAccount.parse(val); + } + exports2.assertConversationAccount = assertConversationAccount; + function isConversationAccount(val) { + return conversationAccount.safeParse(val).success; + } + exports2.isConversationAccount = isConversationAccount; + var messageReaction = z.object({ + type: z.string() + }); + function assertMessageReaction(val, ..._args) { + messageReaction.parse(val); + } + exports2.assertMessageReaction = assertMessageReaction; + function isMessageReaction(val) { + return messageReaction.safeParse(val).success; + } + exports2.isMessageReaction = isMessageReaction; + var cardAction = z.object({ + type: z.string(), + title: z.string(), + image: z.string().optional(), + text: z.string().optional(), + displayText: z.string().optional(), + value: z.unknown(), + channelData: z.unknown(), + imageAltText: z.string().optional() + }); + function assertCardAction(val, ..._args) { + cardAction.parse(val); + } + exports2.assertCardAction = assertCardAction; + function isCardAction(val) { + return cardAction.safeParse(val).success; + } + exports2.isCardAction = isCardAction; + var suggestedActions = z.object({ + to: z.array(z.string()), + actions: z.array(cardAction) + }); + function assertSuggestedActions(val, ..._args) { + suggestedActions.parse(val); + } + exports2.assertSuggestedActions = assertSuggestedActions; + function isSuggestedActions(val) { + return suggestedActions.safeParse(val).success; + } + exports2.isSuggestedActions = isSuggestedActions; + var attachment = z.object({ + contentType: z.string(), + contentUrl: z.string().optional(), + content: z.unknown().optional(), + name: z.string().optional(), + thumbnailUrl: z.string().optional() + }); + function assertAttachment(val, ..._args) { + attachment.parse(val); + } + exports2.assertAttachment = assertAttachment; + function isAttachment(val) { + return attachment.safeParse(val).success; + } + exports2.isAttachment = isAttachment; + var entity = z.record(z.unknown()).refine((val) => typeof val.type === "string"); + function assertEntity(val, ..._args) { + entity.parse(val); + } + exports2.assertEntity = assertEntity; + function isEntity(val) { + return entity.safeParse(val).success; + } + exports2.isEntity = isEntity; + var conversationReference = z.object({ + ActivityId: z.string().optional(), + user: channelAccount.optional(), + locale: z.string().optional(), + bot: channelAccount, + conversation: conversationAccount, + channelId: z.string(), + serviceUrl: z.string() + }); + function assertConversationReference(val, ..._args) { + conversationReference.parse(val); + } + exports2.assertConversationReference = assertConversationReference; + function isConversationReference(val) { + return conversationReference.safeParse(val).success; + } + exports2.isConversationReference = isConversationReference; + var textHighlight = z.object({ + text: z.string(), + occurrence: z.number() + }); + var semanticAction = z.object({ + id: z.string(), + state: z.string(), + entities: z.record(entity) + }); + function assertSemanticAction(val, ..._args) { + semanticAction.parse(val); + } + exports2.assertSemanticAction = assertSemanticAction; + function isSemanticAction(val) { + return semanticAction.safeParse(val).success; + } + exports2.isSemanticAction = isSemanticAction; + var activity = z.object({ + type: z.string(), + id: z.string().optional(), + timestamp: z.instanceof(Date).optional(), + localTimestamp: z.instanceof(Date).optional(), + localTimezone: z.string(), + callerId: z.string(), + serviceUrl: z.string(), + channelId: z.string(), + from: channelAccount, + conversation: conversationAccount, + recipient: channelAccount, + textFormat: z.string().optional(), + attachmentLayout: z.string().optional(), + membersAdded: z.array(channelAccount).optional(), + membersRemoved: z.array(channelAccount).optional(), + reactionsAdded: z.array(messageReaction).optional(), + reactionsRemoved: z.array(messageReaction).optional(), + topicName: z.string().optional(), + historyDisclosed: z.boolean().optional(), + locale: z.string().optional(), + text: z.string(), + speak: z.string().optional(), + inputHint: z.string().optional(), + summary: z.string().optional(), + suggestedActions: suggestedActions.optional(), + attachments: z.array(attachment).optional(), + entities: z.array(entity).optional(), + channelData: z.unknown().optional(), + action: z.string().optional(), + replyToId: z.string().optional(), + label: z.string(), + valueType: z.string(), + value: z.unknown().optional(), + name: z.string().optional(), + relatesTo: conversationReference.optional(), + code: z.string().optional(), + importance: z.string().optional(), + deliveryMode: z.string().optional(), + listenFor: z.array(z.string()).optional(), + textHighlights: z.array(textHighlight).optional(), + semanticAction: semanticAction.optional() + }); + function assertActivity(val, ..._args) { + activity.parse(val); + } + exports2.assertActivity = assertActivity; + function isActivity(val) { + return activity.safeParse(val).success; + } + exports2.isActivity = isActivity; + exports2.conversationParametersObject = z.object({ + isGroup: z.boolean(), + bot: channelAccount, + members: z.array(channelAccount).optional(), + topicName: z.string().optional(), + tenantId: z.string().optional(), + activity, + channelData: z.unknown().optional() + }); + var RoleTypes; + (function(RoleTypes2) { + RoleTypes2["User"] = "user"; + RoleTypes2["Bot"] = "bot"; + RoleTypes2["Skill"] = "skill"; + })(RoleTypes = exports2.RoleTypes || (exports2.RoleTypes = {})); + var ActivityEventNames; + (function(ActivityEventNames2) { + ActivityEventNames2["ContinueConversation"] = "ContinueConversation"; + ActivityEventNames2["CreateConversation"] = "CreateConversation"; + })(ActivityEventNames = exports2.ActivityEventNames || (exports2.ActivityEventNames = {})); + var ActivityTypes; + (function(ActivityTypes2) { + ActivityTypes2["Message"] = "message"; + ActivityTypes2["ContactRelationUpdate"] = "contactRelationUpdate"; + ActivityTypes2["ConversationUpdate"] = "conversationUpdate"; + ActivityTypes2["Typing"] = "typing"; + ActivityTypes2["EndOfConversation"] = "endOfConversation"; + ActivityTypes2["Event"] = "event"; + ActivityTypes2["Invoke"] = "invoke"; + ActivityTypes2["InvokeResponse"] = "invokeResponse"; + ActivityTypes2["DeleteUserData"] = "deleteUserData"; + ActivityTypes2["MessageUpdate"] = "messageUpdate"; + ActivityTypes2["MessageDelete"] = "messageDelete"; + ActivityTypes2["InstallationUpdate"] = "installationUpdate"; + ActivityTypes2["MessageReaction"] = "messageReaction"; + ActivityTypes2["Suggestion"] = "suggestion"; + ActivityTypes2["Trace"] = "trace"; + ActivityTypes2["Handoff"] = "handoff"; + ActivityTypes2["Command"] = "command"; + ActivityTypes2["CommandResult"] = "commandResult"; + })(ActivityTypes = exports2.ActivityTypes || (exports2.ActivityTypes = {})); + var TextFormatTypes; + (function(TextFormatTypes2) { + TextFormatTypes2["Markdown"] = "markdown"; + TextFormatTypes2["Plain"] = "plain"; + TextFormatTypes2["Xml"] = "xml"; + })(TextFormatTypes = exports2.TextFormatTypes || (exports2.TextFormatTypes = {})); + var AttachmentLayoutTypes; + (function(AttachmentLayoutTypes2) { + AttachmentLayoutTypes2["List"] = "list"; + AttachmentLayoutTypes2["Carousel"] = "carousel"; + })(AttachmentLayoutTypes = exports2.AttachmentLayoutTypes || (exports2.AttachmentLayoutTypes = {})); + var MessageReactionTypes; + (function(MessageReactionTypes2) { + MessageReactionTypes2["Like"] = "like"; + MessageReactionTypes2["PlusOne"] = "plusOne"; + })(MessageReactionTypes = exports2.MessageReactionTypes || (exports2.MessageReactionTypes = {})); + var InputHints; + (function(InputHints2) { + InputHints2["AcceptingInput"] = "acceptingInput"; + InputHints2["IgnoringInput"] = "ignoringInput"; + InputHints2["ExpectingInput"] = "expectingInput"; + })(InputHints = exports2.InputHints || (exports2.InputHints = {})); + var ActionTypes; + (function(ActionTypes2) { + ActionTypes2["OpenUrl"] = "openUrl"; + ActionTypes2["ImBack"] = "imBack"; + ActionTypes2["PostBack"] = "postBack"; + ActionTypes2["PlayAudio"] = "playAudio"; + ActionTypes2["PlayVideo"] = "playVideo"; + ActionTypes2["ShowImage"] = "showImage"; + ActionTypes2["DownloadFile"] = "downloadFile"; + ActionTypes2["Signin"] = "signin"; + ActionTypes2["Call"] = "call"; + ActionTypes2["Payment"] = "payment"; + ActionTypes2["MessageBack"] = "messageBack"; + ActionTypes2["OpenApp"] = "openApp"; + })(ActionTypes = exports2.ActionTypes || (exports2.ActionTypes = {})); + var EndOfConversationCodes; + (function(EndOfConversationCodes2) { + EndOfConversationCodes2["Unknown"] = "unknown"; + EndOfConversationCodes2["CompletedSuccessfully"] = "completedSuccessfully"; + EndOfConversationCodes2["UserCancelled"] = "userCancelled"; + EndOfConversationCodes2["BotTimedOut"] = "botTimedOut"; + EndOfConversationCodes2["BotIssuedInvalidMessage"] = "botIssuedInvalidMessage"; + EndOfConversationCodes2["ChannelFailed"] = "channelFailed"; + })(EndOfConversationCodes = exports2.EndOfConversationCodes || (exports2.EndOfConversationCodes = {})); + var ActivityImportance; + (function(ActivityImportance2) { + ActivityImportance2["Low"] = "low"; + ActivityImportance2["Normal"] = "normal"; + ActivityImportance2["High"] = "high"; + })(ActivityImportance = exports2.ActivityImportance || (exports2.ActivityImportance = {})); + var DeliveryModes; + (function(DeliveryModes2) { + DeliveryModes2["Normal"] = "normal"; + DeliveryModes2["Notification"] = "notification"; + DeliveryModes2["ExpectReplies"] = "expectReplies"; + DeliveryModes2["Ephemeral"] = "ephemeral"; + })(DeliveryModes = exports2.DeliveryModes || (exports2.DeliveryModes = {})); + var ContactRelationUpdateActionTypes; + (function(ContactRelationUpdateActionTypes2) { + ContactRelationUpdateActionTypes2["Add"] = "add"; + ContactRelationUpdateActionTypes2["Remove"] = "remove"; + })(ContactRelationUpdateActionTypes = exports2.ContactRelationUpdateActionTypes || (exports2.ContactRelationUpdateActionTypes = {})); + var InstallationUpdateActionTypes; + (function(InstallationUpdateActionTypes2) { + InstallationUpdateActionTypes2["Add"] = "add"; + InstallationUpdateActionTypes2["Remove"] = "remove"; + })(InstallationUpdateActionTypes = exports2.InstallationUpdateActionTypes || (exports2.InstallationUpdateActionTypes = {})); + var SemanticActionStateTypes; + (function(SemanticActionStateTypes2) { + SemanticActionStateTypes2["Start"] = "start"; + SemanticActionStateTypes2["Continue"] = "continue"; + SemanticActionStateTypes2["Done"] = "done"; + })(SemanticActionStateTypes = exports2.SemanticActionStateTypes || (exports2.SemanticActionStateTypes = {})); + var Channels; + (function(Channels2) { + Channels2["Alexa"] = "alexa"; + Channels2["Console"] = "console"; + Channels2["Directline"] = "directline"; + Channels2["DirectlineSpeech"] = "directlinespeech"; + Channels2["Email"] = "email"; + Channels2["Emulator"] = "emulator"; + Channels2["Facebook"] = "facebook"; + Channels2["Groupme"] = "groupme"; + Channels2["Kik"] = "kik"; + Channels2["Line"] = "line"; + Channels2["M365"] = "m365extensions"; + Channels2["Msteams"] = "msteams"; + Channels2["Omni"] = "omnichannel"; + Channels2["Outlook"] = "outlook"; + Channels2["Skype"] = "skype"; + Channels2["Skypeforbusiness"] = "skypeforbusiness"; + Channels2["Slack"] = "slack"; + Channels2["Sms"] = "sms"; + Channels2["Telegram"] = "telegram"; + Channels2["Telephony"] = "telephony"; + Channels2["Test"] = "test"; + Channels2["Twilio"] = "twilio-sms"; + Channels2["Webchat"] = "webchat"; + })(Channels = exports2.Channels || (exports2.Channels = {})); + var StatusCodes; + (function(StatusCodes2) { + StatusCodes2[StatusCodes2["OK"] = 200] = "OK"; + StatusCodes2[StatusCodes2["CREATED"] = 201] = "CREATED"; + StatusCodes2[StatusCodes2["MULTIPLE_CHOICES"] = 300] = "MULTIPLE_CHOICES"; + StatusCodes2[StatusCodes2["BAD_REQUEST"] = 400] = "BAD_REQUEST"; + StatusCodes2[StatusCodes2["UNAUTHORIZED"] = 401] = "UNAUTHORIZED"; + StatusCodes2[StatusCodes2["NOT_FOUND"] = 404] = "NOT_FOUND"; + StatusCodes2[StatusCodes2["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED"; + StatusCodes2[StatusCodes2["CONFLICT"] = 409] = "CONFLICT"; + StatusCodes2[StatusCodes2["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED"; + StatusCodes2[StatusCodes2["UPGRADE_REQUIRED"] = 426] = "UPGRADE_REQUIRED"; + StatusCodes2[StatusCodes2["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR"; + StatusCodes2[StatusCodes2["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED"; + StatusCodes2[StatusCodes2["BAD_GATEWAY"] = 502] = "BAD_GATEWAY"; + })(StatusCodes = exports2.StatusCodes || (exports2.StatusCodes = {})); + } +}); + +// node_modules/botbuilder-core/lib/cardFactory.js +var require_cardFactory = __commonJS({ + "node_modules/botbuilder-core/lib/cardFactory.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CardFactory = void 0; + var botframework_schema_1 = require_lib4(); + var CardFactory = class _CardFactory { + /** + * Returns an attachment for an Adaptive Card. + * + * @param card A description of the Adaptive Card to return. + * @returns An [Attachment](xref:botframework-schema.Attachment). + * @remarks + * Adaptive Cards are an open card exchange format enabling developers to exchange UI content in a common and consistent way. + * For channels that don't yet support Adaptive Cards natively, the Bot Framework will + * down-render the card to an image that's been styled to look good on the target channel. For + * channels that support [hero cards](#herocards) you can continue to include Adaptive Card + * actions and they will be sent as buttons along with the rendered version of the card. + * + * For more information about Adaptive Cards and to download the latest SDK, visit + * [adaptivecards.io](http://adaptivecards.io/). + * + * For example: + * ```JavaScript + * const card = CardFactory.adaptiveCard({ + * "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + * "type": "AdaptiveCard", + * "version": "1.0", + * "body": [ + * { + * "type": "TextBlock", + * "text": "Default text input" + * } + * ], + * "actions": [ + * { + * "type": "Action.Submit", + * "title": "OK" + * } + * ] + * }); + * ``` + */ + static adaptiveCard(card) { + return { contentType: _CardFactory.contentTypes.adaptiveCard, content: card }; + } + /** + * Returns an attachment for an animation card. + * + * @param title The card title. + * @param media The media URLs for the card. + * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array + * is converted to an `imBack` button with a title and value set to the value of the string. + * @param other Optional. Any additional properties to include on the card. + * @returns An [Attachment](xref:botframework-schema.Attachment). + */ + static animationCard(title, media, buttons, other) { + return mediaCard(_CardFactory.contentTypes.animationCard, title, media, buttons, other); + } + /** + * Returns an attachment for an audio card. + * + * @param title The card title. + * @param media The media URL for the card. + * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array + * is converted to an `imBack` button with a title and value set to the value of the string. + * @param other Optional. Any additional properties to include on the card. + * @returns An [Attachment](xref:botframework-schema.Attachment). + */ + static audioCard(title, media, buttons, other) { + return mediaCard(_CardFactory.contentTypes.audioCard, title, media, buttons, other); + } + /** + * Returns an attachment for a hero card. + * + * @param title The card title. + * @param text Optional. The card text. + * @param images Optional. The array of images to include on the card. Each element can be a + * [CardImage](ref:botframework-schema.CardImage) or the URL of the image to include. + * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array + * is converted to an `imBack` button with a title and value set to the value of the string. + * @param other Optional. Any additional properties to include on the card. + * @returns An [Attachment](xref:botframework-schema.Attachment). + * @remarks + * Hero cards tend to have one dominant, full-width image. + * Channels typically render the card's text and buttons below the image. + * For example: + * ```javascript + * const card = CardFactory.heroCard( + * 'White T-Shirt', + * ['https://example.com/whiteShirt.jpg'], + * ['buy'] + * ); + * ``` + */ + static heroCard(title, text, images, buttons, other) { + const a = _CardFactory.thumbnailCard(title, text, images, buttons, other); + a.contentType = _CardFactory.contentTypes.heroCard; + return a; + } + /** + * Returns an attachment for an OAuth card. + * + * @param connectionName The name of the OAuth connection to use. + * @param title The title for the card's sign-in button. + * @param text Optional. Additional text to include on the card. + * @param link Optional. The sign-in link to use. + * @param tokenExchangeResource optional. The resource to try to perform token exchange with. + * @param tokenPostResource optional. The resource for directly post a token to token service. + * @returns An [Attachment](xref:botframework-schema.Attachment). + * @remarks OAuth cards support the Bot Framework's single sign on (SSO) service. + */ + static oauthCard(connectionName, title, text, link, tokenExchangeResource, tokenPostResource) { + const card = { + buttons: [{ type: botframework_schema_1.ActionTypes.Signin, title, value: link, channelData: void 0 }], + connectionName, + tokenExchangeResource, + tokenPostResource + }; + if (text) { + card.text = text; + } + return { contentType: _CardFactory.contentTypes.oauthCard, content: card }; + } + /** + * Returns an attachment for an Office 365 connector card. + * + * @param card a description of the Office 365 connector card to return. + * @returns An [Attachment](xref:botframework-schema.Attachment). + * @remarks + * For example: + * ```JavaScript + * const card = CardFactory.o365ConnectorCard({ + * "title": "card title", + * "text": "card text", + * "summary": "O365 card summary", + * "themeColor": "#E67A9E", + * "sections": [ + * { + * "title": "**section title**", + * "text": "section text", + * "activityTitle": "activity title", + * } + * ] + * }); + * ``` + */ + static o365ConnectorCard(card) { + return { contentType: _CardFactory.contentTypes.o365ConnectorCard, content: card }; + } + /** + * Returns an attachment for a receipt card. + * + * @param card A description of the receipt card to return. + * @returns An [Attachment](xref:botframework-schema.Attachment). + */ + static receiptCard(card) { + return { contentType: _CardFactory.contentTypes.receiptCard, content: card }; + } + /** + * Returns an attachment for a sign-in card. + * + * @param title The title for the card's sign-in button. + * @param url The URL of the sign-in page to use. + * @param text Optional. Additional text to include on the card. + * @returns An [Attachment](xref:botframework-schema.Attachment). + * @remarks + * For channels that don't natively support sign-in cards, an alternative message is rendered. + */ + static signinCard(title, url, text) { + const card = { + buttons: [{ type: botframework_schema_1.ActionTypes.Signin, title, value: url, channelData: void 0 }] + }; + if (text) { + card.text = text; + } + return { contentType: _CardFactory.contentTypes.signinCard, content: card }; + } + /** + * Returns an attachment for a thumbnail card. + * + * @param title The card title. + * @param text Optional. The card text. + * @param images Optional. The array of images to include on the card. Each element can be a + * [CardImage](ref:botframework-schema.CardImage) or the URL of the image to include. + * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array + * is converted to an `imBack` button with a title and value set to the value of the string. + * @param other Optional. Any additional properties to include on the card. + * @returns An [Attachment](xref:botframework-schema.Attachment). + * @remarks + * Thumbnail cards are similar to hero cards but instead of a full width image, + * they're typically rendered with a smaller thumbnail version of the image. + * Channels typically render the card's text to one side of the image, + * with any buttons displayed below the card. + */ + static thumbnailCard(title, text, images, buttons, other) { + if (typeof text !== "string") { + other = buttons; + buttons = images; + images = text; + text = void 0; + } + const card = Object.assign({}, other); + if (title) { + card.title = title; + } + if (text) { + card.text = text; + } + if (images) { + card.images = _CardFactory.images(images); + } + if (buttons) { + card.buttons = _CardFactory.actions(buttons); + } + return { contentType: _CardFactory.contentTypes.thumbnailCard, content: card }; + } + /** + * Returns an attachment for a video card. + * + * @param title The card title. + * @param media The media URLs for the card. + * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array + * is converted to an `imBack` button with a title and value set to the value of the string. + * @param other Optional. Any additional properties to include on the card. + * @returns An [Attachment](xref:botframework-schema.Attachment). + */ + static videoCard(title, media, buttons, other) { + return mediaCard(_CardFactory.contentTypes.videoCard, title, media, buttons, other); + } + /** + * Returns a properly formatted array of actions. + * + * @param actions The array of action to include on the card. Each `string` in the array + * is converted to an `imBack` button with a title and value set to the value of the string. + * @returns A properly formatted array of actions. + */ + static actions(actions) { + const list = []; + (actions || []).forEach((a) => { + if (typeof a === "object") { + list.push(a); + } else { + list.push({ + type: botframework_schema_1.ActionTypes.ImBack, + value: a.toString(), + title: a.toString(), + channelData: void 0 + }); + } + }); + return list; + } + /** + * Returns a properly formatted array of card images. + * + * @param images The array of images to include on the card. Each element can be a + * [CardImage](ref:botframework-schema.CardImage) or the URL of the image to include. + * @returns A properly formatted array of card images. + */ + static images(images) { + const list = []; + (images || []).forEach((img) => { + if (typeof img === "object") { + list.push(img); + } else { + list.push({ url: img }); + } + }); + return list; + } + /** + * Returns a properly formatted array of media URL objects. + * + * @param links The media URLs. Each `string` is converted to a media URL object. + * @returns A properly formatted array of media URL objects. + */ + static media(links) { + const list = []; + (links || []).forEach((lnk) => { + if (typeof lnk === "object") { + list.push(lnk); + } else { + list.push({ url: lnk }); + } + }); + return list; + } + }; + exports2.CardFactory = CardFactory; + CardFactory.contentTypes = { + adaptiveCard: "application/vnd.microsoft.card.adaptive", + animationCard: "application/vnd.microsoft.card.animation", + audioCard: "application/vnd.microsoft.card.audio", + heroCard: "application/vnd.microsoft.card.hero", + receiptCard: "application/vnd.microsoft.card.receipt", + oauthCard: "application/vnd.microsoft.card.oauth", + o365ConnectorCard: "application/vnd.microsoft.teams.card.o365connector", + signinCard: "application/vnd.microsoft.card.signin", + thumbnailCard: "application/vnd.microsoft.card.thumbnail", + videoCard: "application/vnd.microsoft.card.video" + }; + function mediaCard(contentType, title, media, buttons, other) { + const card = Object.assign({}, other); + if (title) { + card.title = title; + } + card.media = CardFactory.media(media); + if (buttons) { + card.buttons = CardFactory.actions(buttons); + } + return { contentType, content: card }; + } + } +}); + +// node_modules/botbuilder-core/lib/messageFactory.js +var require_messageFactory = __commonJS({ + "node_modules/botbuilder-core/lib/messageFactory.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MessageFactory = void 0; + var botframework_schema_1 = require_lib4(); + var cardFactory_1 = require_cardFactory(); + var MessageFactory = class { + /** + * Returns a simple text message. + * + * @remarks + * This example shows sending a simple text message: + * + * ```JavaScript + * const message = MessageFactory.text('Greetings from example message'); + * ``` + * @param text Text to include in the message. + * @param speak (Optional) SSML to include in the message. + * @param inputHint (Optional) input hint for the message. Defaults to `acceptingInput`. + * @returns A message activity containing the text. + */ + static text(text, speak, inputHint) { + const msg = { + type: botframework_schema_1.ActivityTypes.Message, + text, + inputHint: inputHint || botframework_schema_1.InputHints.AcceptingInput + }; + if (speak) { + msg.speak = speak; + } + return msg; + } + /** + * Returns a message that includes a set of suggested actions and optional text. + * + * @remarks + * This example shows creating a message with suggested actions: + * + * ```JavaScript + * const message = MessageFactory.suggestedActions(['red', 'green', 'blue'], `Choose a color`); + * ``` + * @param actions Array of card actions or strings to include. Strings will be converted to `messageBack` actions. + * @param text (Optional) text of the message. + * @param speak (Optional) SSML to include with the message. + * @param inputHint (Optional) input hint for the message. Defaults to `acceptingInput`. + * @returns A message activity that contains the suggested actions. + */ + static suggestedActions(actions, text, speak, inputHint) { + const msg = { + type: botframework_schema_1.ActivityTypes.Message, + inputHint: inputHint || botframework_schema_1.InputHints.AcceptingInput, + suggestedActions: { + actions: cardFactory_1.CardFactory.actions(actions) + } + }; + if (text) { + msg.text = text; + } + if (speak) { + msg.speak = speak; + } + return msg; + } + /** + * Returns a single message activity containing an attachment. + * + * @remarks + * This example shows creating a message with a hero card attachment: + * + * ```JavaScript + * const message = MessageFactory.attachment( + * CardFactory.heroCard( + * 'White T-Shirt', + * ['https://example.com/whiteShirt.jpg'], + * ['buy'] + * ) + * ); + * ``` + * @param attachment Adaptive card to include in the message. + * @param text (Optional) text of the message. + * @param speak (Optional) SSML to include with the message. + * @param inputHint (Optional) input hint for the message. Defaults to `acceptingInput`. + * @returns A message activity containing the attachment. + */ + static attachment(attachment, text, speak, inputHint) { + return attachmentActivity(botframework_schema_1.AttachmentLayoutTypes.List, [attachment], text, speak, inputHint); + } + /** + * Returns a message that will display a set of attachments in list form. + * + * @remarks + * This example shows creating a message with a list of hero cards: + * + * ```JavaScript + * const message = MessageFactory.list([ + * CardFactory.heroCard('title1', ['imageUrl1'], ['button1']), + * CardFactory.heroCard('title2', ['imageUrl2'], ['button2']), + * CardFactory.heroCard('title3', ['imageUrl3'], ['button3']) + * ]); + * ``` + * @param attachments Array of attachments to include in the message. + * @param text (Optional) text of the message. + * @param speak (Optional) SSML to include with the message. + * @param inputHint (Optional) input hint for the message. + * @returns A message activity that will display a set of attachments in list form. + */ + static list(attachments, text, speak, inputHint) { + return attachmentActivity(botframework_schema_1.AttachmentLayoutTypes.List, attachments, text, speak, inputHint); + } + /** + * Returns a message that will display a set of attachments using a carousel layout. + * + * @remarks + * This example shows creating a message with a carousel of hero cards: + * + * ```JavaScript + * const message = MessageFactory.carousel([ + * CardFactory.heroCard('title1', ['imageUrl1'], ['button1']), + * CardFactory.heroCard('title2', ['imageUrl2'], ['button2']), + * CardFactory.heroCard('title3', ['imageUrl3'], ['button3']) + * ]); + * ``` + * @param attachments Array of attachments to include in the message. + * @param text (Optional) text of the message. + * @param speak (Optional) SSML to include with the message. + * @param inputHint (Optional) input hint for the message. + * @returns A message activity that will display a set of attachments using a carousel layout. + */ + static carousel(attachments, text, speak, inputHint) { + return attachmentActivity(botframework_schema_1.AttachmentLayoutTypes.Carousel, attachments, text, speak, inputHint); + } + /** + * Returns a message that will display a single image or video to a user. + * + * @remarks + * This example shows sending an image to the user: + * + * ```JavaScript + * const message = MessageFactory.contentUrl('https://example.com/hawaii.jpg', 'image/jpeg', 'Hawaii Trip', 'A photo from our family vacation.'); + * ``` + * @param url Url of the image/video to send. + * @param contentType The MIME type of the image/video. + * @param name (Optional) Name of the image/video file. + * @param text (Optional) text of the message. + * @param speak (Optional) SSML to include with the message. + * @param inputHint (Optional) input hint for the message. + * @returns A message activity that will display a single image or video to a user. + */ + static contentUrl(url, contentType, name, text, speak, inputHint) { + const a = { contentType, contentUrl: url }; + if (name) { + a.name = name; + } + return attachmentActivity(botframework_schema_1.AttachmentLayoutTypes.List, [a], text, speak, inputHint); + } + }; + exports2.MessageFactory = MessageFactory; + function attachmentActivity(attachmentLayout, attachments, text, speak, inputHint) { + const msg = { + type: botframework_schema_1.ActivityTypes.Message, + attachmentLayout, + attachments, + inputHint: inputHint || botframework_schema_1.InputHints.AcceptingInput + }; + if (text) { + msg.text = text; + } + if (speak) { + msg.speak = speak; + } + return msg; + } + } +}); + +// node_modules/botbuilder-core/lib/activityFactory.js +var require_activityFactory = __commonJS({ + "node_modules/botbuilder-core/lib/activityFactory.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ActivityFactory = void 0; + var botframework_schema_1 = require_lib4(); + var messageFactory_1 = require_messageFactory(); + var cardFactory_1 = require_cardFactory(); + var ActivityFactory = class { + /** + * Generate the activity. + * + * @param lgResult string result from languageGenerator. + * @returns The generated MessageActivity. + */ + static fromObject(lgResult) { + if (lgResult == null) { + return { type: botframework_schema_1.ActivityTypes.Message }; + } + if (typeof lgResult === "string") { + return this.buildActivityFromText(lgResult.trim()); + } + if (typeof lgResult === "object") { + return this.buildActivityFromLGStructuredResult(lgResult); + } else { + return this.buildActivityFromText(JSON.stringify(lgResult).trim()); + } + } + /** + * Given a lg result, create a text activity. This method will create a MessageActivity from text. + * + * @param text lg text output. + * @returns The created MessageActivity. + */ + static buildActivityFromText(text) { + const msg = { + type: botframework_schema_1.ActivityTypes.Message + }; + if (text) { + msg.text = text; + msg.speak = text; + } + return msg; + } + /** + * Given a structured lg result, create an activity. This method will create an MessageActivity from object + * + * @param lgValue lg output. + * @returns The created MessageActivity. + */ + static buildActivityFromLGStructuredResult(lgValue) { + let activity = {}; + const type = this.getStructureType(lgValue); + if (this.genericCardTypeMapping.has(type) || type === "attachment") { + activity = messageFactory_1.MessageFactory.attachment(this.getAttachment(lgValue)); + } else if (type === "activity") { + activity = this.buildActivity(lgValue); + } else if (lgValue) { + activity = this.buildActivityFromText(JSON.stringify(lgValue).trim()); + } + return activity; + } + /** + * Builds an [Activity](xref:botframework-schema.Activity) with a given message. + * + * @param messageValue Message value on which to base the activity. + * @returns [Activity](xref:botframework-schema.Activity) with the given message. + */ + static buildActivity(messageValue) { + const activity = { type: botframework_schema_1.ActivityTypes.Message }; + for (const key of Object.keys(messageValue)) { + const property = key.trim(); + if (property === this.lgType) { + continue; + } + const value = messageValue[key]; + switch (property.toLowerCase()) { + case "text": + activity.text = typeof value === "string" ? value : JSON.stringify(value); + break; + case "speak": + activity.speak = typeof value === "string" ? value : JSON.stringify(value); + break; + case "attachments": + activity.attachments = this.getAttachments(value); + break; + case "suggestedactions": + activity.suggestedActions = this.getSuggestions(value); + break; + default: + activity[this.realProperty(property, this.activityProperties)] = value; + break; + } + } + return activity; + } + /** + * @private + */ + static getSuggestions(suggestionsValue) { + const actions = this.normalizedToList(suggestionsValue); + const suggestedActions = { + actions: this.getCardActions(actions), + to: [] + }; + return suggestedActions; + } + /** + * @private + */ + static getButtons(buttonsValue) { + const actions = this.normalizedToList(buttonsValue); + return this.getCardActions(actions); + } + /** + * @private + */ + static getCardActions(actions) { + return actions.map((u) => this.getCardAction(u)); + } + /** + * @private + */ + static getCardAction(action) { + let cardAction; + if (typeof action === "string") { + cardAction = { type: botframework_schema_1.ActionTypes.ImBack, value: action, title: action, channelData: void 0 }; + } else { + const type = this.getStructureType(action); + cardAction = { + type: botframework_schema_1.ActionTypes.ImBack, + title: "", + value: "" + }; + if (type === "cardaction") { + for (const key of Object.keys(action)) { + const property = key.trim(); + if (property === this.lgType) { + continue; + } + cardAction[this.realProperty(property, this.cardActionProperties)] = action[key]; + } + } + } + return cardAction; + } + /** + * @private + */ + static getAttachments(input) { + const attachments = []; + const attachmentsJsonList = this.normalizedToList(input); + for (const attachmentsJson of attachmentsJsonList) { + if (typeof attachmentsJson === "object") { + attachments.push(this.getAttachment(attachmentsJson)); + } + } + return attachments; + } + /** + * @private + */ + static getAttachment(input) { + let attachment = { + contentType: "" + }; + const type = this.getStructureType(input); + if (this.genericCardTypeMapping.has(type)) { + attachment = this.getCardAttachment(this.genericCardTypeMapping.get(type), input); + } else if (type === "adaptivecard") { + attachment = cardFactory_1.CardFactory.adaptiveCard(input); + } else if (type === "attachment") { + attachment = this.getNormalAttachment(input); + } else { + attachment = { contentType: type, content: input }; + } + return attachment; + } + /** + * @private + */ + static getNormalAttachment(input) { + const attachment = { contentType: "" }; + for (const key of Object.keys(input)) { + const property = key.trim(); + const value = input[key]; + switch (property.toLowerCase()) { + case "contenttype": { + const type = value.toString().toLowerCase(); + if (this.genericCardTypeMapping.has(type)) { + attachment.contentType = this.genericCardTypeMapping.get(type); + } else if (type === "adaptivecard") { + attachment.contentType = this.adaptiveCardType; + } else { + attachment.contentType = type; + } + break; + } + default: { + attachment[this.realProperty(property, this.attachmentProperties)] = value; + break; + } + } + } + return attachment; + } + /** + * @private + */ + static getCardAttachment(type, input) { + const card = {}; + for (const key of Object.keys(input)) { + const property = key.trim().toLowerCase(); + const value = input[key]; + switch (property) { + case "tap": { + card[property] = this.getCardAction(value); + break; + } + case "image": + case "images": { + if (type === cardFactory_1.CardFactory.contentTypes.heroCard || type === cardFactory_1.CardFactory.contentTypes.thumbnailCard) { + if (!("images" in card)) { + card["images"] = []; + } + const imageList = this.normalizedToList(value); + imageList.forEach((u) => card["images"].push(this.normalizedToMediaOrImage(u))); + } else { + card["image"] = this.normalizedToMediaOrImage(value); + } + break; + } + case "media": { + if (!("media" in card)) { + card["media"] = []; + } + const mediaList = this.normalizedToList(value); + mediaList.forEach((u) => card["media"].push(this.normalizedToMediaOrImage(u))); + break; + } + case "buttons": { + if (!("buttons" in card)) { + card["buttons"] = []; + } + const buttons = this.getButtons(value); + buttons.forEach((u) => card[property].push(u)); + break; + } + case "autostart": + case "shareable": + case "autoloop": { + const boolValue = this.getValidBooleanValue(value.toString()); + if (boolValue !== void 0) { + card[property] = boolValue; + } else { + card[property] = value; + } + break; + } + default: { + card[this.realProperty(key.trim(), this.cardProperties)] = value; + break; + } + } + } + const attachment = { + contentType: type, + content: card + }; + return attachment; + } + /** + * @private + */ + static realProperty(property, builtinProperties) { + const properties = builtinProperties.map((u) => u.toLowerCase()); + if (properties.includes(property.toLowerCase())) { + return builtinProperties[properties.indexOf(property.toLowerCase())]; + } else { + return property; + } + } + /** + * @private + */ + static normalizedToList(item) { + if (item === void 0) { + return []; + } else if (Array.isArray(item)) { + return item; + } else { + return [item]; + } + } + /** + * @private + */ + static getStructureType(input) { + let result = ""; + if (input && typeof input === "object") { + if (this.lgType in input) { + result = input[this.lgType].toString(); + } else if ("type" in input) { + result = input["type"].toString(); + } + } + return result.trim().toLowerCase(); + } + /** + * @private + */ + static normalizedToMediaOrImage(item) { + if (!item) { + return {}; + } else if (typeof item === "string") { + return { url: item }; + } else + return item; + } + /** + * @private + */ + static getValidBooleanValue(boolValue) { + if (typeof boolValue === "boolean") { + return boolValue; + } + if (boolValue.toLowerCase() === "true") { + return true; + } else if (boolValue.toLowerCase() === "false") { + return false; + } + return void 0; + } + }; + exports2.ActivityFactory = ActivityFactory; + ActivityFactory.lgType = "lgType"; + ActivityFactory.adaptiveCardType = cardFactory_1.CardFactory.contentTypes.adaptiveCard; + ActivityFactory.genericCardTypeMapping = /* @__PURE__ */ new Map([ + ["herocard", cardFactory_1.CardFactory.contentTypes.heroCard], + ["thumbnailcard", cardFactory_1.CardFactory.contentTypes.thumbnailCard], + ["audiocard", cardFactory_1.CardFactory.contentTypes.audioCard], + ["videocard", cardFactory_1.CardFactory.contentTypes.videoCard], + ["animationcard", cardFactory_1.CardFactory.contentTypes.animationCard], + ["signincard", cardFactory_1.CardFactory.contentTypes.signinCard], + ["oauthcard", cardFactory_1.CardFactory.contentTypes.oauthCard], + ["receiptcard", cardFactory_1.CardFactory.contentTypes.receiptCard] + ]); + ActivityFactory.activityProperties = [ + "type", + "id", + "timestamp", + "localTimestamp", + "localTimezone", + "callerId", + "serviceUrl", + "channelId", + "from", + "conversation", + "recipient", + "textFormat", + "attachmentLayout", + "membersAdded", + "membersRemoved", + "reactionsAdded", + "reactionsRemoved", + "topicName", + "historyDisclosed", + "locale", + "text", + "speak", + "inputHint", + "summary", + "suggestedActions", + "attachments", + "entities", + "channelData", + "action", + "replyToId", + "label", + "valueType", + "value", + "name", + "typrelatesToe", + "code", + "expiration", + "importance", + "deliveryMode", + "listenFor", + "textHighlights", + "semanticAction" + ]; + ActivityFactory.cardActionProperties = [ + "type", + "title", + "image", + "text", + "displayText", + "value", + "channelData" + ]; + ActivityFactory.attachmentProperties = [ + "contentType", + "contentUrl", + "content", + "name", + "thumbnailUrl" + ]; + ActivityFactory.cardProperties = [ + "title", + "subtitle", + "text", + "images", + "image", + "buttons", + "tap", + "media", + "shareable", + "autoloop", + "autostart", + "aspect", + "duration", + "value", + "connectionName", + "tokenExchangeResource", + "facts", + "items", + "total", + "tax", + "vat" + ]; + } +}); + +// node_modules/botbuilder-core/lib/activityHandlerBase.js +var require_activityHandlerBase = __commonJS({ + "node_modules/botbuilder-core/lib/activityHandlerBase.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ActivityHandlerBase = exports2.INVOKE_RESPONSE_KEY = void 0; + var _1 = require_lib10(); + var botframework_schema_1 = require_lib4(); + exports2.INVOKE_RESPONSE_KEY = Symbol("invokeResponse"); + var ActivityHandlerBase = class { + /** + * Called at the start of the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to use custom logic for emitting events. + * + * The default logic is to call any type-specific and sub-type handlers registered via + * the various _on event_ methods. Type-specific events are defined for: + * - Message activities + * - Conversation update activities + * - Message reaction activities + * - Event activities + * - Invoke activities + * - _Unrecognized_ activities, ones that this class has not otherwise defined an _on event_ method for. + */ + onTurnActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + switch (context.activity.type) { + case _1.ActivityTypes.Message: + yield this.onMessageActivity(context); + break; + case _1.ActivityTypes.MessageUpdate: + yield this.onMessageUpdateActivity(context); + break; + case _1.ActivityTypes.MessageDelete: + yield this.onMessageDeleteActivity(context); + break; + case _1.ActivityTypes.ConversationUpdate: + yield this.onConversationUpdateActivity(context); + break; + case _1.ActivityTypes.MessageReaction: + yield this.onMessageReactionActivity(context); + break; + case _1.ActivityTypes.Event: + yield this.onEventActivity(context); + break; + case _1.ActivityTypes.Invoke: { + const invokeResponse = yield this.onInvokeActivity(context); + if (invokeResponse && !context.turnState.get(exports2.INVOKE_RESPONSE_KEY)) { + yield context.sendActivity({ value: invokeResponse, type: "invokeResponse" }); + } + break; + } + case _1.ActivityTypes.EndOfConversation: + yield this.onEndOfConversationActivity(context); + break; + case _1.ActivityTypes.Typing: + yield this.onTypingActivity(context); + break; + case _1.ActivityTypes.InstallationUpdate: + yield this.onInstallationUpdateActivity(context); + break; + case _1.ActivityTypes.Command: + yield this.onCommandActivity(context); + break; + case _1.ActivityTypes.CommandResult: + yield this.onCommandResultActivity(context); + break; + default: + yield this.onUnrecognizedActivity(context); + break; + } + }); + } + /** + * Provides a hook for emitting the _message_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _message_ handlers and then continue the event + * emission process. + */ + onMessageActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _message update_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _message update_ handlers and then continue the event + * emission process. + */ + onMessageUpdateActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _message delete_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _message delete_ handlers and then continue the event + * emission process. + */ + onMessageDeleteActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _conversation update_ event. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to run registered _conversation update_ handlers and then continue the event + * emission process. + * + * The default logic is: + * - If members other than the bot were added to the conversation, + * call [onMembersAddedActivity](xref:botbuilder-core.ActivityHandlerBase.onMembersAddedActivity). + * - If members other than the bot were removed from the conversation, + * call [onMembersRemovedActivity](xref:botbuilder-core.ActivityHandlerBase.onMembersRemovedActivity). + */ + onConversationUpdateActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.membersAdded && context.activity.membersAdded.length > 0) { + if (context.activity.membersAdded.filter((m) => context.activity.recipient && context.activity.recipient.id !== m.id).length) { + yield this.onMembersAddedActivity(context.activity.membersAdded, context); + } + } else if (context.activity.membersRemoved && context.activity.membersRemoved.length > 0) { + if (context.activity.membersRemoved.filter((m) => context.activity.recipient && context.activity.recipient.id !== m.id).length) { + yield this.onMembersRemovedActivity(context.activity.membersRemoved, context); + } + } + }); + } + /** + * Provides a hook for emitting the _message reaction_ event. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to run registered _message reaction_ handlers and then continue the event + * emission process. + * + * The default logic is: + * - If reactions were added to a message, + * call [onReactionsAddedActivity](xref:botbuilder-core.ActivityHandlerBase.onReactionsAddedActivity). + * - If reactions were removed from a message, + * call [onReactionsRemovedActivity](xref:botbuilder-core.ActivityHandlerBase.onReactionsRemovedActivity). + */ + onMessageReactionActivity(context) { + var _a, _b; + return __awaiter2(this, void 0, void 0, function* () { + if ((_a = context.activity.reactionsAdded) === null || _a === void 0 ? void 0 : _a.length) { + yield this.onReactionsAddedActivity(context.activity.reactionsAdded, context); + } + if ((_b = context.activity.reactionsRemoved) === null || _b === void 0 ? void 0 : _b.length) { + yield this.onReactionsRemovedActivity(context.activity.reactionsRemoved, context); + } + }); + } + /** + * Provides a hook for emitting the _event_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _event_ handlers and then continue the event + * emission process. + */ + onEventActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for invoke calls. + * + * @param _context The context object for the current turn. + * @returns {Promise} An Invoke Response for the activity. + * @remarks + * Override this method to handle particular invoke calls. + */ + onInvokeActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return { status: botframework_schema_1.StatusCodes.NOT_IMPLEMENTED }; + }); + } + /** + * Provides a hook for emitting the _end of conversation_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _end of conversation_ handlers and then continue the event + * emission process. + */ + onEndOfConversationActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _typing_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _typing_ handlers and then continue the event + * emission process. + */ + onTypingActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _installationupdate_ event. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to run registered _installationupdate_ handlers and then continue the event + * emission process. + */ + onInstallationUpdateActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + switch (context.activity.action) { + case "add": + case "add-upgrade": + yield this.onInstallationUpdateAddActivity(context); + return; + case "remove": + case "remove-upgrade": + yield this.onInstallationUpdateRemoveActivity(context); + return; + } + }); + } + /** + * Provides a hook for emitting the _installationupdateadd_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _installationupdateadd_ handlers and then continue the event + * emission process. + */ + onInstallationUpdateAddActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _installationupdateremove_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _installationupdateremove_ handlers and then continue the event + * emission process. + */ + onInstallationUpdateRemoveActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _unrecognized_ event. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _unrecognized_ handlers and then continue the event + * emission process. + */ + onUnrecognizedActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _members added_ event, + * a sub-type of the _conversation update_ event. + * + * @param _membersAdded An array of the members added to the conversation. + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _members added_ handlers and then continue the event + * emission process. + */ + onMembersAddedActivity(_membersAdded, _context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _members removed_ event, + * a sub-type of the _conversation update_ event. + * + * @param _membersRemoved An array of the members removed from the conversation. + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _members removed_ handlers and then continue the event + * emission process. + */ + onMembersRemovedActivity(_membersRemoved, _context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _reactions added_ event, + * a sub-type of the _message reaction_ event. + * + * @param _reactionsAdded An array of the reactions added to a message. + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _reactions added_ handlers and then continue the event + * emission process. + */ + onReactionsAddedActivity(_reactionsAdded, _context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Provides a hook for emitting the _reactions removed_ event, + * a sub-type of the _message reaction_ event. + * + * @param _reactionsRemoved An array of the reactions removed from a message. + * @param _context The context object for the current turn. + * @remarks + * Override this method to run registered _reactions removed_ handlers and then continue the event + * emission process. + */ + onReactionsRemovedActivity(_reactionsRemoved, _context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Invoked when a command activity is received when the base behavior of + * `onTurn()` is used. + * Commands are requests to perform an action and receivers typically respond with + * one or more commandResult activities. Receivers are also expected to explicitly + * reject unsupported command activities. + * + * @param _context A context object for this turn. + * @returns A promise that represents the work queued to execute. + */ + onCommandActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Invoked when a commandResult activity is received when the base behavior of + * `onTurn()` is used. + * CommandResult activity can be used to communicate the result of a command execution. + * + * @param _context A context object for this turn. + * @returns A promise that represents the work queued to execute. + */ + onCommandResultActivity(_context) { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * Called to initiate the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Typically, you would provide this method as the function handler that the adapter calls + * to perform the bot's logic after the received activity has been pre-processed by the adapter + * and routed through any middleware. + * + * For example: + * ```javascript + * server.post('/api/messages', (req, res) => { + * adapter.processActivity(req, res, async (context) => { + * // Route to main dialog. + * await bot.run(context); + * }); + * }); + * ``` + * + * **See also** + * - [BotFrameworkAdapter.processActivity](xref:botbuilder.BotFrameworkAdapter.processActivity) + */ + run(context) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context) { + throw new Error("Missing TurnContext parameter"); + } + if (!context.activity) { + throw new Error("TurnContext does not include an activity"); + } + if (!context.activity.type) { + throw new Error("Activity is missing its type"); + } + yield this.onTurnActivity(context); + }); + } + }; + exports2.ActivityHandlerBase = ActivityHandlerBase; + } +}); + +// node_modules/botbuilder-core/lib/invokeException.js +var require_invokeException = __commonJS({ + "node_modules/botbuilder-core/lib/invokeException.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.InvokeException = void 0; + var InvokeException = class extends Error { + /** + * @param status The Http status code of the error. + * @param response optional. The body of the exception. Default is null. + */ + constructor(status, response) { + super(); + this.status = status; + this.response = response; + this.name = "InvokeException"; + } + /** + * A factory method that creates a new [InvokeResponse](xref:botbuilder-core.InvokeResponse) object with the status code and body of the current object. + * + * @returns A new [InvokeResponse](xref:botbuilder-core.InvokeResponse) object. + */ + createInvokeResponse() { + return { + status: this.status, + body: this.response + }; + } + }; + exports2.InvokeException = InvokeException; + } +}); + +// node_modules/botbuilder-core/lib/signInConstants.js +var require_signInConstants = __commonJS({ + "node_modules/botbuilder-core/lib/signInConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.sharePointTokenExchange = exports2.tokenResponseEventName = exports2.tokenExchangeOperationName = exports2.verifyStateOperationName = void 0; + exports2.verifyStateOperationName = "signin/verifyState"; + exports2.tokenExchangeOperationName = "signin/tokenExchange"; + exports2.tokenResponseEventName = "tokens/response"; + exports2.sharePointTokenExchange = "cardExtension/token"; + } +}); + +// node_modules/botbuilder-core/lib/activityHandler.js +var require_activityHandler = __commonJS({ + "node_modules/botbuilder-core/lib/activityHandler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ActivityHandler = void 0; + var activityHandlerBase_1 = require_activityHandlerBase(); + var invokeException_1 = require_invokeException(); + var signInConstants_1 = require_signInConstants(); + var botframework_schema_1 = require_lib4(); + var ActivityHandler = class extends activityHandlerBase_1.ActivityHandlerBase { + constructor() { + super(...arguments); + this.handlers = {}; + } + /** + * Registers an activity event handler for the _turn_ event, emitted for every incoming activity, regardless of type. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + */ + onTurn(handler) { + return this.on("Turn", handler); + } + /** + * Registers an activity event handler for the _message_ event, emitted for every incoming message activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * Message activities represent content intended to be shown within a conversational interface + * and can contain text, speech, interactive cards, and binary or unknown attachments. + * Not all message activities contain text, the activity's [text](xref:botframework-schema.Activity.text) + * property can be `null` or `undefined`. + */ + onMessage(handler) { + return this.on("Message", handler); + } + /** + * Registers an activity event handler for the _message update_ event, emitted for every incoming message activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * Message update activities represent an update of an existing message activity within a conversation. + * The updated activity is referred to by the [id](xref:botbuilder-core.TurnContext.activity.id) and + * [conversation](xref:botbuilder-core.TurnContext.activity.conversation) fields within the activity, and the + * message update activity contains all fields in the revised message activity. + * Message update activities are identified by a [type](xref:botbuilder-core.TurnContext.activity.type) value of + * `messageUpdate`. + */ + onMessageUpdate(handler) { + return this.on("MessageUpdate", handler); + } + /** + * Registers an activity event handler for the _message delete_ event, emitted for every incoming message activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * Message delete activities represent a deletion of an existing message activity within a conversation. + * The deleted activity is referred to by the [id](xref:botbuilder-core.TurnContext.activity.id) and + * [conversation](xref:botbuilder-core.TurnContext.activity.conversation) fields within the activity. + * Message delete activities are identified by a [type](xref:botbuilder-core.TurnContext.activity.type) value of + * `messageDelete`. + */ + onMessageDelete(handler) { + return this.on("MessageDelete", handler); + } + /** + * Registers an activity event handler for the _conversation update_ event, emitted for every incoming + * conversation update activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * Conversation update activities describe a changes to a conversation's metadata, such as title, participants, + * or other channel-specific information. + * + * To handle when members are added to or removed from the conversation, use the + * [onMembersAdded](xref:botbuilder-core.ActivityHandler.onMembersAdded) and + * [onMembersRemoved](xref:botbuilder-core.ActivityHandler.onMembersRemoved) sub-type event handlers. + */ + onConversationUpdate(handler) { + return this.on("ConversationUpdate", handler); + } + /** + * Registers an activity event handler for the _members added_ event, emitted for any incoming + * conversation update activity that includes members added to the conversation. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * The activity's [membersAdded](xref:botframework-schema.Activity.membersAdded) property + * contains the members added to the conversation, which can include the bot. + * + * To handle conversation update events in general, use the + * [onConversationUpdate](xref:botbuilder-core.ActivityHandler.onConversationUpdate) type-specific event handler. + */ + onMembersAdded(handler) { + return this.on("MembersAdded", handler); + } + /** + * Registers an activity event handler for the _members removed_ event, emitted for any incoming + * conversation update activity that includes members removed from the conversation. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * The activity's [membersRemoved](xref:botframework-schema.Activity.membersRemoved) property + * contains the members removed from the conversation, which can include the bot. + * + * To handle conversation update events in general, use the + * [onConversationUpdate](xref:botbuilder-core.ActivityHandler.onConversationUpdate) type-specific event handler. + */ + onMembersRemoved(handler) { + return this.on("MembersRemoved", handler); + } + /** + * Registers an activity event handler for the _message reaction_ event, emitted for every incoming + * message reaction activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * Message reaction activities represent a social interaction on an existing message activity + * within a conversation. The original activity is referred to by the message reaction activity's + * [replyToId](xref:botframework-schema.Activity.replyToId) property. The + * [from](xref:botframework-schema.Activity.from) property represents the source of the reaction, + * such as the user that reacted to the message. + * + * To handle when reactions are added to or removed from messages in the conversation, use the + * [onReactionsAdded](xref:botbuilder-core.ActivityHandler.onReactionsAdded) and + * [onReactionsRemoved](xref:botbuilder-core.ActivityHandler.onReactionsRemoved) sub-type event handlers. + */ + onMessageReaction(handler) { + return this.on("MessageReaction", handler); + } + /** + * Registers an activity event handler for the _reactions added_ event, emitted for any incoming + * message reaction activity that describes reactions added to a message. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * The activity's [reactionsAdded](xref:botframework-schema.Activity.reactionsAdded) property + * includes one or more reactions that were added. + * + * To handle message reaction events in general, use the + * [onMessageReaction](xref:botbuilder-core.ActivityHandler.onMessageReaction) type-specific event handler. + */ + onReactionsAdded(handler) { + return this.on("ReactionsAdded", handler); + } + /** + * Registers an activity event handler for the _reactions removed_ event, emitted for any incoming + * message reaction activity that describes reactions removed from a message. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * The activity's [reactionsRemoved](xref:botframework-schema.Activity.reactionsRemoved) property + * includes one or more reactions that were removed. + * + * To handle message reaction events in general, use the + * [onMessageReaction](xref:botbuilder-core.ActivityHandler.onMessageReaction) type-specific event handler. + */ + onReactionsRemoved(handler) { + return this.on("ReactionsRemoved", handler); + } + /** + * Registers an activity event handler for the _event_ event, emitted for every incoming event activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * Event activities communicate programmatic information from a client or channel to a bot. + * The meaning of an event activity is defined by the activity's + * [name](xref:botframework-schema.Activity.name) property, which is meaningful within the scope + * of a channel. Event activities are designed to carry both interactive information (such as + * button clicks) and non-interactive information (such as a notification of a client + * automatically updating an embedded speech model). + * + * To handle a `tokens/response` event event, use the + * [onTokenResponseEvent](xref:botbuilder-core.ActivityHandler.onTokenResponseEvent) sub-type + * event handler. To handle other named events, add logic to this handler. + */ + onEvent(handler) { + return this.on("Event", handler); + } + /** + * Registers an activity event handler for the _end of conversation_ activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * This activity is typically send from a Skill to a Skill caller indicating the end of that particular child conversation. + * + * To handle an End of Conversation, use the + * [onEndOfConversation](xref:botbuilder-core.ActivityHandler.onEndOfConversation) type-specific event handler. + */ + onEndOfConversation(handler) { + return this.on("EndOfConversation", handler); + } + /** + * Registers an activity event handler for the _typing_ activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * To handle a Typing event, use the + * [onTyping](xref:botbuilder-core.ActivityHandler.onTyping) type-specific event handler. + */ + onTyping(handler) { + return this.on("Typing", handler); + } + /** + * Registers an activity event handler for the _installationupdate_ activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * To handle a InstallationUpdate event, use the + * [onInstallationUpdate](xref:botbuilder-core.ActivityHandler.onInstallationUpdate) type-specific event handler. + */ + onInstallationUpdate(handler) { + return this.on("InstallationUpdate", handler); + } + /** + * Registers an activity event handler for the _installationupdate add_ activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * To handle a InstallationUpdateAdd event, use the + * [onInstallationUpdateAdd](xref:botbuilder-core.ActivityHandler.onInstallationUpdateAdd) type-specific event handler. + */ + onInstallationUpdateAdd(handler) { + return this.on("InstallationUpdateAdd", handler); + } + /** + * Registers an activity event handler for the _installationupdate remove_ activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * To handle a InstallationUpdateRemove event, use the + * [onInstallationUpdateRemove](xref:botbuilder-core.ActivityHandler.onInstallationUpdateRemove) type-specific event handler. + */ + onInstallationUpdateRemove(handler) { + return this.on("InstallationUpdateRemove", handler); + } + /** + * Registers an activity event handler for the _tokens-response_ event, emitted for any incoming + * `tokens/response` event activity. These are generated as part of the OAuth authentication flow. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * The activity's [value](xref:botframework-schema.Activity.value) property contains the user token. + * + * If your bot handles authentication using an [OAuthPrompt](xref:botbuilder-dialogs.OAuthPrompt) + * within a dialog, then the dialog will need to receive this activity to complete the authentication flow. + * + * To handle other named events and event events in general, use the + * [onEvent](xref:botbuilder-core.ActivityHandler.onEvent) type-specific event handler. + */ + onTokenResponseEvent(handler) { + return this.on("TokenResponseEvent", handler); + } + /** + * Registers an activity event handler for the _command_ activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * To handle a Command event, use the + * [onCommand](xref:botbuilder-core.ActivityHandler.onCommand) type-specific event handler. + */ + onCommand(handler) { + return this.on("Command", handler); + } + /** + * Registers an activity event handler for the _CommandResult_ activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * To handle a CommandResult event, use the + * [onCommandResult](xref:botbuilder-core.ActivityHandler.onCommandResult) type-specific event handler. + */ + onCommandResult(handler) { + return this.on("CommandResult", handler); + } + /** + * Registers an activity event handler for the _unrecognized activity type_ event, emitted for an + * incoming activity with a type for which the [ActivityHandler](xref:botbuilder-core.ActivityHandler) + * doesn't provide an event handler. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * @remarks + * The `ActivityHandler` does not define events for all activity types defined in the + * [Bot Framework Activity schema](http://aka.ms/botSpecs-activitySchema). In addition, + * channels and custom adapters can create [Activities](xref:botframework-schema.Activity) with + * types not in the schema. When the activity handler receives such an event, it emits an unrecognized activity type event. + * + * The activity's [type](xref:botframework-schema.Activity.type) property contains the activity type. + */ + onUnrecognizedActivityType(handler) { + return this.on("UnrecognizedActivityType", handler); + } + /** + * Registers an activity event handler for the _dialog_ event, emitted as the last event for an incoming activity. + * + * @param handler The event handler. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + */ + onDialog(handler) { + return this.on("Dialog", handler); + } + /** + * Called to initiate the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Typically, you would provide this method as the function handler that the adapter calls + * to perform the bot's logic after the received activity has been pre-processed by the adapter + * and routed through any middleware. + * + * For example: + * ```javascript + * server.post('/api/messages', (req, res) => { + * adapter.processActivity(req, res, async (context) => { + * // Route to bot's activity logic. + * await bot.run(context); + * }); + * }); + * ``` + * + * **See also** + * - [BotFrameworkAdapter.processActivity](xref:botbuilder.BotFrameworkAdapter.processActivity) + */ + run(context) { + const _super = Object.create(null, { + run: { get: () => super.run } + }); + return __awaiter2(this, void 0, void 0, function* () { + yield _super.run.call(this, context); + }); + } + /** + * Called at the start of the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to use custom logic for emitting events. + * + * The default logic is to call any handlers registered via [onTurn](xref:botbuilder-core.ActivityHandler.onTurn), + * and then continue by calling [ActivityHandlerBase.onTurnActivity](xref:botbuilder-core.ActivityHandlerBase.onTurnActivity). + */ + onTurnActivity(context) { + const _super = Object.create(null, { + onTurnActivity: { get: () => super.onTurnActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "Turn", () => __awaiter2(this, void 0, void 0, function* () { + yield _super.onTurnActivity.call(this, context); + })); + }); + } + /** + * Runs all registered _message_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onMessage](xref:botbuilder-core.ActivityHandler.onMessage), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onMessageActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "Message", this.defaultNextEvent(context)); + }); + } + /** + * Runs all registered _message update_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onMessageUpdate](xref:botbuilder-core.ActivityHandler.onMessageUpdate), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onMessageUpdateActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "MessageUpdate", () => __awaiter2(this, void 0, void 0, function* () { + yield this.dispatchMessageUpdateActivity(context); + })); + }); + } + /** + * Runs all registered _message delete_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onMessageDelete](xref:botbuilder-core.ActivityHandler.onMessageDelete), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onMessageDeleteActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "MessageDelete", () => __awaiter2(this, void 0, void 0, function* () { + yield this.dispatchMessageDeleteActivity(context); + })); + }); + } + /** + * Provides default behavior for invoke activities. + * + * @param context The context object for the current turn. + * @returns {Promise} An Invoke Response for the activity. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * The default logic is to check for a signIn invoke and handle that + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onInvokeActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + try { + switch (context.activity.name) { + case "application/search": { + const invokeValue = this.getSearchInvokeValue(context.activity); + const response = yield this.onSearchInvoke(context, invokeValue); + return { status: response.statusCode, body: response }; + } + case "adaptiveCard/action": { + const invokeValue = this.getAdaptiveCardInvokeValue(context.activity); + const response = yield this.onAdaptiveCardInvoke(context, invokeValue); + return { status: response.statusCode, body: response }; + } + case signInConstants_1.verifyStateOperationName: + case signInConstants_1.tokenExchangeOperationName: + yield this.onSignInInvoke(context); + return { status: botframework_schema_1.StatusCodes.OK }; + default: + throw new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.NOT_IMPLEMENTED); + } + } catch (err) { + if (err.message === "NotImplemented") { + return { status: botframework_schema_1.StatusCodes.NOT_IMPLEMENTED }; + } + if (err instanceof invokeException_1.InvokeException) { + return err.createInvokeResponse(); + } + throw err; + } finally { + this.defaultNextEvent(context)(); + } + }); + } + /** + * Handle _signin invoke activity type_. + * + * @param _context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + */ + onSignInInvoke(_context) { + return __awaiter2(this, void 0, void 0, function* () { + throw new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.NOT_IMPLEMENTED); + }); + } + /** + * Invoked when the bot is sent an Adaptive Card Action Execute. + * + * @param _context the context object for the current turn + * @param _invokeValue incoming activity value + * @returns {Promise} An Adaptive Card Invoke Response for the activity. + */ + onAdaptiveCardInvoke(_context, _invokeValue) { + return Promise.reject(new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.NOT_IMPLEMENTED)); + } + /** + * Invoked when the bot is sent an invoke activity with name of 'application/search'. + * + * @param _context the context object for the current turn. + * @param _invokeValue incoming activity value. + * @returns {Promise} A Search Invoke Response for the activity. + */ + onSearchInvoke(_context, _invokeValue) { + return Promise.reject(new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.NOT_IMPLEMENTED)); + } + /** + * Runs all registered _endOfConversation_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onEndOfConversationActivity](xref:botbuilder-core.ActivityHandler.onMessage), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onEndOfConversationActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "EndOfConversation", this.defaultNextEvent(context)); + }); + } + /** + * Runs all registered _typing_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onTypingActivity](xref:botbuilder-core.ActivityHandler.onTypingActivity), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onTypingActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "Typing", this.defaultNextEvent(context)); + }); + } + /** + * Runs all registered _instllationupdate_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onInstallationUpdateActivity](xref:botbuilder-core.ActivityHandler.onInstallationUpdateActivity), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onInstallationUpdateActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "InstallationUpdate", () => __awaiter2(this, void 0, void 0, function* () { + yield this.dispatchInstallationUpdateActivity(context); + })); + }); + } + /** + * Runs all registered _command_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + */ + onCommandActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "Command", this.defaultNextEvent(context)); + }); + } + /** + * Runs all registered _commandresult_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + */ + onCommandResultActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "CommandResult", this.defaultNextEvent(context)); + }); + } + /** + * Runs the _installation update_ sub-type handlers, as appropriate, and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels or to add + * custom conversation update sub-type events. + * + * The default logic is: + * - If any members were added, call handlers registered via [onMembersAdded](xref:botbuilder-core.ActivityHandler.onMembersAdded). + * - If any members were removed, call handlers registered via [onMembersRemoved](xref:botbuilder-core.ActivityHandler.onMembersRemoved). + * - Continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + dispatchInstallationUpdateActivity(context) { + const _super = Object.create(null, { + onInstallationUpdateActivity: { get: () => super.onInstallationUpdateActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + switch (context.activity.action) { + case "add": + case "add-upgrade": + case "remove": + case "remove-upgrade": + yield _super.onInstallationUpdateActivity.call(this, context); + break; + default: + yield this.defaultNextEvent(context)(); + } + }); + } + /** + * Runs all registered _installation update add_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onInstallationUpdateAdd](xref:botbuilder-core.ActivityHandler.onInstallationUpdateAdd), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onInstallationUpdateAddActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "InstallationUpdateAdd", this.defaultNextEvent(context)); + }); + } + /** + * Runs all registered _installation update remove_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onInstallationUpdateRemove](xref:botbuilder-core.ActivityHandler.onInstallationUpdateRemove), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onInstallationUpdateRemoveActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "InstallationUpdateRemove", this.defaultNextEvent(context)); + }); + } + /** + * Runs all registered _unrecognized activity type_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onUnrecognizedActivityType](xref:botbuilder-core.ActivityHandler.onUnrecognizedActivityType), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onUnrecognizedActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "UnrecognizedActivityType", this.defaultNextEvent(context)); + }); + } + getSearchInvokeValue(activity) { + const { value } = activity; + if (!value) { + const response = this.createAdaptiveCardInvokeErrorResponse(botframework_schema_1.StatusCodes.BAD_REQUEST, "BadRequest", "Missing value property for search"); + throw new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.BAD_REQUEST, response); + } + if (!value.kind) { + if (activity.channelId === botframework_schema_1.Channels.Msteams) { + value.kind = "search"; + } else { + const response = this.createAdaptiveCardInvokeErrorResponse(botframework_schema_1.StatusCodes.BAD_REQUEST, "BadRequest", "Missing kind property for search."); + throw new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.BAD_REQUEST, response); + } + } + if (!value.queryText) { + const response = this.createAdaptiveCardInvokeErrorResponse(botframework_schema_1.StatusCodes.BAD_REQUEST, "BadRequest", "Missing queryText for search."); + throw new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.BAD_REQUEST, response); + } + return value; + } + getAdaptiveCardInvokeValue(activity) { + const { value } = activity; + if (!value) { + const response = this.createAdaptiveCardInvokeErrorResponse(botframework_schema_1.StatusCodes.BAD_REQUEST, "BadRequest", "Missing value property"); + throw new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.BAD_REQUEST, response); + } + if (value.action.type !== "Action.Execute") { + const response = this.createAdaptiveCardInvokeErrorResponse(botframework_schema_1.StatusCodes.BAD_REQUEST, "NotSupported", `The action '${value.action.type}' is not supported.`); + throw new invokeException_1.InvokeException(botframework_schema_1.StatusCodes.BAD_REQUEST, response); + } + const { action, authentication, state } = value; + const { data, id: actionId, type, verb } = action !== null && action !== void 0 ? action : {}; + const { connectionName, id: authenticationId, token } = authentication !== null && authentication !== void 0 ? authentication : {}; + return { + action: { + data, + id: actionId, + type, + verb + }, + authentication: { + connectionName, + id: authenticationId, + token + }, + state + }; + } + createAdaptiveCardInvokeErrorResponse(statusCode, code, message) { + return { + statusCode, + type: "application/vnd.microsoft.error", + value: { code, message } + }; + } + /** + * Runs all registered _conversation update_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onConversationUpdate](xref:botbuilder-core.ActivityHandler.onConversationUpdate), + * and then continue by calling + * [dispatchConversationUpdateActivity](xref:botbuilder-core.ActivityHandler.dispatchConversationUpdateActivity). + */ + onConversationUpdateActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "ConversationUpdate", () => __awaiter2(this, void 0, void 0, function* () { + yield this.dispatchConversationUpdateActivity(context); + })); + }); + } + /** + * Runs the _conversation update_ sub-type handlers, as appropriate, and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels or to add + * custom conversation update sub-type events. + * + * The default logic is: + * - If any members were added, call handlers registered via [onMembersAdded](xref:botbuilder-core.ActivityHandler.onMembersAdded). + * - If any members were removed, call handlers registered via [onMembersRemoved](xref:botbuilder-core.ActivityHandler.onMembersRemoved). + * - Continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + dispatchConversationUpdateActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.membersAdded && context.activity.membersAdded.length > 0) { + yield this.handle(context, "MembersAdded", this.defaultNextEvent(context)); + } else if (context.activity.membersRemoved && context.activity.membersRemoved.length > 0) { + yield this.handle(context, "MembersRemoved", this.defaultNextEvent(context)); + } else { + yield this.defaultNextEvent(context)(); + } + }); + } + /** + * Runs the _message update_ sub-type handlers, as appropriate, and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels or to add + * custom conversation update sub-type events. + * + * The default logic to simple call [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + dispatchMessageUpdateActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.defaultNextEvent(context)(); + }); + } + /** + * Runs the _message delete_ sub-type handlers, as appropriate, and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels or to add + * custom conversation update sub-type events. + * + * The default logic to simple call [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + dispatchMessageDeleteActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.defaultNextEvent(context)(); + }); + } + /** + * Runs all registered _message reaction_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onMessageReaction](xref:botbuilder-core.ActivityHandler.onMessageReaction), + * and then continue by calling + * [dispatchMessageReactionActivity](xref:botbuilder-core.ActivityHandler.dispatchMessageReactionActivity). + */ + onMessageReactionActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "MessageReaction", () => __awaiter2(this, void 0, void 0, function* () { + yield this.dispatchMessageReactionActivity(context); + })); + }); + } + /** + * Runs all registered _reactions added_ handlers and then continues the event emission process. + * + * @param reactionsAdded The list of reactions added. + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onReactionsAdded](xref:botbuilder-core.ActivityHandler.onReactionsAdded), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onReactionsAddedActivity(reactionsAdded, context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "ReactionsAdded", this.defaultNextEvent(context)); + }); + } + /** + * Runs all registered _reactions removed_ handlers and then continues the event emission process. + * + * @param reactionsRemoved The list of reactions removed. + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onReactionsRemoved](xref:botbuilder-core.ActivityHandler.onReactionsRemoved), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + onReactionsRemovedActivity(reactionsRemoved, context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "ReactionsRemoved", this.defaultNextEvent(context)); + }); + } + /** + * Runs the _message reaction_ sub-type handlers, as appropriate, and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels or to add + * custom message reaction sub-type events. + * + * The default logic is: + * - If reactions were added, call handlers registered via [onReactionsAdded](xref:botbuilder-core.ActivityHandler.onReactionsAdded). + * - If reactions were removed, call handlers registered via [onMembersRemoved](xref:botbuilder-core.ActivityHandler.onMembersRemoved). + * - Continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + dispatchMessageReactionActivity(context) { + const _super = Object.create(null, { + onMessageReactionActivity: { get: () => super.onMessageReactionActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.reactionsAdded || context.activity.reactionsRemoved) { + yield _super.onMessageReactionActivity.call(this, context); + } else { + yield this.defaultNextEvent(context)(); + } + }); + } + /** + * Runs all registered event_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onEvent](xref:botbuilder-core.ActivityHandler.onEvent), + * and then continue by calling + * [dispatchEventActivity](xref:botbuilder-core.ActivityHandler.dispatchEventActivity). + */ + onEventActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "Event", () => __awaiter2(this, void 0, void 0, function* () { + yield this.dispatchEventActivity(context); + })); + }); + } + /** + * Runs the _event_ sub-type handlers, as appropriate, and then continues the event emission process. + * + * @param context The context object for the current turn. + * @remarks + * Override this method to support channel-specific behavior across multiple channels or to add custom event sub-type events. + * For certain channels, such as Web Chat and custom Direct Line clients, developers can emit custom event activities from the client. + * + * The default logic is: + * - If the activity is a 'tokens/response' event, call handlers registered via + * [onTokenResponseEvent](xref:botbuilder-core.ActivityHandler.onTokenResponseEvent). + * - Continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + dispatchEventActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.name === signInConstants_1.tokenResponseEventName) { + yield this.handle(context, "TokenResponseEvent", this.defaultNextEvent(context)); + } else { + yield this.defaultNextEvent(context)(); + } + }); + } + /** + * Called at the end of the event emission process. + * + * @param context The context object for the current turn. + * @returns {Promise} A promise representing the async operation. + * @remarks + * Override this method to use custom logic for emitting events. + * + * The default logic is to call any handlers registered via [onDialog](xref:botbuilder-core.ActivityHandler.onDialog), + * and then complete the event emission process. + */ + defaultNextEvent(context) { + const runDialogs = () => __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "Dialog", () => __awaiter2(this, void 0, void 0, function* () { + })); + }); + return runDialogs; + } + /** + * Registers a bot event handler to receive a specific event. + * + * @param type The identifier for the event type. + * @param handler The event handler to register. + * @returns A reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + */ + on(type, handler) { + if (!this.handlers[type]) { + this.handlers[type] = [handler]; + } else { + this.handlers[type].push(handler); + } + return this; + } + /** + * Emits an event and executes any registered handlers. + * + * @param context The context object for the current turn. + * @param type The identifier for the event type. + * @param onNext The continuation function to call after all registered handlers for this event complete. + * @returns {Promise} The handler's return value. + * @remarks + * Runs any registered handlers for this event type and then calls the continuation function. + * + * This optionally produces a return value, to support _invoke_ activities. If multiple handlers + * produce a return value, the first one produced is returned. + */ + handle(context, type, onNext) { + return __awaiter2(this, void 0, void 0, function* () { + let returnValue = null; + function runHandler(index) { + return __awaiter2(this, void 0, void 0, function* () { + if (index < handlers.length) { + const val = yield handlers[index](context, () => runHandler(index + 1)); + if (typeof val !== "undefined" && returnValue === null) { + returnValue = val; + } + } else { + const val = yield onNext(); + if (typeof val !== "undefined") { + returnValue = val; + } + } + }); + } + const handlers = this.handlers[type] || []; + yield runHandler(0); + return returnValue; + }); + } + /** + * An [InvokeResponse](xref:botbuilder.InvokeResponse) factory that initializes the body to the parameter passed and status equal to OK. + * + * @param body JSON serialized content from a POST response. + * @returns A new [InvokeResponse](xref:botbuilder.InvokeResponse) object. + */ + static createInvokeResponse(body) { + return { status: 200, body }; + } + }; + exports2.ActivityHandler = ActivityHandler; + } +}); + +// node_modules/botbuilder-core/lib/registerClassMiddleware.js +var require_registerClassMiddleware = __commonJS({ + "node_modules/botbuilder-core/lib/registerClassMiddleware.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RegisterClassMiddleware = void 0; + var RegisterClassMiddleware = class { + /** + * Initialize a new instance of the RegisterClassMiddleware class. + * + * @param service The object or service to add. + * @param key The key for service object in turn state. + */ + constructor(service, key) { + this.service = service; + this._key = key; + } + /** + * Adds the associated object or service to the current turn context. + * + * @param turnContext The context object for this turn. + * @param next The delegate to call to continue the bot middleware pipeline. + */ + onTurn(turnContext, next) { + return __awaiter2(this, void 0, void 0, function* () { + turnContext.turnState.set(this._key, this.service); + if (next) { + yield next(); + } + }); + } + }; + exports2.RegisterClassMiddleware = RegisterClassMiddleware; + } +}); + +// node_modules/botbuilder-core/lib/adapterExtensions.js +var require_adapterExtensions = __commonJS({ + "node_modules/botbuilder-core/lib/adapterExtensions.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.useBotState = void 0; + var registerClassMiddleware_1 = require_registerClassMiddleware(); + function useBotState(botAdapter, ...botStates) { + for (const botState of botStates) { + const key = botState.constructor.name; + botAdapter.use(new registerClassMiddleware_1.RegisterClassMiddleware(botState, key)); + } + return botAdapter; + } + exports2.useBotState = useBotState; + } +}); + +// node_modules/botbuilder-core/lib/botStateSet.js +var require_botStateSet = __commonJS({ + "node_modules/botbuilder-core/lib/botStateSet.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotStateSet = void 0; + var BotStateSet = class _BotStateSet { + /** + * Creates a new BotStateSet instance. + * + * @param botStates One or more BotState plugins to register. + */ + constructor(...botStates) { + this.botStates = []; + _BotStateSet.prototype.add.apply(this, botStates); + } + /** + * Registers one or more `BotState` plugins with the set. + * + * @param botStates One or more BotState plugins to register. + * @returns The updated BotStateSet. + */ + add(...botStates) { + botStates.forEach((botstate) => { + if (typeof botstate.load === "function" && typeof botstate.saveChanges === "function") { + this.botStates.push(botstate); + } else { + throw new Error("BotStateSet: a object was added that isn't an instance of BotState."); + } + }); + return this; + } + /** + * Calls `BotState.load()` on all of the BotState plugins in the set. + * + * @remarks + * This will trigger all of the plugins to read in their state in parallel. + * + * ```JavaScript + * await stateSet.readAll(context); + * ``` + * @param context Context for current turn of conversation with the user. + * @param force (Optional) If `true` the cache will be bypassed and the state will always be read in directly from storage. Defaults to `false`. + */ + loadAll(context, force = false) { + return __awaiter2(this, void 0, void 0, function* () { + const promises = this.botStates.map((botstate) => botstate.load(context, force)); + yield Promise.all(promises); + return; + }); + } + /** + * Calls `BotState.saveChanges()` on all of the BotState plugins in the set. + * + * @remarks + * This will trigger all of the plugins to write out their state in parallel. + * + * ```JavaScript + * await stateSet.saveAllChanges(context); + * ``` + * @param context Context for current turn of conversation with the user. + * @param force (Optional) if `true` the state will always be written out regardless of its change state. Defaults to `false`. + */ + saveAllChanges(context, force = false) { + return __awaiter2(this, void 0, void 0, function* () { + const promises = this.botStates.map((botstate) => botstate.saveChanges(context, force)); + yield Promise.all(promises); + return; + }); + } + }; + exports2.BotStateSet = BotStateSet; + } +}); + +// node_modules/botbuilder-core/lib/autoSaveStateMiddleware.js +var require_autoSaveStateMiddleware = __commonJS({ + "node_modules/botbuilder-core/lib/autoSaveStateMiddleware.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AutoSaveStateMiddleware = void 0; + var botStateSet_1 = require_botStateSet(); + var AutoSaveStateMiddleware = class { + /** + * Creates a new AutoSaveStateMiddleware instance. + * + * @param botStates One or more BotState plugins to automatically save at the end of the turn. + */ + constructor(...botStates) { + this.botStateSet = new botStateSet_1.BotStateSet(); + botStateSet_1.BotStateSet.prototype.add.apply(this.botStateSet, botStates); + } + /** + * Called by the adapter (for example, a `BotFrameworkAdapter`) at runtime in order to process an inbound [Activity](xref:botframework-schema.Activity). + * + * @param context The context object for this turn. + * @param next {function} The next delegate function. + */ + onTurn(context, next) { + return __awaiter2(this, void 0, void 0, function* () { + yield next(); + yield this.botStateSet.saveAllChanges(context, false); + }); + } + /** + * Adds additional `BotState` plugins to be saved. + * + * @param botStates One or more BotState plugins to add. + * @returns The updated BotStateSet object. + */ + add(...botStates) { + botStateSet_1.BotStateSet.prototype.add.apply(this.botStateSet, botStates); + return this; + } + }; + exports2.AutoSaveStateMiddleware = AutoSaveStateMiddleware; + } +}); + +// node_modules/botbuilder-core/lib/internal.js +var require_internal2 = __commonJS({ + "node_modules/botbuilder-core/lib/internal.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.makeRevocable = exports2.shallowCopy = void 0; + function shallowCopy(value) { + if (Array.isArray(value)) { + return value.slice(0); + } + if (typeof value === "object") { + return Object.assign({}, value); + } + return value; + } + exports2.shallowCopy = shallowCopy; + function makeRevocable(target, handler) { + if (typeof Proxy !== "undefined" && Proxy.revocable) { + return Proxy.revocable(target, handler || {}); + } else { + return { + proxy: target, + revoke: () => { + } + }; + } + } + exports2.makeRevocable = makeRevocable; + } +}); + +// node_modules/botbuilder-core/lib/middlewareSet.js +var require_middlewareSet = __commonJS({ + "node_modules/botbuilder-core/lib/middlewareSet.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MiddlewareSet = void 0; + var MiddlewareSet = class { + /** + * Creates a new MiddlewareSet instance. + * + * @param {...any} middlewares One or more middleware handlers(s) to register. + */ + constructor(...middlewares) { + this.middleware = []; + this.use(...middlewares); + } + /** + * Processes an incoming activity. + * + * @param context [TurnContext](xref:botbuilder-core.TurnContext) object for this turn. + * @param next Delegate to call to continue the bot middleware pipeline. + * @returns {Promise} A Promise representing the async operation. + */ + onTurn(context, next) { + return this.run(context, next); + } + /** + * Registers middleware handlers(s) with the set. + * + * @remarks This example adds a new piece of middleware to a set: + * ```JavaScript + * set.use(async (context, next) => { + * console.log(`Leading Edge`); + * await next(); + * console.log(`Trailing Edge`); + * }); + * ``` + * @param {...any} middlewares One or more middleware handlers(s) to register. + * @returns The updated middleware set. + */ + use(...middlewares) { + middlewares.forEach((plugin) => { + if (typeof plugin === "function") { + this.middleware.push(plugin); + } else if (typeof plugin === "object" && plugin.onTurn) { + this.middleware.push((context, next) => plugin.onTurn(context, next)); + } else { + throw new Error("MiddlewareSet.use(): invalid plugin type being added."); + } + }); + return this; + } + /** + * Executes a set of middleware in series. + * + * @param context Context for the current turn of conversation with the user. + * @param next Function to invoke at the end of the middleware chain. + * @returns A promise that resolves after the handler chain is complete. + */ + run(context, next) { + const runHandlers = ([handler, ...remaining]) => { + try { + return Promise.resolve(handler ? handler(context, () => runHandlers(remaining)) : next()); + } catch (err) { + return Promise.reject(err); + } + }; + return runHandlers(this.middleware); + } + }; + exports2.MiddlewareSet = MiddlewareSet; + } +}); + +// node_modules/botbuilder-core/lib/botAdapter.js +var require_botAdapter = __commonJS({ + "node_modules/botbuilder-core/lib/botAdapter.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotAdapter = void 0; + var internal_1 = require_internal2(); + var middlewareSet_1 = require_middlewareSet(); + var BotAdapter = class { + constructor() { + this.middleware = new middlewareSet_1.MiddlewareSet(); + this.BotIdentityKey = Symbol("BotIdentity"); + this.ConnectorClientKey = Symbol("ConnectorClient"); + this.OAuthScopeKey = Symbol("OAuthScope"); + } + /** + * @internal + */ + continueConversationAsync(_botAppIdOrClaimsIdentity, _reference, _logicOrAudience, _maybeLogic) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Creates a conversation on the specified channel. + * + * @param _botAppId The application ID of the bot. + * @param _channelId The ID for the channel. + * @param _serviceUrl The ID for the channel. + * @param _audience The audience for the connector. + * + * @param _conversationParameters The conversation information to use to create the conversation + * @param _logic The method to call for the resulting bot turn. + * @returns A promise that represents the asynchronous operation + * @remarks + * To start a conversation, your bot must know its account information and the user's account information on that + * channel. Most _channels only support initiating a direct message (non-group) conversation. + * + * The adapter attempts to create a new conversation on the channel, and then sends a `conversationUpdate` activity + * through its middleware pipeline to the logic method. + * + * If the conversation is established with the specified users, the ID of the activity's converstion will contain + * the ID of the new conversation. + */ + createConversationAsync(_botAppId, _channelId, _serviceUrl, _audience, _conversationParameters, _logic) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Gets or sets an error handler that can catch exceptions in the middleware or application. + * + * @remarks + * The error handler is called with these parameters: + * + * | Name | Type | Description | + * | :--- | :--- | :--- | + * | `context` | [TurnContext](xref:botbuilder-core.TurnContext) | The context object for the turn. | + * | `error` | `Error` | The Node.js error thrown. | + * @returns {Promise} A promise representing the async operation. + */ + get onTurnError() { + return this.turnError; + } + /** + * Sets an error handler that can catch exceptions in the middleware or application. + * + * @remarks + * The error handler is called with these parameters: + * + * | Name | Type | Description | + * | :--- | :--- | :--- | + * | `context` | [TurnContext](xref:botbuilder-core.TurnContext) | The context object for the turn. | + * | `error` | `Error` | The Node.js error thrown. | + */ + set onTurnError(value) { + this.turnError = value; + } + /** + * Adds middleware to the adapter's pipeline. + * + * @param {...any} middlewares The middleware or middleware handlers to add. + * @returns The updated adapter object. + * @remarks Middleware is added to the adapter at initialization time. + * Each turn, the adapter calls its middleware in the order in which you added it. + */ + use(...middlewares) { + this.middleware.use(...middlewares); + return this; + } + /** + * Starts activity processing for the current bot turn. + * + * @param context The context object for the turn. + * @param next A callback method to run at the end of the pipeline. + * @returns A promise that resolves when the middleware chain is finished + * @remarks + * The adapter creates a revokable proxy for the turn context and then calls its middleware in + * the order in which you added it. If the middleware chain completes without short circuiting, + * the adapter calls the callback method. If any middleware short circuits, the adapter does not + * call any of the subsequent middleware or the callback method, and the pipeline short circuits. + * + * The adapter calls middleware with a `next` parameter, which represents the next step in the + * pipeline. Middleware should call the `next` method to continue processing without short circuiting. + * + * When the turn is initiated by a user activity (reactive messaging), the callback method will + * be a reference to the bot's turn handler. When the turn is initiated by a call to + * [continueConversation](xref:botbuilder-core.BotAdapter.continueConversation) (proactive messaging), + * the callback method is the callback method that was provided in the call. + */ + runMiddleware(context, next) { + return __awaiter2(this, void 0, void 0, function* () { + if (context && context.activity && context.activity.locale) { + context.locale = context.activity.locale; + } + const pContext = (0, internal_1.makeRevocable)(context); + try { + yield this.middleware.run(pContext.proxy, () => next(pContext.proxy)); + } catch (err) { + if (this.onTurnError) { + yield this.onTurnError(pContext.proxy, err); + } else { + throw err; + } + } finally { + pContext.revoke(); + } + }); + } + }; + exports2.BotAdapter = BotAdapter; + } +}); + +// node_modules/botbuilder-core/lib/botComponent.js +var require_botComponent = __commonJS({ + "node_modules/botbuilder-core/lib/botComponent.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.assertBotComponent = exports2.BotComponent = void 0; + var z = __importStar2(require_zod()); + var BotComponent = class { + }; + exports2.BotComponent = BotComponent; + BotComponent.z = z.custom((val) => typeof val.configureServices === "function", { + message: "BotComponent" + }); + function assertBotComponent(val, ..._args) { + BotComponent.z.parse(val); + } + exports2.assertBotComponent = assertBotComponent; + } +}); + +// node_modules/botbuilder-core/lib/botStatePropertyAccessor.js +var require_botStatePropertyAccessor = __commonJS({ + "node_modules/botbuilder-core/lib/botStatePropertyAccessor.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotStatePropertyAccessor = void 0; + var BotStatePropertyAccessor = class { + /** + * Creates a new BotStatePropertyAccessor instance. + * + * @param state Parent BotState instance. + * @param name Unique name of the property for the parent BotState. + */ + constructor(state, name) { + this.state = state; + this.name = name; + } + /** + * Deletes the persisted property from its backing storage object. + * + * @param context [TurnContext](xref:botbuilder-core.TurnContext) object for this turn. + */ + delete(context) { + return __awaiter2(this, void 0, void 0, function* () { + const obj = yield this.state.load(context); + if (Object.prototype.hasOwnProperty.call(obj, this.name)) { + delete obj[this.name]; + } + }); + } + /** + * Reads a persisted property from its backing storage object. + * + * @param context [TurnContext](xref:botbuilder-core.TurnContext) object for this turn. + * @param defaultValue Optional. Default value for the property. + * @returns A JSON representation of the cached state. + */ + get(context, defaultValue) { + return __awaiter2(this, void 0, void 0, function* () { + const obj = yield this.state.load(context); + if (!Object.prototype.hasOwnProperty.call(obj, this.name) && defaultValue !== void 0) { + const clone = typeof defaultValue === "object" || Array.isArray(defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : defaultValue; + obj[this.name] = clone; + } + return obj[this.name]; + }); + } + /** + * Assigns a new value to the properties backing storage object. + * + * @param context [TurnContext](xref:botbuilder-core.TurnContext) object for this turn. + * @param value Value to set on the property. + */ + set(context, value) { + return __awaiter2(this, void 0, void 0, function* () { + const obj = yield this.state.load(context); + obj[this.name] = value; + }); + } + }; + exports2.BotStatePropertyAccessor = BotStatePropertyAccessor; + } +}); + +// node_modules/botbuilder-stdlib/lib/types.js +var require_types3 = __commonJS({ + "node_modules/botbuilder-stdlib/lib/types.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botbuilder-stdlib/lib/stringExt.js +var require_stringExt = __commonJS({ + "node_modules/botbuilder-stdlib/lib/stringExt.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isNilOrEmpty = void 0; + function isNilOrEmpty(val) { + return val == null || val === ""; + } + exports2.isNilOrEmpty = isNilOrEmpty; + } +}); + +// node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/interfaces.js +var require_interfaces = __commonJS({ + "node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/interfaces.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/abort-controller/AbortError.js +var require_AbortError = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/abort-controller/AbortError.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var AbortError_exports = {}; + __export2(AbortError_exports, { + AbortError: () => AbortError2 + }); + module2.exports = __toCommonJS2(AbortError_exports); + var AbortError2 = class extends Error { + constructor(message) { + super(message); + this.name = "AbortError"; + } + }; + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/logger/log.js +var require_log = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/logger/log.js"(exports2, module2) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var log_exports = {}; + __export2(log_exports, { + log: () => log + }); + module2.exports = __toCommonJS2(log_exports); + var import_node_os2 = require("node:os"); + var import_node_util6 = __toESM2(require("node:util")); + var import_node_process7 = __toESM2(require("node:process")); + function log(message, ...args) { + import_node_process7.default.stderr.write(`${import_node_util6.default.format(message, ...args)}${import_node_os2.EOL}`); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/logger/debug.js +var require_debug5 = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/logger/debug.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var debug_exports = {}; + __export2(debug_exports, { + default: () => debug_default + }); + module2.exports = __toCommonJS2(debug_exports); + var import_log = require_log(); + var debugEnvVariable = typeof process !== "undefined" && process.env && process.env.DEBUG || void 0; + var enabledString; + var enabledNamespaces = []; + var skippedNamespaces = []; + var debuggers = []; + if (debugEnvVariable) { + enable(debugEnvVariable); + } + var debugObj = Object.assign( + (namespace) => { + return createDebugger(namespace); + }, + { + enable, + enabled, + disable, + log: import_log.log + } + ); + function enable(namespaces) { + enabledString = namespaces; + enabledNamespaces = []; + skippedNamespaces = []; + const namespaceList = namespaces.split(",").map((ns) => ns.trim()); + for (const ns of namespaceList) { + if (ns.startsWith("-")) { + skippedNamespaces.push(ns.substring(1)); + } else { + enabledNamespaces.push(ns); + } + } + for (const instance of debuggers) { + instance.enabled = enabled(instance.namespace); + } + } + function enabled(namespace) { + if (namespace.endsWith("*")) { + return true; + } + for (const skipped of skippedNamespaces) { + if (namespaceMatches(namespace, skipped)) { + return false; + } + } + for (const enabledNamespace of enabledNamespaces) { + if (namespaceMatches(namespace, enabledNamespace)) { + return true; + } + } + return false; + } + function namespaceMatches(namespace, patternToMatch) { + if (patternToMatch.indexOf("*") === -1) { + return namespace === patternToMatch; + } + let pattern = patternToMatch; + if (patternToMatch.indexOf("**") !== -1) { + const patternParts = []; + let lastCharacter = ""; + for (const character of patternToMatch) { + if (character === "*" && lastCharacter === "*") { + continue; + } else { + lastCharacter = character; + patternParts.push(character); + } + } + pattern = patternParts.join(""); + } + let namespaceIndex = 0; + let patternIndex = 0; + const patternLength = pattern.length; + const namespaceLength = namespace.length; + let lastWildcard = -1; + let lastWildcardNamespace = -1; + while (namespaceIndex < namespaceLength && patternIndex < patternLength) { + if (pattern[patternIndex] === "*") { + lastWildcard = patternIndex; + patternIndex++; + if (patternIndex === patternLength) { + return true; + } + while (namespace[namespaceIndex] !== pattern[patternIndex]) { + namespaceIndex++; + if (namespaceIndex === namespaceLength) { + return false; + } + } + lastWildcardNamespace = namespaceIndex; + namespaceIndex++; + patternIndex++; + continue; + } else if (pattern[patternIndex] === namespace[namespaceIndex]) { + patternIndex++; + namespaceIndex++; + } else if (lastWildcard >= 0) { + patternIndex = lastWildcard + 1; + namespaceIndex = lastWildcardNamespace + 1; + if (namespaceIndex === namespaceLength) { + return false; + } + while (namespace[namespaceIndex] !== pattern[patternIndex]) { + namespaceIndex++; + if (namespaceIndex === namespaceLength) { + return false; + } + } + lastWildcardNamespace = namespaceIndex; + namespaceIndex++; + patternIndex++; + continue; + } else { + return false; + } + } + const namespaceDone = namespaceIndex === namespace.length; + const patternDone = patternIndex === pattern.length; + const trailingWildCard = patternIndex === pattern.length - 1 && pattern[patternIndex] === "*"; + return namespaceDone && (patternDone || trailingWildCard); + } + function disable() { + const result = enabledString || ""; + enable(""); + return result; + } + function createDebugger(namespace) { + const newDebugger = Object.assign(debug, { + enabled: enabled(namespace), + destroy, + log: debugObj.log, + namespace, + extend + }); + function debug(...args) { + if (!newDebugger.enabled) { + return; + } + if (args.length > 0) { + args[0] = `${namespace} ${args[0]}`; + } + newDebugger.log(...args); + } + debuggers.push(newDebugger); + return newDebugger; + } + function destroy() { + const index = debuggers.indexOf(this); + if (index >= 0) { + debuggers.splice(index, 1); + return true; + } + return false; + } + function extend(namespace) { + const newDebugger = createDebugger(`${this.namespace}:${namespace}`); + newDebugger.log = this.log; + return newDebugger; + } + var debug_default = debugObj; + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/logger/logger.js +var require_logger = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/logger/logger.js"(exports2, module2) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var logger_exports = {}; + __export2(logger_exports, { + TypeSpecRuntimeLogger: () => TypeSpecRuntimeLogger2, + createClientLogger: () => createClientLogger2, + createLoggerContext: () => createLoggerContext2, + getLogLevel: () => getLogLevel2, + setLogLevel: () => setLogLevel2 + }); + module2.exports = __toCommonJS2(logger_exports); + var import_debug = __toESM2(require_debug5()); + var TYPESPEC_RUNTIME_LOG_LEVELS = ["verbose", "info", "warning", "error"]; + var levelMap = { + verbose: 400, + info: 300, + warning: 200, + error: 100 + }; + function patchLogMethod(parent, child) { + child.log = (...args) => { + parent.log(...args); + }; + } + function isTypeSpecRuntimeLogLevel(level) { + return TYPESPEC_RUNTIME_LOG_LEVELS.includes(level); + } + function createLoggerContext2(options) { + const registeredLoggers = /* @__PURE__ */ new Set(); + const logLevelFromEnv = typeof process !== "undefined" && process.env && process.env[options.logLevelEnvVarName] || void 0; + let logLevel; + const clientLogger = (0, import_debug.default)(options.namespace); + clientLogger.log = (...args) => { + import_debug.default.log(...args); + }; + function contextSetLogLevel(level) { + if (level && !isTypeSpecRuntimeLogLevel(level)) { + throw new Error( + `Unknown log level '${level}'. Acceptable values: ${TYPESPEC_RUNTIME_LOG_LEVELS.join(",")}` + ); + } + logLevel = level; + const enabledNamespaces = []; + for (const logger of registeredLoggers) { + if (shouldEnable(logger)) { + enabledNamespaces.push(logger.namespace); + } + } + import_debug.default.enable(enabledNamespaces.join(",")); + } + if (logLevelFromEnv) { + if (isTypeSpecRuntimeLogLevel(logLevelFromEnv)) { + contextSetLogLevel(logLevelFromEnv); + } else { + console.error( + `${options.logLevelEnvVarName} set to unknown log level '${logLevelFromEnv}'; logging is not enabled. Acceptable values: ${TYPESPEC_RUNTIME_LOG_LEVELS.join( + ", " + )}.` + ); + } + } + function shouldEnable(logger) { + return Boolean(logLevel && levelMap[logger.level] <= levelMap[logLevel]); + } + function createLogger(parent, level) { + const logger = Object.assign(parent.extend(level), { + level + }); + patchLogMethod(parent, logger); + if (shouldEnable(logger)) { + const enabledNamespaces = import_debug.default.disable(); + import_debug.default.enable(enabledNamespaces + "," + logger.namespace); + } + registeredLoggers.add(logger); + return logger; + } + function contextGetLogLevel() { + return logLevel; + } + function contextCreateClientLogger(namespace) { + const clientRootLogger = clientLogger.extend(namespace); + patchLogMethod(clientLogger, clientRootLogger); + return { + error: createLogger(clientRootLogger, "error"), + warning: createLogger(clientRootLogger, "warning"), + info: createLogger(clientRootLogger, "info"), + verbose: createLogger(clientRootLogger, "verbose") + }; + } + return { + setLogLevel: contextSetLogLevel, + getLogLevel: contextGetLogLevel, + createClientLogger: contextCreateClientLogger, + logger: clientLogger + }; + } + var context = createLoggerContext2({ + logLevelEnvVarName: "TYPESPEC_RUNTIME_LOG_LEVEL", + namespace: "typeSpecRuntime" + }); + var TypeSpecRuntimeLogger2 = context.logger; + function setLogLevel2(logLevel) { + context.setLogLevel(logLevel); + } + function getLogLevel2() { + return context.getLogLevel(); + } + function createClientLogger2(namespace) { + return context.createClientLogger(namespace); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/httpHeaders.js +var require_httpHeaders = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/httpHeaders.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var httpHeaders_exports = {}; + __export2(httpHeaders_exports, { + createHttpHeaders: () => createHttpHeaders2 + }); + module2.exports = __toCommonJS2(httpHeaders_exports); + function normalizeName(name) { + return name.toLowerCase(); + } + function* headerIterator(map) { + for (const entry of map.values()) { + yield [entry.name, entry.value]; + } + } + var HttpHeadersImpl = class { + _headersMap; + constructor(rawHeaders) { + this._headersMap = /* @__PURE__ */ new Map(); + if (rawHeaders) { + for (const headerName of Object.keys(rawHeaders)) { + this.set(headerName, rawHeaders[headerName]); + } + } + } + /** + * Set a header in this collection with the provided name and value. The name is + * case-insensitive. + * @param name - The name of the header to set. This value is case-insensitive. + * @param value - The value of the header to set. + */ + set(name, value) { + this._headersMap.set(normalizeName(name), { name, value: String(value).trim() }); + } + /** + * Get the header value for the provided header name, or undefined if no header exists in this + * collection with the provided name. + * @param name - The name of the header. This value is case-insensitive. + */ + get(name) { + return this._headersMap.get(normalizeName(name))?.value; + } + /** + * Get whether or not this header collection contains a header entry for the provided header name. + * @param name - The name of the header to set. This value is case-insensitive. + */ + has(name) { + return this._headersMap.has(normalizeName(name)); + } + /** + * Remove the header with the provided headerName. + * @param name - The name of the header to remove. + */ + delete(name) { + this._headersMap.delete(normalizeName(name)); + } + /** + * Get the JSON object representation of this HTTP header collection. + */ + toJSON(options = {}) { + const result = {}; + if (options.preserveCase) { + for (const entry of this._headersMap.values()) { + result[entry.name] = entry.value; + } + } else { + for (const [normalizedName, entry] of this._headersMap) { + result[normalizedName] = entry.value; + } + } + return result; + } + /** + * Get the string representation of this HTTP header collection. + */ + toString() { + return JSON.stringify(this.toJSON({ preserveCase: true })); + } + /** + * Iterate over tuples of header [name, value] pairs. + */ + [Symbol.iterator]() { + return headerIterator(this._headersMap); + } + }; + function createHttpHeaders2(rawHeaders) { + return new HttpHeadersImpl(rawHeaders); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/uuidUtils.js +var require_uuidUtils = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/uuidUtils.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var uuidUtils_exports = {}; + __export2(uuidUtils_exports, { + randomUUID: () => randomUUID2 + }); + module2.exports = __toCommonJS2(uuidUtils_exports); + function randomUUID2() { + return crypto.randomUUID(); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/pipelineRequest.js +var require_pipelineRequest = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/pipelineRequest.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var pipelineRequest_exports = {}; + __export2(pipelineRequest_exports, { + createPipelineRequest: () => createPipelineRequest2 + }); + module2.exports = __toCommonJS2(pipelineRequest_exports); + var import_httpHeaders = require_httpHeaders(); + var import_uuidUtils = require_uuidUtils(); + var PipelineRequestImpl = class { + url; + method; + headers; + timeout; + withCredentials; + body; + multipartBody; + formData; + streamResponseStatusCodes; + enableBrowserStreams; + proxySettings; + disableKeepAlive; + abortSignal; + requestId; + allowInsecureConnection; + onUploadProgress; + onDownloadProgress; + requestOverrides; + authSchemes; + constructor(options) { + this.url = options.url; + this.body = options.body; + this.headers = options.headers ?? (0, import_httpHeaders.createHttpHeaders)(); + this.method = options.method ?? "GET"; + this.timeout = options.timeout ?? 0; + this.multipartBody = options.multipartBody; + this.formData = options.formData; + this.disableKeepAlive = options.disableKeepAlive ?? false; + this.proxySettings = options.proxySettings; + this.streamResponseStatusCodes = options.streamResponseStatusCodes; + this.withCredentials = options.withCredentials ?? false; + this.abortSignal = options.abortSignal; + this.onUploadProgress = options.onUploadProgress; + this.onDownloadProgress = options.onDownloadProgress; + this.requestId = options.requestId || (0, import_uuidUtils.randomUUID)(); + this.allowInsecureConnection = options.allowInsecureConnection ?? false; + this.enableBrowserStreams = options.enableBrowserStreams ?? false; + this.requestOverrides = options.requestOverrides; + this.authSchemes = options.authSchemes; + } + }; + function createPipelineRequest2(options) { + return new PipelineRequestImpl(options); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/pipeline.js +var require_pipeline = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/pipeline.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var pipeline_exports = {}; + __export2(pipeline_exports, { + createEmptyPipeline: () => createEmptyPipeline2 + }); + module2.exports = __toCommonJS2(pipeline_exports); + var ValidPhaseNames = /* @__PURE__ */ new Set(["Deserialize", "Serialize", "Retry", "Sign"]); + var HttpPipeline = class _HttpPipeline { + _policies = []; + _orderedPolicies; + constructor(policies) { + this._policies = policies?.slice(0) ?? []; + this._orderedPolicies = void 0; + } + addPolicy(policy, options = {}) { + if (options.phase && options.afterPhase) { + throw new Error("Policies inside a phase cannot specify afterPhase."); + } + if (options.phase && !ValidPhaseNames.has(options.phase)) { + throw new Error(`Invalid phase name: ${options.phase}`); + } + if (options.afterPhase && !ValidPhaseNames.has(options.afterPhase)) { + throw new Error(`Invalid afterPhase name: ${options.afterPhase}`); + } + this._policies.push({ + policy, + options + }); + this._orderedPolicies = void 0; + } + removePolicy(options) { + const removedPolicies = []; + this._policies = this._policies.filter((policyDescriptor) => { + if (options.name && policyDescriptor.policy.name === options.name || options.phase && policyDescriptor.options.phase === options.phase) { + removedPolicies.push(policyDescriptor.policy); + return false; + } else { + return true; + } + }); + this._orderedPolicies = void 0; + return removedPolicies; + } + sendRequest(httpClient, request) { + const policies = this.getOrderedPolicies(); + const pipeline = policies.reduceRight( + (next, policy) => { + return (req) => { + return policy.sendRequest(req, next); + }; + }, + (req) => httpClient.sendRequest(req) + ); + return pipeline(request); + } + getOrderedPolicies() { + if (!this._orderedPolicies) { + this._orderedPolicies = this.orderPolicies(); + } + return this._orderedPolicies; + } + clone() { + return new _HttpPipeline(this._policies); + } + static create() { + return new _HttpPipeline(); + } + orderPolicies() { + const result = []; + const policyMap = /* @__PURE__ */ new Map(); + function createPhase(name) { + return { + name, + policies: /* @__PURE__ */ new Set(), + hasRun: false, + hasAfterPolicies: false + }; + } + const serializePhase = createPhase("Serialize"); + const noPhase = createPhase("None"); + const deserializePhase = createPhase("Deserialize"); + const retryPhase = createPhase("Retry"); + const signPhase = createPhase("Sign"); + const orderedPhases = [serializePhase, noPhase, deserializePhase, retryPhase, signPhase]; + function getPhase(phase) { + if (phase === "Retry") { + return retryPhase; + } else if (phase === "Serialize") { + return serializePhase; + } else if (phase === "Deserialize") { + return deserializePhase; + } else if (phase === "Sign") { + return signPhase; + } else { + return noPhase; + } + } + for (const descriptor of this._policies) { + const policy = descriptor.policy; + const options = descriptor.options; + const policyName = policy.name; + if (policyMap.has(policyName)) { + throw new Error("Duplicate policy names not allowed in pipeline"); + } + const node = { + policy, + dependsOn: /* @__PURE__ */ new Set(), + dependants: /* @__PURE__ */ new Set() + }; + if (options.afterPhase) { + node.afterPhase = getPhase(options.afterPhase); + node.afterPhase.hasAfterPolicies = true; + } + policyMap.set(policyName, node); + const phase = getPhase(options.phase); + phase.policies.add(node); + } + for (const descriptor of this._policies) { + const { policy, options } = descriptor; + const policyName = policy.name; + const node = policyMap.get(policyName); + if (!node) { + throw new Error(`Missing node for policy ${policyName}`); + } + if (options.afterPolicies) { + for (const afterPolicyName of options.afterPolicies) { + const afterNode = policyMap.get(afterPolicyName); + if (afterNode) { + node.dependsOn.add(afterNode); + afterNode.dependants.add(node); + } + } + } + if (options.beforePolicies) { + for (const beforePolicyName of options.beforePolicies) { + const beforeNode = policyMap.get(beforePolicyName); + if (beforeNode) { + beforeNode.dependsOn.add(node); + node.dependants.add(beforeNode); + } + } + } + } + function walkPhase(phase) { + phase.hasRun = true; + for (const node of phase.policies) { + if (node.afterPhase && (!node.afterPhase.hasRun || node.afterPhase.policies.size)) { + continue; + } + if (node.dependsOn.size === 0) { + result.push(node.policy); + for (const dependant of node.dependants) { + dependant.dependsOn.delete(node); + } + policyMap.delete(node.policy.name); + phase.policies.delete(node); + } + } + } + function walkPhases() { + for (const phase of orderedPhases) { + walkPhase(phase); + if (phase.policies.size > 0 && phase !== noPhase) { + if (!noPhase.hasRun) { + walkPhase(noPhase); + } + return; + } + if (phase.hasAfterPolicies) { + walkPhase(noPhase); + } + } + } + let iteration = 0; + while (policyMap.size > 0) { + iteration++; + const initialResultLength = result.length; + walkPhases(); + if (result.length <= initialResultLength && iteration > 1) { + throw new Error("Cannot satisfy policy dependencies due to requirements cycle."); + } + } + return result; + } + }; + function createEmptyPipeline2() { + return HttpPipeline.create(); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/object.js +var require_object = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/object.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var object_exports = {}; + __export2(object_exports, { + isObject: () => isObject2 + }); + module2.exports = __toCommonJS2(object_exports); + function isObject2(input) { + return typeof input === "object" && input !== null && !Array.isArray(input) && !(input instanceof RegExp) && !(input instanceof Date); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/error.js +var require_error = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/error.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var error_exports = {}; + __export2(error_exports, { + isError: () => isError2 + }); + module2.exports = __toCommonJS2(error_exports); + var import_object = require_object(); + function isError2(e) { + if ((0, import_object.isObject)(e)) { + const hasName = typeof e.name === "string"; + const hasMessage = typeof e.message === "string"; + return hasName && hasMessage; + } + return false; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/inspect.js +var require_inspect = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/inspect.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var inspect_exports = {}; + __export2(inspect_exports, { + custom: () => custom + }); + module2.exports = __toCommonJS2(inspect_exports); + var import_node_util6 = require("node:util"); + var custom = import_node_util6.inspect.custom; + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/sanitizer.js +var require_sanitizer = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/sanitizer.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var sanitizer_exports = {}; + __export2(sanitizer_exports, { + Sanitizer: () => Sanitizer2 + }); + module2.exports = __toCommonJS2(sanitizer_exports); + var import_object = require_object(); + var RedactedString = "REDACTED"; + var defaultAllowedHeaderNames = [ + "x-ms-client-request-id", + "x-ms-return-client-request-id", + "x-ms-useragent", + "x-ms-correlation-request-id", + "x-ms-request-id", + "client-request-id", + "ms-cv", + "return-client-request-id", + "traceparent", + "Access-Control-Allow-Credentials", + "Access-Control-Allow-Headers", + "Access-Control-Allow-Methods", + "Access-Control-Allow-Origin", + "Access-Control-Expose-Headers", + "Access-Control-Max-Age", + "Access-Control-Request-Headers", + "Access-Control-Request-Method", + "Origin", + "Accept", + "Accept-Encoding", + "Cache-Control", + "Connection", + "Content-Length", + "Content-Type", + "Date", + "ETag", + "Expires", + "If-Match", + "If-Modified-Since", + "If-None-Match", + "If-Unmodified-Since", + "Last-Modified", + "Pragma", + "Request-Id", + "Retry-After", + "Server", + "Transfer-Encoding", + "User-Agent", + "WWW-Authenticate" + ]; + var defaultAllowedQueryParameters = ["api-version"]; + var Sanitizer2 = class { + allowedHeaderNames; + allowedQueryParameters; + constructor({ + additionalAllowedHeaderNames: allowedHeaderNames = [], + additionalAllowedQueryParameters: allowedQueryParameters = [] + } = {}) { + allowedHeaderNames = defaultAllowedHeaderNames.concat(allowedHeaderNames); + allowedQueryParameters = defaultAllowedQueryParameters.concat(allowedQueryParameters); + this.allowedHeaderNames = new Set(allowedHeaderNames.map((n) => n.toLowerCase())); + this.allowedQueryParameters = new Set(allowedQueryParameters.map((p) => p.toLowerCase())); + } + /** + * Sanitizes an object for logging. + * @param obj - The object to sanitize + * @returns - The sanitized object as a string + */ + sanitize(obj) { + const seen = /* @__PURE__ */ new Set(); + return JSON.stringify( + obj, + (key, value) => { + if (value instanceof Error) { + return { + ...value, + name: value.name, + message: value.message + }; + } + if (key === "headers" && (0, import_object.isObject)(value)) { + return this.sanitizeHeaders(value); + } else if (key === "url" && typeof value === "string") { + return this.sanitizeUrl(value); + } else if (key === "query" && (0, import_object.isObject)(value)) { + return this.sanitizeQuery(value); + } else if (key === "body") { + return void 0; + } else if (key === "response") { + return void 0; + } else if (key === "operationSpec") { + return void 0; + } else if (Array.isArray(value) || (0, import_object.isObject)(value)) { + if (seen.has(value)) { + return "[Circular]"; + } + seen.add(value); + } + return value; + }, + 2 + ); + } + /** + * Sanitizes a URL for logging. + * @param value - The URL to sanitize + * @returns - The sanitized URL as a string + */ + sanitizeUrl(value) { + if (typeof value !== "string" || value === null || value === "") { + return value; + } + const url = new URL(value); + if (!url.search) { + return value; + } + for (const [key] of url.searchParams) { + if (!this.allowedQueryParameters.has(key.toLowerCase())) { + url.searchParams.set(key, RedactedString); + } + } + return url.toString(); + } + sanitizeHeaders(obj) { + const sanitized = {}; + for (const key of Object.keys(obj)) { + if (this.allowedHeaderNames.has(key.toLowerCase())) { + sanitized[key] = obj[key]; + } else { + sanitized[key] = RedactedString; + } + } + return sanitized; + } + sanitizeQuery(value) { + if (typeof value !== "object" || value === null) { + return value; + } + const sanitized = {}; + for (const k of Object.keys(value)) { + if (this.allowedQueryParameters.has(k.toLowerCase())) { + sanitized[k] = value[k]; + } else { + sanitized[k] = RedactedString; + } + } + return sanitized; + } + }; + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/restError.js +var require_restError = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/restError.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var restError_exports = {}; + __export2(restError_exports, { + RestError: () => RestError2, + isRestError: () => isRestError2 + }); + module2.exports = __toCommonJS2(restError_exports); + var import_error = require_error(); + var import_inspect = require_inspect(); + var import_sanitizer = require_sanitizer(); + var errorSanitizer = new import_sanitizer.Sanitizer(); + var RestError2 = class _RestError extends Error { + /** + * Something went wrong when making the request. + * This means the actual request failed for some reason, + * such as a DNS issue or the connection being lost. + */ + static REQUEST_SEND_ERROR = "REQUEST_SEND_ERROR"; + /** + * This means that parsing the response from the server failed. + * It may have been malformed. + */ + static PARSE_ERROR = "PARSE_ERROR"; + /** + * The code of the error itself (use statics on RestError if possible.) + */ + code; + /** + * The HTTP status code of the request (if applicable.) + */ + statusCode; + /** + * The request that was made. + * This property is non-enumerable. + */ + request; + /** + * The response received (if any.) + * This property is non-enumerable. + */ + response; + /** + * Bonus property set by the throw site. + */ + details; + constructor(message, options = {}) { + super(message); + this.name = "RestError"; + this.code = options.code; + this.statusCode = options.statusCode; + Object.defineProperty(this, "request", { value: options.request, enumerable: false }); + Object.defineProperty(this, "response", { value: options.response, enumerable: false }); + const agent = this.request?.agent ? { + maxFreeSockets: this.request.agent.maxFreeSockets, + maxSockets: this.request.agent.maxSockets + } : void 0; + Object.defineProperty(this, import_inspect.custom, { + value: () => { + return `RestError: ${this.message} + ${errorSanitizer.sanitize({ + ...this, + request: { ...this.request, agent }, + response: this.response + })}`; + }, + enumerable: false + }); + Object.setPrototypeOf(this, _RestError.prototype); + } + }; + function isRestError2(e) { + if (e instanceof RestError2) { + return true; + } + return (0, import_error.isError)(e) && e.name === "RestError"; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/bytesEncoding.js +var require_bytesEncoding = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/bytesEncoding.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var bytesEncoding_exports = {}; + __export2(bytesEncoding_exports, { + stringToUint8Array: () => stringToUint8Array2, + uint8ArrayToString: () => uint8ArrayToString2 + }); + module2.exports = __toCommonJS2(bytesEncoding_exports); + function uint8ArrayToString2(bytes, format) { + return Buffer.from(bytes).toString(format); + } + function stringToUint8Array2(value, format) { + return Buffer.from(value, format); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/log.js +var require_log2 = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/log.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var log_exports = {}; + __export2(log_exports, { + logger: () => logger + }); + module2.exports = __toCommonJS2(log_exports); + var import_logger = require_logger(); + var logger = (0, import_logger.createClientLogger)("ts-http-runtime"); + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/nodeHttpClient.js +var require_nodeHttpClient = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/nodeHttpClient.js"(exports2, module2) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var nodeHttpClient_exports = {}; + __export2(nodeHttpClient_exports, { + createNodeHttpClient: () => createNodeHttpClient, + getBodyLength: () => getBodyLength + }); + module2.exports = __toCommonJS2(nodeHttpClient_exports); + var import_node_http = __toESM2(require("node:http")); + var import_node_https = __toESM2(require("node:https")); + var import_node_zlib = __toESM2(require("node:zlib")); + var import_node_stream = require("node:stream"); + var import_AbortError = require_AbortError(); + var import_httpHeaders = require_httpHeaders(); + var import_restError = require_restError(); + var import_log = require_log2(); + var import_sanitizer = require_sanitizer(); + var DEFAULT_TLS_SETTINGS = {}; + function isReadableStream(body) { + return body && typeof body.pipe === "function"; + } + function isStreamComplete(stream) { + if (stream.readable === false) { + return Promise.resolve(); + } + return new Promise((resolve) => { + const handler = () => { + resolve(); + stream.removeListener("close", handler); + stream.removeListener("end", handler); + stream.removeListener("error", handler); + }; + stream.on("close", handler); + stream.on("end", handler); + stream.on("error", handler); + }); + } + function isArrayBuffer(body) { + return body && typeof body.byteLength === "number"; + } + var ReportTransform = class extends import_node_stream.Transform { + loadedBytes = 0; + progressCallback; + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + _transform(chunk, _encoding, callback) { + this.push(chunk); + this.loadedBytes += chunk.length; + try { + this.progressCallback({ loadedBytes: this.loadedBytes }); + callback(); + } catch (e) { + callback(e); + } + } + constructor(progressCallback) { + super(); + this.progressCallback = progressCallback; + } + }; + var NodeHttpClient = class { + cachedHttpAgent; + cachedHttpsAgents = /* @__PURE__ */ new WeakMap(); + /** + * Makes a request over an underlying transport layer and returns the response. + * @param request - The request to be made. + */ + async sendRequest(request) { + const abortController = new AbortController(); + let abortListener; + if (request.abortSignal) { + if (request.abortSignal.aborted) { + throw new import_AbortError.AbortError("The operation was aborted. Request has already been canceled."); + } + abortListener = (event) => { + if (event.type === "abort") { + abortController.abort(); + } + }; + request.abortSignal.addEventListener("abort", abortListener); + } + let timeoutId; + if (request.timeout > 0) { + timeoutId = setTimeout(() => { + const sanitizer = new import_sanitizer.Sanitizer(); + import_log.logger.info(`request to '${sanitizer.sanitizeUrl(request.url)}' timed out. canceling...`); + abortController.abort(); + }, request.timeout); + } + const acceptEncoding = request.headers.get("Accept-Encoding"); + const shouldDecompress = acceptEncoding?.includes("gzip") || acceptEncoding?.includes("deflate"); + let body = typeof request.body === "function" ? request.body() : request.body; + if (body && !request.headers.has("Content-Length")) { + const bodyLength = getBodyLength(body); + if (bodyLength !== null) { + request.headers.set("Content-Length", bodyLength); + } + } + let responseStream; + try { + if (body && request.onUploadProgress) { + const onUploadProgress = request.onUploadProgress; + const uploadReportStream = new ReportTransform(onUploadProgress); + uploadReportStream.on("error", (e) => { + import_log.logger.error("Error in upload progress", e); + }); + if (isReadableStream(body)) { + body.pipe(uploadReportStream); + } else { + uploadReportStream.end(body); + } + body = uploadReportStream; + } + const res = await this.makeRequest(request, abortController, body); + if (timeoutId !== void 0) { + clearTimeout(timeoutId); + } + const headers = getResponseHeaders(res); + const status = res.statusCode ?? 0; + const response = { + status, + headers, + request + }; + if (request.method === "HEAD") { + res.resume(); + return response; + } + responseStream = shouldDecompress ? getDecodedResponseStream(res, headers) : res; + const onDownloadProgress = request.onDownloadProgress; + if (onDownloadProgress) { + const downloadReportStream = new ReportTransform(onDownloadProgress); + downloadReportStream.on("error", (e) => { + import_log.logger.error("Error in download progress", e); + }); + responseStream.pipe(downloadReportStream); + responseStream = downloadReportStream; + } + if ( + // Value of POSITIVE_INFINITY in streamResponseStatusCodes is considered as any status code + request.streamResponseStatusCodes?.has(Number.POSITIVE_INFINITY) || request.streamResponseStatusCodes?.has(response.status) + ) { + response.readableStreamBody = responseStream; + } else { + response.bodyAsText = await streamToText(responseStream); + } + return response; + } finally { + if (request.abortSignal && abortListener) { + let uploadStreamDone = Promise.resolve(); + if (isReadableStream(body)) { + uploadStreamDone = isStreamComplete(body); + } + let downloadStreamDone = Promise.resolve(); + if (isReadableStream(responseStream)) { + downloadStreamDone = isStreamComplete(responseStream); + } + Promise.all([uploadStreamDone, downloadStreamDone]).then(() => { + if (abortListener) { + request.abortSignal?.removeEventListener("abort", abortListener); + } + }).catch((e) => { + import_log.logger.warning("Error when cleaning up abortListener on httpRequest", e); + }); + } + } + } + makeRequest(request, abortController, body) { + const url = new URL(request.url); + const isInsecure = url.protocol !== "https:"; + if (isInsecure && !request.allowInsecureConnection) { + throw new Error(`Cannot connect to ${request.url} while allowInsecureConnection is false.`); + } + const agent = request.agent ?? this.getOrCreateAgent(request, isInsecure); + const options = { + agent, + hostname: url.hostname, + path: `${url.pathname}${url.search}`, + port: url.port, + method: request.method, + headers: request.headers.toJSON({ preserveCase: true }), + ...request.requestOverrides + }; + return new Promise((resolve, reject) => { + const req = isInsecure ? import_node_http.default.request(options, resolve) : import_node_https.default.request(options, resolve); + req.once("error", (err) => { + reject( + new import_restError.RestError(err.message, { code: err.code ?? import_restError.RestError.REQUEST_SEND_ERROR, request }) + ); + }); + abortController.signal.addEventListener("abort", () => { + const abortError = new import_AbortError.AbortError( + "The operation was aborted. Rejecting from abort signal callback while making request." + ); + req.destroy(abortError); + reject(abortError); + }); + if (body && isReadableStream(body)) { + body.pipe(req); + } else if (body) { + if (typeof body === "string" || Buffer.isBuffer(body)) { + req.end(body); + } else if (isArrayBuffer(body)) { + req.end(ArrayBuffer.isView(body) ? Buffer.from(body.buffer) : Buffer.from(body)); + } else { + import_log.logger.error("Unrecognized body type", body); + reject(new import_restError.RestError("Unrecognized body type")); + } + } else { + req.end(); + } + }); + } + getOrCreateAgent(request, isInsecure) { + const disableKeepAlive = request.disableKeepAlive; + if (isInsecure) { + if (disableKeepAlive) { + return import_node_http.default.globalAgent; + } + if (!this.cachedHttpAgent) { + this.cachedHttpAgent = new import_node_http.default.Agent({ keepAlive: true }); + } + return this.cachedHttpAgent; + } else { + if (disableKeepAlive && !request.tlsSettings) { + return import_node_https.default.globalAgent; + } + const tlsSettings = request.tlsSettings ?? DEFAULT_TLS_SETTINGS; + let agent = this.cachedHttpsAgents.get(tlsSettings); + if (agent && agent.options.keepAlive === !disableKeepAlive) { + return agent; + } + import_log.logger.info("No cached TLS Agent exist, creating a new Agent"); + agent = new import_node_https.default.Agent({ + // keepAlive is true if disableKeepAlive is false. + keepAlive: !disableKeepAlive, + // Since we are spreading, if no tslSettings were provided, nothing is added to the agent options. + ...tlsSettings + }); + this.cachedHttpsAgents.set(tlsSettings, agent); + return agent; + } + } + }; + function getResponseHeaders(res) { + const headers = (0, import_httpHeaders.createHttpHeaders)(); + for (const header of Object.keys(res.headers)) { + const value = res.headers[header]; + if (Array.isArray(value)) { + if (value.length > 0) { + headers.set(header, value[0]); + } + } else if (value) { + headers.set(header, value); + } + } + return headers; + } + function getDecodedResponseStream(stream, headers) { + const contentEncoding = headers.get("Content-Encoding"); + if (contentEncoding === "gzip") { + const unzip = import_node_zlib.default.createGunzip(); + stream.pipe(unzip); + return unzip; + } else if (contentEncoding === "deflate") { + const inflate = import_node_zlib.default.createInflate(); + stream.pipe(inflate); + return inflate; + } + return stream; + } + function streamToText(stream) { + return new Promise((resolve, reject) => { + const buffer = []; + stream.on("data", (chunk) => { + if (Buffer.isBuffer(chunk)) { + buffer.push(chunk); + } else { + buffer.push(Buffer.from(chunk)); + } + }); + stream.on("end", () => { + resolve(Buffer.concat(buffer).toString("utf8")); + }); + stream.on("error", (e) => { + if (e && e?.name === "AbortError") { + reject(e); + } else { + reject( + new import_restError.RestError(`Error reading response as text: ${e.message}`, { + code: import_restError.RestError.PARSE_ERROR + }) + ); + } + }); + }); + } + function getBodyLength(body) { + if (!body) { + return 0; + } else if (Buffer.isBuffer(body)) { + return body.length; + } else if (isReadableStream(body)) { + return null; + } else if (isArrayBuffer(body)) { + return body.byteLength; + } else if (typeof body === "string") { + return Buffer.from(body).length; + } else { + return null; + } + } + function createNodeHttpClient() { + return new NodeHttpClient(); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/defaultHttpClient.js +var require_defaultHttpClient = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/defaultHttpClient.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var defaultHttpClient_exports = {}; + __export2(defaultHttpClient_exports, { + createDefaultHttpClient: () => createDefaultHttpClient2 + }); + module2.exports = __toCommonJS2(defaultHttpClient_exports); + var import_nodeHttpClient = require_nodeHttpClient(); + function createDefaultHttpClient2() { + return (0, import_nodeHttpClient.createNodeHttpClient)(); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/logPolicy.js +var require_logPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/logPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var logPolicy_exports = {}; + __export2(logPolicy_exports, { + logPolicy: () => logPolicy2, + logPolicyName: () => logPolicyName2 + }); + module2.exports = __toCommonJS2(logPolicy_exports); + var import_log = require_log2(); + var import_sanitizer = require_sanitizer(); + var logPolicyName2 = "logPolicy"; + function logPolicy2(options = {}) { + const logger = options.logger ?? import_log.logger.info; + const sanitizer = new import_sanitizer.Sanitizer({ + additionalAllowedHeaderNames: options.additionalAllowedHeaderNames, + additionalAllowedQueryParameters: options.additionalAllowedQueryParameters + }); + return { + name: logPolicyName2, + async sendRequest(request, next) { + if (!logger.enabled) { + return next(request); + } + logger(`Request: ${sanitizer.sanitize(request)}`); + const response = await next(request); + logger(`Response status code: ${response.status}`); + logger(`Headers: ${sanitizer.sanitize(response.headers)}`); + return response; + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/redirectPolicy.js +var require_redirectPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/redirectPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var redirectPolicy_exports = {}; + __export2(redirectPolicy_exports, { + redirectPolicy: () => redirectPolicy2, + redirectPolicyName: () => redirectPolicyName2 + }); + module2.exports = __toCommonJS2(redirectPolicy_exports); + var import_log = require_log2(); + var redirectPolicyName2 = "redirectPolicy"; + var allowedRedirect = ["GET", "HEAD"]; + function redirectPolicy2(options = {}) { + const { maxRetries = 20, allowCrossOriginRedirects = false } = options; + return { + name: redirectPolicyName2, + async sendRequest(request, next) { + const response = await next(request); + return handleRedirect(next, response, maxRetries, allowCrossOriginRedirects); + } + }; + } + async function handleRedirect(next, response, maxRetries, allowCrossOriginRedirects, currentRetries = 0) { + const { request, status, headers } = response; + const locationHeader = headers.get("location"); + if (locationHeader && (status === 300 || status === 301 && allowedRedirect.includes(request.method) || status === 302 && allowedRedirect.includes(request.method) || status === 303 && request.method === "POST" || status === 307) && currentRetries < maxRetries) { + const url = new URL(locationHeader, request.url); + if (!allowCrossOriginRedirects) { + const originalUrl = new URL(request.url); + if (url.origin !== originalUrl.origin) { + import_log.logger.verbose( + `Skipping cross-origin redirect from ${originalUrl.origin} to ${url.origin}.` + ); + return response; + } + } + request.url = url.toString(); + if (status === 303) { + request.method = "GET"; + request.headers.delete("Content-Length"); + delete request.body; + } + request.headers.delete("Authorization"); + const res = await next(request); + return handleRedirect(next, res, maxRetries, allowCrossOriginRedirects, currentRetries + 1); + } + return response; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/userAgentPlatform.js +var require_userAgentPlatform = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/userAgentPlatform.js"(exports2, module2) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var userAgentPlatform_exports = {}; + __export2(userAgentPlatform_exports, { + getHeaderName: () => getHeaderName, + setPlatformSpecificData: () => setPlatformSpecificData + }); + module2.exports = __toCommonJS2(userAgentPlatform_exports); + var import_node_os2 = __toESM2(require("node:os")); + var import_node_process7 = __toESM2(require("node:process")); + function getHeaderName() { + return "User-Agent"; + } + async function setPlatformSpecificData(map) { + if (import_node_process7.default && import_node_process7.default.versions) { + const osInfo = `${import_node_os2.default.type()} ${import_node_os2.default.release()}; ${import_node_os2.default.arch()}`; + if (import_node_process7.default.versions.bun) { + map.set("Bun", `${import_node_process7.default.versions.bun} (${osInfo})`); + } else if (import_node_process7.default.versions.deno) { + map.set("Deno", `${import_node_process7.default.versions.deno} (${osInfo})`); + } else if (import_node_process7.default.versions.node) { + map.set("Node", `${import_node_process7.default.versions.node} (${osInfo})`); + } + } + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/constants.js +var require_constants = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/constants.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var constants_exports = {}; + __export2(constants_exports, { + DEFAULT_RETRY_POLICY_COUNT: () => DEFAULT_RETRY_POLICY_COUNT, + SDK_VERSION: () => SDK_VERSION + }); + module2.exports = __toCommonJS2(constants_exports); + var SDK_VERSION = "0.3.5"; + var DEFAULT_RETRY_POLICY_COUNT = 3; + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/userAgent.js +var require_userAgent = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/userAgent.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var userAgent_exports = {}; + __export2(userAgent_exports, { + getUserAgentHeaderName: () => getUserAgentHeaderName, + getUserAgentValue: () => getUserAgentValue + }); + module2.exports = __toCommonJS2(userAgent_exports); + var import_userAgentPlatform = require_userAgentPlatform(); + var import_constants = require_constants(); + function getUserAgentString(telemetryInfo) { + const parts = []; + for (const [key, value] of telemetryInfo) { + const token = value ? `${key}/${value}` : key; + parts.push(token); + } + return parts.join(" "); + } + function getUserAgentHeaderName() { + return (0, import_userAgentPlatform.getHeaderName)(); + } + async function getUserAgentValue(prefix) { + const runtimeInfo = /* @__PURE__ */ new Map(); + runtimeInfo.set("ts-http-runtime", import_constants.SDK_VERSION); + await (0, import_userAgentPlatform.setPlatformSpecificData)(runtimeInfo); + const defaultAgent = getUserAgentString(runtimeInfo); + const userAgentValue = prefix ? `${prefix} ${defaultAgent}` : defaultAgent; + return userAgentValue; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/userAgentPolicy.js +var require_userAgentPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/userAgentPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var userAgentPolicy_exports = {}; + __export2(userAgentPolicy_exports, { + userAgentPolicy: () => userAgentPolicy2, + userAgentPolicyName: () => userAgentPolicyName2 + }); + module2.exports = __toCommonJS2(userAgentPolicy_exports); + var import_userAgent = require_userAgent(); + var UserAgentHeaderName = (0, import_userAgent.getUserAgentHeaderName)(); + var userAgentPolicyName2 = "userAgentPolicy"; + function userAgentPolicy2(options = {}) { + const userAgentValue = (0, import_userAgent.getUserAgentValue)(options.userAgentPrefix); + return { + name: userAgentPolicyName2, + async sendRequest(request, next) { + if (!request.headers.has(UserAgentHeaderName)) { + request.headers.set(UserAgentHeaderName, await userAgentValue); + } + return next(request); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/decompressResponsePolicy.js +var require_decompressResponsePolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/decompressResponsePolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var decompressResponsePolicy_exports = {}; + __export2(decompressResponsePolicy_exports, { + decompressResponsePolicy: () => decompressResponsePolicy2, + decompressResponsePolicyName: () => decompressResponsePolicyName2 + }); + module2.exports = __toCommonJS2(decompressResponsePolicy_exports); + var decompressResponsePolicyName2 = "decompressResponsePolicy"; + function decompressResponsePolicy2() { + return { + name: decompressResponsePolicyName2, + async sendRequest(request, next) { + if (request.method !== "HEAD") { + request.headers.set("Accept-Encoding", "gzip,deflate"); + } + return next(request); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/random.js +var require_random = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/random.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var random_exports = {}; + __export2(random_exports, { + getRandomIntegerInclusive: () => getRandomIntegerInclusive2 + }); + module2.exports = __toCommonJS2(random_exports); + function getRandomIntegerInclusive2(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + const offset = Math.floor(Math.random() * (max - min + 1)); + return offset + min; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/delay.js +var require_delay = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/delay.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var delay_exports = {}; + __export2(delay_exports, { + calculateRetryDelay: () => calculateRetryDelay2 + }); + module2.exports = __toCommonJS2(delay_exports); + var import_random = require_random(); + function calculateRetryDelay2(retryAttempt, config) { + const exponentialDelay = config.retryDelayInMs * Math.pow(2, retryAttempt); + const clampedDelay = Math.min(config.maxRetryDelayInMs, exponentialDelay); + const retryAfterInMs = clampedDelay / 2 + (0, import_random.getRandomIntegerInclusive)(0, clampedDelay / 2); + return { retryAfterInMs }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/helpers.js +var require_helpers = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/helpers.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var helpers_exports = {}; + __export2(helpers_exports, { + delay: () => delay, + parseHeaderValueAsNumber: () => parseHeaderValueAsNumber + }); + module2.exports = __toCommonJS2(helpers_exports); + var import_AbortError = require_AbortError(); + var StandardAbortMessage = "The operation was aborted."; + function delay(delayInMs, value, options) { + return new Promise((resolve, reject) => { + let timer = void 0; + let onAborted = void 0; + const rejectOnAbort = () => { + return reject( + new import_AbortError.AbortError(options?.abortErrorMsg ? options?.abortErrorMsg : StandardAbortMessage) + ); + }; + const removeListeners = () => { + if (options?.abortSignal && onAborted) { + options.abortSignal.removeEventListener("abort", onAborted); + } + }; + onAborted = () => { + if (timer) { + clearTimeout(timer); + } + removeListeners(); + return rejectOnAbort(); + }; + if (options?.abortSignal && options.abortSignal.aborted) { + return rejectOnAbort(); + } + timer = setTimeout(() => { + removeListeners(); + resolve(value); + }, delayInMs); + if (options?.abortSignal) { + options.abortSignal.addEventListener("abort", onAborted); + } + }); + } + function parseHeaderValueAsNumber(response, headerName) { + const value = response.headers.get(headerName); + if (!value) return; + const valueAsNum = Number(value); + if (Number.isNaN(valueAsNum)) return; + return valueAsNum; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/retryStrategies/throttlingRetryStrategy.js +var require_throttlingRetryStrategy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/retryStrategies/throttlingRetryStrategy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var throttlingRetryStrategy_exports = {}; + __export2(throttlingRetryStrategy_exports, { + isThrottlingRetryResponse: () => isThrottlingRetryResponse, + throttlingRetryStrategy: () => throttlingRetryStrategy + }); + module2.exports = __toCommonJS2(throttlingRetryStrategy_exports); + var import_helpers = require_helpers(); + var RetryAfterHeader = "Retry-After"; + var AllRetryAfterHeaders = ["retry-after-ms", "x-ms-retry-after-ms", RetryAfterHeader]; + function getRetryAfterInMs(response) { + if (!(response && [429, 503].includes(response.status))) return void 0; + try { + for (const header of AllRetryAfterHeaders) { + const retryAfterValue = (0, import_helpers.parseHeaderValueAsNumber)(response, header); + if (retryAfterValue === 0 || retryAfterValue) { + const multiplyingFactor = header === RetryAfterHeader ? 1e3 : 1; + return retryAfterValue * multiplyingFactor; + } + } + const retryAfterHeader = response.headers.get(RetryAfterHeader); + if (!retryAfterHeader) return; + const date = Date.parse(retryAfterHeader); + const diff = date - Date.now(); + return Number.isFinite(diff) ? Math.max(0, diff) : void 0; + } catch { + return void 0; + } + } + function isThrottlingRetryResponse(response) { + return Number.isFinite(getRetryAfterInMs(response)); + } + function throttlingRetryStrategy() { + return { + name: "throttlingRetryStrategy", + retry({ response }) { + const retryAfterInMs = getRetryAfterInMs(response); + if (!Number.isFinite(retryAfterInMs)) { + return { skipStrategy: true }; + } + return { + retryAfterInMs + }; + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/retryStrategies/exponentialRetryStrategy.js +var require_exponentialRetryStrategy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/retryStrategies/exponentialRetryStrategy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var exponentialRetryStrategy_exports = {}; + __export2(exponentialRetryStrategy_exports, { + exponentialRetryStrategy: () => exponentialRetryStrategy, + isExponentialRetryResponse: () => isExponentialRetryResponse, + isSystemError: () => isSystemError + }); + module2.exports = __toCommonJS2(exponentialRetryStrategy_exports); + var import_delay = require_delay(); + var import_throttlingRetryStrategy = require_throttlingRetryStrategy(); + var DEFAULT_CLIENT_RETRY_INTERVAL = 1e3; + var DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1e3 * 64; + function exponentialRetryStrategy(options = {}) { + const retryInterval = options.retryDelayInMs ?? DEFAULT_CLIENT_RETRY_INTERVAL; + const maxRetryInterval = options.maxRetryDelayInMs ?? DEFAULT_CLIENT_MAX_RETRY_INTERVAL; + return { + name: "exponentialRetryStrategy", + retry({ retryCount, response, responseError }) { + const matchedSystemError = isSystemError(responseError); + const ignoreSystemErrors = matchedSystemError && options.ignoreSystemErrors; + const isExponential = isExponentialRetryResponse(response); + const ignoreExponentialResponse = isExponential && options.ignoreHttpStatusCodes; + const unknownResponse = response && ((0, import_throttlingRetryStrategy.isThrottlingRetryResponse)(response) || !isExponential); + if (unknownResponse || ignoreExponentialResponse || ignoreSystemErrors) { + return { skipStrategy: true }; + } + if (responseError && !matchedSystemError && !isExponential) { + return { errorToThrow: responseError }; + } + return (0, import_delay.calculateRetryDelay)(retryCount, { + retryDelayInMs: retryInterval, + maxRetryDelayInMs: maxRetryInterval + }); + } + }; + } + function isExponentialRetryResponse(response) { + return Boolean( + response && response.status !== void 0 && (response.status >= 500 || response.status === 408) && response.status !== 501 && response.status !== 505 + ); + } + function isSystemError(err) { + if (!err) { + return false; + } + return err.code === "ETIMEDOUT" || err.code === "ESOCKETTIMEDOUT" || err.code === "ECONNREFUSED" || err.code === "ECONNRESET" || err.code === "ENOENT" || err.code === "ENOTFOUND"; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/retryPolicy.js +var require_retryPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/retryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var retryPolicy_exports = {}; + __export2(retryPolicy_exports, { + retryPolicy: () => retryPolicy2 + }); + module2.exports = __toCommonJS2(retryPolicy_exports); + var import_helpers = require_helpers(); + var import_restError = require_restError(); + var import_AbortError = require_AbortError(); + var import_logger = require_logger(); + var import_constants = require_constants(); + var retryPolicyLogger = (0, import_logger.createClientLogger)("ts-http-runtime retryPolicy"); + var retryPolicyName = "retryPolicy"; + function retryPolicy2(strategies, options = { maxRetries: import_constants.DEFAULT_RETRY_POLICY_COUNT }) { + const logger = options.logger || retryPolicyLogger; + return { + name: retryPolicyName, + async sendRequest(request, next) { + let response; + let responseError; + let retryCount = -1; + retryRequest: while (true) { + retryCount += 1; + response = void 0; + responseError = void 0; + try { + logger.info(`Retry ${retryCount}: Attempting to send request`, request.requestId); + response = await next(request); + logger.info(`Retry ${retryCount}: Received a response from request`, request.requestId); + } catch (e) { + logger.error(`Retry ${retryCount}: Received an error from request`, request.requestId); + if (!(0, import_restError.isRestError)(e)) { + throw e; + } + responseError = e; + response = e.response; + } + if (request.abortSignal?.aborted) { + logger.error(`Retry ${retryCount}: Request aborted.`); + const abortError = new import_AbortError.AbortError(); + throw abortError; + } + if (retryCount >= (options.maxRetries ?? import_constants.DEFAULT_RETRY_POLICY_COUNT)) { + logger.info( + `Retry ${retryCount}: Maximum retries reached. Returning the last received response, or throwing the last received error.` + ); + if (responseError) { + throw responseError; + } else if (response) { + return response; + } else { + throw new Error("Maximum retries reached with no response or error to throw"); + } + } + logger.info(`Retry ${retryCount}: Processing ${strategies.length} retry strategies.`); + strategiesLoop: for (const strategy of strategies) { + const strategyLogger = strategy.logger || logger; + strategyLogger.info(`Retry ${retryCount}: Processing retry strategy ${strategy.name}.`); + const modifiers = strategy.retry({ + retryCount, + response, + responseError + }); + if (modifiers.skipStrategy) { + strategyLogger.info(`Retry ${retryCount}: Skipped.`); + continue strategiesLoop; + } + const { errorToThrow, retryAfterInMs, redirectTo } = modifiers; + if (errorToThrow) { + strategyLogger.error( + `Retry ${retryCount}: Retry strategy ${strategy.name} throws error:`, + errorToThrow + ); + throw errorToThrow; + } + if (retryAfterInMs || retryAfterInMs === 0) { + strategyLogger.info( + `Retry ${retryCount}: Retry strategy ${strategy.name} retries after ${retryAfterInMs}` + ); + await (0, import_helpers.delay)(retryAfterInMs, void 0, { abortSignal: request.abortSignal }); + continue retryRequest; + } + if (redirectTo) { + strategyLogger.info( + `Retry ${retryCount}: Retry strategy ${strategy.name} redirects to ${redirectTo}` + ); + request.url = redirectTo; + continue retryRequest; + } + } + if (responseError) { + logger.info( + `None of the retry strategies could work with the received error. Throwing it.` + ); + throw responseError; + } + if (response) { + logger.info( + `None of the retry strategies could work with the received response. Returning it.` + ); + return response; + } + } + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/defaultRetryPolicy.js +var require_defaultRetryPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/defaultRetryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var defaultRetryPolicy_exports = {}; + __export2(defaultRetryPolicy_exports, { + defaultRetryPolicy: () => defaultRetryPolicy2, + defaultRetryPolicyName: () => defaultRetryPolicyName2 + }); + module2.exports = __toCommonJS2(defaultRetryPolicy_exports); + var import_exponentialRetryStrategy = require_exponentialRetryStrategy(); + var import_throttlingRetryStrategy = require_throttlingRetryStrategy(); + var import_retryPolicy = require_retryPolicy(); + var import_constants = require_constants(); + var defaultRetryPolicyName2 = "defaultRetryPolicy"; + function defaultRetryPolicy2(options = {}) { + return { + name: defaultRetryPolicyName2, + sendRequest: (0, import_retryPolicy.retryPolicy)([(0, import_throttlingRetryStrategy.throttlingRetryStrategy)(), (0, import_exponentialRetryStrategy.exponentialRetryStrategy)(options)], { + maxRetries: options.maxRetries ?? import_constants.DEFAULT_RETRY_POLICY_COUNT + }).sendRequest + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/checkEnvironment.js +var require_checkEnvironment = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/checkEnvironment.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var checkEnvironment_exports = {}; + __export2(checkEnvironment_exports, { + isBrowser: () => isBrowser2, + isBun: () => isBun2, + isDeno: () => isDeno2, + isNodeLike: () => isNodeLike2, + isNodeRuntime: () => isNodeRuntime2, + isReactNative: () => isReactNative2, + isWebWorker: () => isWebWorker2 + }); + module2.exports = __toCommonJS2(checkEnvironment_exports); + var isBrowser2 = typeof window !== "undefined" && typeof window.document !== "undefined"; + var isWebWorker2 = typeof self === "object" && typeof self?.importScripts === "function" && (self.constructor?.name === "DedicatedWorkerGlobalScope" || self.constructor?.name === "ServiceWorkerGlobalScope" || self.constructor?.name === "SharedWorkerGlobalScope"); + var isDeno2 = typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined"; + var isBun2 = typeof Bun !== "undefined" && typeof Bun.version !== "undefined"; + var isNodeLike2 = typeof globalThis.process !== "undefined" && Boolean(globalThis.process.version) && Boolean(globalThis.process.versions?.node); + var isNodeRuntime2 = isNodeLike2 && !isBun2 && !isDeno2; + var isReactNative2 = typeof navigator !== "undefined" && navigator?.product === "ReactNative"; + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/formDataPolicy.js +var require_formDataPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/formDataPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var formDataPolicy_exports = {}; + __export2(formDataPolicy_exports, { + formDataPolicy: () => formDataPolicy2, + formDataPolicyName: () => formDataPolicyName2 + }); + module2.exports = __toCommonJS2(formDataPolicy_exports); + var import_bytesEncoding = require_bytesEncoding(); + var import_checkEnvironment = require_checkEnvironment(); + var import_httpHeaders = require_httpHeaders(); + var formDataPolicyName2 = "formDataPolicy"; + function formDataToFormDataMap(formData) { + const formDataMap = {}; + for (const [key, value] of formData.entries()) { + formDataMap[key] ??= []; + formDataMap[key].push(value); + } + return formDataMap; + } + function formDataPolicy2() { + return { + name: formDataPolicyName2, + async sendRequest(request, next) { + if (import_checkEnvironment.isNodeLike && typeof FormData !== "undefined" && request.body instanceof FormData) { + request.formData = formDataToFormDataMap(request.body); + request.body = void 0; + } + if (request.formData) { + const contentType = request.headers.get("Content-Type"); + if (contentType && contentType.indexOf("application/x-www-form-urlencoded") !== -1) { + request.body = wwwFormUrlEncode(request.formData); + } else { + await prepareFormData(request.formData, request); + } + request.formData = void 0; + } + return next(request); + } + }; + } + function wwwFormUrlEncode(formData) { + const urlSearchParams = new URLSearchParams(); + for (const [key, value] of Object.entries(formData)) { + if (Array.isArray(value)) { + for (const subValue of value) { + urlSearchParams.append(key, subValue.toString()); + } + } else { + urlSearchParams.append(key, value.toString()); + } + } + return urlSearchParams.toString(); + } + async function prepareFormData(formData, request) { + const contentType = request.headers.get("Content-Type"); + if (contentType && !contentType.startsWith("multipart/form-data")) { + return; + } + request.headers.set("Content-Type", contentType ?? "multipart/form-data"); + const parts = []; + for (const [fieldName, values] of Object.entries(formData)) { + for (const value of Array.isArray(values) ? values : [values]) { + if (typeof value === "string") { + parts.push({ + headers: (0, import_httpHeaders.createHttpHeaders)({ + "Content-Disposition": `form-data; name="${fieldName}"` + }), + body: (0, import_bytesEncoding.stringToUint8Array)(value, "utf-8") + }); + } else if (value === void 0 || value === null || typeof value !== "object") { + throw new Error( + `Unexpected value for key ${fieldName}: ${value}. Value should be serialized to string first.` + ); + } else { + const fileName = value.name || "blob"; + const headers = (0, import_httpHeaders.createHttpHeaders)(); + headers.set( + "Content-Disposition", + `form-data; name="${fieldName}"; filename="${fileName}"` + ); + headers.set("Content-Type", value.type || "application/octet-stream"); + parts.push({ + headers, + body: value + }); + } + } + } + request.multipartBody = { parts }; + } + } +}); + +// node_modules/debug/src/common.js +var require_common = __commonJS({ + "node_modules/debug/src/common.js"(exports2, module2) { + function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require_ms5(); + createDebug.destroy = destroy; + Object.keys(env).forEach((key) => { + createDebug[key] = env[key]; + }); + createDebug.names = []; + createDebug.skips = []; + createDebug.formatters = {}; + function selectColor(namespace) { + let hash = 0; + for (let i = 0; i < namespace.length; i++) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; + function createDebug(namespace) { + let prevTime; + let enableOverride = null; + let namespacesCache; + let enabledCache; + function debug(...args) { + if (!debug.enabled) { + return; + } + const self2 = debug; + const curr = Number(/* @__PURE__ */ new Date()); + const ms = curr - (prevTime || curr); + self2.diff = ms; + self2.prev = prevTime; + self2.curr = curr; + prevTime = curr; + args[0] = createDebug.coerce(args[0]); + if (typeof args[0] !== "string") { + args.unshift("%O"); + } + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + if (match === "%%") { + return "%"; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === "function") { + const val = args[index]; + match = formatter.call(self2, val); + args.splice(index, 1); + index--; + } + return match; + }); + createDebug.formatArgs.call(self2, args); + const logFn = self2.log || createDebug.log; + logFn.apply(self2, args); + } + debug.namespace = namespace; + debug.useColors = createDebug.useColors(); + debug.color = createDebug.selectColor(namespace); + debug.extend = extend; + debug.destroy = createDebug.destroy; + Object.defineProperty(debug, "enabled", { + enumerable: true, + configurable: false, + get: () => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + return enabledCache; + }, + set: (v) => { + enableOverride = v; + } + }); + if (typeof createDebug.init === "function") { + createDebug.init(debug); + } + return debug; + } + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.namespaces = namespaces; + createDebug.names = []; + createDebug.skips = []; + const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean); + for (const ns of split) { + if (ns[0] === "-") { + createDebug.skips.push(ns.slice(1)); + } else { + createDebug.names.push(ns); + } + } + } + function matchesTemplate(search, template) { + let searchIndex = 0; + let templateIndex = 0; + let starIndex = -1; + let matchIndex = 0; + while (searchIndex < search.length) { + if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) { + if (template[templateIndex] === "*") { + starIndex = templateIndex; + matchIndex = searchIndex; + templateIndex++; + } else { + searchIndex++; + templateIndex++; + } + } else if (starIndex !== -1) { + templateIndex = starIndex + 1; + matchIndex++; + searchIndex = matchIndex; + } else { + return false; + } + } + while (templateIndex < template.length && template[templateIndex] === "*") { + templateIndex++; + } + return templateIndex === template.length; + } + function disable() { + const namespaces = [ + ...createDebug.names, + ...createDebug.skips.map((namespace) => "-" + namespace) + ].join(","); + createDebug.enable(""); + return namespaces; + } + function enabled(name) { + for (const skip of createDebug.skips) { + if (matchesTemplate(name, skip)) { + return false; + } + } + for (const ns of createDebug.names) { + if (matchesTemplate(name, ns)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + function destroy() { + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + } + createDebug.enable(createDebug.load()); + return createDebug; + } + module2.exports = setup; + } +}); + +// node_modules/debug/src/browser.js +var require_browser5 = __commonJS({ + "node_modules/debug/src/browser.js"(exports2, module2) { + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.storage = localstorage(); + exports2.destroy = /* @__PURE__ */ (() => { + let warned = false; + return () => { + if (!warned) { + warned = true; + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + } + }; + })(); + exports2.colors = [ + "#0000CC", + "#0000FF", + "#0033CC", + "#0033FF", + "#0066CC", + "#0066FF", + "#0099CC", + "#0099FF", + "#00CC00", + "#00CC33", + "#00CC66", + "#00CC99", + "#00CCCC", + "#00CCFF", + "#3300CC", + "#3300FF", + "#3333CC", + "#3333FF", + "#3366CC", + "#3366FF", + "#3399CC", + "#3399FF", + "#33CC00", + "#33CC33", + "#33CC66", + "#33CC99", + "#33CCCC", + "#33CCFF", + "#6600CC", + "#6600FF", + "#6633CC", + "#6633FF", + "#66CC00", + "#66CC33", + "#9900CC", + "#9900FF", + "#9933CC", + "#9933FF", + "#99CC00", + "#99CC33", + "#CC0000", + "#CC0033", + "#CC0066", + "#CC0099", + "#CC00CC", + "#CC00FF", + "#CC3300", + "#CC3333", + "#CC3366", + "#CC3399", + "#CC33CC", + "#CC33FF", + "#CC6600", + "#CC6633", + "#CC9900", + "#CC9933", + "#CCCC00", + "#CCCC33", + "#FF0000", + "#FF0033", + "#FF0066", + "#FF0099", + "#FF00CC", + "#FF00FF", + "#FF3300", + "#FF3333", + "#FF3366", + "#FF3399", + "#FF33CC", + "#FF33FF", + "#FF6600", + "#FF6633", + "#FF9900", + "#FF9933", + "#FFCC00", + "#FFCC33" + ]; + function useColors() { + if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) { + return true; + } + if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + let m; + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + function formatArgs(args) { + args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module2.exports.humanize(this.diff); + if (!this.useColors) { + return; + } + const c = "color: " + this.color; + args.splice(1, 0, c, "color: inherit"); + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, (match) => { + if (match === "%%") { + return; + } + index++; + if (match === "%c") { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + exports2.log = console.debug || console.log || (() => { + }); + function save(namespaces) { + try { + if (namespaces) { + exports2.storage.setItem("debug", namespaces); + } else { + exports2.storage.removeItem("debug"); + } + } catch (error) { + } + } + function load() { + let r; + try { + r = exports2.storage.getItem("debug") || exports2.storage.getItem("DEBUG"); + } catch (error) { + } + if (!r && typeof process !== "undefined" && "env" in process) { + r = process.env.DEBUG; + } + return r; + } + function localstorage() { + try { + return localStorage; + } catch (error) { + } + } + module2.exports = require_common()(exports2); + var { formatters } = module2.exports; + formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (error) { + return "[UnexpectedJSONParseError]: " + error.message; + } + }; + } +}); + +// node_modules/has-flag/index.js +var require_has_flag = __commonJS({ + "node_modules/has-flag/index.js"(exports2, module2) { + "use strict"; + module2.exports = (flag, argv = process.argv) => { + const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--"; + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf("--"); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); + }; + } +}); + +// node_modules/supports-color/index.js +var require_supports_color = __commonJS({ + "node_modules/supports-color/index.js"(exports2, module2) { + "use strict"; + var os2 = require("os"); + var tty = require("tty"); + var hasFlag = require_has_flag(); + var { env } = process; + var forceColor; + if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) { + forceColor = 0; + } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) { + forceColor = 1; + } + if ("FORCE_COLOR" in env) { + if (env.FORCE_COLOR === "true") { + forceColor = 1; + } else if (env.FORCE_COLOR === "false") { + forceColor = 0; + } else { + forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); + } + } + function translateLevel(level) { + if (level === 0) { + return false; + } + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; + } + function supportsColor(haveStream, streamIsTTY) { + if (forceColor === 0) { + return 0; + } + if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) { + return 3; + } + if (hasFlag("color=256")) { + return 2; + } + if (haveStream && !streamIsTTY && forceColor === void 0) { + return 0; + } + const min = forceColor || 0; + if (env.TERM === "dumb") { + return min; + } + if (process.platform === "win32") { + const osRelease = os2.release().split("."); + if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } + return 1; + } + if ("CI" in env) { + if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") { + return 1; + } + return min; + } + if ("TEAMCITY_VERSION" in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + if (env.COLORTERM === "truecolor") { + return 3; + } + if ("TERM_PROGRAM" in env) { + const version4 = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10); + switch (env.TERM_PROGRAM) { + case "iTerm.app": + return version4 >= 3 ? 3 : 2; + case "Apple_Terminal": + return 2; + } + } + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + if ("COLORTERM" in env) { + return 1; + } + return min; + } + function getSupportLevel(stream) { + const level = supportsColor(stream, stream && stream.isTTY); + return translateLevel(level); + } + module2.exports = { + supportsColor: getSupportLevel, + stdout: translateLevel(supportsColor(true, tty.isatty(1))), + stderr: translateLevel(supportsColor(true, tty.isatty(2))) + }; + } +}); + +// node_modules/debug/src/node.js +var require_node5 = __commonJS({ + "node_modules/debug/src/node.js"(exports2, module2) { + var tty = require("tty"); + var util = require("util"); + exports2.init = init; + exports2.log = log; + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.destroy = util.deprecate( + () => { + }, + "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`." + ); + exports2.colors = [6, 2, 3, 4, 5, 1]; + try { + const supportsColor = require_supports_color(); + if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { + exports2.colors = [ + 20, + 21, + 26, + 27, + 32, + 33, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 56, + 57, + 62, + 63, + 68, + 69, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 92, + 93, + 98, + 99, + 112, + 113, + 128, + 129, + 134, + 135, + 148, + 149, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 178, + 179, + 184, + 185, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 214, + 215, + 220, + 221 + ]; + } + } catch (error) { + } + exports2.inspectOpts = Object.keys(process.env).filter((key) => { + return /^debug_/i.test(key); + }).reduce((obj, key) => { + const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_, k) => { + return k.toUpperCase(); + }); + let val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) { + val = true; + } else if (/^(no|off|false|disabled)$/i.test(val)) { + val = false; + } else if (val === "null") { + val = null; + } else { + val = Number(val); + } + obj[prop] = val; + return obj; + }, {}); + function useColors() { + return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty.isatty(process.stderr.fd); + } + function formatArgs(args) { + const { namespace: name, useColors: useColors2 } = this; + if (useColors2) { + const c = this.color; + const colorCode = "\x1B[3" + (c < 8 ? c : "8;5;" + c); + const prefix = ` ${colorCode};1m${name} \x1B[0m`; + args[0] = prefix + args[0].split("\n").join("\n" + prefix); + args.push(colorCode + "m+" + module2.exports.humanize(this.diff) + "\x1B[0m"); + } else { + args[0] = getDate() + name + " " + args[0]; + } + } + function getDate() { + if (exports2.inspectOpts.hideDate) { + return ""; + } + return (/* @__PURE__ */ new Date()).toISOString() + " "; + } + function log(...args) { + return process.stderr.write(util.formatWithOptions(exports2.inspectOpts, ...args) + "\n"); + } + function save(namespaces) { + if (namespaces) { + process.env.DEBUG = namespaces; + } else { + delete process.env.DEBUG; + } + } + function load() { + return process.env.DEBUG; + } + function init(debug) { + debug.inspectOpts = {}; + const keys = Object.keys(exports2.inspectOpts); + for (let i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports2.inspectOpts[keys[i]]; + } + } + module2.exports = require_common()(exports2); + var { formatters } = module2.exports; + formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts).split("\n").map((str) => str.trim()).join(" "); + }; + formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); + }; + } +}); + +// node_modules/debug/src/index.js +var require_src5 = __commonJS({ + "node_modules/debug/src/index.js"(exports2, module2) { + if (typeof process === "undefined" || process.type === "renderer" || process.browser === true || process.__nwjs) { + module2.exports = require_browser5(); + } else { + module2.exports = require_node5(); + } + } +}); + +// node_modules/agent-base/dist/helpers.js +var require_helpers2 = __commonJS({ + "node_modules/agent-base/dist/helpers.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.req = exports2.json = exports2.toBuffer = void 0; + var http = __importStar2(require("http")); + var https = __importStar2(require("https")); + async function toBuffer(stream) { + let length = 0; + const chunks = []; + for await (const chunk of stream) { + length += chunk.length; + chunks.push(chunk); + } + return Buffer.concat(chunks, length); + } + exports2.toBuffer = toBuffer; + async function json(stream) { + const buf = await toBuffer(stream); + const str = buf.toString("utf8"); + try { + return JSON.parse(str); + } catch (_err) { + const err = _err; + err.message += ` (input: ${str})`; + throw err; + } + } + exports2.json = json; + function req(url, opts = {}) { + const href = typeof url === "string" ? url : url.href; + const req2 = (href.startsWith("https:") ? https : http).request(url, opts); + const promise = new Promise((resolve, reject) => { + req2.once("response", resolve).once("error", reject).end(); + }); + req2.then = promise.then.bind(promise); + return req2; + } + exports2.req = req; + } +}); + +// node_modules/agent-base/dist/index.js +var require_dist = __commonJS({ + "node_modules/agent-base/dist/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Agent = void 0; + var net = __importStar2(require("net")); + var http = __importStar2(require("http")); + var https_1 = require("https"); + __exportStar2(require_helpers2(), exports2); + var INTERNAL = Symbol("AgentBaseInternalState"); + var Agent = class extends http.Agent { + constructor(opts) { + super(opts); + this[INTERNAL] = {}; + } + /** + * Determine whether this is an `http` or `https` request. + */ + isSecureEndpoint(options) { + if (options) { + if (typeof options.secureEndpoint === "boolean") { + return options.secureEndpoint; + } + if (typeof options.protocol === "string") { + return options.protocol === "https:"; + } + } + const { stack } = new Error(); + if (typeof stack !== "string") + return false; + return stack.split("\n").some((l) => l.indexOf("(https.js:") !== -1 || l.indexOf("node:https:") !== -1); + } + // In order to support async signatures in `connect()` and Node's native + // connection pooling in `http.Agent`, the array of sockets for each origin + // has to be updated synchronously. This is so the length of the array is + // accurate when `addRequest()` is next called. We achieve this by creating a + // fake socket and adding it to `sockets[origin]` and incrementing + // `totalSocketCount`. + incrementSockets(name) { + if (this.maxSockets === Infinity && this.maxTotalSockets === Infinity) { + return null; + } + if (!this.sockets[name]) { + this.sockets[name] = []; + } + const fakeSocket = new net.Socket({ writable: false }); + this.sockets[name].push(fakeSocket); + this.totalSocketCount++; + return fakeSocket; + } + decrementSockets(name, socket) { + if (!this.sockets[name] || socket === null) { + return; + } + const sockets = this.sockets[name]; + const index = sockets.indexOf(socket); + if (index !== -1) { + sockets.splice(index, 1); + this.totalSocketCount--; + if (sockets.length === 0) { + delete this.sockets[name]; + } + } + } + // In order to properly update the socket pool, we need to call `getName()` on + // the core `https.Agent` if it is a secureEndpoint. + getName(options) { + const secureEndpoint = this.isSecureEndpoint(options); + if (secureEndpoint) { + return https_1.Agent.prototype.getName.call(this, options); + } + return super.getName(options); + } + createSocket(req, options, cb) { + const connectOpts = { + ...options, + secureEndpoint: this.isSecureEndpoint(options) + }; + const name = this.getName(connectOpts); + const fakeSocket = this.incrementSockets(name); + Promise.resolve().then(() => this.connect(req, connectOpts)).then((socket) => { + this.decrementSockets(name, fakeSocket); + if (socket instanceof http.Agent) { + try { + return socket.addRequest(req, connectOpts); + } catch (err) { + return cb(err); + } + } + this[INTERNAL].currentSocket = socket; + super.createSocket(req, options, cb); + }, (err) => { + this.decrementSockets(name, fakeSocket); + cb(err); + }); + } + createConnection() { + const socket = this[INTERNAL].currentSocket; + this[INTERNAL].currentSocket = void 0; + if (!socket) { + throw new Error("No socket was returned in the `connect()` function"); + } + return socket; + } + get defaultPort() { + return this[INTERNAL].defaultPort ?? (this.protocol === "https:" ? 443 : 80); + } + set defaultPort(v) { + if (this[INTERNAL]) { + this[INTERNAL].defaultPort = v; + } + } + get protocol() { + return this[INTERNAL].protocol ?? (this.isSecureEndpoint() ? "https:" : "http:"); + } + set protocol(v) { + if (this[INTERNAL]) { + this[INTERNAL].protocol = v; + } + } + }; + exports2.Agent = Agent; + } +}); + +// node_modules/https-proxy-agent/dist/parse-proxy-response.js +var require_parse_proxy_response = __commonJS({ + "node_modules/https-proxy-agent/dist/parse-proxy-response.js"(exports2) { + "use strict"; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.parseProxyResponse = void 0; + var debug_1 = __importDefault2(require_src5()); + var debug = (0, debug_1.default)("https-proxy-agent:parse-proxy-response"); + function parseProxyResponse(socket) { + return new Promise((resolve, reject) => { + let buffersLength = 0; + const buffers = []; + function read() { + const b = socket.read(); + if (b) + ondata(b); + else + socket.once("readable", read); + } + function cleanup() { + socket.removeListener("end", onend); + socket.removeListener("error", onerror); + socket.removeListener("readable", read); + } + function onend() { + cleanup(); + debug("onend"); + reject(new Error("Proxy connection ended before receiving CONNECT response")); + } + function onerror(err) { + cleanup(); + debug("onerror %o", err); + reject(err); + } + function ondata(b) { + buffers.push(b); + buffersLength += b.length; + const buffered = Buffer.concat(buffers, buffersLength); + const endOfHeaders = buffered.indexOf("\r\n\r\n"); + if (endOfHeaders === -1) { + debug("have not received end of HTTP headers yet..."); + read(); + return; + } + const headerParts = buffered.slice(0, endOfHeaders).toString("ascii").split("\r\n"); + const firstLine = headerParts.shift(); + if (!firstLine) { + socket.destroy(); + return reject(new Error("No header received from proxy CONNECT response")); + } + const firstLineParts = firstLine.split(" "); + const statusCode = +firstLineParts[1]; + const statusText = firstLineParts.slice(2).join(" "); + const headers = {}; + for (const header of headerParts) { + if (!header) + continue; + const firstColon = header.indexOf(":"); + if (firstColon === -1) { + socket.destroy(); + return reject(new Error(`Invalid header from proxy CONNECT response: "${header}"`)); + } + const key = header.slice(0, firstColon).toLowerCase(); + const value = header.slice(firstColon + 1).trimStart(); + const current = headers[key]; + if (typeof current === "string") { + headers[key] = [current, value]; + } else if (Array.isArray(current)) { + current.push(value); + } else { + headers[key] = value; + } + } + debug("got proxy server response: %o %o", firstLine, headers); + cleanup(); + resolve({ + connect: { + statusCode, + statusText, + headers + }, + buffered + }); + } + socket.on("error", onerror); + socket.on("end", onend); + read(); + }); + } + exports2.parseProxyResponse = parseProxyResponse; + } +}); + +// node_modules/https-proxy-agent/dist/index.js +var require_dist2 = __commonJS({ + "node_modules/https-proxy-agent/dist/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.HttpsProxyAgent = void 0; + var net = __importStar2(require("net")); + var tls = __importStar2(require("tls")); + var assert_1 = __importDefault2(require("assert")); + var debug_1 = __importDefault2(require_src5()); + var agent_base_1 = require_dist(); + var url_1 = require("url"); + var parse_proxy_response_1 = require_parse_proxy_response(); + var debug = (0, debug_1.default)("https-proxy-agent"); + var setServernameFromNonIpHost = (options) => { + if (options.servername === void 0 && options.host && !net.isIP(options.host)) { + return { + ...options, + servername: options.host + }; + } + return options; + }; + var HttpsProxyAgent = class extends agent_base_1.Agent { + constructor(proxy, opts) { + super(opts); + this.options = { path: void 0 }; + this.proxy = typeof proxy === "string" ? new url_1.URL(proxy) : proxy; + this.proxyHeaders = opts?.headers ?? {}; + debug("Creating new HttpsProxyAgent instance: %o", this.proxy.href); + const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, ""); + const port = this.proxy.port ? parseInt(this.proxy.port, 10) : this.proxy.protocol === "https:" ? 443 : 80; + this.connectOpts = { + // Attempt to negotiate http/1.1 for proxy servers that support http/2 + ALPNProtocols: ["http/1.1"], + ...opts ? omit(opts, "headers") : null, + host, + port + }; + } + /** + * Called when the node-core HTTP client library is creating a + * new HTTP request. + */ + async connect(req, opts) { + const { proxy } = this; + if (!opts.host) { + throw new TypeError('No "host" provided'); + } + let socket; + if (proxy.protocol === "https:") { + debug("Creating `tls.Socket`: %o", this.connectOpts); + socket = tls.connect(setServernameFromNonIpHost(this.connectOpts)); + } else { + debug("Creating `net.Socket`: %o", this.connectOpts); + socket = net.connect(this.connectOpts); + } + const headers = typeof this.proxyHeaders === "function" ? this.proxyHeaders() : { ...this.proxyHeaders }; + const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host; + let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r +`; + if (proxy.username || proxy.password) { + const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; + headers["Proxy-Authorization"] = `Basic ${Buffer.from(auth).toString("base64")}`; + } + headers.Host = `${host}:${opts.port}`; + if (!headers["Proxy-Connection"]) { + headers["Proxy-Connection"] = this.keepAlive ? "Keep-Alive" : "close"; + } + for (const name of Object.keys(headers)) { + payload += `${name}: ${headers[name]}\r +`; + } + const proxyResponsePromise = (0, parse_proxy_response_1.parseProxyResponse)(socket); + socket.write(`${payload}\r +`); + const { connect, buffered } = await proxyResponsePromise; + req.emit("proxyConnect", connect); + this.emit("proxyConnect", connect, req); + if (connect.statusCode === 200) { + req.once("socket", resume); + if (opts.secureEndpoint) { + debug("Upgrading socket connection to TLS"); + return tls.connect({ + ...omit(setServernameFromNonIpHost(opts), "host", "path", "port"), + socket + }); + } + return socket; + } + socket.destroy(); + const fakeSocket = new net.Socket({ writable: false }); + fakeSocket.readable = true; + req.once("socket", (s) => { + debug("Replaying proxy buffer for failed request"); + (0, assert_1.default)(s.listenerCount("data") > 0); + s.push(buffered); + s.push(null); + }); + return fakeSocket; + } + }; + HttpsProxyAgent.protocols = ["http", "https"]; + exports2.HttpsProxyAgent = HttpsProxyAgent; + function resume(socket) { + socket.resume(); + } + function omit(obj, ...keys) { + const ret = {}; + let key; + for (key in obj) { + if (!keys.includes(key)) { + ret[key] = obj[key]; + } + } + return ret; + } + } +}); + +// node_modules/http-proxy-agent/dist/index.js +var require_dist3 = __commonJS({ + "node_modules/http-proxy-agent/dist/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.HttpProxyAgent = void 0; + var net = __importStar2(require("net")); + var tls = __importStar2(require("tls")); + var debug_1 = __importDefault2(require_src5()); + var events_1 = require("events"); + var agent_base_1 = require_dist(); + var url_1 = require("url"); + var debug = (0, debug_1.default)("http-proxy-agent"); + var HttpProxyAgent = class extends agent_base_1.Agent { + constructor(proxy, opts) { + super(opts); + this.proxy = typeof proxy === "string" ? new url_1.URL(proxy) : proxy; + this.proxyHeaders = opts?.headers ?? {}; + debug("Creating new HttpProxyAgent instance: %o", this.proxy.href); + const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, ""); + const port = this.proxy.port ? parseInt(this.proxy.port, 10) : this.proxy.protocol === "https:" ? 443 : 80; + this.connectOpts = { + ...opts ? omit(opts, "headers") : null, + host, + port + }; + } + addRequest(req, opts) { + req._header = null; + this.setRequestProps(req, opts); + super.addRequest(req, opts); + } + setRequestProps(req, opts) { + const { proxy } = this; + const protocol = opts.secureEndpoint ? "https:" : "http:"; + const hostname = req.getHeader("host") || "localhost"; + const base = `${protocol}//${hostname}`; + const url = new url_1.URL(req.path, base); + if (opts.port !== 80) { + url.port = String(opts.port); + } + req.path = String(url); + const headers = typeof this.proxyHeaders === "function" ? this.proxyHeaders() : { ...this.proxyHeaders }; + if (proxy.username || proxy.password) { + const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; + headers["Proxy-Authorization"] = `Basic ${Buffer.from(auth).toString("base64")}`; + } + if (!headers["Proxy-Connection"]) { + headers["Proxy-Connection"] = this.keepAlive ? "Keep-Alive" : "close"; + } + for (const name of Object.keys(headers)) { + const value = headers[name]; + if (value) { + req.setHeader(name, value); + } + } + } + async connect(req, opts) { + req._header = null; + if (!req.path.includes("://")) { + this.setRequestProps(req, opts); + } + let first; + let endOfHeaders; + debug("Regenerating stored HTTP header string for request"); + req._implicitHeader(); + if (req.outputData && req.outputData.length > 0) { + debug("Patching connection write() output buffer with updated header"); + first = req.outputData[0].data; + endOfHeaders = first.indexOf("\r\n\r\n") + 4; + req.outputData[0].data = req._header + first.substring(endOfHeaders); + debug("Output buffer: %o", req.outputData[0].data); + } + let socket; + if (this.proxy.protocol === "https:") { + debug("Creating `tls.Socket`: %o", this.connectOpts); + socket = tls.connect(this.connectOpts); + } else { + debug("Creating `net.Socket`: %o", this.connectOpts); + socket = net.connect(this.connectOpts); + } + await (0, events_1.once)(socket, "connect"); + return socket; + } + }; + HttpProxyAgent.protocols = ["http", "https"]; + exports2.HttpProxyAgent = HttpProxyAgent; + function omit(obj, ...keys) { + const ret = {}; + let key; + for (key in obj) { + if (!keys.includes(key)) { + ret[key] = obj[key]; + } + } + return ret; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/proxyPolicy.js +var require_proxyPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/proxyPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var proxyPolicy_exports = {}; + __export2(proxyPolicy_exports, { + getDefaultProxySettings: () => getDefaultProxySettings2, + globalNoProxyList: () => globalNoProxyList, + loadNoProxy: () => loadNoProxy, + proxyPolicy: () => proxyPolicy2, + proxyPolicyName: () => proxyPolicyName2 + }); + module2.exports = __toCommonJS2(proxyPolicy_exports); + var import_https_proxy_agent = require_dist2(); + var import_http_proxy_agent = require_dist3(); + var import_log = require_log2(); + var HTTPS_PROXY = "HTTPS_PROXY"; + var HTTP_PROXY = "HTTP_PROXY"; + var ALL_PROXY = "ALL_PROXY"; + var NO_PROXY = "NO_PROXY"; + var proxyPolicyName2 = "proxyPolicy"; + var globalNoProxyList = []; + var noProxyListLoaded = false; + var globalBypassedMap = /* @__PURE__ */ new Map(); + function getEnvironmentValue(name) { + if (process.env[name]) { + return process.env[name]; + } else if (process.env[name.toLowerCase()]) { + return process.env[name.toLowerCase()]; + } + return void 0; + } + function loadEnvironmentProxyValue() { + if (!process) { + return void 0; + } + const httpsProxy = getEnvironmentValue(HTTPS_PROXY); + const allProxy = getEnvironmentValue(ALL_PROXY); + const httpProxy = getEnvironmentValue(HTTP_PROXY); + return httpsProxy || allProxy || httpProxy; + } + function isBypassed(uri, noProxyList, bypassedMap) { + if (noProxyList.length === 0) { + return false; + } + const host = new URL(uri).hostname; + if (bypassedMap?.has(host)) { + return bypassedMap.get(host); + } + let isBypassedFlag = false; + for (const pattern of noProxyList) { + if (pattern[0] === ".") { + if (host.endsWith(pattern)) { + isBypassedFlag = true; + } else { + if (host.length === pattern.length - 1 && host === pattern.slice(1)) { + isBypassedFlag = true; + } + } + } else { + if (host === pattern) { + isBypassedFlag = true; + } + } + } + bypassedMap?.set(host, isBypassedFlag); + return isBypassedFlag; + } + function loadNoProxy() { + const noProxy = getEnvironmentValue(NO_PROXY); + noProxyListLoaded = true; + if (noProxy) { + return noProxy.split(",").map((item) => item.trim()).filter((item) => item.length); + } + return []; + } + function getDefaultProxySettings2(proxyUrl) { + if (!proxyUrl) { + proxyUrl = loadEnvironmentProxyValue(); + if (!proxyUrl) { + return void 0; + } + } + const parsedUrl = new URL(proxyUrl); + const schema = parsedUrl.protocol ? parsedUrl.protocol + "//" : ""; + return { + host: schema + parsedUrl.hostname, + port: Number.parseInt(parsedUrl.port || "80"), + username: parsedUrl.username, + password: parsedUrl.password + }; + } + function getDefaultProxySettingsInternal() { + const envProxy = loadEnvironmentProxyValue(); + return envProxy ? new URL(envProxy) : void 0; + } + function getUrlFromProxySettings(settings) { + let parsedProxyUrl; + try { + parsedProxyUrl = new URL(settings.host); + } catch { + throw new Error( + `Expecting a valid host string in proxy settings, but found "${settings.host}".` + ); + } + parsedProxyUrl.port = String(settings.port); + if (settings.username) { + parsedProxyUrl.username = settings.username; + } + if (settings.password) { + parsedProxyUrl.password = settings.password; + } + return parsedProxyUrl; + } + function setProxyAgentOnRequest(request, cachedAgents, proxyUrl) { + if (request.agent) { + return; + } + const url = new URL(request.url); + const isInsecure = url.protocol !== "https:"; + if (request.tlsSettings) { + import_log.logger.warning( + "TLS settings are not supported in combination with custom Proxy, certificates provided to the client will be ignored." + ); + } + if (isInsecure) { + if (!cachedAgents.httpProxyAgent) { + cachedAgents.httpProxyAgent = new import_http_proxy_agent.HttpProxyAgent(proxyUrl); + } + request.agent = cachedAgents.httpProxyAgent; + } else { + if (!cachedAgents.httpsProxyAgent) { + cachedAgents.httpsProxyAgent = new import_https_proxy_agent.HttpsProxyAgent(proxyUrl); + } + request.agent = cachedAgents.httpsProxyAgent; + } + } + function proxyPolicy2(proxySettings, options) { + if (!noProxyListLoaded) { + globalNoProxyList.push(...loadNoProxy()); + } + const defaultProxy = proxySettings ? getUrlFromProxySettings(proxySettings) : getDefaultProxySettingsInternal(); + const cachedAgents = {}; + return { + name: proxyPolicyName2, + async sendRequest(request, next) { + if (!request.proxySettings && defaultProxy && !isBypassed( + request.url, + options?.customNoProxyList ?? globalNoProxyList, + options?.customNoProxyList ? void 0 : globalBypassedMap + )) { + setProxyAgentOnRequest(request, cachedAgents, defaultProxy); + } else if (request.proxySettings) { + setProxyAgentOnRequest( + request, + cachedAgents, + getUrlFromProxySettings(request.proxySettings) + ); + } + return next(request); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/agentPolicy.js +var require_agentPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/agentPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var agentPolicy_exports = {}; + __export2(agentPolicy_exports, { + agentPolicy: () => agentPolicy2, + agentPolicyName: () => agentPolicyName2 + }); + module2.exports = __toCommonJS2(agentPolicy_exports); + var agentPolicyName2 = "agentPolicy"; + function agentPolicy2(agent) { + return { + name: agentPolicyName2, + sendRequest: async (req, next) => { + if (!req.agent) { + req.agent = agent; + } + return next(req); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/tlsPolicy.js +var require_tlsPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/tlsPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var tlsPolicy_exports = {}; + __export2(tlsPolicy_exports, { + tlsPolicy: () => tlsPolicy2, + tlsPolicyName: () => tlsPolicyName2 + }); + module2.exports = __toCommonJS2(tlsPolicy_exports); + var tlsPolicyName2 = "tlsPolicy"; + function tlsPolicy2(tlsSettings) { + return { + name: tlsPolicyName2, + sendRequest: async (req, next) => { + if (!req.tlsSettings) { + req.tlsSettings = tlsSettings; + } + return next(req); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/typeGuards.js +var require_typeGuards = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/typeGuards.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var typeGuards_exports = {}; + __export2(typeGuards_exports, { + isBinaryBody: () => isBinaryBody, + isBlob: () => isBlob, + isNodeReadableStream: () => isNodeReadableStream, + isReadableStream: () => isReadableStream, + isWebReadableStream: () => isWebReadableStream + }); + module2.exports = __toCommonJS2(typeGuards_exports); + function isNodeReadableStream(x) { + return Boolean(x && typeof x["pipe"] === "function"); + } + function isWebReadableStream(x) { + return Boolean( + x && typeof x.getReader === "function" && typeof x.tee === "function" + ); + } + function isBinaryBody(body) { + return body !== void 0 && (body instanceof Uint8Array || isReadableStream(body) || typeof body === "function" || typeof Blob !== "undefined" && body instanceof Blob); + } + function isReadableStream(x) { + return isNodeReadableStream(x) || isWebReadableStream(x); + } + function isBlob(x) { + return typeof Blob !== "undefined" && x instanceof Blob; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/concat.js +var require_concat = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/concat.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var concat_exports = {}; + __export2(concat_exports, { + concat: () => concat + }); + module2.exports = __toCommonJS2(concat_exports); + var import_stream = require("stream"); + var import_typeGuards = require_typeGuards(); + async function* streamAsyncIterator() { + const reader = this.getReader(); + try { + while (true) { + const { done, value } = await reader.read(); + if (done) { + return; + } + yield value; + } + } finally { + reader.releaseLock(); + } + } + function makeAsyncIterable(webStream) { + if (!webStream[Symbol.asyncIterator]) { + webStream[Symbol.asyncIterator] = streamAsyncIterator.bind(webStream); + } + if (!webStream.values) { + webStream.values = streamAsyncIterator.bind(webStream); + } + } + function ensureNodeStream(stream) { + if (stream instanceof ReadableStream) { + makeAsyncIterable(stream); + return import_stream.Readable.fromWeb(stream); + } else { + return stream; + } + } + function toStream(source) { + if (source instanceof Uint8Array) { + return import_stream.Readable.from(Buffer.from(source)); + } else if ((0, import_typeGuards.isBlob)(source)) { + return ensureNodeStream(source.stream()); + } else { + return ensureNodeStream(source); + } + } + async function concat(sources) { + return function() { + const streams = sources.map((x) => typeof x === "function" ? x() : x).map(toStream); + return import_stream.Readable.from( + (async function* () { + for (const stream of streams) { + for await (const chunk of stream) { + yield chunk; + } + } + })() + ); + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/multipartPolicy.js +var require_multipartPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/multipartPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var multipartPolicy_exports = {}; + __export2(multipartPolicy_exports, { + multipartPolicy: () => multipartPolicy2, + multipartPolicyName: () => multipartPolicyName2 + }); + module2.exports = __toCommonJS2(multipartPolicy_exports); + var import_bytesEncoding = require_bytesEncoding(); + var import_typeGuards = require_typeGuards(); + var import_uuidUtils = require_uuidUtils(); + var import_concat = require_concat(); + function generateBoundary() { + return `----AzSDKFormBoundary${(0, import_uuidUtils.randomUUID)()}`; + } + function encodeHeaders(headers) { + let result = ""; + for (const [key, value] of headers) { + result += `${key}: ${value}\r +`; + } + return result; + } + function getLength(source) { + if (source instanceof Uint8Array) { + return source.byteLength; + } else if ((0, import_typeGuards.isBlob)(source)) { + return source.size === -1 ? void 0 : source.size; + } else { + return void 0; + } + } + function getTotalLength(sources) { + let total = 0; + for (const source of sources) { + const partLength = getLength(source); + if (partLength === void 0) { + return void 0; + } else { + total += partLength; + } + } + return total; + } + async function buildRequestBody(request, parts, boundary) { + const sources = [ + (0, import_bytesEncoding.stringToUint8Array)(`--${boundary}`, "utf-8"), + ...parts.flatMap((part) => [ + (0, import_bytesEncoding.stringToUint8Array)("\r\n", "utf-8"), + (0, import_bytesEncoding.stringToUint8Array)(encodeHeaders(part.headers), "utf-8"), + (0, import_bytesEncoding.stringToUint8Array)("\r\n", "utf-8"), + part.body, + (0, import_bytesEncoding.stringToUint8Array)(`\r +--${boundary}`, "utf-8") + ]), + (0, import_bytesEncoding.stringToUint8Array)("--\r\n\r\n", "utf-8") + ]; + const contentLength = getTotalLength(sources); + if (contentLength) { + request.headers.set("Content-Length", contentLength); + } + request.body = await (0, import_concat.concat)(sources); + } + var multipartPolicyName2 = "multipartPolicy"; + var maxBoundaryLength = 70; + var validBoundaryCharacters = new Set( + `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'()+,-./:=?` + ); + function assertValidBoundary(boundary) { + if (boundary.length > maxBoundaryLength) { + throw new Error(`Multipart boundary "${boundary}" exceeds maximum length of 70 characters`); + } + if (Array.from(boundary).some((x) => !validBoundaryCharacters.has(x))) { + throw new Error(`Multipart boundary "${boundary}" contains invalid characters`); + } + } + function multipartPolicy2() { + return { + name: multipartPolicyName2, + async sendRequest(request, next) { + if (!request.multipartBody) { + return next(request); + } + if (request.body) { + throw new Error("multipartBody and regular body cannot be set at the same time"); + } + let boundary = request.multipartBody.boundary; + const contentTypeHeader = request.headers.get("Content-Type") ?? "multipart/mixed"; + const parsedHeader = contentTypeHeader.match(/^(multipart\/[^ ;]+)(?:; *boundary=(.+))?$/); + if (!parsedHeader) { + throw new Error( + `Got multipart request body, but content-type header was not multipart: ${contentTypeHeader}` + ); + } + const [, contentType, parsedBoundary] = parsedHeader; + if (parsedBoundary && boundary && parsedBoundary !== boundary) { + throw new Error( + `Multipart boundary was specified as ${parsedBoundary} in the header, but got ${boundary} in the request body` + ); + } + boundary ??= parsedBoundary; + if (boundary) { + assertValidBoundary(boundary); + } else { + boundary = generateBoundary(); + } + request.headers.set("Content-Type", `${contentType}; boundary=${boundary}`); + await buildRequestBody(request, request.multipartBody.parts, boundary); + request.multipartBody = void 0; + return next(request); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/createPipelineFromOptions.js +var require_createPipelineFromOptions = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/createPipelineFromOptions.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var createPipelineFromOptions_exports = {}; + __export2(createPipelineFromOptions_exports, { + createPipelineFromOptions: () => createPipelineFromOptions2 + }); + module2.exports = __toCommonJS2(createPipelineFromOptions_exports); + var import_logPolicy = require_logPolicy(); + var import_pipeline = require_pipeline(); + var import_redirectPolicy = require_redirectPolicy(); + var import_userAgentPolicy = require_userAgentPolicy(); + var import_decompressResponsePolicy = require_decompressResponsePolicy(); + var import_defaultRetryPolicy = require_defaultRetryPolicy(); + var import_formDataPolicy = require_formDataPolicy(); + var import_checkEnvironment = require_checkEnvironment(); + var import_proxyPolicy = require_proxyPolicy(); + var import_agentPolicy = require_agentPolicy(); + var import_tlsPolicy = require_tlsPolicy(); + var import_multipartPolicy = require_multipartPolicy(); + function createPipelineFromOptions2(options) { + const pipeline = (0, import_pipeline.createEmptyPipeline)(); + if (import_checkEnvironment.isNodeLike) { + if (options.agent) { + pipeline.addPolicy((0, import_agentPolicy.agentPolicy)(options.agent)); + } + if (options.tlsOptions) { + pipeline.addPolicy((0, import_tlsPolicy.tlsPolicy)(options.tlsOptions)); + } + pipeline.addPolicy((0, import_proxyPolicy.proxyPolicy)(options.proxyOptions)); + pipeline.addPolicy((0, import_decompressResponsePolicy.decompressResponsePolicy)()); + } + pipeline.addPolicy((0, import_formDataPolicy.formDataPolicy)(), { beforePolicies: [import_multipartPolicy.multipartPolicyName] }); + pipeline.addPolicy((0, import_userAgentPolicy.userAgentPolicy)(options.userAgentOptions)); + pipeline.addPolicy((0, import_multipartPolicy.multipartPolicy)(), { afterPhase: "Deserialize" }); + pipeline.addPolicy((0, import_defaultRetryPolicy.defaultRetryPolicy)(options.retryOptions), { phase: "Retry" }); + if (import_checkEnvironment.isNodeLike) { + pipeline.addPolicy((0, import_redirectPolicy.redirectPolicy)(options.redirectOptions), { afterPhase: "Retry" }); + } + pipeline.addPolicy((0, import_logPolicy.logPolicy)(options.loggingOptions), { afterPhase: "Sign" }); + return pipeline; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/client/apiVersionPolicy.js +var require_apiVersionPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/client/apiVersionPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var apiVersionPolicy_exports = {}; + __export2(apiVersionPolicy_exports, { + apiVersionPolicy: () => apiVersionPolicy, + apiVersionPolicyName: () => apiVersionPolicyName + }); + module2.exports = __toCommonJS2(apiVersionPolicy_exports); + var apiVersionPolicyName = "ApiVersionPolicy"; + function apiVersionPolicy(options) { + return { + name: apiVersionPolicyName, + sendRequest: (req, next) => { + const url = new URL(req.url); + if (!url.searchParams.get("api-version") && options.apiVersion) { + req.url = `${req.url}${Array.from(url.searchParams.keys()).length > 0 ? "&" : "?"}api-version=${options.apiVersion}`; + } + return next(req); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/auth/credentials.js +var require_credentials = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/auth/credentials.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var credentials_exports = {}; + __export2(credentials_exports, { + isApiKeyCredential: () => isApiKeyCredential, + isBasicCredential: () => isBasicCredential, + isBearerTokenCredential: () => isBearerTokenCredential, + isOAuth2TokenCredential: () => isOAuth2TokenCredential + }); + module2.exports = __toCommonJS2(credentials_exports); + function isOAuth2TokenCredential(credential) { + return "getOAuth2Token" in credential; + } + function isBearerTokenCredential(credential) { + return "getBearerToken" in credential; + } + function isBasicCredential(credential) { + return "username" in credential && "password" in credential; + } + function isApiKeyCredential(credential) { + return "key" in credential; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/checkInsecureConnection.js +var require_checkInsecureConnection = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/checkInsecureConnection.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var checkInsecureConnection_exports = {}; + __export2(checkInsecureConnection_exports, { + ensureSecureConnection: () => ensureSecureConnection + }); + module2.exports = __toCommonJS2(checkInsecureConnection_exports); + var import_log = require_log2(); + var insecureConnectionWarningEmmitted = false; + function allowInsecureConnection(request, options) { + if (options.allowInsecureConnection && request.allowInsecureConnection) { + const url = new URL(request.url); + if (url.hostname === "localhost" || url.hostname === "127.0.0.1") { + return true; + } + } + return false; + } + function emitInsecureConnectionWarning() { + const warning = "Sending token over insecure transport. Assume any token issued is compromised."; + import_log.logger.warning(warning); + if (typeof process?.emitWarning === "function" && !insecureConnectionWarningEmmitted) { + insecureConnectionWarningEmmitted = true; + process.emitWarning(warning); + } + } + function ensureSecureConnection(request, options) { + if (!request.url.toLowerCase().startsWith("https://")) { + if (allowInsecureConnection(request, options)) { + emitInsecureConnectionWarning(); + } else { + throw new Error( + "Authentication is not permitted for non-TLS protected (non-https) URLs when allowInsecureConnection is false." + ); + } + } + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/apiKeyAuthenticationPolicy.js +var require_apiKeyAuthenticationPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/apiKeyAuthenticationPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var apiKeyAuthenticationPolicy_exports = {}; + __export2(apiKeyAuthenticationPolicy_exports, { + apiKeyAuthenticationPolicy: () => apiKeyAuthenticationPolicy, + apiKeyAuthenticationPolicyName: () => apiKeyAuthenticationPolicyName + }); + module2.exports = __toCommonJS2(apiKeyAuthenticationPolicy_exports); + var import_checkInsecureConnection = require_checkInsecureConnection(); + var apiKeyAuthenticationPolicyName = "apiKeyAuthenticationPolicy"; + function apiKeyAuthenticationPolicy(options) { + return { + name: apiKeyAuthenticationPolicyName, + async sendRequest(request, next) { + (0, import_checkInsecureConnection.ensureSecureConnection)(request, options); + const scheme = (request.authSchemes ?? options.authSchemes)?.find((x) => x.kind === "apiKey"); + if (!scheme) { + return next(request); + } + if (scheme.apiKeyLocation !== "header") { + throw new Error(`Unsupported API key location: ${scheme.apiKeyLocation}`); + } + request.headers.set(scheme.name, options.credential.key); + return next(request); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/basicAuthenticationPolicy.js +var require_basicAuthenticationPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/basicAuthenticationPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var basicAuthenticationPolicy_exports = {}; + __export2(basicAuthenticationPolicy_exports, { + basicAuthenticationPolicy: () => basicAuthenticationPolicy, + basicAuthenticationPolicyName: () => basicAuthenticationPolicyName + }); + module2.exports = __toCommonJS2(basicAuthenticationPolicy_exports); + var import_bytesEncoding = require_bytesEncoding(); + var import_checkInsecureConnection = require_checkInsecureConnection(); + var basicAuthenticationPolicyName = "bearerAuthenticationPolicy"; + function basicAuthenticationPolicy(options) { + return { + name: basicAuthenticationPolicyName, + async sendRequest(request, next) { + (0, import_checkInsecureConnection.ensureSecureConnection)(request, options); + const scheme = (request.authSchemes ?? options.authSchemes)?.find( + (x) => x.kind === "http" && x.scheme === "basic" + ); + if (!scheme) { + return next(request); + } + const { username, password } = options.credential; + const headerValue = (0, import_bytesEncoding.uint8ArrayToString)( + (0, import_bytesEncoding.stringToUint8Array)(`${username}:${password}`, "utf-8"), + "base64" + ); + request.headers.set("Authorization", `Basic ${headerValue}`); + return next(request); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/bearerAuthenticationPolicy.js +var require_bearerAuthenticationPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/bearerAuthenticationPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var bearerAuthenticationPolicy_exports = {}; + __export2(bearerAuthenticationPolicy_exports, { + bearerAuthenticationPolicy: () => bearerAuthenticationPolicy, + bearerAuthenticationPolicyName: () => bearerAuthenticationPolicyName + }); + module2.exports = __toCommonJS2(bearerAuthenticationPolicy_exports); + var import_checkInsecureConnection = require_checkInsecureConnection(); + var bearerAuthenticationPolicyName = "bearerAuthenticationPolicy"; + function bearerAuthenticationPolicy(options) { + return { + name: bearerAuthenticationPolicyName, + async sendRequest(request, next) { + (0, import_checkInsecureConnection.ensureSecureConnection)(request, options); + const scheme = (request.authSchemes ?? options.authSchemes)?.find( + (x) => x.kind === "http" && x.scheme === "bearer" + ); + if (!scheme) { + return next(request); + } + const token = await options.credential.getBearerToken({ + abortSignal: request.abortSignal + }); + request.headers.set("Authorization", `Bearer ${token}`); + return next(request); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/oauth2AuthenticationPolicy.js +var require_oauth2AuthenticationPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/auth/oauth2AuthenticationPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var oauth2AuthenticationPolicy_exports = {}; + __export2(oauth2AuthenticationPolicy_exports, { + oauth2AuthenticationPolicy: () => oauth2AuthenticationPolicy, + oauth2AuthenticationPolicyName: () => oauth2AuthenticationPolicyName + }); + module2.exports = __toCommonJS2(oauth2AuthenticationPolicy_exports); + var import_checkInsecureConnection = require_checkInsecureConnection(); + var oauth2AuthenticationPolicyName = "oauth2AuthenticationPolicy"; + function oauth2AuthenticationPolicy(options) { + return { + name: oauth2AuthenticationPolicyName, + async sendRequest(request, next) { + (0, import_checkInsecureConnection.ensureSecureConnection)(request, options); + const scheme = (request.authSchemes ?? options.authSchemes)?.find((x) => x.kind === "oauth2"); + if (!scheme) { + return next(request); + } + const token = await options.credential.getOAuth2Token(scheme.flows, { + abortSignal: request.abortSignal + }); + request.headers.set("Authorization", `Bearer ${token}`); + return next(request); + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/client/clientHelpers.js +var require_clientHelpers = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/client/clientHelpers.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var clientHelpers_exports = {}; + __export2(clientHelpers_exports, { + createDefaultPipeline: () => createDefaultPipeline, + getCachedDefaultHttpsClient: () => getCachedDefaultHttpsClient + }); + module2.exports = __toCommonJS2(clientHelpers_exports); + var import_defaultHttpClient = require_defaultHttpClient(); + var import_createPipelineFromOptions = require_createPipelineFromOptions(); + var import_apiVersionPolicy = require_apiVersionPolicy(); + var import_credentials = require_credentials(); + var import_apiKeyAuthenticationPolicy = require_apiKeyAuthenticationPolicy(); + var import_basicAuthenticationPolicy = require_basicAuthenticationPolicy(); + var import_bearerAuthenticationPolicy = require_bearerAuthenticationPolicy(); + var import_oauth2AuthenticationPolicy = require_oauth2AuthenticationPolicy(); + var cachedHttpClient; + function createDefaultPipeline(options = {}) { + const pipeline = (0, import_createPipelineFromOptions.createPipelineFromOptions)(options); + pipeline.addPolicy((0, import_apiVersionPolicy.apiVersionPolicy)(options)); + const { credential, authSchemes, allowInsecureConnection } = options; + if (credential) { + if ((0, import_credentials.isApiKeyCredential)(credential)) { + pipeline.addPolicy( + (0, import_apiKeyAuthenticationPolicy.apiKeyAuthenticationPolicy)({ authSchemes, credential, allowInsecureConnection }) + ); + } else if ((0, import_credentials.isBasicCredential)(credential)) { + pipeline.addPolicy( + (0, import_basicAuthenticationPolicy.basicAuthenticationPolicy)({ authSchemes, credential, allowInsecureConnection }) + ); + } else if ((0, import_credentials.isBearerTokenCredential)(credential)) { + pipeline.addPolicy( + (0, import_bearerAuthenticationPolicy.bearerAuthenticationPolicy)({ authSchemes, credential, allowInsecureConnection }) + ); + } else if ((0, import_credentials.isOAuth2TokenCredential)(credential)) { + pipeline.addPolicy( + (0, import_oauth2AuthenticationPolicy.oauth2AuthenticationPolicy)({ authSchemes, credential, allowInsecureConnection }) + ); + } + } + return pipeline; + } + function getCachedDefaultHttpsClient() { + if (!cachedHttpClient) { + cachedHttpClient = (0, import_defaultHttpClient.createDefaultHttpClient)(); + } + return cachedHttpClient; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/client/multipart.js +var require_multipart = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/client/multipart.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var multipart_exports = {}; + __export2(multipart_exports, { + buildBodyPart: () => buildBodyPart, + buildMultipartBody: () => buildMultipartBody + }); + module2.exports = __toCommonJS2(multipart_exports); + var import_restError = require_restError(); + var import_httpHeaders = require_httpHeaders(); + var import_bytesEncoding = require_bytesEncoding(); + var import_typeGuards = require_typeGuards(); + function getHeaderValue(descriptor, headerName) { + if (descriptor.headers) { + const actualHeaderName = Object.keys(descriptor.headers).find( + (x) => x.toLowerCase() === headerName.toLowerCase() + ); + if (actualHeaderName) { + return descriptor.headers[actualHeaderName]; + } + } + return void 0; + } + function getPartContentType(descriptor) { + const contentTypeHeader = getHeaderValue(descriptor, "content-type"); + if (contentTypeHeader) { + return contentTypeHeader; + } + if (descriptor.contentType === null) { + return void 0; + } + if (descriptor.contentType) { + return descriptor.contentType; + } + const { body } = descriptor; + if (body === null || body === void 0) { + return void 0; + } + if (typeof body === "string" || typeof body === "number" || typeof body === "boolean") { + return "text/plain; charset=UTF-8"; + } + if (body instanceof Blob) { + return body.type || "application/octet-stream"; + } + if ((0, import_typeGuards.isBinaryBody)(body)) { + return "application/octet-stream"; + } + return "application/json"; + } + function escapeDispositionField(value) { + return JSON.stringify(value); + } + function getContentDisposition(descriptor) { + const contentDispositionHeader = getHeaderValue(descriptor, "content-disposition"); + if (contentDispositionHeader) { + return contentDispositionHeader; + } + if (descriptor.dispositionType === void 0 && descriptor.name === void 0 && descriptor.filename === void 0) { + return void 0; + } + const dispositionType = descriptor.dispositionType ?? "form-data"; + let disposition = dispositionType; + if (descriptor.name) { + disposition += `; name=${escapeDispositionField(descriptor.name)}`; + } + let filename = void 0; + if (descriptor.filename) { + filename = descriptor.filename; + } else if (typeof File !== "undefined" && descriptor.body instanceof File) { + const filenameFromFile = descriptor.body.name; + if (filenameFromFile !== "") { + filename = filenameFromFile; + } + } + if (filename) { + disposition += `; filename=${escapeDispositionField(filename)}`; + } + return disposition; + } + function normalizeBody(body, contentType) { + if (body === void 0) { + return new Uint8Array([]); + } + if ((0, import_typeGuards.isBinaryBody)(body)) { + return body; + } + if (typeof body === "string" || typeof body === "number" || typeof body === "boolean") { + return (0, import_bytesEncoding.stringToUint8Array)(String(body), "utf-8"); + } + if (contentType && /application\/(.+\+)?json(;.+)?/i.test(String(contentType))) { + return (0, import_bytesEncoding.stringToUint8Array)(JSON.stringify(body), "utf-8"); + } + throw new import_restError.RestError(`Unsupported body/content-type combination: ${body}, ${contentType}`); + } + function buildBodyPart(descriptor) { + const contentType = getPartContentType(descriptor); + const contentDisposition = getContentDisposition(descriptor); + const headers = (0, import_httpHeaders.createHttpHeaders)(descriptor.headers ?? {}); + if (contentType) { + headers.set("content-type", contentType); + } + if (contentDisposition) { + headers.set("content-disposition", contentDisposition); + } + const body = normalizeBody(descriptor.body, contentType); + return { + headers, + body + }; + } + function buildMultipartBody(parts) { + return { parts: parts.map(buildBodyPart) }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/client/sendRequest.js +var require_sendRequest = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/client/sendRequest.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var sendRequest_exports = {}; + __export2(sendRequest_exports, { + getRequestBody: () => getRequestBody, + sendRequest: () => sendRequest + }); + module2.exports = __toCommonJS2(sendRequest_exports); + var import_restError = require_restError(); + var import_httpHeaders = require_httpHeaders(); + var import_pipelineRequest = require_pipelineRequest(); + var import_clientHelpers = require_clientHelpers(); + var import_typeGuards = require_typeGuards(); + var import_multipart = require_multipart(); + async function sendRequest(method, url, pipeline, options = {}, customHttpClient) { + const httpClient = customHttpClient ?? (0, import_clientHelpers.getCachedDefaultHttpsClient)(); + const request = buildPipelineRequest(method, url, options); + try { + const response = await pipeline.sendRequest(httpClient, request); + const headers = response.headers.toJSON(); + const stream = response.readableStreamBody ?? response.browserStreamBody; + const parsedBody = options.responseAsStream || stream !== void 0 ? void 0 : getResponseBody(response); + const body = stream ?? parsedBody; + if (options?.onResponse) { + options.onResponse({ ...response, request, rawHeaders: headers, parsedBody }); + } + return { + request, + headers, + status: `${response.status}`, + body + }; + } catch (e) { + if ((0, import_restError.isRestError)(e) && e.response && options.onResponse) { + const { response } = e; + const rawHeaders = response.headers.toJSON(); + options?.onResponse({ ...response, request, rawHeaders }, e); + } + throw e; + } + } + function getRequestContentType(options = {}) { + if (options.contentType) { + return options.contentType; + } + const headerContentType = options.headers?.["content-type"]; + if (typeof headerContentType === "string") { + return headerContentType; + } + return getContentType(options.body); + } + function getContentType(body) { + if (body === void 0) { + return void 0; + } + if (ArrayBuffer.isView(body)) { + return "application/octet-stream"; + } + if ((0, import_typeGuards.isBlob)(body) && body.type) { + return body.type; + } + if (typeof body === "string") { + try { + JSON.parse(body); + return "application/json"; + } catch (error) { + return void 0; + } + } + return "application/json"; + } + function buildPipelineRequest(method, url, options = {}) { + const requestContentType = getRequestContentType(options); + const { body, multipartBody } = getRequestBody(options.body, requestContentType); + const headers = (0, import_httpHeaders.createHttpHeaders)({ + ...options.headers ? options.headers : {}, + accept: options.accept ?? options.headers?.accept ?? "application/json", + ...requestContentType && { + "content-type": requestContentType + } + }); + return (0, import_pipelineRequest.createPipelineRequest)({ + url, + method, + body, + multipartBody, + headers, + allowInsecureConnection: options.allowInsecureConnection, + abortSignal: options.abortSignal, + onUploadProgress: options.onUploadProgress, + onDownloadProgress: options.onDownloadProgress, + timeout: options.timeout, + enableBrowserStreams: true, + streamResponseStatusCodes: options.responseAsStream ? /* @__PURE__ */ new Set([Number.POSITIVE_INFINITY]) : void 0 + }); + } + function getRequestBody(body, contentType = "") { + if (body === void 0) { + return { body: void 0 }; + } + if (typeof FormData !== "undefined" && body instanceof FormData) { + return { body }; + } + if ((0, import_typeGuards.isBlob)(body)) { + return { body }; + } + if ((0, import_typeGuards.isReadableStream)(body)) { + return { body }; + } + if (typeof body === "function") { + return { body }; + } + if (ArrayBuffer.isView(body)) { + return { body: body instanceof Uint8Array ? body : JSON.stringify(body) }; + } + const firstType = contentType.split(";")[0]; + switch (firstType) { + case "application/json": + return { body: JSON.stringify(body) }; + case "multipart/form-data": + if (Array.isArray(body)) { + return { multipartBody: (0, import_multipart.buildMultipartBody)(body) }; + } + return { body: JSON.stringify(body) }; + case "text/plain": + return { body: String(body) }; + default: + if (typeof body === "string") { + return { body }; + } + return { body: JSON.stringify(body) }; + } + } + function getResponseBody(response) { + const contentType = response.headers.get("content-type") ?? ""; + const firstType = contentType.split(";")[0]; + const bodyToParse = response.bodyAsText ?? ""; + if (firstType === "text/plain") { + return String(bodyToParse); + } + try { + return bodyToParse ? JSON.parse(bodyToParse) : void 0; + } catch (error) { + if (firstType === "application/json") { + throw createParseError(response, error); + } + return String(bodyToParse); + } + } + function createParseError(response, err) { + const msg = `Error "${err}" occurred while parsing the response body - ${response.bodyAsText}.`; + const errCode = err.code ?? import_restError.RestError.PARSE_ERROR; + return new import_restError.RestError(msg, { + code: errCode, + statusCode: response.status, + request: response.request, + response + }); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/client/urlHelpers.js +var require_urlHelpers = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/client/urlHelpers.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var urlHelpers_exports = {}; + __export2(urlHelpers_exports, { + appendQueryParams: () => appendQueryParams, + buildBaseUrl: () => buildBaseUrl, + buildRequestUrl: () => buildRequestUrl, + replaceAll: () => replaceAll + }); + module2.exports = __toCommonJS2(urlHelpers_exports); + function isQueryParameterWithOptions(x) { + if (typeof x !== "object" || x === null || !Object.hasOwn(x, "value")) { + return false; + } + const value = x.value; + return typeof value?.toString === "function"; + } + function buildRequestUrl(endpoint, routePath, pathParameters, options = {}) { + if (routePath.startsWith("https://") || routePath.startsWith("http://")) { + return routePath; + } + endpoint = buildBaseUrl(endpoint, options); + const updatedRoutePath = buildRoutePath(routePath, pathParameters, options); + const requestUrl = appendQueryParams(appendPath(endpoint, updatedRoutePath), options); + const url = new URL(requestUrl); + return url.toString(); + } + function appendPath(endpoint, pathToAppend) { + const endpointSearchStart = endpoint.indexOf("?"); + const pathSearchStart = pathToAppend.indexOf("?"); + const endpointParts = endpointSearchStart !== -1 ? [endpoint.substring(0, endpointSearchStart), endpoint.substring(endpointSearchStart + 1)] : [endpoint, ""]; + const pathParts = pathSearchStart !== -1 ? [pathToAppend.substring(0, pathSearchStart), pathToAppend.substring(pathSearchStart + 1)] : [pathToAppend, ""]; + const combinedSearch = [endpointParts[1], pathParts[1].replaceAll("?", "&")].filter(Boolean).join("&"); + const baseEndpoint = endpointParts[0].replace(/(^[^:]+:\/\/[^/]+)\/\/+/, "$1/"); + const basePathToAppend = pathParts[0]; + let combinedUrl = baseEndpoint; + if (!baseEndpoint.endsWith("/") && !basePathToAppend.startsWith("/") && basePathToAppend !== "") { + combinedUrl += `/${basePathToAppend}`; + } else if (baseEndpoint.endsWith("/") && basePathToAppend.startsWith("/")) { + combinedUrl += basePathToAppend.substring(1); + } else { + combinedUrl += basePathToAppend; + } + if (combinedSearch) { + combinedUrl += `?${combinedSearch}`; + } + return combinedUrl; + } + function getQueryParamValue(key, allowReserved, style, param) { + let separator; + if (style === "pipeDelimited") { + separator = "|"; + } else if (style === "spaceDelimited") { + separator = "%20"; + } else { + separator = ","; + } + let paramValues; + if (Array.isArray(param)) { + paramValues = param; + } else if (typeof param === "object" && param.toString === Object.prototype.toString) { + paramValues = Object.entries(param).flat(); + } else { + paramValues = [param]; + } + const value = paramValues.map((p) => { + if (p === null || p === void 0) { + return ""; + } + if (!p.toString || typeof p.toString !== "function") { + throw new Error(`Query parameters must be able to be represented as string, ${key} can't`); + } + const rawValue = p.toISOString !== void 0 ? p.toISOString() : p.toString(); + return allowReserved ? rawValue : encodeURIComponent(rawValue); + }).join(separator); + return `${allowReserved ? key : encodeURIComponent(key)}=${value}`; + } + function simpleParseQueryParams(queryString) { + const result = /* @__PURE__ */ new Map(); + if (!queryString || queryString[0] !== "?") { + return result; + } + queryString = queryString.slice(1); + const pairs = queryString.split("&"); + for (const pair of pairs) { + const eqIndex = pair.indexOf("="); + const name = eqIndex === -1 ? pair : pair.substring(0, eqIndex); + const value = eqIndex === -1 ? "" : pair.substring(eqIndex + 1); + const existingValue = result.get(name); + if (existingValue !== void 0) { + if (Array.isArray(existingValue)) { + existingValue.push(value); + } else { + result.set(name, [existingValue, value]); + } + } else { + result.set(name, value); + } + } + return result; + } + function appendQueryParams(url, options = {}) { + if (!options.queryParameters) { + return url; + } + const parsedUrl = new URL(url); + const queryParams = options.queryParameters; + const existingParams = simpleParseQueryParams(parsedUrl.search); + const newParamStrings = []; + for (const key of Object.keys(queryParams)) { + const param = queryParams[key]; + if (param === void 0 || param === null) { + continue; + } + const hasMetadata = isQueryParameterWithOptions(param); + const rawValue = hasMetadata ? param.value : param; + const explode = hasMetadata ? param.explode ?? false : false; + const style = hasMetadata && param.style ? param.style : "form"; + if (explode) { + if (Array.isArray(rawValue)) { + for (const item of rawValue) { + newParamStrings.push( + getQueryParamValue(key, options.skipUrlEncoding ?? false, style, item) + ); + } + } else if (rawValue !== null && typeof rawValue === "object") { + for (const [actualKey, value] of Object.entries(rawValue)) { + newParamStrings.push( + getQueryParamValue(actualKey, options.skipUrlEncoding ?? false, style, value) + ); + } + } else { + throw new Error("explode can only be set to true for objects and arrays"); + } + } else { + newParamStrings.push( + getQueryParamValue(key, options.skipUrlEncoding ?? false, style, rawValue) + ); + } + } + for (const paramString of newParamStrings) { + const eqIndex = paramString.indexOf("="); + const name = paramString.substring(0, eqIndex); + const value = paramString.substring(eqIndex + 1); + const existingValue = existingParams.get(name); + if (existingValue !== void 0) { + if (Array.isArray(existingValue)) { + if (!existingValue.includes(value)) { + existingValue.push(value); + } + } else if (existingValue !== value) { + existingParams.set(name, [existingValue, value]); + } + } else { + existingParams.set(name, value); + } + } + const searchPieces = []; + for (const [name, value] of existingParams) { + if (Array.isArray(value)) { + for (const subValue of value) { + searchPieces.push(`${name}=${subValue}`); + } + } else { + searchPieces.push(`${name}=${value}`); + } + } + parsedUrl.search = searchPieces.length ? `?${searchPieces.join("&")}` : ""; + return parsedUrl.toString(); + } + function buildBaseUrl(endpoint, options) { + if (!options.pathParameters) { + return endpoint; + } + const pathParams = options.pathParameters; + for (const [key, param] of Object.entries(pathParams)) { + if (param === void 0 || param === null) { + throw new Error(`Path parameters ${key} must not be undefined or null`); + } + if (!param.toString || typeof param.toString !== "function") { + throw new Error(`Path parameters must be able to be represented as string, ${key} can't`); + } + let value = param.toISOString !== void 0 ? param.toISOString() : String(param); + if (!options.skipUrlEncoding) { + value = encodeURIComponent(param); + } + endpoint = replaceAll(endpoint, `{${key}}`, value) ?? ""; + } + return endpoint; + } + function buildRoutePath(routePath, pathParameters, options = {}) { + for (const pathParam of pathParameters) { + const allowReserved = typeof pathParam === "object" && (pathParam.allowReserved ?? false); + let value = typeof pathParam === "object" ? pathParam.value : pathParam; + if (!options.skipUrlEncoding && !allowReserved) { + value = encodeURIComponent(value); + } + routePath = routePath.replace(/\{[\w-]+\}/, String(value)); + } + return routePath; + } + function replaceAll(value, searchValue, replaceValue) { + return !value || !searchValue ? value : value.split(searchValue).join(replaceValue || ""); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/client/getClient.js +var require_getClient = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/client/getClient.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var getClient_exports = {}; + __export2(getClient_exports, { + getClient: () => getClient2 + }); + module2.exports = __toCommonJS2(getClient_exports); + var import_clientHelpers = require_clientHelpers(); + var import_sendRequest = require_sendRequest(); + var import_urlHelpers = require_urlHelpers(); + var import_checkEnvironment = require_checkEnvironment(); + function getClient2(endpoint, clientOptions = {}) { + const pipeline = clientOptions.pipeline ?? (0, import_clientHelpers.createDefaultPipeline)(clientOptions); + if (clientOptions.additionalPolicies?.length) { + for (const { policy, position } of clientOptions.additionalPolicies) { + const afterPhase = position === "perRetry" ? "Sign" : void 0; + pipeline.addPolicy(policy, { + afterPhase + }); + } + } + const { allowInsecureConnection, httpClient } = clientOptions; + const endpointUrl = clientOptions.endpoint ?? endpoint; + const client = (path3, ...args) => { + const getUrl = (requestOptions) => (0, import_urlHelpers.buildRequestUrl)(endpointUrl, path3, args, { allowInsecureConnection, ...requestOptions }); + return { + get: (requestOptions = {}) => { + return buildOperation( + "GET", + getUrl(requestOptions), + pipeline, + requestOptions, + allowInsecureConnection, + httpClient + ); + }, + post: (requestOptions = {}) => { + return buildOperation( + "POST", + getUrl(requestOptions), + pipeline, + requestOptions, + allowInsecureConnection, + httpClient + ); + }, + put: (requestOptions = {}) => { + return buildOperation( + "PUT", + getUrl(requestOptions), + pipeline, + requestOptions, + allowInsecureConnection, + httpClient + ); + }, + patch: (requestOptions = {}) => { + return buildOperation( + "PATCH", + getUrl(requestOptions), + pipeline, + requestOptions, + allowInsecureConnection, + httpClient + ); + }, + delete: (requestOptions = {}) => { + return buildOperation( + "DELETE", + getUrl(requestOptions), + pipeline, + requestOptions, + allowInsecureConnection, + httpClient + ); + }, + head: (requestOptions = {}) => { + return buildOperation( + "HEAD", + getUrl(requestOptions), + pipeline, + requestOptions, + allowInsecureConnection, + httpClient + ); + }, + options: (requestOptions = {}) => { + return buildOperation( + "OPTIONS", + getUrl(requestOptions), + pipeline, + requestOptions, + allowInsecureConnection, + httpClient + ); + }, + trace: (requestOptions = {}) => { + return buildOperation( + "TRACE", + getUrl(requestOptions), + pipeline, + requestOptions, + allowInsecureConnection, + httpClient + ); + } + }; + }; + return { + path: client, + pathUnchecked: client, + pipeline + }; + } + function buildOperation(method, url, pipeline, options, allowInsecureConnection, httpClient) { + allowInsecureConnection = options.allowInsecureConnection ?? allowInsecureConnection; + return { + then: function(onFulfilled, onrejected) { + return (0, import_sendRequest.sendRequest)( + method, + url, + pipeline, + { ...options, allowInsecureConnection }, + httpClient + ).then(onFulfilled, onrejected); + }, + async asBrowserStream() { + if (import_checkEnvironment.isNodeLike) { + throw new Error( + "`asBrowserStream` is supported only in the browser environment. Use `asNodeStream` instead to obtain the response body stream. If you require a Web stream of the response in Node, consider using `Readable.toWeb` on the result of `asNodeStream`." + ); + } else { + return (0, import_sendRequest.sendRequest)( + method, + url, + pipeline, + { ...options, allowInsecureConnection, responseAsStream: true }, + httpClient + ); + } + }, + async asNodeStream() { + if (import_checkEnvironment.isNodeLike) { + return (0, import_sendRequest.sendRequest)( + method, + url, + pipeline, + { ...options, allowInsecureConnection, responseAsStream: true }, + httpClient + ); + } else { + throw new Error( + "`isNodeStream` is not supported in the browser environment. Use `asBrowserStream` to obtain the response body stream." + ); + } + } + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/client/operationOptionHelpers.js +var require_operationOptionHelpers = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/client/operationOptionHelpers.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var operationOptionHelpers_exports = {}; + __export2(operationOptionHelpers_exports, { + operationOptionsToRequestParameters: () => operationOptionsToRequestParameters2 + }); + module2.exports = __toCommonJS2(operationOptionHelpers_exports); + function operationOptionsToRequestParameters2(options) { + return { + allowInsecureConnection: options.requestOptions?.allowInsecureConnection, + timeout: options.requestOptions?.timeout, + skipUrlEncoding: options.requestOptions?.skipUrlEncoding, + abortSignal: options.abortSignal, + onUploadProgress: options.requestOptions?.onUploadProgress, + onDownloadProgress: options.requestOptions?.onDownloadProgress, + headers: { ...options.requestOptions?.headers }, + onResponse: options.onResponse + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/client/restError.js +var require_restError2 = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/client/restError.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var restError_exports = {}; + __export2(restError_exports, { + createRestError: () => createRestError2 + }); + module2.exports = __toCommonJS2(restError_exports); + var import_restError = require_restError(); + var import_httpHeaders = require_httpHeaders(); + function createRestError2(messageOrResponse, response) { + const resp = typeof messageOrResponse === "string" ? response : messageOrResponse; + const internalError = resp.body?.error ?? resp.body; + const message = typeof messageOrResponse === "string" ? messageOrResponse : internalError?.message ?? `Unexpected status code: ${resp.status}`; + return new import_restError.RestError(message, { + statusCode: statusCodeToNumber(resp.status), + code: internalError?.code, + request: resp.request, + response: toPipelineResponse(resp) + }); + } + function toPipelineResponse(response) { + return { + headers: (0, import_httpHeaders.createHttpHeaders)(response.headers), + request: response.request, + status: statusCodeToNumber(response.status) ?? -1 + }; + } + function statusCodeToNumber(statusCode) { + const status = Number.parseInt(statusCode); + return Number.isNaN(status) ? void 0 : status; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/index.js +var require_commonjs = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/index.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var src_exports = {}; + __export2(src_exports, { + AbortError: () => import_AbortError.AbortError, + RestError: () => import_restError.RestError, + TypeSpecRuntimeLogger: () => import_logger.TypeSpecRuntimeLogger, + createClientLogger: () => import_logger.createClientLogger, + createDefaultHttpClient: () => import_defaultHttpClient.createDefaultHttpClient, + createEmptyPipeline: () => import_pipeline.createEmptyPipeline, + createHttpHeaders: () => import_httpHeaders.createHttpHeaders, + createPipelineRequest: () => import_pipelineRequest.createPipelineRequest, + createRestError: () => import_restError2.createRestError, + getClient: () => import_getClient.getClient, + getLogLevel: () => import_logger.getLogLevel, + isRestError: () => import_restError.isRestError, + operationOptionsToRequestParameters: () => import_operationOptionHelpers.operationOptionsToRequestParameters, + setLogLevel: () => import_logger.setLogLevel, + stringToUint8Array: () => import_bytesEncoding.stringToUint8Array, + uint8ArrayToString: () => import_bytesEncoding.uint8ArrayToString + }); + module2.exports = __toCommonJS2(src_exports); + var import_AbortError = require_AbortError(); + var import_logger = require_logger(); + var import_httpHeaders = require_httpHeaders(); + var import_pipelineRequest = require_pipelineRequest(); + var import_pipeline = require_pipeline(); + var import_restError = require_restError(); + var import_bytesEncoding = require_bytesEncoding(); + var import_defaultHttpClient = require_defaultHttpClient(); + var import_getClient = require_getClient(); + var import_operationOptionHelpers = require_operationOptionHelpers(); + var import_restError2 = require_restError2(); + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/pipeline.js +var require_pipeline2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/pipeline.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var pipeline_exports = {}; + __export2(pipeline_exports, { + createEmptyPipeline: () => createEmptyPipeline2 + }); + module2.exports = __toCommonJS2(pipeline_exports); + var import_ts_http_runtime = require_commonjs(); + function createEmptyPipeline2() { + return (0, import_ts_http_runtime.createEmptyPipeline)(); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/logger/internal.js +var require_internal3 = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/logger/internal.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var internal_exports = {}; + __export2(internal_exports, { + createLoggerContext: () => import_logger.createLoggerContext + }); + module2.exports = __toCommonJS2(internal_exports); + var import_logger = require_logger(); + } +}); + +// node_modules/@azure/logger/dist/commonjs/index.js +var require_commonjs2 = __commonJS({ + "node_modules/@azure/logger/dist/commonjs/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AzureLogger = void 0; + exports2.setLogLevel = setLogLevel2; + exports2.getLogLevel = getLogLevel2; + exports2.createClientLogger = createClientLogger2; + var logger_1 = require_internal3(); + var context = (0, logger_1.createLoggerContext)({ + logLevelEnvVarName: "AZURE_LOG_LEVEL", + namespace: "azure" + }); + exports2.AzureLogger = context.logger; + function setLogLevel2(level) { + context.setLogLevel(level); + } + function getLogLevel2() { + return context.getLogLevel(); + } + function createClientLogger2(namespace) { + return context.createClientLogger(namespace); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/log.js +var require_log3 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/log.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var log_exports = {}; + __export2(log_exports, { + logger: () => logger + }); + module2.exports = __toCommonJS2(log_exports); + var import_logger = require_commonjs2(); + var logger = (0, import_logger.createClientLogger)("core-rest-pipeline"); + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/exponentialRetryPolicy.js +var require_exponentialRetryPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/exponentialRetryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var exponentialRetryPolicy_exports = {}; + __export2(exponentialRetryPolicy_exports, { + exponentialRetryPolicy: () => exponentialRetryPolicy2, + exponentialRetryPolicyName: () => exponentialRetryPolicyName2 + }); + module2.exports = __toCommonJS2(exponentialRetryPolicy_exports); + var import_exponentialRetryStrategy = require_exponentialRetryStrategy(); + var import_retryPolicy = require_retryPolicy(); + var import_constants = require_constants(); + var exponentialRetryPolicyName2 = "exponentialRetryPolicy"; + function exponentialRetryPolicy2(options = {}) { + return (0, import_retryPolicy.retryPolicy)( + [ + (0, import_exponentialRetryStrategy.exponentialRetryStrategy)({ + ...options, + ignoreSystemErrors: true + }) + ], + { + maxRetries: options.maxRetries ?? import_constants.DEFAULT_RETRY_POLICY_COUNT + } + ); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/systemErrorRetryPolicy.js +var require_systemErrorRetryPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/systemErrorRetryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var systemErrorRetryPolicy_exports = {}; + __export2(systemErrorRetryPolicy_exports, { + systemErrorRetryPolicy: () => systemErrorRetryPolicy2, + systemErrorRetryPolicyName: () => systemErrorRetryPolicyName2 + }); + module2.exports = __toCommonJS2(systemErrorRetryPolicy_exports); + var import_exponentialRetryStrategy = require_exponentialRetryStrategy(); + var import_retryPolicy = require_retryPolicy(); + var import_constants = require_constants(); + var systemErrorRetryPolicyName2 = "systemErrorRetryPolicy"; + function systemErrorRetryPolicy2(options = {}) { + return { + name: systemErrorRetryPolicyName2, + sendRequest: (0, import_retryPolicy.retryPolicy)( + [ + (0, import_exponentialRetryStrategy.exponentialRetryStrategy)({ + ...options, + ignoreHttpStatusCodes: true + }) + ], + { + maxRetries: options.maxRetries ?? import_constants.DEFAULT_RETRY_POLICY_COUNT + } + ).sendRequest + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/throttlingRetryPolicy.js +var require_throttlingRetryPolicy = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/throttlingRetryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var throttlingRetryPolicy_exports = {}; + __export2(throttlingRetryPolicy_exports, { + throttlingRetryPolicy: () => throttlingRetryPolicy2, + throttlingRetryPolicyName: () => throttlingRetryPolicyName2 + }); + module2.exports = __toCommonJS2(throttlingRetryPolicy_exports); + var import_throttlingRetryStrategy = require_throttlingRetryStrategy(); + var import_retryPolicy = require_retryPolicy(); + var import_constants = require_constants(); + var throttlingRetryPolicyName2 = "throttlingRetryPolicy"; + function throttlingRetryPolicy2(options = {}) { + return { + name: throttlingRetryPolicyName2, + sendRequest: (0, import_retryPolicy.retryPolicy)([(0, import_throttlingRetryStrategy.throttlingRetryStrategy)()], { + maxRetries: options.maxRetries ?? import_constants.DEFAULT_RETRY_POLICY_COUNT + }).sendRequest + }; + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/internal.js +var require_internal4 = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/policies/internal.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var internal_exports = {}; + __export2(internal_exports, { + agentPolicy: () => import_agentPolicy.agentPolicy, + agentPolicyName: () => import_agentPolicy.agentPolicyName, + decompressResponsePolicy: () => import_decompressResponsePolicy.decompressResponsePolicy, + decompressResponsePolicyName: () => import_decompressResponsePolicy.decompressResponsePolicyName, + defaultRetryPolicy: () => import_defaultRetryPolicy.defaultRetryPolicy, + defaultRetryPolicyName: () => import_defaultRetryPolicy.defaultRetryPolicyName, + exponentialRetryPolicy: () => import_exponentialRetryPolicy.exponentialRetryPolicy, + exponentialRetryPolicyName: () => import_exponentialRetryPolicy.exponentialRetryPolicyName, + formDataPolicy: () => import_formDataPolicy.formDataPolicy, + formDataPolicyName: () => import_formDataPolicy.formDataPolicyName, + getDefaultProxySettings: () => import_proxyPolicy.getDefaultProxySettings, + logPolicy: () => import_logPolicy.logPolicy, + logPolicyName: () => import_logPolicy.logPolicyName, + multipartPolicy: () => import_multipartPolicy.multipartPolicy, + multipartPolicyName: () => import_multipartPolicy.multipartPolicyName, + proxyPolicy: () => import_proxyPolicy.proxyPolicy, + proxyPolicyName: () => import_proxyPolicy.proxyPolicyName, + redirectPolicy: () => import_redirectPolicy.redirectPolicy, + redirectPolicyName: () => import_redirectPolicy.redirectPolicyName, + retryPolicy: () => import_retryPolicy.retryPolicy, + systemErrorRetryPolicy: () => import_systemErrorRetryPolicy.systemErrorRetryPolicy, + systemErrorRetryPolicyName: () => import_systemErrorRetryPolicy.systemErrorRetryPolicyName, + throttlingRetryPolicy: () => import_throttlingRetryPolicy.throttlingRetryPolicy, + throttlingRetryPolicyName: () => import_throttlingRetryPolicy.throttlingRetryPolicyName, + tlsPolicy: () => import_tlsPolicy.tlsPolicy, + tlsPolicyName: () => import_tlsPolicy.tlsPolicyName, + userAgentPolicy: () => import_userAgentPolicy.userAgentPolicy, + userAgentPolicyName: () => import_userAgentPolicy.userAgentPolicyName + }); + module2.exports = __toCommonJS2(internal_exports); + var import_agentPolicy = require_agentPolicy(); + var import_decompressResponsePolicy = require_decompressResponsePolicy(); + var import_defaultRetryPolicy = require_defaultRetryPolicy(); + var import_exponentialRetryPolicy = require_exponentialRetryPolicy(); + var import_retryPolicy = require_retryPolicy(); + var import_systemErrorRetryPolicy = require_systemErrorRetryPolicy(); + var import_throttlingRetryPolicy = require_throttlingRetryPolicy(); + var import_formDataPolicy = require_formDataPolicy(); + var import_logPolicy = require_logPolicy(); + var import_multipartPolicy = require_multipartPolicy(); + var import_proxyPolicy = require_proxyPolicy(); + var import_redirectPolicy = require_redirectPolicy(); + var import_tlsPolicy = require_tlsPolicy(); + var import_userAgentPolicy = require_userAgentPolicy(); + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/logPolicy.js +var require_logPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/logPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var logPolicy_exports = {}; + __export2(logPolicy_exports, { + logPolicy: () => logPolicy2, + logPolicyName: () => logPolicyName2 + }); + module2.exports = __toCommonJS2(logPolicy_exports); + var import_log = require_log3(); + var import_policies = require_internal4(); + var logPolicyName2 = import_policies.logPolicyName; + function logPolicy2(options = {}) { + return (0, import_policies.logPolicy)({ + logger: import_log.logger.info, + ...options + }); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/redirectPolicy.js +var require_redirectPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/redirectPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var redirectPolicy_exports = {}; + __export2(redirectPolicy_exports, { + redirectPolicy: () => redirectPolicy2, + redirectPolicyName: () => redirectPolicyName2 + }); + module2.exports = __toCommonJS2(redirectPolicy_exports); + var import_policies = require_internal4(); + var redirectPolicyName2 = import_policies.redirectPolicyName; + function redirectPolicy2(options = {}) { + return (0, import_policies.redirectPolicy)(options); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/util/userAgentPlatform.js +var require_userAgentPlatform2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/util/userAgentPlatform.js"(exports2, module2) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var userAgentPlatform_exports = {}; + __export2(userAgentPlatform_exports, { + getHeaderName: () => getHeaderName, + setPlatformSpecificData: () => setPlatformSpecificData + }); + module2.exports = __toCommonJS2(userAgentPlatform_exports); + var import_node_os2 = __toESM2(require("node:os")); + var import_node_process7 = __toESM2(require("node:process")); + function getHeaderName() { + return "User-Agent"; + } + async function setPlatformSpecificData(map) { + if (import_node_process7.default && import_node_process7.default.versions) { + const osInfo = `${import_node_os2.default.type()} ${import_node_os2.default.release()}; ${import_node_os2.default.arch()}`; + const versions = import_node_process7.default.versions; + if (versions.bun) { + map.set("Bun", `${versions.bun} (${osInfo})`); + } else if (versions.deno) { + map.set("Deno", `${versions.deno} (${osInfo})`); + } else if (versions.node) { + map.set("Node", `${versions.node} (${osInfo})`); + } + } + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/constants.js +var require_constants2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/constants.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var constants_exports = {}; + __export2(constants_exports, { + DEFAULT_RETRY_POLICY_COUNT: () => DEFAULT_RETRY_POLICY_COUNT, + SDK_VERSION: () => SDK_VERSION + }); + module2.exports = __toCommonJS2(constants_exports); + var SDK_VERSION = "1.22.3"; + var DEFAULT_RETRY_POLICY_COUNT = 3; + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/util/userAgent.js +var require_userAgent2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/util/userAgent.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var userAgent_exports = {}; + __export2(userAgent_exports, { + getUserAgentHeaderName: () => getUserAgentHeaderName, + getUserAgentValue: () => getUserAgentValue + }); + module2.exports = __toCommonJS2(userAgent_exports); + var import_userAgentPlatform = require_userAgentPlatform2(); + var import_constants = require_constants2(); + function getUserAgentString(telemetryInfo) { + const parts = []; + for (const [key, value] of telemetryInfo) { + const token = value ? `${key}/${value}` : key; + parts.push(token); + } + return parts.join(" "); + } + function getUserAgentHeaderName() { + return (0, import_userAgentPlatform.getHeaderName)(); + } + async function getUserAgentValue(prefix) { + const runtimeInfo = /* @__PURE__ */ new Map(); + runtimeInfo.set("core-rest-pipeline", import_constants.SDK_VERSION); + await (0, import_userAgentPlatform.setPlatformSpecificData)(runtimeInfo); + const defaultAgent = getUserAgentString(runtimeInfo); + const userAgentValue = prefix ? `${prefix} ${defaultAgent}` : defaultAgent; + return userAgentValue; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/userAgentPolicy.js +var require_userAgentPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/userAgentPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var userAgentPolicy_exports = {}; + __export2(userAgentPolicy_exports, { + userAgentPolicy: () => userAgentPolicy2, + userAgentPolicyName: () => userAgentPolicyName2 + }); + module2.exports = __toCommonJS2(userAgentPolicy_exports); + var import_userAgent = require_userAgent2(); + var UserAgentHeaderName = (0, import_userAgent.getUserAgentHeaderName)(); + var userAgentPolicyName2 = "userAgentPolicy"; + function userAgentPolicy2(options = {}) { + const userAgentValue = (0, import_userAgent.getUserAgentValue)(options.userAgentPrefix); + return { + name: userAgentPolicyName2, + async sendRequest(request, next) { + if (!request.headers.has(UserAgentHeaderName)) { + request.headers.set(UserAgentHeaderName, await userAgentValue); + } + return next(request); + } + }; + } + } +}); + +// node_modules/tslib/tslib.es6.mjs +var tslib_es6_exports = {}; +__export(tslib_es6_exports, { + __addDisposableResource: () => __addDisposableResource, + __assign: () => __assign, + __asyncDelegator: () => __asyncDelegator, + __asyncGenerator: () => __asyncGenerator, + __asyncValues: () => __asyncValues, + __await: () => __await, + __awaiter: () => __awaiter, + __classPrivateFieldGet: () => __classPrivateFieldGet, + __classPrivateFieldIn: () => __classPrivateFieldIn, + __classPrivateFieldSet: () => __classPrivateFieldSet, + __createBinding: () => __createBinding, + __decorate: () => __decorate, + __disposeResources: () => __disposeResources, + __esDecorate: () => __esDecorate, + __exportStar: () => __exportStar, + __extends: () => __extends, + __generator: () => __generator, + __importDefault: () => __importDefault, + __importStar: () => __importStar, + __makeTemplateObject: () => __makeTemplateObject, + __metadata: () => __metadata, + __param: () => __param, + __propKey: () => __propKey, + __read: () => __read, + __rest: () => __rest, + __rewriteRelativeImportExtension: () => __rewriteRelativeImportExtension, + __runInitializers: () => __runInitializers, + __setFunctionName: () => __setFunctionName, + __spread: () => __spread, + __spreadArray: () => __spreadArray, + __spreadArrays: () => __spreadArrays, + __values: () => __values, + default: () => tslib_es6_default +}); +function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} +function __param(paramIndex, decorator) { + return function(target, key) { + decorator(target, key, paramIndex); + }; +} +function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { + if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); + return f; + } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function(f) { + if (done) throw new TypeError("Cannot add initializers after decoration has completed"); + extraInitializers.push(accept(f || null)); + }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +} +function __runInitializers(thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +} +function __propKey(x) { + return typeof x === "symbol" ? x : "".concat(x); +} +function __setFunctionName(f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +} +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { + if (t[0] & 1) throw t[1]; + return t[1]; + }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { + return this; + }), g; + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } +} +function __exportStar(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); +} +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function() { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { error }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + return ar; +} +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} +function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +} +function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function() { + return this; + }, i; + function awaitReturn(f) { + return function(v) { + return Promise.resolve(v).then(f, reject); + }; + } + function verb(n, f) { + if (g[n]) { + i[n] = function(v) { + return new Promise(function(a, b) { + q.push([n, v, a, b]) > 1 || resume(n, v); + }); + }; + if (f) i[n] = f(i[n]); + } + } + function resume(n, v) { + try { + step(g[n](v)); + } catch (e) { + settle(q[0][3], e); + } + } + function step(r) { + r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); + } + function fulfill(value) { + resume("next", value); + } + function reject(value) { + resume("throw", value); + } + function settle(f, v) { + if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); + } +} +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function(e) { + throw e; + }), verb("return"), i[Symbol.iterator] = function() { + return this; + }, i; + function verb(n, f) { + i[n] = o[n] ? function(v) { + return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; + } : f; + } +} +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i); + function verb(n) { + i[n] = o[n] && function(v) { + return new Promise(function(resolve, reject) { + v = o[n](v), settle(resolve, reject, v.done, v.value); + }); + }; + } + function settle(resolve, reject, d, v) { + Promise.resolve(v).then(function(v2) { + resolve({ value: v2, done: d }); + }, reject); + } +} +function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { + Object.defineProperty(cooked, "raw", { value: raw }); + } else { + cooked.raw = raw; + } + return cooked; +} +function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; +} +function __importDefault(mod) { + return mod && mod.__esModule ? mod : { default: mod }; +} +function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +} +function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; +} +function __classPrivateFieldIn(state, receiver) { + if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function") throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); +} +function __addDisposableResource(env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose, inner; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + if (async) inner = dispose; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + if (inner) dispose = function() { + try { + inner.call(this); + } catch (e) { + return Promise.reject(e); + } + }; + env.stack.push({ value, dispose, async }); + } else if (async) { + env.stack.push({ async: true }); + } + return value; +} +function __disposeResources(env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + var r, s = 0; + function next() { + while (r = env.stack.pop()) { + try { + if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); + if (r.dispose) { + var result = r.dispose.call(r.value); + if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { + fail(e); + return next(); + }); + } else s |= 1; + } catch (e) { + fail(e); + } + } + if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); + if (env.hasError) throw env.error; + } + return next(); +} +function __rewriteRelativeImportExtension(path3, preserveJsx) { + if (typeof path3 === "string" && /^\.\.?\//.test(path3)) { + return path3.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js"; + }); + } + return path3; +} +var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default; +var init_tslib_es6 = __esm({ + "node_modules/tslib/tslib.es6.mjs"() { + extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { + d2.__proto__ = b2; + } || function(d2, b2) { + for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p]; + }; + return extendStatics(d, b); + }; + __assign = function() { + __assign = Object.assign || function __assign2(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }; + ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + tslib_es6_default = { + __extends, + __assign, + __rest, + __decorate, + __param, + __esDecorate, + __runInitializers, + __propKey, + __setFunctionName, + __metadata, + __awaiter, + __generator, + __createBinding, + __exportStar, + __values, + __read, + __spread, + __spreadArrays, + __spreadArray, + __await, + __asyncGenerator, + __asyncDelegator, + __asyncValues, + __makeTemplateObject, + __importStar, + __importDefault, + __classPrivateFieldGet, + __classPrivateFieldSet, + __classPrivateFieldIn, + __addDisposableResource, + __disposeResources, + __rewriteRelativeImportExtension + }; + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/sha256.js +var require_sha256 = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/sha256.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var sha256_exports = {}; + __export2(sha256_exports, { + computeSha256Hash: () => computeSha256Hash2, + computeSha256Hmac: () => computeSha256Hmac2 + }); + module2.exports = __toCommonJS2(sha256_exports); + var import_node_crypto5 = require("node:crypto"); + async function computeSha256Hmac2(key, stringToSign, encoding) { + const decodedKey = Buffer.from(key, "base64"); + return (0, import_node_crypto5.createHmac)("sha256", decodedKey).update(stringToSign).digest(encoding); + } + async function computeSha256Hash2(content, encoding) { + return (0, import_node_crypto5.createHash)("sha256").update(content).digest(encoding); + } + } +}); + +// node_modules/@typespec/ts-http-runtime/dist/commonjs/util/internal.js +var require_internal5 = __commonJS({ + "node_modules/@typespec/ts-http-runtime/dist/commonjs/util/internal.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var internal_exports = {}; + __export2(internal_exports, { + Sanitizer: () => import_sanitizer.Sanitizer, + calculateRetryDelay: () => import_delay.calculateRetryDelay, + computeSha256Hash: () => import_sha256.computeSha256Hash, + computeSha256Hmac: () => import_sha256.computeSha256Hmac, + getRandomIntegerInclusive: () => import_random.getRandomIntegerInclusive, + isBrowser: () => import_checkEnvironment.isBrowser, + isBun: () => import_checkEnvironment.isBun, + isDeno: () => import_checkEnvironment.isDeno, + isError: () => import_error.isError, + isNodeLike: () => import_checkEnvironment.isNodeLike, + isNodeRuntime: () => import_checkEnvironment.isNodeRuntime, + isObject: () => import_object.isObject, + isReactNative: () => import_checkEnvironment.isReactNative, + isWebWorker: () => import_checkEnvironment.isWebWorker, + randomUUID: () => import_uuidUtils.randomUUID, + stringToUint8Array: () => import_bytesEncoding.stringToUint8Array, + uint8ArrayToString: () => import_bytesEncoding.uint8ArrayToString + }); + module2.exports = __toCommonJS2(internal_exports); + var import_delay = require_delay(); + var import_random = require_random(); + var import_object = require_object(); + var import_error = require_error(); + var import_sha256 = require_sha256(); + var import_uuidUtils = require_uuidUtils(); + var import_checkEnvironment = require_checkEnvironment(); + var import_bytesEncoding = require_bytesEncoding(); + var import_sanitizer = require_sanitizer(); + } +}); + +// node_modules/@azure/core-util/dist/commonjs/aborterUtils.js +var require_aborterUtils = __commonJS({ + "node_modules/@azure/core-util/dist/commonjs/aborterUtils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.cancelablePromiseRace = cancelablePromiseRace; + async function cancelablePromiseRace(abortablePromiseBuilders, options) { + const aborter = new AbortController(); + function abortHandler() { + aborter.abort(); + } + options?.abortSignal?.addEventListener("abort", abortHandler); + try { + return await Promise.race(abortablePromiseBuilders.map((p) => p({ abortSignal: aborter.signal }))); + } finally { + aborter.abort(); + options?.abortSignal?.removeEventListener("abort", abortHandler); + } + } + } +}); + +// node_modules/@azure/abort-controller/dist/commonjs/AbortError.js +var require_AbortError2 = __commonJS({ + "node_modules/@azure/abort-controller/dist/commonjs/AbortError.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AbortError = void 0; + var AbortError2 = class extends Error { + constructor(message) { + super(message); + this.name = "AbortError"; + } + }; + exports2.AbortError = AbortError2; + } +}); + +// node_modules/@azure/abort-controller/dist/commonjs/index.js +var require_commonjs3 = __commonJS({ + "node_modules/@azure/abort-controller/dist/commonjs/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AbortError = void 0; + var AbortError_js_1 = require_AbortError2(); + Object.defineProperty(exports2, "AbortError", { enumerable: true, get: function() { + return AbortError_js_1.AbortError; + } }); + } +}); + +// node_modules/@azure/core-util/dist/commonjs/createAbortablePromise.js +var require_createAbortablePromise = __commonJS({ + "node_modules/@azure/core-util/dist/commonjs/createAbortablePromise.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createAbortablePromise = createAbortablePromise; + var abort_controller_1 = require_commonjs3(); + function createAbortablePromise(buildPromise, options) { + const { cleanupBeforeAbort, abortSignal, abortErrorMsg } = options ?? {}; + return new Promise((resolve, reject) => { + function rejectOnAbort() { + reject(new abort_controller_1.AbortError(abortErrorMsg ?? "The operation was aborted.")); + } + function removeListeners() { + abortSignal?.removeEventListener("abort", onAbort); + } + function onAbort() { + cleanupBeforeAbort?.(); + removeListeners(); + rejectOnAbort(); + } + if (abortSignal?.aborted) { + return rejectOnAbort(); + } + try { + buildPromise((x) => { + removeListeners(); + resolve(x); + }, (x) => { + removeListeners(); + reject(x); + }); + } catch (err) { + reject(err); + } + abortSignal?.addEventListener("abort", onAbort); + }); + } + } +}); + +// node_modules/@azure/core-util/dist/commonjs/delay.js +var require_delay2 = __commonJS({ + "node_modules/@azure/core-util/dist/commonjs/delay.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.delay = delay; + exports2.calculateRetryDelay = calculateRetryDelay2; + var createAbortablePromise_js_1 = require_createAbortablePromise(); + var util_1 = require_internal5(); + var StandardAbortMessage = "The delay was aborted."; + function delay(timeInMs, options) { + let token; + const { abortSignal, abortErrorMsg } = options ?? {}; + return (0, createAbortablePromise_js_1.createAbortablePromise)((resolve) => { + token = setTimeout(resolve, timeInMs); + }, { + cleanupBeforeAbort: () => clearTimeout(token), + abortSignal, + abortErrorMsg: abortErrorMsg ?? StandardAbortMessage + }); + } + function calculateRetryDelay2(retryAttempt, config) { + const exponentialDelay = config.retryDelayInMs * Math.pow(2, retryAttempt); + const clampedDelay = Math.min(config.maxRetryDelayInMs, exponentialDelay); + const retryAfterInMs = clampedDelay / 2 + (0, util_1.getRandomIntegerInclusive)(0, clampedDelay / 2); + return { retryAfterInMs }; + } + } +}); + +// node_modules/@azure/core-util/dist/commonjs/error.js +var require_error2 = __commonJS({ + "node_modules/@azure/core-util/dist/commonjs/error.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getErrorMessage = getErrorMessage; + var util_1 = require_internal5(); + function getErrorMessage(e) { + if ((0, util_1.isError)(e)) { + return e.message; + } else { + let stringified; + try { + if (typeof e === "object" && e) { + stringified = JSON.stringify(e); + } else { + stringified = String(e); + } + } catch (err) { + stringified = "[unable to stringify input]"; + } + return `Unknown error ${stringified}`; + } + } + } +}); + +// node_modules/@azure/core-util/dist/commonjs/typeGuards.js +var require_typeGuards2 = __commonJS({ + "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isDefined = isDefined; + exports2.isObjectWithProperties = isObjectWithProperties; + exports2.objectHasProperty = objectHasProperty; + function isDefined(thing) { + return typeof thing !== "undefined" && thing !== null; + } + function isObjectWithProperties(thing, properties) { + if (!isDefined(thing) || typeof thing !== "object") { + return false; + } + for (const property of properties) { + if (!objectHasProperty(thing, property)) { + return false; + } + } + return true; + } + function objectHasProperty(thing, property) { + return isDefined(thing) && typeof thing === "object" && property in thing; + } + } +}); + +// node_modules/@azure/core-util/dist/commonjs/index.js +var require_commonjs4 = __commonJS({ + "node_modules/@azure/core-util/dist/commonjs/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isWebWorker = exports2.isReactNative = exports2.isNodeRuntime = exports2.isNodeLike = exports2.isNode = exports2.isDeno = exports2.isBun = exports2.isBrowser = exports2.objectHasProperty = exports2.isObjectWithProperties = exports2.isDefined = exports2.getErrorMessage = exports2.delay = exports2.createAbortablePromise = exports2.cancelablePromiseRace = void 0; + exports2.calculateRetryDelay = calculateRetryDelay2; + exports2.computeSha256Hash = computeSha256Hash2; + exports2.computeSha256Hmac = computeSha256Hmac2; + exports2.getRandomIntegerInclusive = getRandomIntegerInclusive2; + exports2.isError = isError2; + exports2.isObject = isObject2; + exports2.randomUUID = randomUUID2; + exports2.uint8ArrayToString = uint8ArrayToString2; + exports2.stringToUint8Array = stringToUint8Array2; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var tspRuntime = tslib_1.__importStar(require_internal5()); + var aborterUtils_js_1 = require_aborterUtils(); + Object.defineProperty(exports2, "cancelablePromiseRace", { enumerable: true, get: function() { + return aborterUtils_js_1.cancelablePromiseRace; + } }); + var createAbortablePromise_js_1 = require_createAbortablePromise(); + Object.defineProperty(exports2, "createAbortablePromise", { enumerable: true, get: function() { + return createAbortablePromise_js_1.createAbortablePromise; + } }); + var delay_js_1 = require_delay2(); + Object.defineProperty(exports2, "delay", { enumerable: true, get: function() { + return delay_js_1.delay; + } }); + var error_js_1 = require_error2(); + Object.defineProperty(exports2, "getErrorMessage", { enumerable: true, get: function() { + return error_js_1.getErrorMessage; + } }); + var typeGuards_js_1 = require_typeGuards2(); + Object.defineProperty(exports2, "isDefined", { enumerable: true, get: function() { + return typeGuards_js_1.isDefined; + } }); + Object.defineProperty(exports2, "isObjectWithProperties", { enumerable: true, get: function() { + return typeGuards_js_1.isObjectWithProperties; + } }); + Object.defineProperty(exports2, "objectHasProperty", { enumerable: true, get: function() { + return typeGuards_js_1.objectHasProperty; + } }); + function calculateRetryDelay2(retryAttempt, config) { + return tspRuntime.calculateRetryDelay(retryAttempt, config); + } + function computeSha256Hash2(content, encoding) { + return tspRuntime.computeSha256Hash(content, encoding); + } + function computeSha256Hmac2(key, stringToSign, encoding) { + return tspRuntime.computeSha256Hmac(key, stringToSign, encoding); + } + function getRandomIntegerInclusive2(min, max) { + return tspRuntime.getRandomIntegerInclusive(min, max); + } + function isError2(e) { + return tspRuntime.isError(e); + } + function isObject2(input) { + return tspRuntime.isObject(input); + } + function randomUUID2() { + return tspRuntime.randomUUID(); + } + exports2.isBrowser = tspRuntime.isBrowser; + exports2.isBun = tspRuntime.isBun; + exports2.isDeno = tspRuntime.isDeno; + exports2.isNode = tspRuntime.isNodeLike; + exports2.isNodeLike = tspRuntime.isNodeLike; + exports2.isNodeRuntime = tspRuntime.isNodeRuntime; + exports2.isReactNative = tspRuntime.isReactNative; + exports2.isWebWorker = tspRuntime.isWebWorker; + function uint8ArrayToString2(bytes, format) { + return tspRuntime.uint8ArrayToString(bytes, format); + } + function stringToUint8Array2(value, format) { + return tspRuntime.stringToUint8Array(value, format); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/util/file.js +var require_file = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/util/file.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var file_exports = {}; + __export2(file_exports, { + createFile: () => createFile2, + createFileFromStream: () => createFileFromStream2, + getRawContent: () => getRawContent, + hasRawContent: () => hasRawContent + }); + module2.exports = __toCommonJS2(file_exports); + var import_core_util = require_commonjs4(); + function isNodeReadableStream(x) { + return Boolean(x && typeof x["pipe"] === "function"); + } + var unimplementedMethods = { + arrayBuffer: () => { + throw new Error("Not implemented"); + }, + bytes: () => { + throw new Error("Not implemented"); + }, + slice: () => { + throw new Error("Not implemented"); + }, + text: () => { + throw new Error("Not implemented"); + } + }; + var rawContent = /* @__PURE__ */ Symbol("rawContent"); + function hasRawContent(x) { + return typeof x[rawContent] === "function"; + } + function getRawContent(blob) { + if (hasRawContent(blob)) { + return blob[rawContent](); + } else { + return blob; + } + } + function createFileFromStream2(stream, name, options = {}) { + return { + ...unimplementedMethods, + type: options.type ?? "", + lastModified: options.lastModified ?? (/* @__PURE__ */ new Date()).getTime(), + webkitRelativePath: options.webkitRelativePath ?? "", + size: options.size ?? -1, + name, + stream: () => { + const s = stream(); + if (isNodeReadableStream(s)) { + throw new Error( + "Not supported: a Node stream was provided as input to createFileFromStream." + ); + } + return s; + }, + [rawContent]: stream + }; + } + function createFile2(content, name, options = {}) { + if (import_core_util.isNodeLike) { + return { + ...unimplementedMethods, + type: options.type ?? "", + lastModified: options.lastModified ?? (/* @__PURE__ */ new Date()).getTime(), + webkitRelativePath: options.webkitRelativePath ?? "", + size: content.byteLength, + name, + arrayBuffer: async () => content.buffer, + stream: () => new Blob([toArrayBuffer(content)]).stream(), + [rawContent]: () => content + }; + } else { + return new File([toArrayBuffer(content)], name, options); + } + } + function toArrayBuffer(source) { + if ("resize" in source.buffer) { + return source; + } + return source.map((x) => x); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/multipartPolicy.js +var require_multipartPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/multipartPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var multipartPolicy_exports = {}; + __export2(multipartPolicy_exports, { + multipartPolicy: () => multipartPolicy2, + multipartPolicyName: () => multipartPolicyName2 + }); + module2.exports = __toCommonJS2(multipartPolicy_exports); + var import_policies = require_internal4(); + var import_file = require_file(); + var multipartPolicyName2 = import_policies.multipartPolicyName; + function multipartPolicy2() { + const tspPolicy = (0, import_policies.multipartPolicy)(); + return { + name: multipartPolicyName2, + sendRequest: async (request, next) => { + if (request.multipartBody) { + for (const part of request.multipartBody.parts) { + if ((0, import_file.hasRawContent)(part.body)) { + part.body = (0, import_file.getRawContent)(part.body); + } + } + } + return tspPolicy.sendRequest(request, next); + } + }; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/decompressResponsePolicy.js +var require_decompressResponsePolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/decompressResponsePolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var decompressResponsePolicy_exports = {}; + __export2(decompressResponsePolicy_exports, { + decompressResponsePolicy: () => decompressResponsePolicy2, + decompressResponsePolicyName: () => decompressResponsePolicyName2 + }); + module2.exports = __toCommonJS2(decompressResponsePolicy_exports); + var import_policies = require_internal4(); + var decompressResponsePolicyName2 = import_policies.decompressResponsePolicyName; + function decompressResponsePolicy2() { + return (0, import_policies.decompressResponsePolicy)(); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/defaultRetryPolicy.js +var require_defaultRetryPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/defaultRetryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var defaultRetryPolicy_exports = {}; + __export2(defaultRetryPolicy_exports, { + defaultRetryPolicy: () => defaultRetryPolicy2, + defaultRetryPolicyName: () => defaultRetryPolicyName2 + }); + module2.exports = __toCommonJS2(defaultRetryPolicy_exports); + var import_policies = require_internal4(); + var defaultRetryPolicyName2 = import_policies.defaultRetryPolicyName; + function defaultRetryPolicy2(options = {}) { + return (0, import_policies.defaultRetryPolicy)(options); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/formDataPolicy.js +var require_formDataPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/formDataPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var formDataPolicy_exports = {}; + __export2(formDataPolicy_exports, { + formDataPolicy: () => formDataPolicy2, + formDataPolicyName: () => formDataPolicyName2 + }); + module2.exports = __toCommonJS2(formDataPolicy_exports); + var import_policies = require_internal4(); + var formDataPolicyName2 = import_policies.formDataPolicyName; + function formDataPolicy2() { + return (0, import_policies.formDataPolicy)(); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/proxyPolicy.js +var require_proxyPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/proxyPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var proxyPolicy_exports = {}; + __export2(proxyPolicy_exports, { + getDefaultProxySettings: () => getDefaultProxySettings2, + proxyPolicy: () => proxyPolicy2, + proxyPolicyName: () => proxyPolicyName2 + }); + module2.exports = __toCommonJS2(proxyPolicy_exports); + var import_policies = require_internal4(); + var proxyPolicyName2 = import_policies.proxyPolicyName; + function getDefaultProxySettings2(proxyUrl) { + return (0, import_policies.getDefaultProxySettings)(proxyUrl); + } + function proxyPolicy2(proxySettings, options) { + return (0, import_policies.proxyPolicy)(proxySettings, options); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/setClientRequestIdPolicy.js +var require_setClientRequestIdPolicy = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/setClientRequestIdPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var setClientRequestIdPolicy_exports = {}; + __export2(setClientRequestIdPolicy_exports, { + setClientRequestIdPolicy: () => setClientRequestIdPolicy2, + setClientRequestIdPolicyName: () => setClientRequestIdPolicyName2 + }); + module2.exports = __toCommonJS2(setClientRequestIdPolicy_exports); + var setClientRequestIdPolicyName2 = "setClientRequestIdPolicy"; + function setClientRequestIdPolicy2(requestIdHeaderName = "x-ms-client-request-id") { + return { + name: setClientRequestIdPolicyName2, + async sendRequest(request, next) { + if (!request.headers.has(requestIdHeaderName)) { + request.headers.set(requestIdHeaderName, request.requestId); + } + return next(request); + } + }; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/agentPolicy.js +var require_agentPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/agentPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var agentPolicy_exports = {}; + __export2(agentPolicy_exports, { + agentPolicy: () => agentPolicy2, + agentPolicyName: () => agentPolicyName2 + }); + module2.exports = __toCommonJS2(agentPolicy_exports); + var import_policies = require_internal4(); + var agentPolicyName2 = import_policies.agentPolicyName; + function agentPolicy2(agent) { + return (0, import_policies.agentPolicy)(agent); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/tlsPolicy.js +var require_tlsPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/tlsPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var tlsPolicy_exports = {}; + __export2(tlsPolicy_exports, { + tlsPolicy: () => tlsPolicy2, + tlsPolicyName: () => tlsPolicyName2 + }); + module2.exports = __toCommonJS2(tlsPolicy_exports); + var import_policies = require_internal4(); + var tlsPolicyName2 = import_policies.tlsPolicyName; + function tlsPolicy2(tlsSettings) { + return (0, import_policies.tlsPolicy)(tlsSettings); + } + } +}); + +// node_modules/@azure/core-tracing/dist/commonjs/tracingContext.js +var require_tracingContext = __commonJS({ + "node_modules/@azure/core-tracing/dist/commonjs/tracingContext.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TracingContextImpl = exports2.knownContextKeys = void 0; + exports2.createTracingContext = createTracingContext; + exports2.knownContextKeys = { + span: Symbol.for("@azure/core-tracing span"), + namespace: Symbol.for("@azure/core-tracing namespace") + }; + function createTracingContext(options = {}) { + let context = new TracingContextImpl(options.parentContext); + if (options.span) { + context = context.setValue(exports2.knownContextKeys.span, options.span); + } + if (options.namespace) { + context = context.setValue(exports2.knownContextKeys.namespace, options.namespace); + } + return context; + } + var TracingContextImpl = class _TracingContextImpl { + _contextMap; + constructor(initialContext) { + this._contextMap = initialContext instanceof _TracingContextImpl ? new Map(initialContext._contextMap) : /* @__PURE__ */ new Map(); + } + setValue(key, value) { + const newContext = new _TracingContextImpl(this); + newContext._contextMap.set(key, value); + return newContext; + } + getValue(key) { + return this._contextMap.get(key); + } + deleteValue(key) { + const newContext = new _TracingContextImpl(this); + newContext._contextMap.delete(key); + return newContext; + } + }; + exports2.TracingContextImpl = TracingContextImpl; + } +}); + +// node_modules/@azure/core-tracing/dist/commonjs/state.js +var require_state = __commonJS({ + "node_modules/@azure/core-tracing/dist/commonjs/state.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.state = void 0; + exports2.state = { + instrumenterImplementation: void 0 + }; + } +}); + +// node_modules/@azure/core-tracing/dist/commonjs/instrumenter.js +var require_instrumenter = __commonJS({ + "node_modules/@azure/core-tracing/dist/commonjs/instrumenter.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createDefaultTracingSpan = createDefaultTracingSpan; + exports2.createDefaultInstrumenter = createDefaultInstrumenter; + exports2.useInstrumenter = useInstrumenter; + exports2.getInstrumenter = getInstrumenter; + var tracingContext_js_1 = require_tracingContext(); + var state_js_1 = require_state(); + function createDefaultTracingSpan() { + return { + end: () => { + }, + isRecording: () => false, + recordException: () => { + }, + setAttribute: () => { + }, + setStatus: () => { + }, + addEvent: () => { + } + }; + } + function createDefaultInstrumenter() { + return { + createRequestHeaders: () => { + return {}; + }, + parseTraceparentHeader: () => { + return void 0; + }, + startSpan: (_name, spanOptions) => { + return { + span: createDefaultTracingSpan(), + tracingContext: (0, tracingContext_js_1.createTracingContext)({ parentContext: spanOptions.tracingContext }) + }; + }, + withContext(_context, callback, ...callbackArgs) { + return callback(...callbackArgs); + } + }; + } + function useInstrumenter(instrumenter) { + state_js_1.state.instrumenterImplementation = instrumenter; + } + function getInstrumenter() { + if (!state_js_1.state.instrumenterImplementation) { + state_js_1.state.instrumenterImplementation = createDefaultInstrumenter(); + } + return state_js_1.state.instrumenterImplementation; + } + } +}); + +// node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js +var require_tracingClient = __commonJS({ + "node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createTracingClient = createTracingClient; + var instrumenter_js_1 = require_instrumenter(); + var tracingContext_js_1 = require_tracingContext(); + function createTracingClient(options) { + const { namespace, packageName, packageVersion } = options; + function startSpan(name, operationOptions, spanOptions) { + const startSpanResult = (0, instrumenter_js_1.getInstrumenter)().startSpan(name, { + ...spanOptions, + packageName, + packageVersion, + tracingContext: operationOptions?.tracingOptions?.tracingContext + }); + let tracingContext = startSpanResult.tracingContext; + const span = startSpanResult.span; + if (!tracingContext.getValue(tracingContext_js_1.knownContextKeys.namespace)) { + tracingContext = tracingContext.setValue(tracingContext_js_1.knownContextKeys.namespace, namespace); + } + span.setAttribute("az.namespace", tracingContext.getValue(tracingContext_js_1.knownContextKeys.namespace)); + const updatedOptions = Object.assign({}, operationOptions, { + tracingOptions: { ...operationOptions?.tracingOptions, tracingContext } + }); + return { + span, + updatedOptions + }; + } + async function withSpan(name, operationOptions, callback, spanOptions) { + const { span, updatedOptions } = startSpan(name, operationOptions, spanOptions); + try { + const result = await withContext(updatedOptions.tracingOptions.tracingContext, () => Promise.resolve(callback(updatedOptions, span))); + span.setStatus({ status: "success" }); + return result; + } catch (err) { + span.setStatus({ status: "error", error: err }); + throw err; + } finally { + span.end(); + } + } + function withContext(context, callback, ...callbackArgs) { + return (0, instrumenter_js_1.getInstrumenter)().withContext(context, callback, ...callbackArgs); + } + function parseTraceparentHeader(traceparentHeader) { + return (0, instrumenter_js_1.getInstrumenter)().parseTraceparentHeader(traceparentHeader); + } + function createRequestHeaders(tracingContext) { + return (0, instrumenter_js_1.getInstrumenter)().createRequestHeaders(tracingContext); + } + return { + startSpan, + withSpan, + withContext, + parseTraceparentHeader, + createRequestHeaders + }; + } + } +}); + +// node_modules/@azure/core-tracing/dist/commonjs/index.js +var require_commonjs5 = __commonJS({ + "node_modules/@azure/core-tracing/dist/commonjs/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createTracingClient = exports2.useInstrumenter = void 0; + var instrumenter_js_1 = require_instrumenter(); + Object.defineProperty(exports2, "useInstrumenter", { enumerable: true, get: function() { + return instrumenter_js_1.useInstrumenter; + } }); + var tracingClient_js_1 = require_tracingClient(); + Object.defineProperty(exports2, "createTracingClient", { enumerable: true, get: function() { + return tracingClient_js_1.createTracingClient; + } }); + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/restError.js +var require_restError3 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/restError.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var restError_exports = {}; + __export2(restError_exports, { + RestError: () => RestError2, + isRestError: () => isRestError2 + }); + module2.exports = __toCommonJS2(restError_exports); + var import_ts_http_runtime = require_commonjs(); + var RestError2 = import_ts_http_runtime.RestError; + function isRestError2(e) { + return (0, import_ts_http_runtime.isRestError)(e); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/tracingPolicy.js +var require_tracingPolicy = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/tracingPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var tracingPolicy_exports = {}; + __export2(tracingPolicy_exports, { + tracingPolicy: () => tracingPolicy2, + tracingPolicyName: () => tracingPolicyName2 + }); + module2.exports = __toCommonJS2(tracingPolicy_exports); + var import_core_tracing = require_commonjs5(); + var import_constants = require_constants2(); + var import_userAgent = require_userAgent2(); + var import_log = require_log3(); + var import_core_util = require_commonjs4(); + var import_restError = require_restError3(); + var import_util = require_internal5(); + var tracingPolicyName2 = "tracingPolicy"; + function tracingPolicy2(options = {}) { + const userAgentPromise = (0, import_userAgent.getUserAgentValue)(options.userAgentPrefix); + const sanitizer = new import_util.Sanitizer({ + additionalAllowedQueryParameters: options.additionalAllowedQueryParameters + }); + const tracingClient = tryCreateTracingClient(); + return { + name: tracingPolicyName2, + async sendRequest(request, next) { + if (!tracingClient) { + return next(request); + } + const userAgent = await userAgentPromise; + const spanAttributes = { + "http.url": sanitizer.sanitizeUrl(request.url), + "http.method": request.method, + "http.user_agent": userAgent, + requestId: request.requestId + }; + if (userAgent) { + spanAttributes["http.user_agent"] = userAgent; + } + const { span, tracingContext } = tryCreateSpan(tracingClient, request, spanAttributes) ?? {}; + if (!span || !tracingContext) { + return next(request); + } + try { + const response = await tracingClient.withContext(tracingContext, next, request); + tryProcessResponse(span, response); + return response; + } catch (err) { + tryProcessError(span, err); + throw err; + } + } + }; + } + function tryCreateTracingClient() { + try { + return (0, import_core_tracing.createTracingClient)({ + namespace: "", + packageName: "@azure/core-rest-pipeline", + packageVersion: import_constants.SDK_VERSION + }); + } catch (e) { + import_log.logger.warning(`Error when creating the TracingClient: ${(0, import_core_util.getErrorMessage)(e)}`); + return void 0; + } + } + function tryCreateSpan(tracingClient, request, spanAttributes) { + try { + const { span, updatedOptions } = tracingClient.startSpan( + `HTTP ${request.method}`, + { tracingOptions: request.tracingOptions }, + { + spanKind: "client", + spanAttributes + } + ); + if (!span.isRecording()) { + span.end(); + return void 0; + } + const headers = tracingClient.createRequestHeaders( + updatedOptions.tracingOptions.tracingContext + ); + for (const [key, value] of Object.entries(headers)) { + request.headers.set(key, value); + } + return { span, tracingContext: updatedOptions.tracingOptions.tracingContext }; + } catch (e) { + import_log.logger.warning(`Skipping creating a tracing span due to an error: ${(0, import_core_util.getErrorMessage)(e)}`); + return void 0; + } + } + function tryProcessError(span, error) { + try { + span.setStatus({ + status: "error", + error: (0, import_core_util.isError)(error) ? error : void 0 + }); + if ((0, import_restError.isRestError)(error) && error.statusCode) { + span.setAttribute("http.status_code", error.statusCode); + } + span.end(); + } catch (e) { + import_log.logger.warning(`Skipping tracing span processing due to an error: ${(0, import_core_util.getErrorMessage)(e)}`); + } + } + function tryProcessResponse(span, response) { + try { + span.setAttribute("http.status_code", response.status); + const serviceRequestId = response.headers.get("x-ms-request-id"); + if (serviceRequestId) { + span.setAttribute("serviceRequestId", serviceRequestId); + } + if (response.status >= 400) { + span.setStatus({ + status: "error" + }); + } + span.end(); + } catch (e) { + import_log.logger.warning(`Skipping tracing span processing due to an error: ${(0, import_core_util.getErrorMessage)(e)}`); + } + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/util/wrapAbortSignal.js +var require_wrapAbortSignal = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/util/wrapAbortSignal.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var wrapAbortSignal_exports = {}; + __export2(wrapAbortSignal_exports, { + wrapAbortSignalLike: () => wrapAbortSignalLike + }); + module2.exports = __toCommonJS2(wrapAbortSignal_exports); + function wrapAbortSignalLike(abortSignalLike) { + if (abortSignalLike instanceof AbortSignal) { + return { abortSignal: abortSignalLike }; + } + if (abortSignalLike.aborted) { + return { abortSignal: AbortSignal.abort(abortSignalLike.reason) }; + } + const controller = new AbortController(); + let needsCleanup = true; + function cleanup() { + if (needsCleanup) { + abortSignalLike.removeEventListener("abort", listener); + needsCleanup = false; + } + } + function listener() { + controller.abort(abortSignalLike.reason); + cleanup(); + } + abortSignalLike.addEventListener("abort", listener); + return { abortSignal: controller.signal, cleanup }; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/wrapAbortSignalLikePolicy.js +var require_wrapAbortSignalLikePolicy = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/wrapAbortSignalLikePolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var wrapAbortSignalLikePolicy_exports = {}; + __export2(wrapAbortSignalLikePolicy_exports, { + wrapAbortSignalLikePolicy: () => wrapAbortSignalLikePolicy, + wrapAbortSignalLikePolicyName: () => wrapAbortSignalLikePolicyName + }); + module2.exports = __toCommonJS2(wrapAbortSignalLikePolicy_exports); + var import_wrapAbortSignal = require_wrapAbortSignal(); + var wrapAbortSignalLikePolicyName = "wrapAbortSignalLikePolicy"; + function wrapAbortSignalLikePolicy() { + return { + name: wrapAbortSignalLikePolicyName, + sendRequest: async (request, next) => { + if (!request.abortSignal) { + return next(request); + } + const { abortSignal, cleanup } = (0, import_wrapAbortSignal.wrapAbortSignalLike)(request.abortSignal); + request.abortSignal = abortSignal; + try { + return await next(request); + } finally { + cleanup?.(); + } + } + }; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/createPipelineFromOptions.js +var require_createPipelineFromOptions2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/createPipelineFromOptions.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var createPipelineFromOptions_exports = {}; + __export2(createPipelineFromOptions_exports, { + createPipelineFromOptions: () => createPipelineFromOptions2 + }); + module2.exports = __toCommonJS2(createPipelineFromOptions_exports); + var import_logPolicy = require_logPolicy2(); + var import_pipeline = require_pipeline2(); + var import_redirectPolicy = require_redirectPolicy2(); + var import_userAgentPolicy = require_userAgentPolicy2(); + var import_multipartPolicy = require_multipartPolicy2(); + var import_decompressResponsePolicy = require_decompressResponsePolicy2(); + var import_defaultRetryPolicy = require_defaultRetryPolicy2(); + var import_formDataPolicy = require_formDataPolicy2(); + var import_core_util = require_commonjs4(); + var import_proxyPolicy = require_proxyPolicy2(); + var import_setClientRequestIdPolicy = require_setClientRequestIdPolicy(); + var import_agentPolicy = require_agentPolicy2(); + var import_tlsPolicy = require_tlsPolicy2(); + var import_tracingPolicy = require_tracingPolicy(); + var import_wrapAbortSignalLikePolicy = require_wrapAbortSignalLikePolicy(); + function createPipelineFromOptions2(options) { + const pipeline = (0, import_pipeline.createEmptyPipeline)(); + if (import_core_util.isNodeLike) { + if (options.agent) { + pipeline.addPolicy((0, import_agentPolicy.agentPolicy)(options.agent)); + } + if (options.tlsOptions) { + pipeline.addPolicy((0, import_tlsPolicy.tlsPolicy)(options.tlsOptions)); + } + pipeline.addPolicy((0, import_proxyPolicy.proxyPolicy)(options.proxyOptions)); + pipeline.addPolicy((0, import_decompressResponsePolicy.decompressResponsePolicy)()); + } + pipeline.addPolicy((0, import_wrapAbortSignalLikePolicy.wrapAbortSignalLikePolicy)()); + pipeline.addPolicy((0, import_formDataPolicy.formDataPolicy)(), { beforePolicies: [import_multipartPolicy.multipartPolicyName] }); + pipeline.addPolicy((0, import_userAgentPolicy.userAgentPolicy)(options.userAgentOptions)); + pipeline.addPolicy((0, import_setClientRequestIdPolicy.setClientRequestIdPolicy)(options.telemetryOptions?.clientRequestIdHeaderName)); + pipeline.addPolicy((0, import_multipartPolicy.multipartPolicy)(), { afterPhase: "Deserialize" }); + pipeline.addPolicy((0, import_defaultRetryPolicy.defaultRetryPolicy)(options.retryOptions), { phase: "Retry" }); + pipeline.addPolicy((0, import_tracingPolicy.tracingPolicy)({ ...options.userAgentOptions, ...options.loggingOptions }), { + afterPhase: "Retry" + }); + if (import_core_util.isNodeLike) { + pipeline.addPolicy((0, import_redirectPolicy.redirectPolicy)(options.redirectOptions), { afterPhase: "Retry" }); + } + pipeline.addPolicy((0, import_logPolicy.logPolicy)(options.loggingOptions), { afterPhase: "Sign" }); + return pipeline; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/defaultHttpClient.js +var require_defaultHttpClient2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/defaultHttpClient.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var defaultHttpClient_exports = {}; + __export2(defaultHttpClient_exports, { + createDefaultHttpClient: () => createDefaultHttpClient2 + }); + module2.exports = __toCommonJS2(defaultHttpClient_exports); + var import_ts_http_runtime = require_commonjs(); + var import_wrapAbortSignal = require_wrapAbortSignal(); + function createDefaultHttpClient2() { + const client = (0, import_ts_http_runtime.createDefaultHttpClient)(); + return { + async sendRequest(request) { + const { abortSignal, cleanup } = request.abortSignal ? (0, import_wrapAbortSignal.wrapAbortSignalLike)(request.abortSignal) : {}; + try { + request.abortSignal = abortSignal; + return await client.sendRequest(request); + } finally { + cleanup?.(); + } + } + }; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/httpHeaders.js +var require_httpHeaders2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/httpHeaders.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var httpHeaders_exports = {}; + __export2(httpHeaders_exports, { + createHttpHeaders: () => createHttpHeaders2 + }); + module2.exports = __toCommonJS2(httpHeaders_exports); + var import_ts_http_runtime = require_commonjs(); + function createHttpHeaders2(rawHeaders) { + return (0, import_ts_http_runtime.createHttpHeaders)(rawHeaders); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/pipelineRequest.js +var require_pipelineRequest2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/pipelineRequest.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var pipelineRequest_exports = {}; + __export2(pipelineRequest_exports, { + createPipelineRequest: () => createPipelineRequest2 + }); + module2.exports = __toCommonJS2(pipelineRequest_exports); + var import_ts_http_runtime = require_commonjs(); + function createPipelineRequest2(options) { + return (0, import_ts_http_runtime.createPipelineRequest)(options); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/exponentialRetryPolicy.js +var require_exponentialRetryPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/exponentialRetryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var exponentialRetryPolicy_exports = {}; + __export2(exponentialRetryPolicy_exports, { + exponentialRetryPolicy: () => exponentialRetryPolicy2, + exponentialRetryPolicyName: () => exponentialRetryPolicyName2 + }); + module2.exports = __toCommonJS2(exponentialRetryPolicy_exports); + var import_policies = require_internal4(); + var exponentialRetryPolicyName2 = import_policies.exponentialRetryPolicyName; + function exponentialRetryPolicy2(options = {}) { + return (0, import_policies.exponentialRetryPolicy)(options); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/systemErrorRetryPolicy.js +var require_systemErrorRetryPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/systemErrorRetryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var systemErrorRetryPolicy_exports = {}; + __export2(systemErrorRetryPolicy_exports, { + systemErrorRetryPolicy: () => systemErrorRetryPolicy2, + systemErrorRetryPolicyName: () => systemErrorRetryPolicyName2 + }); + module2.exports = __toCommonJS2(systemErrorRetryPolicy_exports); + var import_policies = require_internal4(); + var systemErrorRetryPolicyName2 = import_policies.systemErrorRetryPolicyName; + function systemErrorRetryPolicy2(options = {}) { + return (0, import_policies.systemErrorRetryPolicy)(options); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/throttlingRetryPolicy.js +var require_throttlingRetryPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/throttlingRetryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var throttlingRetryPolicy_exports = {}; + __export2(throttlingRetryPolicy_exports, { + throttlingRetryPolicy: () => throttlingRetryPolicy2, + throttlingRetryPolicyName: () => throttlingRetryPolicyName2 + }); + module2.exports = __toCommonJS2(throttlingRetryPolicy_exports); + var import_policies = require_internal4(); + var throttlingRetryPolicyName2 = import_policies.throttlingRetryPolicyName; + function throttlingRetryPolicy2(options = {}) { + return (0, import_policies.throttlingRetryPolicy)(options); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/retryPolicy.js +var require_retryPolicy2 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/retryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var retryPolicy_exports = {}; + __export2(retryPolicy_exports, { + retryPolicy: () => retryPolicy2 + }); + module2.exports = __toCommonJS2(retryPolicy_exports); + var import_logger = require_commonjs2(); + var import_constants = require_constants2(); + var import_policies = require_internal4(); + var retryPolicyLogger = (0, import_logger.createClientLogger)("core-rest-pipeline retryPolicy"); + function retryPolicy2(strategies, options = { maxRetries: import_constants.DEFAULT_RETRY_POLICY_COUNT }) { + return (0, import_policies.retryPolicy)(strategies, { + logger: retryPolicyLogger, + ...options + }); + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js +var require_tokenCycler = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var tokenCycler_exports = {}; + __export2(tokenCycler_exports, { + DEFAULT_CYCLER_OPTIONS: () => DEFAULT_CYCLER_OPTIONS, + createTokenCycler: () => createTokenCycler + }); + module2.exports = __toCommonJS2(tokenCycler_exports); + var import_core_util = require_commonjs4(); + var DEFAULT_CYCLER_OPTIONS = { + forcedRefreshWindowInMs: 1e3, + // Force waiting for a refresh 1s before the token expires + retryIntervalInMs: 3e3, + // Allow refresh attempts every 3s + refreshWindowInMs: 1e3 * 60 * 2 + // Start refreshing 2m before expiry + }; + async function beginRefresh(getAccessToken, retryIntervalInMs, refreshTimeout) { + async function tryGetAccessToken() { + if (Date.now() < refreshTimeout) { + try { + return await getAccessToken(); + } catch { + return null; + } + } else { + const finalToken = await getAccessToken(); + if (finalToken === null) { + throw new Error("Failed to refresh access token."); + } + return finalToken; + } + } + let token = await tryGetAccessToken(); + while (token === null) { + await (0, import_core_util.delay)(retryIntervalInMs); + token = await tryGetAccessToken(); + } + return token; + } + function createTokenCycler(credential, tokenCyclerOptions) { + let refreshWorker = null; + let token = null; + let tenantId; + const options = { + ...DEFAULT_CYCLER_OPTIONS, + ...tokenCyclerOptions + }; + const cycler = { + /** + * Produces true if a refresh job is currently in progress. + */ + get isRefreshing() { + return refreshWorker !== null; + }, + /** + * Produces true if the cycler SHOULD refresh (we are within the refresh + * window and not already refreshing) + */ + get shouldRefresh() { + if (cycler.isRefreshing) { + return false; + } + if (token?.refreshAfterTimestamp && token.refreshAfterTimestamp < Date.now()) { + return true; + } + return (token?.expiresOnTimestamp ?? 0) - options.refreshWindowInMs < Date.now(); + }, + /** + * Produces true if the cycler MUST refresh (null or nearly-expired + * token). + */ + get mustRefresh() { + return token === null || token.expiresOnTimestamp - options.forcedRefreshWindowInMs < Date.now(); + } + }; + function refresh(scopes, getTokenOptions) { + if (!cycler.isRefreshing) { + const tryGetAccessToken = () => credential.getToken(scopes, getTokenOptions); + refreshWorker = beginRefresh( + tryGetAccessToken, + options.retryIntervalInMs, + // If we don't have a token, then we should timeout immediately + token?.expiresOnTimestamp ?? Date.now() + ).then((_token) => { + refreshWorker = null; + token = _token; + tenantId = getTokenOptions.tenantId; + return token; + }).catch((reason) => { + refreshWorker = null; + token = null; + tenantId = void 0; + throw reason; + }); + } + return refreshWorker; + } + return async (scopes, tokenOptions) => { + const hasClaimChallenge = Boolean(tokenOptions.claims); + const tenantIdChanged = tenantId !== tokenOptions.tenantId; + if (hasClaimChallenge) { + token = null; + } + const mustRefresh = tenantIdChanged || hasClaimChallenge || cycler.mustRefresh; + if (mustRefresh) { + return refresh(scopes, tokenOptions); + } + if (cycler.shouldRefresh) { + refresh(scopes, tokenOptions); + } + return token; + }; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js +var require_bearerTokenAuthenticationPolicy = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var bearerTokenAuthenticationPolicy_exports = {}; + __export2(bearerTokenAuthenticationPolicy_exports, { + bearerTokenAuthenticationPolicy: () => bearerTokenAuthenticationPolicy2, + bearerTokenAuthenticationPolicyName: () => bearerTokenAuthenticationPolicyName2, + parseChallenges: () => parseChallenges + }); + module2.exports = __toCommonJS2(bearerTokenAuthenticationPolicy_exports); + var import_tokenCycler = require_tokenCycler(); + var import_log = require_log3(); + var import_restError = require_restError3(); + var bearerTokenAuthenticationPolicyName2 = "bearerTokenAuthenticationPolicy"; + async function trySendRequest(request, next) { + try { + return [await next(request), void 0]; + } catch (e) { + if ((0, import_restError.isRestError)(e) && e.response) { + return [e.response, e]; + } else { + throw e; + } + } + } + async function defaultAuthorizeRequest(options) { + const { scopes, getAccessToken, request } = options; + const getTokenOptions = { + abortSignal: request.abortSignal, + tracingOptions: request.tracingOptions, + enableCae: true + }; + const accessToken = await getAccessToken(scopes, getTokenOptions); + if (accessToken) { + options.request.headers.set("Authorization", `Bearer ${accessToken.token}`); + } + } + function isChallengeResponse(response) { + return response.status === 401 && response.headers.has("WWW-Authenticate"); + } + async function authorizeRequestOnCaeChallenge(onChallengeOptions, caeClaims) { + const { scopes } = onChallengeOptions; + const accessToken = await onChallengeOptions.getAccessToken(scopes, { + enableCae: true, + claims: caeClaims + }); + if (!accessToken) { + return false; + } + onChallengeOptions.request.headers.set( + "Authorization", + `${accessToken.tokenType ?? "Bearer"} ${accessToken.token}` + ); + return true; + } + function bearerTokenAuthenticationPolicy2(options) { + const { credential, scopes, challengeCallbacks } = options; + const logger = options.logger || import_log.logger; + const callbacks = { + authorizeRequest: challengeCallbacks?.authorizeRequest?.bind(challengeCallbacks) ?? defaultAuthorizeRequest, + authorizeRequestOnChallenge: challengeCallbacks?.authorizeRequestOnChallenge?.bind(challengeCallbacks) + }; + const getAccessToken = credential ? (0, import_tokenCycler.createTokenCycler)( + credential + /* , options */ + ) : () => Promise.resolve(null); + return { + name: bearerTokenAuthenticationPolicyName2, + /** + * If there's no challenge parameter: + * - It will try to retrieve the token using the cache, or the credential's getToken. + * - Then it will try the next policy with or without the retrieved token. + * + * It uses the challenge parameters to: + * - Skip a first attempt to get the token from the credential if there's no cached token, + * since it expects the token to be retrievable only after the challenge. + * - Prepare the outgoing request if the `prepareRequest` method has been provided. + * - Send an initial request to receive the challenge if it fails. + * - Process a challenge if the response contains it. + * - Retrieve a token with the challenge information, then re-send the request. + */ + async sendRequest(request, next) { + if (!request.url.toLowerCase().startsWith("https://")) { + throw new Error( + "Bearer token authentication is not permitted for non-TLS protected (non-https) URLs." + ); + } + await callbacks.authorizeRequest({ + scopes: Array.isArray(scopes) ? scopes : [scopes], + request, + getAccessToken, + logger + }); + let response; + let error; + let shouldSendRequest; + [response, error] = await trySendRequest(request, next); + if (isChallengeResponse(response)) { + let claims = getCaeChallengeClaims(response.headers.get("WWW-Authenticate")); + if (claims) { + let parsedClaim; + try { + parsedClaim = atob(claims); + } catch (e) { + logger.warning( + `The WWW-Authenticate header contains "claims" that cannot be parsed. Unable to perform the Continuous Access Evaluation authentication flow. Unparsable claims: ${claims}` + ); + return response; + } + shouldSendRequest = await authorizeRequestOnCaeChallenge( + { + scopes: Array.isArray(scopes) ? scopes : [scopes], + response, + request, + getAccessToken, + logger + }, + parsedClaim + ); + if (shouldSendRequest) { + [response, error] = await trySendRequest(request, next); + } + } else if (callbacks.authorizeRequestOnChallenge) { + shouldSendRequest = await callbacks.authorizeRequestOnChallenge({ + scopes: Array.isArray(scopes) ? scopes : [scopes], + request, + response, + getAccessToken, + logger + }); + if (shouldSendRequest) { + [response, error] = await trySendRequest(request, next); + } + if (isChallengeResponse(response)) { + claims = getCaeChallengeClaims(response.headers.get("WWW-Authenticate")); + if (claims) { + let parsedClaim; + try { + parsedClaim = atob(claims); + } catch (e) { + logger.warning( + `The WWW-Authenticate header contains "claims" that cannot be parsed. Unable to perform the Continuous Access Evaluation authentication flow. Unparsable claims: ${claims}` + ); + return response; + } + shouldSendRequest = await authorizeRequestOnCaeChallenge( + { + scopes: Array.isArray(scopes) ? scopes : [scopes], + response, + request, + getAccessToken, + logger + }, + parsedClaim + ); + if (shouldSendRequest) { + [response, error] = await trySendRequest(request, next); + } + } + } + } + } + if (error) { + throw error; + } else { + return response; + } + } + }; + } + function parseChallenges(challenges) { + const challengeRegex = /(\w+)\s+((?:\w+=(?:"[^"]*"|[^,]*),?\s*)+)/g; + const paramRegex = /(\w+)="([^"]*)"/g; + const parsedChallenges = []; + let match; + while ((match = challengeRegex.exec(challenges)) !== null) { + const scheme = match[1]; + const paramsString = match[2]; + const params = {}; + let paramMatch; + while ((paramMatch = paramRegex.exec(paramsString)) !== null) { + params[paramMatch[1]] = paramMatch[2]; + } + parsedChallenges.push({ scheme, params }); + } + return parsedChallenges; + } + function getCaeChallengeClaims(challenges) { + if (!challenges) { + return; + } + const parsedChallenges = parseChallenges(challenges); + return parsedChallenges.find( + (x) => x.scheme === "Bearer" && x.params.claims && x.params.error === "insufficient_claims" + )?.params.claims; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/ndJsonPolicy.js +var require_ndJsonPolicy = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/ndJsonPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var ndJsonPolicy_exports = {}; + __export2(ndJsonPolicy_exports, { + ndJsonPolicy: () => ndJsonPolicy2, + ndJsonPolicyName: () => ndJsonPolicyName2 + }); + module2.exports = __toCommonJS2(ndJsonPolicy_exports); + var ndJsonPolicyName2 = "ndJsonPolicy"; + function ndJsonPolicy2() { + return { + name: ndJsonPolicyName2, + async sendRequest(request, next) { + if (typeof request.body === "string" && request.body.startsWith("[")) { + const body = JSON.parse(request.body); + if (Array.isArray(body)) { + request.body = body.map((item) => JSON.stringify(item) + "\n").join(""); + } + } + return next(request); + } + }; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/auxiliaryAuthenticationHeaderPolicy.js +var require_auxiliaryAuthenticationHeaderPolicy = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/auxiliaryAuthenticationHeaderPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var auxiliaryAuthenticationHeaderPolicy_exports = {}; + __export2(auxiliaryAuthenticationHeaderPolicy_exports, { + auxiliaryAuthenticationHeaderPolicy: () => auxiliaryAuthenticationHeaderPolicy2, + auxiliaryAuthenticationHeaderPolicyName: () => auxiliaryAuthenticationHeaderPolicyName2 + }); + module2.exports = __toCommonJS2(auxiliaryAuthenticationHeaderPolicy_exports); + var import_tokenCycler = require_tokenCycler(); + var import_log = require_log3(); + var auxiliaryAuthenticationHeaderPolicyName2 = "auxiliaryAuthenticationHeaderPolicy"; + var AUTHORIZATION_AUXILIARY_HEADER = "x-ms-authorization-auxiliary"; + async function sendAuthorizeRequest(options) { + const { scopes, getAccessToken, request } = options; + const getTokenOptions = { + abortSignal: request.abortSignal, + tracingOptions: request.tracingOptions + }; + return (await getAccessToken(scopes, getTokenOptions))?.token ?? ""; + } + function auxiliaryAuthenticationHeaderPolicy2(options) { + const { credentials, scopes } = options; + const logger = options.logger || import_log.logger; + const tokenCyclerMap = /* @__PURE__ */ new WeakMap(); + return { + name: auxiliaryAuthenticationHeaderPolicyName2, + async sendRequest(request, next) { + if (!request.url.toLowerCase().startsWith("https://")) { + throw new Error( + "Bearer token authentication for auxiliary header is not permitted for non-TLS protected (non-https) URLs." + ); + } + if (!credentials || credentials.length === 0) { + logger.info( + `${auxiliaryAuthenticationHeaderPolicyName2} header will not be set due to empty credentials.` + ); + return next(request); + } + const tokenPromises = []; + for (const credential of credentials) { + let getAccessToken = tokenCyclerMap.get(credential); + if (!getAccessToken) { + getAccessToken = (0, import_tokenCycler.createTokenCycler)(credential); + tokenCyclerMap.set(credential, getAccessToken); + } + tokenPromises.push( + sendAuthorizeRequest({ + scopes: Array.isArray(scopes) ? scopes : [scopes], + request, + getAccessToken, + logger + }) + ); + } + const auxiliaryTokens = (await Promise.all(tokenPromises)).filter((token) => Boolean(token)); + if (auxiliaryTokens.length === 0) { + logger.warning( + `None of the auxiliary tokens are valid. ${AUTHORIZATION_AUXILIARY_HEADER} header will not be set.` + ); + return next(request); + } + request.headers.set( + AUTHORIZATION_AUXILIARY_HEADER, + auxiliaryTokens.map((token) => `Bearer ${token}`).join(", ") + ); + return next(request); + } + }; + } + } +}); + +// node_modules/@azure/core-rest-pipeline/dist/commonjs/index.js +var require_commonjs6 = __commonJS({ + "node_modules/@azure/core-rest-pipeline/dist/commonjs/index.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var src_exports = {}; + __export2(src_exports, { + RestError: () => import_restError.RestError, + agentPolicy: () => import_agentPolicy.agentPolicy, + agentPolicyName: () => import_agentPolicy.agentPolicyName, + auxiliaryAuthenticationHeaderPolicy: () => import_auxiliaryAuthenticationHeaderPolicy.auxiliaryAuthenticationHeaderPolicy, + auxiliaryAuthenticationHeaderPolicyName: () => import_auxiliaryAuthenticationHeaderPolicy.auxiliaryAuthenticationHeaderPolicyName, + bearerTokenAuthenticationPolicy: () => import_bearerTokenAuthenticationPolicy.bearerTokenAuthenticationPolicy, + bearerTokenAuthenticationPolicyName: () => import_bearerTokenAuthenticationPolicy.bearerTokenAuthenticationPolicyName, + createDefaultHttpClient: () => import_defaultHttpClient.createDefaultHttpClient, + createEmptyPipeline: () => import_pipeline.createEmptyPipeline, + createFile: () => import_file.createFile, + createFileFromStream: () => import_file.createFileFromStream, + createHttpHeaders: () => import_httpHeaders.createHttpHeaders, + createPipelineFromOptions: () => import_createPipelineFromOptions.createPipelineFromOptions, + createPipelineRequest: () => import_pipelineRequest.createPipelineRequest, + decompressResponsePolicy: () => import_decompressResponsePolicy.decompressResponsePolicy, + decompressResponsePolicyName: () => import_decompressResponsePolicy.decompressResponsePolicyName, + defaultRetryPolicy: () => import_defaultRetryPolicy.defaultRetryPolicy, + exponentialRetryPolicy: () => import_exponentialRetryPolicy.exponentialRetryPolicy, + exponentialRetryPolicyName: () => import_exponentialRetryPolicy.exponentialRetryPolicyName, + formDataPolicy: () => import_formDataPolicy.formDataPolicy, + formDataPolicyName: () => import_formDataPolicy.formDataPolicyName, + getDefaultProxySettings: () => import_proxyPolicy.getDefaultProxySettings, + isRestError: () => import_restError.isRestError, + logPolicy: () => import_logPolicy.logPolicy, + logPolicyName: () => import_logPolicy.logPolicyName, + multipartPolicy: () => import_multipartPolicy.multipartPolicy, + multipartPolicyName: () => import_multipartPolicy.multipartPolicyName, + ndJsonPolicy: () => import_ndJsonPolicy.ndJsonPolicy, + ndJsonPolicyName: () => import_ndJsonPolicy.ndJsonPolicyName, + proxyPolicy: () => import_proxyPolicy.proxyPolicy, + proxyPolicyName: () => import_proxyPolicy.proxyPolicyName, + redirectPolicy: () => import_redirectPolicy.redirectPolicy, + redirectPolicyName: () => import_redirectPolicy.redirectPolicyName, + retryPolicy: () => import_retryPolicy.retryPolicy, + setClientRequestIdPolicy: () => import_setClientRequestIdPolicy.setClientRequestIdPolicy, + setClientRequestIdPolicyName: () => import_setClientRequestIdPolicy.setClientRequestIdPolicyName, + systemErrorRetryPolicy: () => import_systemErrorRetryPolicy.systemErrorRetryPolicy, + systemErrorRetryPolicyName: () => import_systemErrorRetryPolicy.systemErrorRetryPolicyName, + throttlingRetryPolicy: () => import_throttlingRetryPolicy.throttlingRetryPolicy, + throttlingRetryPolicyName: () => import_throttlingRetryPolicy.throttlingRetryPolicyName, + tlsPolicy: () => import_tlsPolicy.tlsPolicy, + tlsPolicyName: () => import_tlsPolicy.tlsPolicyName, + tracingPolicy: () => import_tracingPolicy.tracingPolicy, + tracingPolicyName: () => import_tracingPolicy.tracingPolicyName, + userAgentPolicy: () => import_userAgentPolicy.userAgentPolicy, + userAgentPolicyName: () => import_userAgentPolicy.userAgentPolicyName + }); + module2.exports = __toCommonJS2(src_exports); + var import_pipeline = require_pipeline2(); + var import_createPipelineFromOptions = require_createPipelineFromOptions2(); + var import_defaultHttpClient = require_defaultHttpClient2(); + var import_httpHeaders = require_httpHeaders2(); + var import_pipelineRequest = require_pipelineRequest2(); + var import_restError = require_restError3(); + var import_decompressResponsePolicy = require_decompressResponsePolicy2(); + var import_exponentialRetryPolicy = require_exponentialRetryPolicy2(); + var import_setClientRequestIdPolicy = require_setClientRequestIdPolicy(); + var import_logPolicy = require_logPolicy2(); + var import_multipartPolicy = require_multipartPolicy2(); + var import_proxyPolicy = require_proxyPolicy2(); + var import_redirectPolicy = require_redirectPolicy2(); + var import_systemErrorRetryPolicy = require_systemErrorRetryPolicy2(); + var import_throttlingRetryPolicy = require_throttlingRetryPolicy2(); + var import_retryPolicy = require_retryPolicy2(); + var import_tracingPolicy = require_tracingPolicy(); + var import_defaultRetryPolicy = require_defaultRetryPolicy2(); + var import_userAgentPolicy = require_userAgentPolicy2(); + var import_tlsPolicy = require_tlsPolicy2(); + var import_formDataPolicy = require_formDataPolicy2(); + var import_bearerTokenAuthenticationPolicy = require_bearerTokenAuthenticationPolicy(); + var import_ndJsonPolicy = require_ndJsonPolicy(); + var import_auxiliaryAuthenticationHeaderPolicy = require_auxiliaryAuthenticationHeaderPolicy(); + var import_agentPolicy = require_agentPolicy2(); + var import_file = require_file(); + } +}); + +// node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/util.js +var require_util2 = __commonJS({ + "node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/util.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.HttpHeaders = exports2.toHttpHeadersLike = exports2.toWebResourceLike = exports2.toPipelineRequest = void 0; + var core_rest_pipeline_1 = require_commonjs6(); + var originalRequestSymbol = Symbol("Original PipelineRequest"); + var originalClientRequestSymbol = Symbol.for("@azure/core-client original request"); + function toPipelineRequest(webResource, options = {}) { + const compatWebResource = webResource; + const request = compatWebResource[originalRequestSymbol]; + const headers = (0, core_rest_pipeline_1.createHttpHeaders)(webResource.headers.toJson({ preserveCase: true })); + if (request) { + request.headers = headers; + return request; + } else { + const newRequest = (0, core_rest_pipeline_1.createPipelineRequest)({ + url: webResource.url, + method: webResource.method, + headers, + withCredentials: webResource.withCredentials, + timeout: webResource.timeout, + requestId: webResource.requestId, + abortSignal: webResource.abortSignal, + body: webResource.body, + formData: webResource.formData, + disableKeepAlive: !!webResource.keepAlive, + onDownloadProgress: webResource.onDownloadProgress, + onUploadProgress: webResource.onUploadProgress, + proxySettings: webResource.proxySettings, + streamResponseStatusCodes: webResource.streamResponseStatusCodes + }); + if (options.originalRequest) { + newRequest[originalClientRequestSymbol] = options.originalRequest; + } + return newRequest; + } + } + exports2.toPipelineRequest = toPipelineRequest; + function toWebResourceLike(request, options) { + var _a; + const originalRequest = (_a = options === null || options === void 0 ? void 0 : options.originalRequest) !== null && _a !== void 0 ? _a : request; + const webResource = { + url: request.url, + method: request.method, + headers: toHttpHeadersLike2(request.headers), + withCredentials: request.withCredentials, + timeout: request.timeout, + requestId: request.headers.get("x-ms-client-request-id") || request.requestId, + abortSignal: request.abortSignal, + body: request.body, + formData: request.formData, + keepAlive: !!request.disableKeepAlive, + onDownloadProgress: request.onDownloadProgress, + onUploadProgress: request.onUploadProgress, + proxySettings: request.proxySettings, + streamResponseStatusCodes: request.streamResponseStatusCodes, + clone() { + throw new Error("Cannot clone a non-proxied WebResourceLike"); + }, + prepare() { + throw new Error("WebResourceLike.prepare() is not supported by @azure/core-http-compat"); + }, + validateRequestProperties() { + } + }; + if (options === null || options === void 0 ? void 0 : options.createProxy) { + return new Proxy(webResource, { + get(target, prop, receiver) { + if (prop === originalRequestSymbol) { + return request; + } else if (prop === "clone") { + return () => { + return toWebResourceLike(toPipelineRequest(webResource, { originalRequest }), { + createProxy: true, + originalRequest + }); + }; + } + return Reflect.get(target, prop, receiver); + }, + set(target, prop, value, receiver) { + if (prop === "keepAlive") { + request.disableKeepAlive = !value; + } + const passThroughProps = [ + "url", + "method", + "withCredentials", + "timeout", + "requestId", + "abortSignal", + "body", + "formData", + "onDownloadProgress", + "onUploadProgress", + "proxySettings", + "streamResponseStatusCodes" + ]; + if (typeof prop === "string" && passThroughProps.includes(prop)) { + request[prop] = value; + } + return Reflect.set(target, prop, value, receiver); + } + }); + } else { + return webResource; + } + } + exports2.toWebResourceLike = toWebResourceLike; + function toHttpHeadersLike2(headers) { + return new HttpHeaders(headers.toJSON({ preserveCase: true })); + } + exports2.toHttpHeadersLike = toHttpHeadersLike2; + function getHeaderKey(headerName) { + return headerName.toLowerCase(); + } + var HttpHeaders = class _HttpHeaders { + constructor(rawHeaders) { + this._headersMap = {}; + if (rawHeaders) { + for (const headerName in rawHeaders) { + this.set(headerName, rawHeaders[headerName]); + } + } + } + /** + * Set a header in this collection with the provided name and value. The name is + * case-insensitive. + * @param headerName - The name of the header to set. This value is case-insensitive. + * @param headerValue - The value of the header to set. + */ + set(headerName, headerValue) { + this._headersMap[getHeaderKey(headerName)] = { + name: headerName, + value: headerValue.toString() + }; + } + /** + * Get the header value for the provided header name, or undefined if no header exists in this + * collection with the provided name. + * @param headerName - The name of the header. + */ + get(headerName) { + const header = this._headersMap[getHeaderKey(headerName)]; + return !header ? void 0 : header.value; + } + /** + * Get whether or not this header collection contains a header entry for the provided header name. + */ + contains(headerName) { + return !!this._headersMap[getHeaderKey(headerName)]; + } + /** + * Remove the header with the provided headerName. Return whether or not the header existed and + * was removed. + * @param headerName - The name of the header to remove. + */ + remove(headerName) { + const result = this.contains(headerName); + delete this._headersMap[getHeaderKey(headerName)]; + return result; + } + /** + * Get the headers that are contained this collection as an object. + */ + rawHeaders() { + return this.toJson({ preserveCase: true }); + } + /** + * Get the headers that are contained in this collection as an array. + */ + headersArray() { + const headers = []; + for (const headerKey in this._headersMap) { + headers.push(this._headersMap[headerKey]); + } + return headers; + } + /** + * Get the header names that are contained in this collection. + */ + headerNames() { + const headerNames = []; + const headers = this.headersArray(); + for (let i = 0; i < headers.length; ++i) { + headerNames.push(headers[i].name); + } + return headerNames; + } + /** + * Get the header values that are contained in this collection. + */ + headerValues() { + const headerValues = []; + const headers = this.headersArray(); + for (let i = 0; i < headers.length; ++i) { + headerValues.push(headers[i].value); + } + return headerValues; + } + /** + * Get the JSON object representation of this HTTP header collection. + */ + toJson(options = {}) { + const result = {}; + if (options.preserveCase) { + for (const headerKey in this._headersMap) { + const header = this._headersMap[headerKey]; + result[header.name] = header.value; + } + } else { + for (const headerKey in this._headersMap) { + const header = this._headersMap[headerKey]; + result[getHeaderKey(header.name)] = header.value; + } + } + return result; + } + /** + * Get the string representation of this HTTP header collection. + */ + toString() { + return JSON.stringify(this.toJson({ preserveCase: true })); + } + /** + * Create a deep clone/copy of this HttpHeaders collection. + */ + clone() { + const resultPreservingCasing = {}; + for (const headerKey in this._headersMap) { + const header = this._headersMap[headerKey]; + resultPreservingCasing[header.name] = header.value; + } + return new _HttpHeaders(resultPreservingCasing); + } + }; + exports2.HttpHeaders = HttpHeaders; + } +}); + +// node_modules/@azure/core-auth/dist/commonjs/azureKeyCredential.js +var require_azureKeyCredential = __commonJS({ + "node_modules/@azure/core-auth/dist/commonjs/azureKeyCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AzureKeyCredential = void 0; + var AzureKeyCredential = class { + _key; + /** + * The value of the key to be used in authentication + */ + get key() { + return this._key; + } + /** + * Create an instance of an AzureKeyCredential for use + * with a service client. + * + * @param key - The initial value of the key to use in authentication + */ + constructor(key) { + if (!key) { + throw new Error("key must be a non-empty string"); + } + this._key = key; + } + /** + * Change the value of the key. + * + * Updates will take effect upon the next request after + * updating the key value. + * + * @param newKey - The new key value to be used + */ + update(newKey) { + this._key = newKey; + } + }; + exports2.AzureKeyCredential = AzureKeyCredential; + } +}); + +// node_modules/@azure/core-auth/dist/commonjs/keyCredential.js +var require_keyCredential = __commonJS({ + "node_modules/@azure/core-auth/dist/commonjs/keyCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isKeyCredential = isKeyCredential; + var core_util_1 = require_commonjs4(); + function isKeyCredential(credential) { + return (0, core_util_1.isObjectWithProperties)(credential, ["key"]) && typeof credential.key === "string"; + } + } +}); + +// node_modules/@azure/core-auth/dist/commonjs/azureNamedKeyCredential.js +var require_azureNamedKeyCredential = __commonJS({ + "node_modules/@azure/core-auth/dist/commonjs/azureNamedKeyCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AzureNamedKeyCredential = void 0; + exports2.isNamedKeyCredential = isNamedKeyCredential; + var core_util_1 = require_commonjs4(); + var AzureNamedKeyCredential = class { + _key; + _name; + /** + * The value of the key to be used in authentication. + */ + get key() { + return this._key; + } + /** + * The value of the name to be used in authentication. + */ + get name() { + return this._name; + } + /** + * Create an instance of an AzureNamedKeyCredential for use + * with a service client. + * + * @param name - The initial value of the name to use in authentication. + * @param key - The initial value of the key to use in authentication. + */ + constructor(name, key) { + if (!name || !key) { + throw new TypeError("name and key must be non-empty strings"); + } + this._name = name; + this._key = key; + } + /** + * Change the value of the key. + * + * Updates will take effect upon the next request after + * updating the key value. + * + * @param newName - The new name value to be used. + * @param newKey - The new key value to be used. + */ + update(newName, newKey) { + if (!newName || !newKey) { + throw new TypeError("newName and newKey must be non-empty strings"); + } + this._name = newName; + this._key = newKey; + } + }; + exports2.AzureNamedKeyCredential = AzureNamedKeyCredential; + function isNamedKeyCredential(credential) { + return (0, core_util_1.isObjectWithProperties)(credential, ["name", "key"]) && typeof credential.key === "string" && typeof credential.name === "string"; + } + } +}); + +// node_modules/@azure/core-auth/dist/commonjs/azureSASCredential.js +var require_azureSASCredential = __commonJS({ + "node_modules/@azure/core-auth/dist/commonjs/azureSASCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AzureSASCredential = void 0; + exports2.isSASCredential = isSASCredential; + var core_util_1 = require_commonjs4(); + var AzureSASCredential = class { + _signature; + /** + * The value of the shared access signature to be used in authentication + */ + get signature() { + return this._signature; + } + /** + * Create an instance of an AzureSASCredential for use + * with a service client. + * + * @param signature - The initial value of the shared access signature to use in authentication + */ + constructor(signature) { + if (!signature) { + throw new Error("shared access signature must be a non-empty string"); + } + this._signature = signature; + } + /** + * Change the value of the signature. + * + * Updates will take effect upon the next request after + * updating the signature value. + * + * @param newSignature - The new shared access signature value to be used + */ + update(newSignature) { + if (!newSignature) { + throw new Error("shared access signature must be a non-empty string"); + } + this._signature = newSignature; + } + }; + exports2.AzureSASCredential = AzureSASCredential; + function isSASCredential(credential) { + return (0, core_util_1.isObjectWithProperties)(credential, ["signature"]) && typeof credential.signature === "string"; + } + } +}); + +// node_modules/@azure/core-auth/dist/commonjs/tokenCredential.js +var require_tokenCredential = __commonJS({ + "node_modules/@azure/core-auth/dist/commonjs/tokenCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isBearerToken = isBearerToken; + exports2.isPopToken = isPopToken; + exports2.isTokenCredential = isTokenCredential; + function isBearerToken(accessToken) { + return !accessToken.tokenType || accessToken.tokenType === "Bearer"; + } + function isPopToken(accessToken) { + return accessToken.tokenType === "pop"; + } + function isTokenCredential(credential) { + const castCredential = credential; + return castCredential && typeof castCredential.getToken === "function" && (castCredential.signRequest === void 0 || castCredential.getToken.length > 0); + } + } +}); + +// node_modules/@azure/core-auth/dist/commonjs/index.js +var require_commonjs7 = __commonJS({ + "node_modules/@azure/core-auth/dist/commonjs/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isTokenCredential = exports2.isSASCredential = exports2.AzureSASCredential = exports2.isNamedKeyCredential = exports2.AzureNamedKeyCredential = exports2.isKeyCredential = exports2.AzureKeyCredential = void 0; + var azureKeyCredential_js_1 = require_azureKeyCredential(); + Object.defineProperty(exports2, "AzureKeyCredential", { enumerable: true, get: function() { + return azureKeyCredential_js_1.AzureKeyCredential; + } }); + var keyCredential_js_1 = require_keyCredential(); + Object.defineProperty(exports2, "isKeyCredential", { enumerable: true, get: function() { + return keyCredential_js_1.isKeyCredential; + } }); + var azureNamedKeyCredential_js_1 = require_azureNamedKeyCredential(); + Object.defineProperty(exports2, "AzureNamedKeyCredential", { enumerable: true, get: function() { + return azureNamedKeyCredential_js_1.AzureNamedKeyCredential; + } }); + Object.defineProperty(exports2, "isNamedKeyCredential", { enumerable: true, get: function() { + return azureNamedKeyCredential_js_1.isNamedKeyCredential; + } }); + var azureSASCredential_js_1 = require_azureSASCredential(); + Object.defineProperty(exports2, "AzureSASCredential", { enumerable: true, get: function() { + return azureSASCredential_js_1.AzureSASCredential; + } }); + Object.defineProperty(exports2, "isSASCredential", { enumerable: true, get: function() { + return azureSASCredential_js_1.isSASCredential; + } }); + var tokenCredential_js_1 = require_tokenCredential(); + Object.defineProperty(exports2, "isTokenCredential", { enumerable: true, get: function() { + return tokenCredential_js_1.isTokenCredential; + } }); + } +}); + +// node_modules/@azure/core-client/dist/commonjs/base64.js +var require_base64 = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/base64.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.encodeString = encodeString; + exports2.encodeByteArray = encodeByteArray; + exports2.decodeString = decodeString; + exports2.decodeStringToString = decodeStringToString; + function encodeString(value) { + return Buffer.from(value).toString("base64"); + } + function encodeByteArray(value) { + const bufferValue = value instanceof Buffer ? value : Buffer.from(value.buffer); + return bufferValue.toString("base64"); + } + function decodeString(value) { + return Buffer.from(value, "base64"); + } + function decodeStringToString(value) { + return Buffer.from(value, "base64").toString(); + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/interfaces.js +var require_interfaces2 = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/interfaces.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.XML_CHARKEY = exports2.XML_ATTRKEY = void 0; + exports2.XML_ATTRKEY = "$"; + exports2.XML_CHARKEY = "_"; + } +}); + +// node_modules/@azure/core-client/dist/commonjs/utils.js +var require_utils4 = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/utils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isPrimitiveBody = isPrimitiveBody; + exports2.isDuration = isDuration; + exports2.isValidUuid = isValidUuid; + exports2.flattenResponse = flattenResponse; + function isPrimitiveBody(value, mapperTypeName) { + return mapperTypeName !== "Composite" && mapperTypeName !== "Dictionary" && (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || mapperTypeName?.match(/^(Date|DateTime|DateTimeRfc1123|UnixTime|ByteArray|Base64Url)$/i) !== null || value === void 0 || value === null); + } + var validateISODuration = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + function isDuration(value) { + return validateISODuration.test(value); + } + var validUuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/i; + function isValidUuid(uuid) { + return validUuidRegex.test(uuid); + } + function handleNullableResponseAndWrappableBody(responseObject) { + const combinedHeadersAndBody = { + ...responseObject.headers, + ...responseObject.body + }; + if (responseObject.hasNullableType && Object.getOwnPropertyNames(combinedHeadersAndBody).length === 0) { + return responseObject.shouldWrapBody ? { body: null } : null; + } else { + return responseObject.shouldWrapBody ? { + ...responseObject.headers, + body: responseObject.body + } : combinedHeadersAndBody; + } + } + function flattenResponse(fullResponse, responseSpec) { + const parsedHeaders = fullResponse.parsedHeaders; + if (fullResponse.request.method === "HEAD") { + return { + ...parsedHeaders, + body: fullResponse.parsedBody + }; + } + const bodyMapper = responseSpec && responseSpec.bodyMapper; + const isNullable = Boolean(bodyMapper?.nullable); + const expectedBodyTypeName = bodyMapper?.type.name; + if (expectedBodyTypeName === "Stream") { + return { + ...parsedHeaders, + blobBody: fullResponse.blobBody, + readableStreamBody: fullResponse.readableStreamBody + }; + } + const modelProperties = expectedBodyTypeName === "Composite" && bodyMapper.type.modelProperties || {}; + const isPageableResponse = Object.keys(modelProperties).some((k) => modelProperties[k].serializedName === ""); + if (expectedBodyTypeName === "Sequence" || isPageableResponse) { + const arrayResponse = fullResponse.parsedBody ?? []; + for (const key of Object.keys(modelProperties)) { + if (modelProperties[key].serializedName) { + arrayResponse[key] = fullResponse.parsedBody?.[key]; + } + } + if (parsedHeaders) { + for (const key of Object.keys(parsedHeaders)) { + arrayResponse[key] = parsedHeaders[key]; + } + } + return isNullable && !fullResponse.parsedBody && !parsedHeaders && Object.getOwnPropertyNames(modelProperties).length === 0 ? null : arrayResponse; + } + return handleNullableResponseAndWrappableBody({ + body: fullResponse.parsedBody, + headers: parsedHeaders, + hasNullableType: isNullable, + shouldWrapBody: isPrimitiveBody(fullResponse.parsedBody, expectedBodyTypeName) + }); + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/serializer.js +var require_serializer = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/serializer.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MapperTypeNames = void 0; + exports2.createSerializer = createSerializer; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var base64 = tslib_1.__importStar(require_base64()); + var interfaces_js_1 = require_interfaces2(); + var utils_js_1 = require_utils4(); + var SerializerImpl = class { + modelMappers; + isXML; + constructor(modelMappers = {}, isXML = false) { + this.modelMappers = modelMappers; + this.isXML = isXML; + } + /** + * @deprecated Removing the constraints validation on client side. + */ + validateConstraints(mapper, value, objectName) { + const failValidation = (constraintName, constraintValue) => { + throw new Error(`"${objectName}" with value "${value}" should satisfy the constraint "${constraintName}": ${constraintValue}.`); + }; + if (mapper.constraints && value !== void 0 && value !== null) { + const { ExclusiveMaximum, ExclusiveMinimum, InclusiveMaximum, InclusiveMinimum, MaxItems, MaxLength, MinItems, MinLength, MultipleOf, Pattern, UniqueItems } = mapper.constraints; + if (ExclusiveMaximum !== void 0 && value >= ExclusiveMaximum) { + failValidation("ExclusiveMaximum", ExclusiveMaximum); + } + if (ExclusiveMinimum !== void 0 && value <= ExclusiveMinimum) { + failValidation("ExclusiveMinimum", ExclusiveMinimum); + } + if (InclusiveMaximum !== void 0 && value > InclusiveMaximum) { + failValidation("InclusiveMaximum", InclusiveMaximum); + } + if (InclusiveMinimum !== void 0 && value < InclusiveMinimum) { + failValidation("InclusiveMinimum", InclusiveMinimum); + } + if (MaxItems !== void 0 && value.length > MaxItems) { + failValidation("MaxItems", MaxItems); + } + if (MaxLength !== void 0 && value.length > MaxLength) { + failValidation("MaxLength", MaxLength); + } + if (MinItems !== void 0 && value.length < MinItems) { + failValidation("MinItems", MinItems); + } + if (MinLength !== void 0 && value.length < MinLength) { + failValidation("MinLength", MinLength); + } + if (MultipleOf !== void 0 && value % MultipleOf !== 0) { + failValidation("MultipleOf", MultipleOf); + } + if (Pattern) { + const pattern = typeof Pattern === "string" ? new RegExp(Pattern) : Pattern; + if (typeof value !== "string" || value.match(pattern) === null) { + failValidation("Pattern", Pattern); + } + } + if (UniqueItems && value.some((item, i, ar) => ar.indexOf(item) !== i)) { + failValidation("UniqueItems", UniqueItems); + } + } + } + /** + * Serialize the given object based on its metadata defined in the mapper + * + * @param mapper - The mapper which defines the metadata of the serializable object + * + * @param object - A valid Javascript object to be serialized + * + * @param objectName - Name of the serialized object + * + * @param options - additional options to serialization + * + * @returns A valid serialized Javascript object + */ + serialize(mapper, object, objectName, options = { xml: {} }) { + const updatedOptions = { + xml: { + rootName: options.xml.rootName ?? "", + includeRoot: options.xml.includeRoot ?? false, + xmlCharKey: options.xml.xmlCharKey ?? interfaces_js_1.XML_CHARKEY + } + }; + let payload = {}; + const mapperType = mapper.type.name; + if (!objectName) { + objectName = mapper.serializedName; + } + if (mapperType.match(/^Sequence$/i) !== null) { + payload = []; + } + if (mapper.isConstant) { + object = mapper.defaultValue; + } + const { required, nullable } = mapper; + if (required && nullable && object === void 0) { + throw new Error(`${objectName} cannot be undefined.`); + } + if (required && !nullable && (object === void 0 || object === null)) { + throw new Error(`${objectName} cannot be null or undefined.`); + } + if (!required && nullable === false && object === null) { + throw new Error(`${objectName} cannot be null.`); + } + if (object === void 0 || object === null) { + payload = object; + } else { + if (mapperType.match(/^any$/i) !== null) { + payload = object; + } else if (mapperType.match(/^(Number|String|Boolean|Object|Stream|Uuid)$/i) !== null) { + payload = serializeBasicTypes(mapperType, objectName, object); + } else if (mapperType.match(/^Enum$/i) !== null) { + const enumMapper = mapper; + payload = serializeEnumType(objectName, enumMapper.type.allowedValues, object); + } else if (mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123|UnixTime)$/i) !== null) { + payload = serializeDateTypes(mapperType, object, objectName); + } else if (mapperType.match(/^ByteArray$/i) !== null) { + payload = serializeByteArrayType(objectName, object); + } else if (mapperType.match(/^Base64Url$/i) !== null) { + payload = serializeBase64UrlType(objectName, object); + } else if (mapperType.match(/^Sequence$/i) !== null) { + payload = serializeSequenceType(this, mapper, object, objectName, Boolean(this.isXML), updatedOptions); + } else if (mapperType.match(/^Dictionary$/i) !== null) { + payload = serializeDictionaryType(this, mapper, object, objectName, Boolean(this.isXML), updatedOptions); + } else if (mapperType.match(/^Composite$/i) !== null) { + payload = serializeCompositeType(this, mapper, object, objectName, Boolean(this.isXML), updatedOptions); + } + } + return payload; + } + /** + * Deserialize the given object based on its metadata defined in the mapper + * + * @param mapper - The mapper which defines the metadata of the serializable object + * + * @param responseBody - A valid Javascript entity to be deserialized + * + * @param objectName - Name of the deserialized object + * + * @param options - Controls behavior of XML parser and builder. + * + * @returns A valid deserialized Javascript object + */ + deserialize(mapper, responseBody, objectName, options = { xml: {} }) { + const updatedOptions = { + xml: { + rootName: options.xml.rootName ?? "", + includeRoot: options.xml.includeRoot ?? false, + xmlCharKey: options.xml.xmlCharKey ?? interfaces_js_1.XML_CHARKEY + }, + ignoreUnknownProperties: options.ignoreUnknownProperties ?? false + }; + if (responseBody === void 0 || responseBody === null) { + if (this.isXML && mapper.type.name === "Sequence" && !mapper.xmlIsWrapped) { + responseBody = []; + } + if (mapper.defaultValue !== void 0) { + responseBody = mapper.defaultValue; + } + return responseBody; + } + let payload; + const mapperType = mapper.type.name; + if (!objectName) { + objectName = mapper.serializedName; + } + if (mapperType.match(/^Composite$/i) !== null) { + payload = deserializeCompositeType(this, mapper, responseBody, objectName, updatedOptions); + } else { + if (this.isXML) { + const xmlCharKey = updatedOptions.xml.xmlCharKey; + if (responseBody[interfaces_js_1.XML_ATTRKEY] !== void 0 && responseBody[xmlCharKey] !== void 0) { + responseBody = responseBody[xmlCharKey]; + } + } + if (mapperType.match(/^Number$/i) !== null) { + payload = parseFloat(responseBody); + if (isNaN(payload)) { + payload = responseBody; + } + } else if (mapperType.match(/^Boolean$/i) !== null) { + if (responseBody === "true") { + payload = true; + } else if (responseBody === "false") { + payload = false; + } else { + payload = responseBody; + } + } else if (mapperType.match(/^(String|Enum|Object|Stream|Uuid|TimeSpan|any)$/i) !== null) { + payload = responseBody; + } else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/i) !== null) { + payload = new Date(responseBody); + } else if (mapperType.match(/^UnixTime$/i) !== null) { + payload = unixTimeToDate(responseBody); + } else if (mapperType.match(/^ByteArray$/i) !== null) { + payload = base64.decodeString(responseBody); + } else if (mapperType.match(/^Base64Url$/i) !== null) { + payload = base64UrlToByteArray(responseBody); + } else if (mapperType.match(/^Sequence$/i) !== null) { + payload = deserializeSequenceType(this, mapper, responseBody, objectName, updatedOptions); + } else if (mapperType.match(/^Dictionary$/i) !== null) { + payload = deserializeDictionaryType(this, mapper, responseBody, objectName, updatedOptions); + } + } + if (mapper.isConstant) { + payload = mapper.defaultValue; + } + return payload; + } + }; + function createSerializer(modelMappers = {}, isXML = false) { + return new SerializerImpl(modelMappers, isXML); + } + function trimEnd(str, ch) { + let len = str.length; + while (len - 1 >= 0 && str[len - 1] === ch) { + --len; + } + return str.substr(0, len); + } + function bufferToBase64Url(buffer) { + if (!buffer) { + return void 0; + } + if (!(buffer instanceof Uint8Array)) { + throw new Error(`Please provide an input of type Uint8Array for converting to Base64Url.`); + } + const str = base64.encodeByteArray(buffer); + return trimEnd(str, "=").replace(/\+/g, "-").replace(/\//g, "_"); + } + function base64UrlToByteArray(str) { + if (!str) { + return void 0; + } + if (str && typeof str.valueOf() !== "string") { + throw new Error("Please provide an input of type string for converting to Uint8Array"); + } + str = str.replace(/-/g, "+").replace(/_/g, "/"); + return base64.decodeString(str); + } + function splitSerializeName(prop) { + const classes = []; + let partialclass = ""; + if (prop) { + const subwords = prop.split("."); + for (const item of subwords) { + if (item.charAt(item.length - 1) === "\\") { + partialclass += item.substr(0, item.length - 1) + "."; + } else { + partialclass += item; + classes.push(partialclass); + partialclass = ""; + } + } + } + return classes; + } + function dateToUnixTime(d) { + if (!d) { + return void 0; + } + if (typeof d.valueOf() === "string") { + d = new Date(d); + } + return Math.floor(d.getTime() / 1e3); + } + function unixTimeToDate(n) { + if (!n) { + return void 0; + } + return new Date(n * 1e3); + } + function serializeBasicTypes(typeName, objectName, value) { + if (value !== null && value !== void 0) { + if (typeName.match(/^Number$/i) !== null) { + if (typeof value !== "number") { + throw new Error(`${objectName} with value ${value} must be of type number.`); + } + } else if (typeName.match(/^String$/i) !== null) { + if (typeof value.valueOf() !== "string") { + throw new Error(`${objectName} with value "${value}" must be of type string.`); + } + } else if (typeName.match(/^Uuid$/i) !== null) { + if (!(typeof value.valueOf() === "string" && (0, utils_js_1.isValidUuid)(value))) { + throw new Error(`${objectName} with value "${value}" must be of type string and a valid uuid.`); + } + } else if (typeName.match(/^Boolean$/i) !== null) { + if (typeof value !== "boolean") { + throw new Error(`${objectName} with value ${value} must be of type boolean.`); + } + } else if (typeName.match(/^Stream$/i) !== null) { + const objectType = typeof value; + if (objectType !== "string" && typeof value.pipe !== "function" && // NodeJS.ReadableStream + typeof value.tee !== "function" && // browser ReadableStream + !(value instanceof ArrayBuffer) && !ArrayBuffer.isView(value) && // File objects count as a type of Blob, so we want to use instanceof explicitly + !((typeof Blob === "function" || typeof Blob === "object") && value instanceof Blob) && objectType !== "function") { + throw new Error(`${objectName} must be a string, Blob, ArrayBuffer, ArrayBufferView, ReadableStream, or () => ReadableStream.`); + } + } + } + return value; + } + function serializeEnumType(objectName, allowedValues, value) { + if (!allowedValues) { + throw new Error(`Please provide a set of allowedValues to validate ${objectName} as an Enum Type.`); + } + const isPresent = allowedValues.some((item) => { + if (typeof item.valueOf() === "string") { + return item.toLowerCase() === value.toLowerCase(); + } + return item === value; + }); + if (!isPresent) { + throw new Error(`${value} is not a valid value for ${objectName}. The valid values are: ${JSON.stringify(allowedValues)}.`); + } + return value; + } + function serializeByteArrayType(objectName, value) { + if (value !== void 0 && value !== null) { + if (!(value instanceof Uint8Array)) { + throw new Error(`${objectName} must be of type Uint8Array.`); + } + value = base64.encodeByteArray(value); + } + return value; + } + function serializeBase64UrlType(objectName, value) { + if (value !== void 0 && value !== null) { + if (!(value instanceof Uint8Array)) { + throw new Error(`${objectName} must be of type Uint8Array.`); + } + value = bufferToBase64Url(value); + } + return value; + } + function serializeDateTypes(typeName, value, objectName) { + if (value !== void 0 && value !== null) { + if (typeName.match(/^Date$/i) !== null) { + if (!(value instanceof Date || typeof value.valueOf() === "string" && !isNaN(Date.parse(value)))) { + throw new Error(`${objectName} must be an instanceof Date or a string in ISO8601 format.`); + } + value = value instanceof Date ? value.toISOString().substring(0, 10) : new Date(value).toISOString().substring(0, 10); + } else if (typeName.match(/^DateTime$/i) !== null) { + if (!(value instanceof Date || typeof value.valueOf() === "string" && !isNaN(Date.parse(value)))) { + throw new Error(`${objectName} must be an instanceof Date or a string in ISO8601 format.`); + } + value = value instanceof Date ? value.toISOString() : new Date(value).toISOString(); + } else if (typeName.match(/^DateTimeRfc1123$/i) !== null) { + if (!(value instanceof Date || typeof value.valueOf() === "string" && !isNaN(Date.parse(value)))) { + throw new Error(`${objectName} must be an instanceof Date or a string in RFC-1123 format.`); + } + value = value instanceof Date ? value.toUTCString() : new Date(value).toUTCString(); + } else if (typeName.match(/^UnixTime$/i) !== null) { + if (!(value instanceof Date || typeof value.valueOf() === "string" && !isNaN(Date.parse(value)))) { + throw new Error(`${objectName} must be an instanceof Date or a string in RFC-1123/ISO8601 format for it to be serialized in UnixTime/Epoch format.`); + } + value = dateToUnixTime(value); + } else if (typeName.match(/^TimeSpan$/i) !== null) { + if (!(0, utils_js_1.isDuration)(value)) { + throw new Error(`${objectName} must be a string in ISO 8601 format. Instead was "${value}".`); + } + } + } + return value; + } + function serializeSequenceType(serializer, mapper, object, objectName, isXml, options) { + if (!Array.isArray(object)) { + throw new Error(`${objectName} must be of type Array.`); + } + let elementType = mapper.type.element; + if (!elementType || typeof elementType !== "object") { + throw new Error(`element" metadata for an Array must be defined in the mapper and it must of type "object" in ${objectName}.`); + } + if (elementType.type.name === "Composite" && elementType.type.className) { + elementType = serializer.modelMappers[elementType.type.className] ?? elementType; + } + const tempArray = []; + for (let i = 0; i < object.length; i++) { + const serializedValue = serializer.serialize(elementType, object[i], objectName, options); + if (isXml && elementType.xmlNamespace) { + const xmlnsKey = elementType.xmlNamespacePrefix ? `xmlns:${elementType.xmlNamespacePrefix}` : "xmlns"; + if (elementType.type.name === "Composite") { + tempArray[i] = { ...serializedValue }; + tempArray[i][interfaces_js_1.XML_ATTRKEY] = { [xmlnsKey]: elementType.xmlNamespace }; + } else { + tempArray[i] = {}; + tempArray[i][options.xml.xmlCharKey] = serializedValue; + tempArray[i][interfaces_js_1.XML_ATTRKEY] = { [xmlnsKey]: elementType.xmlNamespace }; + } + } else { + tempArray[i] = serializedValue; + } + } + return tempArray; + } + function serializeDictionaryType(serializer, mapper, object, objectName, isXml, options) { + if (typeof object !== "object") { + throw new Error(`${objectName} must be of type object.`); + } + const valueType = mapper.type.value; + if (!valueType || typeof valueType !== "object") { + throw new Error(`"value" metadata for a Dictionary must be defined in the mapper and it must of type "object" in ${objectName}.`); + } + const tempDictionary = {}; + for (const key of Object.keys(object)) { + const serializedValue = serializer.serialize(valueType, object[key], objectName, options); + tempDictionary[key] = getXmlObjectValue(valueType, serializedValue, isXml, options); + } + if (isXml && mapper.xmlNamespace) { + const xmlnsKey = mapper.xmlNamespacePrefix ? `xmlns:${mapper.xmlNamespacePrefix}` : "xmlns"; + const result = tempDictionary; + result[interfaces_js_1.XML_ATTRKEY] = { [xmlnsKey]: mapper.xmlNamespace }; + return result; + } + return tempDictionary; + } + function resolveAdditionalProperties(serializer, mapper, objectName) { + const additionalProperties = mapper.type.additionalProperties; + if (!additionalProperties && mapper.type.className) { + const modelMapper = resolveReferencedMapper(serializer, mapper, objectName); + return modelMapper?.type.additionalProperties; + } + return additionalProperties; + } + function resolveReferencedMapper(serializer, mapper, objectName) { + const className = mapper.type.className; + if (!className) { + throw new Error(`Class name for model "${objectName}" is not provided in the mapper "${JSON.stringify(mapper, void 0, 2)}".`); + } + return serializer.modelMappers[className]; + } + function resolveModelProperties(serializer, mapper, objectName) { + let modelProps = mapper.type.modelProperties; + if (!modelProps) { + const modelMapper = resolveReferencedMapper(serializer, mapper, objectName); + if (!modelMapper) { + throw new Error(`mapper() cannot be null or undefined for model "${mapper.type.className}".`); + } + modelProps = modelMapper?.type.modelProperties; + if (!modelProps) { + throw new Error(`modelProperties cannot be null or undefined in the mapper "${JSON.stringify(modelMapper)}" of type "${mapper.type.className}" for object "${objectName}".`); + } + } + return modelProps; + } + function serializeCompositeType(serializer, mapper, object, objectName, isXml, options) { + if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) { + mapper = getPolymorphicMapper(serializer, mapper, object, "clientName"); + } + if (object !== void 0 && object !== null) { + const payload = {}; + const modelProps = resolveModelProperties(serializer, mapper, objectName); + for (const key of Object.keys(modelProps)) { + const propertyMapper = modelProps[key]; + if (propertyMapper.readOnly) { + continue; + } + let propName; + let parentObject = payload; + if (serializer.isXML) { + if (propertyMapper.xmlIsWrapped) { + propName = propertyMapper.xmlName; + } else { + propName = propertyMapper.xmlElementName || propertyMapper.xmlName; + } + } else { + const paths = splitSerializeName(propertyMapper.serializedName); + propName = paths.pop(); + for (const pathName of paths) { + const childObject = parentObject[pathName]; + if ((childObject === void 0 || childObject === null) && (object[key] !== void 0 && object[key] !== null || propertyMapper.defaultValue !== void 0)) { + parentObject[pathName] = {}; + } + parentObject = parentObject[pathName]; + } + } + if (parentObject !== void 0 && parentObject !== null) { + if (isXml && mapper.xmlNamespace) { + const xmlnsKey = mapper.xmlNamespacePrefix ? `xmlns:${mapper.xmlNamespacePrefix}` : "xmlns"; + parentObject[interfaces_js_1.XML_ATTRKEY] = { + ...parentObject[interfaces_js_1.XML_ATTRKEY], + [xmlnsKey]: mapper.xmlNamespace + }; + } + const propertyObjectName = propertyMapper.serializedName !== "" ? objectName + "." + propertyMapper.serializedName : objectName; + let toSerialize = object[key]; + const polymorphicDiscriminator = getPolymorphicDiscriminatorRecursively(serializer, mapper); + if (polymorphicDiscriminator && polymorphicDiscriminator.clientName === key && (toSerialize === void 0 || toSerialize === null)) { + toSerialize = mapper.serializedName; + } + const serializedValue = serializer.serialize(propertyMapper, toSerialize, propertyObjectName, options); + if (serializedValue !== void 0 && propName !== void 0 && propName !== null) { + const value = getXmlObjectValue(propertyMapper, serializedValue, isXml, options); + if (isXml && propertyMapper.xmlIsAttribute) { + parentObject[interfaces_js_1.XML_ATTRKEY] = parentObject[interfaces_js_1.XML_ATTRKEY] || {}; + parentObject[interfaces_js_1.XML_ATTRKEY][propName] = serializedValue; + } else if (isXml && propertyMapper.xmlIsWrapped) { + parentObject[propName] = { [propertyMapper.xmlElementName]: value }; + } else { + parentObject[propName] = value; + } + } + } + } + const additionalPropertiesMapper = resolveAdditionalProperties(serializer, mapper, objectName); + if (additionalPropertiesMapper) { + const propNames = Object.keys(modelProps); + for (const clientPropName in object) { + const isAdditionalProperty = propNames.every((pn) => pn !== clientPropName); + if (isAdditionalProperty) { + payload[clientPropName] = serializer.serialize(additionalPropertiesMapper, object[clientPropName], objectName + '["' + clientPropName + '"]', options); + } + } + } + return payload; + } + return object; + } + function getXmlObjectValue(propertyMapper, serializedValue, isXml, options) { + if (!isXml || !propertyMapper.xmlNamespace) { + return serializedValue; + } + const xmlnsKey = propertyMapper.xmlNamespacePrefix ? `xmlns:${propertyMapper.xmlNamespacePrefix}` : "xmlns"; + const xmlNamespace = { [xmlnsKey]: propertyMapper.xmlNamespace }; + if (["Composite"].includes(propertyMapper.type.name)) { + if (serializedValue[interfaces_js_1.XML_ATTRKEY]) { + return serializedValue; + } else { + const result2 = { ...serializedValue }; + result2[interfaces_js_1.XML_ATTRKEY] = xmlNamespace; + return result2; + } + } + const result = {}; + result[options.xml.xmlCharKey] = serializedValue; + result[interfaces_js_1.XML_ATTRKEY] = xmlNamespace; + return result; + } + function isSpecialXmlProperty(propertyName, options) { + return [interfaces_js_1.XML_ATTRKEY, options.xml.xmlCharKey].includes(propertyName); + } + function deserializeCompositeType(serializer, mapper, responseBody, objectName, options) { + const xmlCharKey = options.xml.xmlCharKey ?? interfaces_js_1.XML_CHARKEY; + if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) { + mapper = getPolymorphicMapper(serializer, mapper, responseBody, "serializedName"); + } + const modelProps = resolveModelProperties(serializer, mapper, objectName); + let instance = {}; + const handledPropertyNames = []; + for (const key of Object.keys(modelProps)) { + const propertyMapper = modelProps[key]; + const paths = splitSerializeName(modelProps[key].serializedName); + handledPropertyNames.push(paths[0]); + const { serializedName, xmlName, xmlElementName } = propertyMapper; + let propertyObjectName = objectName; + if (serializedName !== "" && serializedName !== void 0) { + propertyObjectName = objectName + "." + serializedName; + } + const headerCollectionPrefix = propertyMapper.headerCollectionPrefix; + if (headerCollectionPrefix) { + const dictionary = {}; + for (const headerKey of Object.keys(responseBody)) { + if (headerKey.startsWith(headerCollectionPrefix)) { + dictionary[headerKey.substring(headerCollectionPrefix.length)] = serializer.deserialize(propertyMapper.type.value, responseBody[headerKey], propertyObjectName, options); + } + handledPropertyNames.push(headerKey); + } + instance[key] = dictionary; + } else if (serializer.isXML) { + if (propertyMapper.xmlIsAttribute && responseBody[interfaces_js_1.XML_ATTRKEY]) { + instance[key] = serializer.deserialize(propertyMapper, responseBody[interfaces_js_1.XML_ATTRKEY][xmlName], propertyObjectName, options); + } else if (propertyMapper.xmlIsMsText) { + if (responseBody[xmlCharKey] !== void 0) { + instance[key] = responseBody[xmlCharKey]; + } else if (typeof responseBody === "string") { + instance[key] = responseBody; + } + } else { + const propertyName = xmlElementName || xmlName || serializedName; + if (propertyMapper.xmlIsWrapped) { + const wrapped = responseBody[xmlName]; + const elementList = wrapped?.[xmlElementName] ?? []; + instance[key] = serializer.deserialize(propertyMapper, elementList, propertyObjectName, options); + handledPropertyNames.push(xmlName); + } else { + const property = responseBody[propertyName]; + instance[key] = serializer.deserialize(propertyMapper, property, propertyObjectName, options); + handledPropertyNames.push(propertyName); + } + } + } else { + let propertyInstance; + let res = responseBody; + let steps = 0; + for (const item of paths) { + if (!res) + break; + steps++; + res = res[item]; + } + if (res === null && steps < paths.length) { + res = void 0; + } + propertyInstance = res; + const polymorphicDiscriminator = mapper.type.polymorphicDiscriminator; + if (polymorphicDiscriminator && key === polymorphicDiscriminator.clientName && (propertyInstance === void 0 || propertyInstance === null)) { + propertyInstance = mapper.serializedName; + } + let serializedValue; + if (Array.isArray(responseBody[key]) && modelProps[key].serializedName === "") { + propertyInstance = responseBody[key]; + const arrayInstance = serializer.deserialize(propertyMapper, propertyInstance, propertyObjectName, options); + for (const [k, v] of Object.entries(instance)) { + if (!Object.prototype.hasOwnProperty.call(arrayInstance, k)) { + arrayInstance[k] = v; + } + } + instance = arrayInstance; + } else if (propertyInstance !== void 0 || propertyMapper.defaultValue !== void 0) { + serializedValue = serializer.deserialize(propertyMapper, propertyInstance, propertyObjectName, options); + instance[key] = serializedValue; + } + } + } + const additionalPropertiesMapper = mapper.type.additionalProperties; + if (additionalPropertiesMapper) { + const isAdditionalProperty = (responsePropName) => { + for (const clientPropName in modelProps) { + const paths = splitSerializeName(modelProps[clientPropName].serializedName); + if (paths[0] === responsePropName) { + return false; + } + } + return true; + }; + for (const responsePropName in responseBody) { + if (isAdditionalProperty(responsePropName)) { + instance[responsePropName] = serializer.deserialize(additionalPropertiesMapper, responseBody[responsePropName], objectName + '["' + responsePropName + '"]', options); + } + } + } else if (responseBody && !options.ignoreUnknownProperties) { + for (const key of Object.keys(responseBody)) { + if (instance[key] === void 0 && !handledPropertyNames.includes(key) && !isSpecialXmlProperty(key, options)) { + instance[key] = responseBody[key]; + } + } + } + return instance; + } + function deserializeDictionaryType(serializer, mapper, responseBody, objectName, options) { + const value = mapper.type.value; + if (!value || typeof value !== "object") { + throw new Error(`"value" metadata for a Dictionary must be defined in the mapper and it must of type "object" in ${objectName}`); + } + if (responseBody) { + const tempDictionary = {}; + for (const key of Object.keys(responseBody)) { + tempDictionary[key] = serializer.deserialize(value, responseBody[key], objectName, options); + } + return tempDictionary; + } + return responseBody; + } + function deserializeSequenceType(serializer, mapper, responseBody, objectName, options) { + let element = mapper.type.element; + if (!element || typeof element !== "object") { + throw new Error(`element" metadata for an Array must be defined in the mapper and it must of type "object" in ${objectName}`); + } + if (responseBody) { + if (!Array.isArray(responseBody)) { + responseBody = [responseBody]; + } + if (element.type.name === "Composite" && element.type.className) { + element = serializer.modelMappers[element.type.className] ?? element; + } + const tempArray = []; + for (let i = 0; i < responseBody.length; i++) { + tempArray[i] = serializer.deserialize(element, responseBody[i], `${objectName}[${i}]`, options); + } + return tempArray; + } + return responseBody; + } + function getIndexDiscriminator(discriminators, discriminatorValue, typeName) { + const typeNamesToCheck = [typeName]; + while (typeNamesToCheck.length) { + const currentName = typeNamesToCheck.shift(); + const indexDiscriminator = discriminatorValue === currentName ? discriminatorValue : currentName + "." + discriminatorValue; + if (Object.prototype.hasOwnProperty.call(discriminators, indexDiscriminator)) { + return discriminators[indexDiscriminator]; + } else { + for (const [name, mapper] of Object.entries(discriminators)) { + if (name.startsWith(currentName + ".") && mapper.type.uberParent === currentName && mapper.type.className) { + typeNamesToCheck.push(mapper.type.className); + } + } + } + } + return void 0; + } + function getPolymorphicMapper(serializer, mapper, object, polymorphicPropertyName) { + const polymorphicDiscriminator = getPolymorphicDiscriminatorRecursively(serializer, mapper); + if (polymorphicDiscriminator) { + let discriminatorName = polymorphicDiscriminator[polymorphicPropertyName]; + if (discriminatorName) { + if (polymorphicPropertyName === "serializedName") { + discriminatorName = discriminatorName.replace(/\\/gi, ""); + } + const discriminatorValue = object[discriminatorName]; + const typeName = mapper.type.uberParent ?? mapper.type.className; + if (typeof discriminatorValue === "string" && typeName) { + const polymorphicMapper = getIndexDiscriminator(serializer.modelMappers.discriminators, discriminatorValue, typeName); + if (polymorphicMapper) { + mapper = polymorphicMapper; + } + } + } + } + return mapper; + } + function getPolymorphicDiscriminatorRecursively(serializer, mapper) { + return mapper.type.polymorphicDiscriminator || getPolymorphicDiscriminatorSafely(serializer, mapper.type.uberParent) || getPolymorphicDiscriminatorSafely(serializer, mapper.type.className); + } + function getPolymorphicDiscriminatorSafely(serializer, typeName) { + return typeName && serializer.modelMappers[typeName] && serializer.modelMappers[typeName].type.polymorphicDiscriminator; + } + exports2.MapperTypeNames = { + Base64Url: "Base64Url", + Boolean: "Boolean", + ByteArray: "ByteArray", + Composite: "Composite", + Date: "Date", + DateTime: "DateTime", + DateTimeRfc1123: "DateTimeRfc1123", + Dictionary: "Dictionary", + Enum: "Enum", + Number: "Number", + Object: "Object", + Sequence: "Sequence", + String: "String", + Stream: "Stream", + TimeSpan: "TimeSpan", + UnixTime: "UnixTime" + }; + } +}); + +// node_modules/@azure/core-client/dist/commonjs/state.js +var require_state2 = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/state.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.state = void 0; + exports2.state = { + operationRequestMap: /* @__PURE__ */ new WeakMap() + }; + } +}); + +// node_modules/@azure/core-client/dist/commonjs/operationHelpers.js +var require_operationHelpers = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/operationHelpers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getOperationArgumentValueFromParameter = getOperationArgumentValueFromParameter; + exports2.getOperationRequestInfo = getOperationRequestInfo; + var state_js_1 = require_state2(); + function getOperationArgumentValueFromParameter(operationArguments, parameter, fallbackObject) { + let parameterPath = parameter.parameterPath; + const parameterMapper = parameter.mapper; + let value; + if (typeof parameterPath === "string") { + parameterPath = [parameterPath]; + } + if (Array.isArray(parameterPath)) { + if (parameterPath.length > 0) { + if (parameterMapper.isConstant) { + value = parameterMapper.defaultValue; + } else { + let propertySearchResult = getPropertyFromParameterPath(operationArguments, parameterPath); + if (!propertySearchResult.propertyFound && fallbackObject) { + propertySearchResult = getPropertyFromParameterPath(fallbackObject, parameterPath); + } + let useDefaultValue = false; + if (!propertySearchResult.propertyFound) { + useDefaultValue = parameterMapper.required || parameterPath[0] === "options" && parameterPath.length === 2; + } + value = useDefaultValue ? parameterMapper.defaultValue : propertySearchResult.propertyValue; + } + } + } else { + if (parameterMapper.required) { + value = {}; + } + for (const propertyName in parameterPath) { + const propertyMapper = parameterMapper.type.modelProperties[propertyName]; + const propertyPath = parameterPath[propertyName]; + const propertyValue = getOperationArgumentValueFromParameter(operationArguments, { + parameterPath: propertyPath, + mapper: propertyMapper + }, fallbackObject); + if (propertyValue !== void 0) { + if (!value) { + value = {}; + } + value[propertyName] = propertyValue; + } + } + } + return value; + } + function getPropertyFromParameterPath(parent, parameterPath) { + const result = { propertyFound: false }; + let i = 0; + for (; i < parameterPath.length; ++i) { + const parameterPathPart = parameterPath[i]; + if (parent && parameterPathPart in parent) { + parent = parent[parameterPathPart]; + } else { + break; + } + } + if (i === parameterPath.length) { + result.propertyValue = parent; + result.propertyFound = true; + } + return result; + } + var originalRequestSymbol = Symbol.for("@azure/core-client original request"); + function hasOriginalRequest(request) { + return originalRequestSymbol in request; + } + function getOperationRequestInfo(request) { + if (hasOriginalRequest(request)) { + return getOperationRequestInfo(request[originalRequestSymbol]); + } + let info = state_js_1.state.operationRequestMap.get(request); + if (!info) { + info = {}; + state_js_1.state.operationRequestMap.set(request, info); + } + return info; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/deserializationPolicy.js +var require_deserializationPolicy = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/deserializationPolicy.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.deserializationPolicyName = void 0; + exports2.deserializationPolicy = deserializationPolicy; + var interfaces_js_1 = require_interfaces2(); + var core_rest_pipeline_1 = require_commonjs6(); + var serializer_js_1 = require_serializer(); + var operationHelpers_js_1 = require_operationHelpers(); + var defaultJsonContentTypes = ["application/json", "text/json"]; + var defaultXmlContentTypes = ["application/xml", "application/atom+xml"]; + exports2.deserializationPolicyName = "deserializationPolicy"; + function deserializationPolicy(options = {}) { + const jsonContentTypes = options.expectedContentTypes?.json ?? defaultJsonContentTypes; + const xmlContentTypes = options.expectedContentTypes?.xml ?? defaultXmlContentTypes; + const parseXML = options.parseXML; + const serializerOptions = options.serializerOptions; + const updatedOptions = { + xml: { + rootName: serializerOptions?.xml.rootName ?? "", + includeRoot: serializerOptions?.xml.includeRoot ?? false, + xmlCharKey: serializerOptions?.xml.xmlCharKey ?? interfaces_js_1.XML_CHARKEY + } + }; + return { + name: exports2.deserializationPolicyName, + async sendRequest(request, next) { + const response = await next(request); + return deserializeResponseBody(jsonContentTypes, xmlContentTypes, response, updatedOptions, parseXML); + } + }; + } + function getOperationResponseMap(parsedResponse) { + let result; + const request = parsedResponse.request; + const operationInfo = (0, operationHelpers_js_1.getOperationRequestInfo)(request); + const operationSpec = operationInfo?.operationSpec; + if (operationSpec) { + if (!operationInfo?.operationResponseGetter) { + result = operationSpec.responses[parsedResponse.status]; + } else { + result = operationInfo?.operationResponseGetter(operationSpec, parsedResponse); + } + } + return result; + } + function shouldDeserializeResponse(parsedResponse) { + const request = parsedResponse.request; + const operationInfo = (0, operationHelpers_js_1.getOperationRequestInfo)(request); + const shouldDeserialize = operationInfo?.shouldDeserialize; + let result; + if (shouldDeserialize === void 0) { + result = true; + } else if (typeof shouldDeserialize === "boolean") { + result = shouldDeserialize; + } else { + result = shouldDeserialize(parsedResponse); + } + return result; + } + async function deserializeResponseBody(jsonContentTypes, xmlContentTypes, response, options, parseXML) { + const parsedResponse = await parse4(jsonContentTypes, xmlContentTypes, response, options, parseXML); + if (!shouldDeserializeResponse(parsedResponse)) { + return parsedResponse; + } + const operationInfo = (0, operationHelpers_js_1.getOperationRequestInfo)(parsedResponse.request); + const operationSpec = operationInfo?.operationSpec; + if (!operationSpec || !operationSpec.responses) { + return parsedResponse; + } + const responseSpec = getOperationResponseMap(parsedResponse); + const { error, shouldReturnResponse } = handleErrorResponse(parsedResponse, operationSpec, responseSpec, options); + if (error) { + throw error; + } else if (shouldReturnResponse) { + return parsedResponse; + } + if (responseSpec) { + if (responseSpec.bodyMapper) { + let valueToDeserialize = parsedResponse.parsedBody; + if (operationSpec.isXML && responseSpec.bodyMapper.type.name === serializer_js_1.MapperTypeNames.Sequence) { + valueToDeserialize = typeof valueToDeserialize === "object" ? valueToDeserialize[responseSpec.bodyMapper.xmlElementName] : []; + } + try { + parsedResponse.parsedBody = operationSpec.serializer.deserialize(responseSpec.bodyMapper, valueToDeserialize, "operationRes.parsedBody", options); + } catch (deserializeError) { + const restError = new core_rest_pipeline_1.RestError(`Error ${deserializeError} occurred in deserializing the responseBody - ${parsedResponse.bodyAsText}`, { + statusCode: parsedResponse.status, + request: parsedResponse.request, + response: parsedResponse + }); + throw restError; + } + } else if (operationSpec.httpMethod === "HEAD") { + parsedResponse.parsedBody = response.status >= 200 && response.status < 300; + } + if (responseSpec.headersMapper) { + parsedResponse.parsedHeaders = operationSpec.serializer.deserialize(responseSpec.headersMapper, parsedResponse.headers.toJSON(), "operationRes.parsedHeaders", { xml: {}, ignoreUnknownProperties: true }); + } + } + return parsedResponse; + } + function isOperationSpecEmpty(operationSpec) { + const expectedStatusCodes = Object.keys(operationSpec.responses); + return expectedStatusCodes.length === 0 || expectedStatusCodes.length === 1 && expectedStatusCodes[0] === "default"; + } + function handleErrorResponse(parsedResponse, operationSpec, responseSpec, options) { + const isSuccessByStatus = 200 <= parsedResponse.status && parsedResponse.status < 300; + const isExpectedStatusCode = isOperationSpecEmpty(operationSpec) ? isSuccessByStatus : !!responseSpec; + if (isExpectedStatusCode) { + if (responseSpec) { + if (!responseSpec.isError) { + return { error: null, shouldReturnResponse: false }; + } + } else { + return { error: null, shouldReturnResponse: false }; + } + } + const errorResponseSpec = responseSpec ?? operationSpec.responses.default; + const initialErrorMessage = parsedResponse.request.streamResponseStatusCodes?.has(parsedResponse.status) ? `Unexpected status code: ${parsedResponse.status}` : parsedResponse.bodyAsText; + const error = new core_rest_pipeline_1.RestError(initialErrorMessage, { + statusCode: parsedResponse.status, + request: parsedResponse.request, + response: parsedResponse + }); + if (!errorResponseSpec && !(parsedResponse.parsedBody?.error?.code && parsedResponse.parsedBody?.error?.message)) { + throw error; + } + const defaultBodyMapper = errorResponseSpec?.bodyMapper; + const defaultHeadersMapper = errorResponseSpec?.headersMapper; + try { + if (parsedResponse.parsedBody) { + const parsedBody = parsedResponse.parsedBody; + let deserializedError; + if (defaultBodyMapper) { + let valueToDeserialize = parsedBody; + if (operationSpec.isXML && defaultBodyMapper.type.name === serializer_js_1.MapperTypeNames.Sequence) { + valueToDeserialize = []; + const elementName = defaultBodyMapper.xmlElementName; + if (typeof parsedBody === "object" && elementName) { + valueToDeserialize = parsedBody[elementName]; + } + } + deserializedError = operationSpec.serializer.deserialize(defaultBodyMapper, valueToDeserialize, "error.response.parsedBody", options); + } + const internalError = parsedBody.error || deserializedError || parsedBody; + error.code = internalError.code; + if (internalError.message) { + error.message = internalError.message; + } + if (defaultBodyMapper) { + error.response.parsedBody = deserializedError; + } + } + if (parsedResponse.headers && defaultHeadersMapper) { + error.response.parsedHeaders = operationSpec.serializer.deserialize(defaultHeadersMapper, parsedResponse.headers.toJSON(), "operationRes.parsedHeaders"); + } + } catch (defaultError) { + error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody - "${parsedResponse.bodyAsText}" for the default response.`; + } + return { error, shouldReturnResponse: false }; + } + async function parse4(jsonContentTypes, xmlContentTypes, operationResponse, opts, parseXML) { + if (!operationResponse.request.streamResponseStatusCodes?.has(operationResponse.status) && operationResponse.bodyAsText) { + const text = operationResponse.bodyAsText; + const contentType = operationResponse.headers.get("Content-Type") || ""; + const contentComponents = !contentType ? [] : contentType.split(";").map((component) => component.toLowerCase()); + try { + if (contentComponents.length === 0 || contentComponents.some((component) => jsonContentTypes.indexOf(component) !== -1)) { + operationResponse.parsedBody = JSON.parse(text); + return operationResponse; + } else if (contentComponents.some((component) => xmlContentTypes.indexOf(component) !== -1)) { + if (!parseXML) { + throw new Error("Parsing XML not supported."); + } + const body = await parseXML(text, opts.xml); + operationResponse.parsedBody = body; + return operationResponse; + } + } catch (err) { + const msg = `Error "${err}" occurred while parsing the response body - ${operationResponse.bodyAsText}.`; + const errCode = err.code || core_rest_pipeline_1.RestError.PARSE_ERROR; + const e = new core_rest_pipeline_1.RestError(msg, { + code: errCode, + statusCode: operationResponse.status, + request: operationResponse.request, + response: operationResponse + }); + throw e; + } + } + return operationResponse; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/interfaceHelpers.js +var require_interfaceHelpers = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/interfaceHelpers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getStreamingResponseStatusCodes = getStreamingResponseStatusCodes; + exports2.getPathStringFromParameter = getPathStringFromParameter; + var serializer_js_1 = require_serializer(); + function getStreamingResponseStatusCodes(operationSpec) { + const result = /* @__PURE__ */ new Set(); + for (const statusCode in operationSpec.responses) { + const operationResponse = operationSpec.responses[statusCode]; + if (operationResponse.bodyMapper && operationResponse.bodyMapper.type.name === serializer_js_1.MapperTypeNames.Stream) { + result.add(Number(statusCode)); + } + } + return result; + } + function getPathStringFromParameter(parameter) { + const { parameterPath, mapper } = parameter; + let result; + if (typeof parameterPath === "string") { + result = parameterPath; + } else if (Array.isArray(parameterPath)) { + result = parameterPath.join("."); + } else { + result = mapper.serializedName; + } + return result; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/serializationPolicy.js +var require_serializationPolicy = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/serializationPolicy.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.serializationPolicyName = void 0; + exports2.serializationPolicy = serializationPolicy; + exports2.serializeHeaders = serializeHeaders; + exports2.serializeRequestBody = serializeRequestBody; + var interfaces_js_1 = require_interfaces2(); + var operationHelpers_js_1 = require_operationHelpers(); + var serializer_js_1 = require_serializer(); + var interfaceHelpers_js_1 = require_interfaceHelpers(); + exports2.serializationPolicyName = "serializationPolicy"; + function serializationPolicy(options = {}) { + const stringifyXML = options.stringifyXML; + return { + name: exports2.serializationPolicyName, + async sendRequest(request, next) { + const operationInfo = (0, operationHelpers_js_1.getOperationRequestInfo)(request); + const operationSpec = operationInfo?.operationSpec; + const operationArguments = operationInfo?.operationArguments; + if (operationSpec && operationArguments) { + serializeHeaders(request, operationArguments, operationSpec); + serializeRequestBody(request, operationArguments, operationSpec, stringifyXML); + } + return next(request); + } + }; + } + function serializeHeaders(request, operationArguments, operationSpec) { + if (operationSpec.headerParameters) { + for (const headerParameter of operationSpec.headerParameters) { + let headerValue = (0, operationHelpers_js_1.getOperationArgumentValueFromParameter)(operationArguments, headerParameter); + if (headerValue !== null && headerValue !== void 0 || headerParameter.mapper.required) { + headerValue = operationSpec.serializer.serialize(headerParameter.mapper, headerValue, (0, interfaceHelpers_js_1.getPathStringFromParameter)(headerParameter)); + const headerCollectionPrefix = headerParameter.mapper.headerCollectionPrefix; + if (headerCollectionPrefix) { + for (const key of Object.keys(headerValue)) { + request.headers.set(headerCollectionPrefix + key, headerValue[key]); + } + } else { + request.headers.set(headerParameter.mapper.serializedName || (0, interfaceHelpers_js_1.getPathStringFromParameter)(headerParameter), headerValue); + } + } + } + } + const customHeaders = operationArguments.options?.requestOptions?.customHeaders; + if (customHeaders) { + for (const customHeaderName of Object.keys(customHeaders)) { + request.headers.set(customHeaderName, customHeaders[customHeaderName]); + } + } + } + function serializeRequestBody(request, operationArguments, operationSpec, stringifyXML = function() { + throw new Error("XML serialization unsupported!"); + }) { + const serializerOptions = operationArguments.options?.serializerOptions; + const updatedOptions = { + xml: { + rootName: serializerOptions?.xml.rootName ?? "", + includeRoot: serializerOptions?.xml.includeRoot ?? false, + xmlCharKey: serializerOptions?.xml.xmlCharKey ?? interfaces_js_1.XML_CHARKEY + } + }; + const xmlCharKey = updatedOptions.xml.xmlCharKey; + if (operationSpec.requestBody && operationSpec.requestBody.mapper) { + request.body = (0, operationHelpers_js_1.getOperationArgumentValueFromParameter)(operationArguments, operationSpec.requestBody); + const bodyMapper = operationSpec.requestBody.mapper; + const { required, serializedName, xmlName, xmlElementName, xmlNamespace, xmlNamespacePrefix, nullable } = bodyMapper; + const typeName = bodyMapper.type.name; + try { + if (request.body !== void 0 && request.body !== null || nullable && request.body === null || required) { + const requestBodyParameterPathString = (0, interfaceHelpers_js_1.getPathStringFromParameter)(operationSpec.requestBody); + request.body = operationSpec.serializer.serialize(bodyMapper, request.body, requestBodyParameterPathString, updatedOptions); + const isStream = typeName === serializer_js_1.MapperTypeNames.Stream; + if (operationSpec.isXML) { + const xmlnsKey = xmlNamespacePrefix ? `xmlns:${xmlNamespacePrefix}` : "xmlns"; + const value = getXmlValueWithNamespace(xmlNamespace, xmlnsKey, typeName, request.body, updatedOptions); + if (typeName === serializer_js_1.MapperTypeNames.Sequence) { + request.body = stringifyXML(prepareXMLRootList(value, xmlElementName || xmlName || serializedName, xmlnsKey, xmlNamespace), { rootName: xmlName || serializedName, xmlCharKey }); + } else if (!isStream) { + request.body = stringifyXML(value, { + rootName: xmlName || serializedName, + xmlCharKey + }); + } + } else if (typeName === serializer_js_1.MapperTypeNames.String && (operationSpec.contentType?.match("text/plain") || operationSpec.mediaType === "text")) { + return; + } else if (!isStream) { + request.body = JSON.stringify(request.body); + } + } + } catch (error) { + throw new Error(`Error "${error.message}" occurred in serializing the payload - ${JSON.stringify(serializedName, void 0, " ")}.`); + } + } else if (operationSpec.formDataParameters && operationSpec.formDataParameters.length > 0) { + request.formData = {}; + for (const formDataParameter of operationSpec.formDataParameters) { + const formDataParameterValue = (0, operationHelpers_js_1.getOperationArgumentValueFromParameter)(operationArguments, formDataParameter); + if (formDataParameterValue !== void 0 && formDataParameterValue !== null) { + const formDataParameterPropertyName = formDataParameter.mapper.serializedName || (0, interfaceHelpers_js_1.getPathStringFromParameter)(formDataParameter); + request.formData[formDataParameterPropertyName] = operationSpec.serializer.serialize(formDataParameter.mapper, formDataParameterValue, (0, interfaceHelpers_js_1.getPathStringFromParameter)(formDataParameter), updatedOptions); + } + } + } + } + function getXmlValueWithNamespace(xmlNamespace, xmlnsKey, typeName, serializedValue, options) { + if (xmlNamespace && !["Composite", "Sequence", "Dictionary"].includes(typeName)) { + const result = {}; + result[options.xml.xmlCharKey] = serializedValue; + result[interfaces_js_1.XML_ATTRKEY] = { [xmlnsKey]: xmlNamespace }; + return result; + } + return serializedValue; + } + function prepareXMLRootList(obj, elementName, xmlNamespaceKey, xmlNamespace) { + if (!Array.isArray(obj)) { + obj = [obj]; + } + if (!xmlNamespaceKey || !xmlNamespace) { + return { [elementName]: obj }; + } + const result = { [elementName]: obj }; + result[interfaces_js_1.XML_ATTRKEY] = { [xmlNamespaceKey]: xmlNamespace }; + return result; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/pipeline.js +var require_pipeline3 = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/pipeline.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createClientPipeline = createClientPipeline; + var deserializationPolicy_js_1 = require_deserializationPolicy(); + var core_rest_pipeline_1 = require_commonjs6(); + var serializationPolicy_js_1 = require_serializationPolicy(); + function createClientPipeline(options = {}) { + const pipeline = (0, core_rest_pipeline_1.createPipelineFromOptions)(options ?? {}); + if (options.credentialOptions) { + pipeline.addPolicy((0, core_rest_pipeline_1.bearerTokenAuthenticationPolicy)({ + credential: options.credentialOptions.credential, + scopes: options.credentialOptions.credentialScopes + })); + } + pipeline.addPolicy((0, serializationPolicy_js_1.serializationPolicy)(options.serializationOptions), { phase: "Serialize" }); + pipeline.addPolicy((0, deserializationPolicy_js_1.deserializationPolicy)(options.deserializationOptions), { + phase: "Deserialize" + }); + return pipeline; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/httpClientCache.js +var require_httpClientCache = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/httpClientCache.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getCachedDefaultHttpClient = getCachedDefaultHttpClient; + var core_rest_pipeline_1 = require_commonjs6(); + var cachedHttpClient; + function getCachedDefaultHttpClient() { + if (!cachedHttpClient) { + cachedHttpClient = (0, core_rest_pipeline_1.createDefaultHttpClient)(); + } + return cachedHttpClient; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/urlHelpers.js +var require_urlHelpers2 = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/urlHelpers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getRequestUrl = getRequestUrl; + exports2.appendQueryParams = appendQueryParams; + var operationHelpers_js_1 = require_operationHelpers(); + var interfaceHelpers_js_1 = require_interfaceHelpers(); + var CollectionFormatToDelimiterMap = { + CSV: ",", + SSV: " ", + Multi: "Multi", + TSV: " ", + Pipes: "|" + }; + function getRequestUrl(baseUri, operationSpec, operationArguments, fallbackObject) { + const urlReplacements = calculateUrlReplacements(operationSpec, operationArguments, fallbackObject); + let isAbsolutePath = false; + let requestUrl = replaceAll(baseUri, urlReplacements); + if (operationSpec.path) { + let path3 = replaceAll(operationSpec.path, urlReplacements); + if (operationSpec.path === "/{nextLink}" && path3.startsWith("/")) { + path3 = path3.substring(1); + } + if (isAbsoluteUrl(path3)) { + requestUrl = path3; + isAbsolutePath = true; + } else { + requestUrl = appendPath(requestUrl, path3); + } + } + const { queryParams, sequenceParams } = calculateQueryParameters(operationSpec, operationArguments, fallbackObject); + requestUrl = appendQueryParams(requestUrl, queryParams, sequenceParams, isAbsolutePath); + return requestUrl; + } + function replaceAll(input, replacements) { + let result = input; + for (const [searchValue, replaceValue] of replacements) { + result = result.split(searchValue).join(replaceValue); + } + return result; + } + function calculateUrlReplacements(operationSpec, operationArguments, fallbackObject) { + const result = /* @__PURE__ */ new Map(); + if (operationSpec.urlParameters?.length) { + for (const urlParameter of operationSpec.urlParameters) { + let urlParameterValue = (0, operationHelpers_js_1.getOperationArgumentValueFromParameter)(operationArguments, urlParameter, fallbackObject); + const parameterPathString = (0, interfaceHelpers_js_1.getPathStringFromParameter)(urlParameter); + urlParameterValue = operationSpec.serializer.serialize(urlParameter.mapper, urlParameterValue, parameterPathString); + if (!urlParameter.skipEncoding) { + urlParameterValue = encodeURIComponent(urlParameterValue); + } + result.set(`{${urlParameter.mapper.serializedName || parameterPathString}}`, urlParameterValue); + } + } + return result; + } + function isAbsoluteUrl(url) { + return url.includes("://"); + } + function appendPath(url, pathToAppend) { + if (!pathToAppend) { + return url; + } + const parsedUrl = new URL(url); + let newPath = parsedUrl.pathname; + if (!newPath.endsWith("/")) { + newPath = `${newPath}/`; + } + if (pathToAppend.startsWith("/")) { + pathToAppend = pathToAppend.substring(1); + } + const searchStart = pathToAppend.indexOf("?"); + if (searchStart !== -1) { + const path3 = pathToAppend.substring(0, searchStart); + const search = pathToAppend.substring(searchStart + 1); + newPath = newPath + path3; + if (search) { + parsedUrl.search = parsedUrl.search ? `${parsedUrl.search}&${search}` : search; + } + } else { + newPath = newPath + pathToAppend; + } + parsedUrl.pathname = newPath; + return parsedUrl.toString(); + } + function calculateQueryParameters(operationSpec, operationArguments, fallbackObject) { + const result = /* @__PURE__ */ new Map(); + const sequenceParams = /* @__PURE__ */ new Set(); + if (operationSpec.queryParameters?.length) { + for (const queryParameter of operationSpec.queryParameters) { + if (queryParameter.mapper.type.name === "Sequence" && queryParameter.mapper.serializedName) { + sequenceParams.add(queryParameter.mapper.serializedName); + } + let queryParameterValue = (0, operationHelpers_js_1.getOperationArgumentValueFromParameter)(operationArguments, queryParameter, fallbackObject); + if (queryParameterValue !== void 0 && queryParameterValue !== null || queryParameter.mapper.required) { + queryParameterValue = operationSpec.serializer.serialize(queryParameter.mapper, queryParameterValue, (0, interfaceHelpers_js_1.getPathStringFromParameter)(queryParameter)); + const delimiter = queryParameter.collectionFormat ? CollectionFormatToDelimiterMap[queryParameter.collectionFormat] : ""; + if (Array.isArray(queryParameterValue)) { + queryParameterValue = queryParameterValue.map((item) => { + if (item === null || item === void 0) { + return ""; + } + return item; + }); + } + if (queryParameter.collectionFormat === "Multi" && queryParameterValue.length === 0) { + continue; + } else if (Array.isArray(queryParameterValue) && (queryParameter.collectionFormat === "SSV" || queryParameter.collectionFormat === "TSV")) { + queryParameterValue = queryParameterValue.join(delimiter); + } + if (!queryParameter.skipEncoding) { + if (Array.isArray(queryParameterValue)) { + queryParameterValue = queryParameterValue.map((item) => { + return encodeURIComponent(item); + }); + } else { + queryParameterValue = encodeURIComponent(queryParameterValue); + } + } + if (Array.isArray(queryParameterValue) && (queryParameter.collectionFormat === "CSV" || queryParameter.collectionFormat === "Pipes")) { + queryParameterValue = queryParameterValue.join(delimiter); + } + result.set(queryParameter.mapper.serializedName || (0, interfaceHelpers_js_1.getPathStringFromParameter)(queryParameter), queryParameterValue); + } + } + } + return { + queryParams: result, + sequenceParams + }; + } + function simpleParseQueryParams(queryString) { + const result = /* @__PURE__ */ new Map(); + if (!queryString || queryString[0] !== "?") { + return result; + } + queryString = queryString.slice(1); + const pairs = queryString.split("&"); + for (const pair of pairs) { + const [name, value] = pair.split("=", 2); + const existingValue = result.get(name); + if (existingValue) { + if (Array.isArray(existingValue)) { + existingValue.push(value); + } else { + result.set(name, [existingValue, value]); + } + } else { + result.set(name, value); + } + } + return result; + } + function appendQueryParams(url, queryParams, sequenceParams, noOverwrite = false) { + if (queryParams.size === 0) { + return url; + } + const parsedUrl = new URL(url); + const combinedParams = simpleParseQueryParams(parsedUrl.search); + for (const [name, value] of queryParams) { + const existingValue = combinedParams.get(name); + if (Array.isArray(existingValue)) { + if (Array.isArray(value)) { + existingValue.push(...value); + const valueSet = new Set(existingValue); + combinedParams.set(name, Array.from(valueSet)); + } else { + existingValue.push(value); + } + } else if (existingValue) { + if (Array.isArray(value)) { + value.unshift(existingValue); + } else if (sequenceParams.has(name)) { + combinedParams.set(name, [existingValue, value]); + } + if (!noOverwrite) { + combinedParams.set(name, value); + } + } else { + combinedParams.set(name, value); + } + } + const searchPieces = []; + for (const [name, value] of combinedParams) { + if (typeof value === "string") { + searchPieces.push(`${name}=${value}`); + } else if (Array.isArray(value)) { + for (const subValue of value) { + searchPieces.push(`${name}=${subValue}`); + } + } else { + searchPieces.push(`${name}=${value}`); + } + } + parsedUrl.search = searchPieces.length ? `?${searchPieces.join("&")}` : ""; + return parsedUrl.toString(); + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/log.js +var require_log4 = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/log.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.logger = void 0; + var logger_1 = require_commonjs2(); + exports2.logger = (0, logger_1.createClientLogger)("core-client"); + } +}); + +// node_modules/@azure/core-client/dist/commonjs/serviceClient.js +var require_serviceClient = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/serviceClient.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ServiceClient = void 0; + var core_rest_pipeline_1 = require_commonjs6(); + var pipeline_js_1 = require_pipeline3(); + var utils_js_1 = require_utils4(); + var httpClientCache_js_1 = require_httpClientCache(); + var operationHelpers_js_1 = require_operationHelpers(); + var urlHelpers_js_1 = require_urlHelpers2(); + var interfaceHelpers_js_1 = require_interfaceHelpers(); + var log_js_1 = require_log4(); + var ServiceClient = class { + /** + * If specified, this is the base URI that requests will be made against for this ServiceClient. + * If it is not specified, then all OperationSpecs must contain a baseUrl property. + */ + _endpoint; + /** + * The default request content type for the service. + * Used if no requestContentType is present on an OperationSpec. + */ + _requestContentType; + /** + * Set to true if the request is sent over HTTP instead of HTTPS + */ + _allowInsecureConnection; + /** + * The HTTP client that will be used to send requests. + */ + _httpClient; + /** + * The pipeline used by this client to make requests + */ + pipeline; + /** + * The ServiceClient constructor + * @param options - The service client options that govern the behavior of the client. + */ + constructor(options = {}) { + this._requestContentType = options.requestContentType; + this._endpoint = options.endpoint ?? options.baseUri; + if (options.baseUri) { + log_js_1.logger.warning("The baseUri option for SDK Clients has been deprecated, please use endpoint instead."); + } + this._allowInsecureConnection = options.allowInsecureConnection; + this._httpClient = options.httpClient || (0, httpClientCache_js_1.getCachedDefaultHttpClient)(); + this.pipeline = options.pipeline || createDefaultPipeline(options); + if (options.additionalPolicies?.length) { + for (const { policy, position } of options.additionalPolicies) { + const afterPhase = position === "perRetry" ? "Sign" : void 0; + this.pipeline.addPolicy(policy, { + afterPhase + }); + } + } + } + /** + * Send the provided httpRequest. + */ + async sendRequest(request) { + return this.pipeline.sendRequest(this._httpClient, request); + } + /** + * Send an HTTP request that is populated using the provided OperationSpec. + * @typeParam T - The typed result of the request, based on the OperationSpec. + * @param operationArguments - The arguments that the HTTP request's templated values will be populated from. + * @param operationSpec - The OperationSpec to use to populate the httpRequest. + */ + async sendOperationRequest(operationArguments, operationSpec) { + const endpoint = operationSpec.baseUrl || this._endpoint; + if (!endpoint) { + throw new Error("If operationSpec.baseUrl is not specified, then the ServiceClient must have a endpoint string property that contains the base URL to use."); + } + const url = (0, urlHelpers_js_1.getRequestUrl)(endpoint, operationSpec, operationArguments, this); + const request = (0, core_rest_pipeline_1.createPipelineRequest)({ + url + }); + request.method = operationSpec.httpMethod; + const operationInfo = (0, operationHelpers_js_1.getOperationRequestInfo)(request); + operationInfo.operationSpec = operationSpec; + operationInfo.operationArguments = operationArguments; + const contentType = operationSpec.contentType || this._requestContentType; + if (contentType && operationSpec.requestBody) { + request.headers.set("Content-Type", contentType); + } + const options = operationArguments.options; + if (options) { + const requestOptions = options.requestOptions; + if (requestOptions) { + if (requestOptions.timeout) { + request.timeout = requestOptions.timeout; + } + if (requestOptions.onUploadProgress) { + request.onUploadProgress = requestOptions.onUploadProgress; + } + if (requestOptions.onDownloadProgress) { + request.onDownloadProgress = requestOptions.onDownloadProgress; + } + if (requestOptions.shouldDeserialize !== void 0) { + operationInfo.shouldDeserialize = requestOptions.shouldDeserialize; + } + if (requestOptions.allowInsecureConnection) { + request.allowInsecureConnection = true; + } + } + if (options.abortSignal) { + request.abortSignal = options.abortSignal; + } + if (options.tracingOptions) { + request.tracingOptions = options.tracingOptions; + } + } + if (this._allowInsecureConnection) { + request.allowInsecureConnection = true; + } + if (request.streamResponseStatusCodes === void 0) { + request.streamResponseStatusCodes = (0, interfaceHelpers_js_1.getStreamingResponseStatusCodes)(operationSpec); + } + try { + const rawResponse = await this.sendRequest(request); + const flatResponse = (0, utils_js_1.flattenResponse)(rawResponse, operationSpec.responses[rawResponse.status]); + if (options?.onResponse) { + options.onResponse(rawResponse, flatResponse); + } + return flatResponse; + } catch (error) { + if (typeof error === "object" && error?.response) { + const rawResponse = error.response; + const flatResponse = (0, utils_js_1.flattenResponse)(rawResponse, operationSpec.responses[error.statusCode] || operationSpec.responses["default"]); + error.details = flatResponse; + if (options?.onResponse) { + options.onResponse(rawResponse, flatResponse, error); + } + } + throw error; + } + } + }; + exports2.ServiceClient = ServiceClient; + function createDefaultPipeline(options) { + const credentialScopes = getCredentialScopes(options); + const credentialOptions = options.credential && credentialScopes ? { credentialScopes, credential: options.credential } : void 0; + return (0, pipeline_js_1.createClientPipeline)({ + ...options, + credentialOptions + }); + } + function getCredentialScopes(options) { + if (options.credentialScopes) { + return options.credentialScopes; + } + if (options.endpoint) { + return `${options.endpoint}/.default`; + } + if (options.baseUri) { + return `${options.baseUri}/.default`; + } + if (options.credential && !options.credentialScopes) { + throw new Error(`When using credentials, the ServiceClientOptions must contain either a endpoint or a credentialScopes. Unable to create a bearerTokenAuthenticationPolicy`); + } + return void 0; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/authorizeRequestOnClaimChallenge.js +var require_authorizeRequestOnClaimChallenge = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/authorizeRequestOnClaimChallenge.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.parseCAEChallenge = parseCAEChallenge; + exports2.authorizeRequestOnClaimChallenge = authorizeRequestOnClaimChallenge; + var log_js_1 = require_log4(); + var base64_js_1 = require_base64(); + function parseCAEChallenge(challenges) { + const bearerChallenges = `, ${challenges.trim()}`.split(", Bearer ").filter((x) => x); + return bearerChallenges.map((challenge) => { + const challengeParts = `${challenge.trim()}, `.split('", ').filter((x) => x); + const keyValuePairs = challengeParts.map((keyValue) => (([key, value]) => ({ [key]: value }))(keyValue.trim().split('="'))); + return keyValuePairs.reduce((a, b) => ({ ...a, ...b }), {}); + }); + } + async function authorizeRequestOnClaimChallenge(onChallengeOptions) { + const { scopes, response } = onChallengeOptions; + const logger = onChallengeOptions.logger || log_js_1.logger; + const challenge = response.headers.get("WWW-Authenticate"); + if (!challenge) { + logger.info(`The WWW-Authenticate header was missing. Failed to perform the Continuous Access Evaluation authentication flow.`); + return false; + } + const challenges = parseCAEChallenge(challenge) || []; + const parsedChallenge = challenges.find((x) => x.claims); + if (!parsedChallenge) { + logger.info(`The WWW-Authenticate header was missing the necessary "claims" to perform the Continuous Access Evaluation authentication flow.`); + return false; + } + const accessToken = await onChallengeOptions.getAccessToken(parsedChallenge.scope ? [parsedChallenge.scope] : scopes, { + claims: (0, base64_js_1.decodeStringToString)(parsedChallenge.claims) + }); + if (!accessToken) { + return false; + } + onChallengeOptions.request.headers.set("Authorization", `${accessToken.tokenType ?? "Bearer"} ${accessToken.token}`); + return true; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/authorizeRequestOnTenantChallenge.js +var require_authorizeRequestOnTenantChallenge = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/authorizeRequestOnTenantChallenge.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.authorizeRequestOnTenantChallenge = void 0; + var Constants = { + DefaultScope: "/.default", + /** + * Defines constants for use with HTTP headers. + */ + HeaderConstants: { + /** + * The Authorization header. + */ + AUTHORIZATION: "authorization" + } + }; + function isUuid(text) { + return /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/.test(text); + } + var authorizeRequestOnTenantChallenge = async (challengeOptions) => { + const requestOptions = requestToOptions(challengeOptions.request); + const challenge = getChallenge(challengeOptions.response); + if (challenge) { + const challengeInfo = parseChallenge(challenge); + const challengeScopes = buildScopes(challengeOptions, challengeInfo); + const tenantId = extractTenantId(challengeInfo); + if (!tenantId) { + return false; + } + const accessToken = await challengeOptions.getAccessToken(challengeScopes, { + ...requestOptions, + tenantId + }); + if (!accessToken) { + return false; + } + challengeOptions.request.headers.set(Constants.HeaderConstants.AUTHORIZATION, `${accessToken.tokenType ?? "Bearer"} ${accessToken.token}`); + return true; + } + return false; + }; + exports2.authorizeRequestOnTenantChallenge = authorizeRequestOnTenantChallenge; + function extractTenantId(challengeInfo) { + const parsedAuthUri = new URL(challengeInfo.authorization_uri); + const pathSegments = parsedAuthUri.pathname.split("/"); + const tenantId = pathSegments[1]; + if (tenantId && isUuid(tenantId)) { + return tenantId; + } + return void 0; + } + function buildScopes(challengeOptions, challengeInfo) { + if (!challengeInfo.resource_id) { + return challengeOptions.scopes; + } + const challengeScopes = new URL(challengeInfo.resource_id); + challengeScopes.pathname = Constants.DefaultScope; + let scope = challengeScopes.toString(); + if (scope === "https://disk.azure.com/.default") { + scope = "https://disk.azure.com//.default"; + } + return [scope]; + } + function getChallenge(response) { + const challenge = response.headers.get("WWW-Authenticate"); + if (response.status === 401 && challenge) { + return challenge; + } + return; + } + function parseChallenge(challenge) { + const bearerChallenge = challenge.slice("Bearer ".length); + const challengeParts = `${bearerChallenge.trim()} `.split(" ").filter((x) => x); + const keyValuePairs = challengeParts.map((keyValue) => (([key, value]) => ({ [key]: value }))(keyValue.trim().split("="))); + return keyValuePairs.reduce((a, b) => ({ ...a, ...b }), {}); + } + function requestToOptions(request) { + return { + abortSignal: request.abortSignal, + requestOptions: { + timeout: request.timeout + }, + tracingOptions: request.tracingOptions + }; + } + } +}); + +// node_modules/@azure/core-client/dist/commonjs/index.js +var require_commonjs8 = __commonJS({ + "node_modules/@azure/core-client/dist/commonjs/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.authorizeRequestOnTenantChallenge = exports2.authorizeRequestOnClaimChallenge = exports2.serializationPolicyName = exports2.serializationPolicy = exports2.deserializationPolicyName = exports2.deserializationPolicy = exports2.XML_CHARKEY = exports2.XML_ATTRKEY = exports2.createClientPipeline = exports2.ServiceClient = exports2.MapperTypeNames = exports2.createSerializer = void 0; + var serializer_js_1 = require_serializer(); + Object.defineProperty(exports2, "createSerializer", { enumerable: true, get: function() { + return serializer_js_1.createSerializer; + } }); + Object.defineProperty(exports2, "MapperTypeNames", { enumerable: true, get: function() { + return serializer_js_1.MapperTypeNames; + } }); + var serviceClient_js_1 = require_serviceClient(); + Object.defineProperty(exports2, "ServiceClient", { enumerable: true, get: function() { + return serviceClient_js_1.ServiceClient; + } }); + var pipeline_js_1 = require_pipeline3(); + Object.defineProperty(exports2, "createClientPipeline", { enumerable: true, get: function() { + return pipeline_js_1.createClientPipeline; + } }); + var interfaces_js_1 = require_interfaces2(); + Object.defineProperty(exports2, "XML_ATTRKEY", { enumerable: true, get: function() { + return interfaces_js_1.XML_ATTRKEY; + } }); + Object.defineProperty(exports2, "XML_CHARKEY", { enumerable: true, get: function() { + return interfaces_js_1.XML_CHARKEY; + } }); + var deserializationPolicy_js_1 = require_deserializationPolicy(); + Object.defineProperty(exports2, "deserializationPolicy", { enumerable: true, get: function() { + return deserializationPolicy_js_1.deserializationPolicy; + } }); + Object.defineProperty(exports2, "deserializationPolicyName", { enumerable: true, get: function() { + return deserializationPolicy_js_1.deserializationPolicyName; + } }); + var serializationPolicy_js_1 = require_serializationPolicy(); + Object.defineProperty(exports2, "serializationPolicy", { enumerable: true, get: function() { + return serializationPolicy_js_1.serializationPolicy; + } }); + Object.defineProperty(exports2, "serializationPolicyName", { enumerable: true, get: function() { + return serializationPolicy_js_1.serializationPolicyName; + } }); + var authorizeRequestOnClaimChallenge_js_1 = require_authorizeRequestOnClaimChallenge(); + Object.defineProperty(exports2, "authorizeRequestOnClaimChallenge", { enumerable: true, get: function() { + return authorizeRequestOnClaimChallenge_js_1.authorizeRequestOnClaimChallenge; + } }); + var authorizeRequestOnTenantChallenge_js_1 = require_authorizeRequestOnTenantChallenge(); + Object.defineProperty(exports2, "authorizeRequestOnTenantChallenge", { enumerable: true, get: function() { + return authorizeRequestOnTenantChallenge_js_1.authorizeRequestOnTenantChallenge; + } }); + } +}); + +// node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/compat.js +var require_compat = __commonJS({ + "node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/compat.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Constants = exports2.createWebResource = exports2.createSerializer = exports2.isTokenCredential = exports2.HttpHeaders = void 0; + __exportStar2(require_interfaces(), exports2); + var util_1 = require_util2(); + Object.defineProperty(exports2, "HttpHeaders", { enumerable: true, get: function() { + return util_1.HttpHeaders; + } }); + var core_auth_1 = require_commonjs7(); + Object.defineProperty(exports2, "isTokenCredential", { enumerable: true, get: function() { + return core_auth_1.isTokenCredential; + } }); + var core_client_1 = require_commonjs8(); + Object.defineProperty(exports2, "createSerializer", { enumerable: true, get: function() { + return core_client_1.createSerializer; + } }); + var core_rest_pipeline_1 = require_commonjs6(); + var util_2 = require_util2(); + function createWebResource(resource) { + return (0, util_2.toWebResourceLike)((0, core_rest_pipeline_1.createPipelineRequest)(resource !== null && resource !== void 0 ? resource : { url: "" })); + } + exports2.createWebResource = createWebResource; + exports2.Constants = { + /** + * Defines constants for use with HTTP headers. + */ + HeaderConstants: { + /** + * The Authorization header. + */ + AUTHORIZATION: "Authorization", + AUTHORIZATION_SCHEME: "Bearer" + } + }; + } +}); + +// node_modules/@azure/core-http-compat/dist/commonjs/policies/disableKeepAlivePolicy.js +var require_disableKeepAlivePolicy = __commonJS({ + "node_modules/@azure/core-http-compat/dist/commonjs/policies/disableKeepAlivePolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var disableKeepAlivePolicy_exports = {}; + __export2(disableKeepAlivePolicy_exports, { + createDisableKeepAlivePolicy: () => createDisableKeepAlivePolicy, + disableKeepAlivePolicyName: () => disableKeepAlivePolicyName2, + pipelineContainsDisableKeepAlivePolicy: () => pipelineContainsDisableKeepAlivePolicy + }); + module2.exports = __toCommonJS2(disableKeepAlivePolicy_exports); + var disableKeepAlivePolicyName2 = "DisableKeepAlivePolicy"; + function createDisableKeepAlivePolicy() { + return { + name: disableKeepAlivePolicyName2, + async sendRequest(request, next) { + request.disableKeepAlive = true; + return next(request); + } + }; + } + function pipelineContainsDisableKeepAlivePolicy(pipeline) { + return pipeline.getOrderedPolicies().some((policy) => policy.name === disableKeepAlivePolicyName2); + } + } +}); + +// node_modules/@azure/core-http-compat/dist/commonjs/util.js +var require_util3 = __commonJS({ + "node_modules/@azure/core-http-compat/dist/commonjs/util.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var util_exports = {}; + __export2(util_exports, { + HttpHeaders: () => HttpHeaders, + toHttpHeadersLike: () => toHttpHeadersLike2, + toPipelineRequest: () => toPipelineRequest, + toWebResourceLike: () => toWebResourceLike + }); + module2.exports = __toCommonJS2(util_exports); + var import_core_rest_pipeline = require_commonjs6(); + var originalRequestSymbol = /* @__PURE__ */ Symbol("Original PipelineRequest"); + var originalClientRequestSymbol = /* @__PURE__ */ Symbol.for("@azure/core-client original request"); + function toPipelineRequest(webResource, options = {}) { + const compatWebResource = webResource; + const request = compatWebResource[originalRequestSymbol]; + const headers = (0, import_core_rest_pipeline.createHttpHeaders)(webResource.headers.toJson({ preserveCase: true })); + if (request) { + request.headers = headers; + return request; + } else { + const newRequest = (0, import_core_rest_pipeline.createPipelineRequest)({ + url: webResource.url, + method: webResource.method, + headers, + withCredentials: webResource.withCredentials, + timeout: webResource.timeout, + requestId: webResource.requestId, + abortSignal: webResource.abortSignal, + body: webResource.body, + formData: webResource.formData, + disableKeepAlive: !!webResource.keepAlive, + onDownloadProgress: webResource.onDownloadProgress, + onUploadProgress: webResource.onUploadProgress, + proxySettings: webResource.proxySettings, + streamResponseStatusCodes: webResource.streamResponseStatusCodes, + agent: webResource.agent, + requestOverrides: webResource.requestOverrides + }); + if (options.originalRequest) { + newRequest[originalClientRequestSymbol] = options.originalRequest; + } + return newRequest; + } + } + function toWebResourceLike(request, options) { + const originalRequest = options?.originalRequest ?? request; + const webResource = { + url: request.url, + method: request.method, + headers: toHttpHeadersLike2(request.headers), + withCredentials: request.withCredentials, + timeout: request.timeout, + requestId: request.headers.get("x-ms-client-request-id") || request.requestId, + abortSignal: request.abortSignal, + body: request.body, + formData: request.formData, + keepAlive: !!request.disableKeepAlive, + onDownloadProgress: request.onDownloadProgress, + onUploadProgress: request.onUploadProgress, + proxySettings: request.proxySettings, + streamResponseStatusCodes: request.streamResponseStatusCodes, + agent: request.agent, + requestOverrides: request.requestOverrides, + clone() { + throw new Error("Cannot clone a non-proxied WebResourceLike"); + }, + prepare() { + throw new Error("WebResourceLike.prepare() is not supported by @azure/core-http-compat"); + }, + validateRequestProperties() { + } + }; + if (options?.createProxy) { + return new Proxy(webResource, { + get(target, prop, receiver) { + if (prop === originalRequestSymbol) { + return request; + } else if (prop === "clone") { + return () => { + return toWebResourceLike(toPipelineRequest(webResource, { originalRequest }), { + createProxy: true, + originalRequest + }); + }; + } + return Reflect.get(target, prop, receiver); + }, + set(target, prop, value, receiver) { + if (prop === "keepAlive") { + request.disableKeepAlive = !value; + } + const passThroughProps = [ + "url", + "method", + "withCredentials", + "timeout", + "requestId", + "abortSignal", + "body", + "formData", + "onDownloadProgress", + "onUploadProgress", + "proxySettings", + "streamResponseStatusCodes", + "agent", + "requestOverrides" + ]; + if (typeof prop === "string" && passThroughProps.includes(prop)) { + request[prop] = value; + } + return Reflect.set(target, prop, value, receiver); + } + }); + } else { + return webResource; + } + } + function toHttpHeadersLike2(headers) { + return new HttpHeaders(headers.toJSON({ preserveCase: true })); + } + function getHeaderKey(headerName) { + return headerName.toLowerCase(); + } + var HttpHeaders = class _HttpHeaders { + _headersMap; + constructor(rawHeaders) { + this._headersMap = {}; + if (rawHeaders) { + for (const headerName in rawHeaders) { + this.set(headerName, rawHeaders[headerName]); + } + } + } + /** + * Set a header in this collection with the provided name and value. The name is + * case-insensitive. + * @param headerName - The name of the header to set. This value is case-insensitive. + * @param headerValue - The value of the header to set. + */ + set(headerName, headerValue) { + this._headersMap[getHeaderKey(headerName)] = { + name: headerName, + value: headerValue.toString() + }; + } + /** + * Get the header value for the provided header name, or undefined if no header exists in this + * collection with the provided name. + * @param headerName - The name of the header. + */ + get(headerName) { + const header = this._headersMap[getHeaderKey(headerName)]; + return !header ? void 0 : header.value; + } + /** + * Get whether or not this header collection contains a header entry for the provided header name. + */ + contains(headerName) { + return !!this._headersMap[getHeaderKey(headerName)]; + } + /** + * Remove the header with the provided headerName. Return whether or not the header existed and + * was removed. + * @param headerName - The name of the header to remove. + */ + remove(headerName) { + const result = this.contains(headerName); + delete this._headersMap[getHeaderKey(headerName)]; + return result; + } + /** + * Get the headers that are contained this collection as an object. + */ + rawHeaders() { + return this.toJson({ preserveCase: true }); + } + /** + * Get the headers that are contained in this collection as an array. + */ + headersArray() { + const headers = []; + for (const headerKey in this._headersMap) { + headers.push(this._headersMap[headerKey]); + } + return headers; + } + /** + * Get the header names that are contained in this collection. + */ + headerNames() { + const headerNames = []; + const headers = this.headersArray(); + for (let i = 0; i < headers.length; ++i) { + headerNames.push(headers[i].name); + } + return headerNames; + } + /** + * Get the header values that are contained in this collection. + */ + headerValues() { + const headerValues = []; + const headers = this.headersArray(); + for (let i = 0; i < headers.length; ++i) { + headerValues.push(headers[i].value); + } + return headerValues; + } + /** + * Get the JSON object representation of this HTTP header collection. + */ + toJson(options = {}) { + const result = {}; + if (options.preserveCase) { + for (const headerKey in this._headersMap) { + const header = this._headersMap[headerKey]; + result[header.name] = header.value; + } + } else { + for (const headerKey in this._headersMap) { + const header = this._headersMap[headerKey]; + result[getHeaderKey(header.name)] = header.value; + } + } + return result; + } + /** + * Get the string representation of this HTTP header collection. + */ + toString() { + return JSON.stringify(this.toJson({ preserveCase: true })); + } + /** + * Create a deep clone/copy of this HttpHeaders collection. + */ + clone() { + const resultPreservingCasing = {}; + for (const headerKey in this._headersMap) { + const header = this._headersMap[headerKey]; + resultPreservingCasing[header.name] = header.value; + } + return new _HttpHeaders(resultPreservingCasing); + } + }; + } +}); + +// node_modules/@azure/core-http-compat/dist/commonjs/response.js +var require_response2 = __commonJS({ + "node_modules/@azure/core-http-compat/dist/commonjs/response.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var response_exports = {}; + __export2(response_exports, { + toCompatResponse: () => toCompatResponse2, + toPipelineResponse: () => toPipelineResponse + }); + module2.exports = __toCommonJS2(response_exports); + var import_core_rest_pipeline = require_commonjs6(); + var import_util = require_util3(); + var originalResponse = /* @__PURE__ */ Symbol("Original FullOperationResponse"); + function toCompatResponse2(response, options) { + let request = (0, import_util.toWebResourceLike)(response.request); + let headers = (0, import_util.toHttpHeadersLike)(response.headers); + if (options?.createProxy) { + return new Proxy(response, { + get(target, prop, receiver) { + if (prop === "headers") { + return headers; + } else if (prop === "request") { + return request; + } else if (prop === originalResponse) { + return response; + } + return Reflect.get(target, prop, receiver); + }, + set(target, prop, value, receiver) { + if (prop === "headers") { + headers = value; + } else if (prop === "request") { + request = value; + } + return Reflect.set(target, prop, value, receiver); + } + }); + } else { + return { + ...response, + request, + headers + }; + } + } + function toPipelineResponse(compatResponse) { + const extendedCompatResponse = compatResponse; + const response = extendedCompatResponse[originalResponse]; + const headers = (0, import_core_rest_pipeline.createHttpHeaders)(compatResponse.headers.toJson({ preserveCase: true })); + if (response) { + response.headers = headers; + return response; + } else { + return { + ...compatResponse, + headers, + request: (0, import_util.toPipelineRequest)(compatResponse.request) + }; + } + } + } +}); + +// node_modules/@azure/core-http-compat/dist/commonjs/extendedClient.js +var require_extendedClient = __commonJS({ + "node_modules/@azure/core-http-compat/dist/commonjs/extendedClient.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var extendedClient_exports = {}; + __export2(extendedClient_exports, { + ExtendedServiceClient: () => ExtendedServiceClient2 + }); + module2.exports = __toCommonJS2(extendedClient_exports); + var import_disableKeepAlivePolicy = require_disableKeepAlivePolicy(); + var import_core_rest_pipeline = require_commonjs6(); + var import_core_client = require_commonjs8(); + var import_response = require_response2(); + var ExtendedServiceClient2 = class extends import_core_client.ServiceClient { + constructor(options) { + super(options); + if (options.keepAliveOptions?.enable === false && !(0, import_disableKeepAlivePolicy.pipelineContainsDisableKeepAlivePolicy)(this.pipeline)) { + this.pipeline.addPolicy((0, import_disableKeepAlivePolicy.createDisableKeepAlivePolicy)()); + } + if (options.redirectOptions?.handleRedirects === false) { + this.pipeline.removePolicy({ + name: import_core_rest_pipeline.redirectPolicyName + }); + } + } + /** + * Compatible send operation request function. + * + * @param operationArguments - Operation arguments + * @param operationSpec - Operation Spec + * @returns + */ + async sendOperationRequest(operationArguments, operationSpec) { + const userProvidedCallBack = operationArguments?.options?.onResponse; + let lastResponse; + function onResponse(rawResponse, flatResponse, error) { + lastResponse = rawResponse; + if (userProvidedCallBack) { + userProvidedCallBack(rawResponse, flatResponse, error); + } + } + operationArguments.options = { + ...operationArguments.options, + onResponse + }; + const result = await super.sendOperationRequest(operationArguments, operationSpec); + if (lastResponse) { + Object.defineProperty(result, "_response", { + value: (0, import_response.toCompatResponse)(lastResponse) + }); + } + return result; + } + }; + } +}); + +// node_modules/@azure/core-http-compat/dist/commonjs/policies/requestPolicyFactoryPolicy.js +var require_requestPolicyFactoryPolicy = __commonJS({ + "node_modules/@azure/core-http-compat/dist/commonjs/policies/requestPolicyFactoryPolicy.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var requestPolicyFactoryPolicy_exports = {}; + __export2(requestPolicyFactoryPolicy_exports, { + HttpPipelineLogLevel: () => HttpPipelineLogLevel2, + createRequestPolicyFactoryPolicy: () => createRequestPolicyFactoryPolicy2, + requestPolicyFactoryPolicyName: () => requestPolicyFactoryPolicyName2 + }); + module2.exports = __toCommonJS2(requestPolicyFactoryPolicy_exports); + var import_util = require_util3(); + var import_response = require_response2(); + var HttpPipelineLogLevel2 = /* @__PURE__ */ ((HttpPipelineLogLevel22) => { + HttpPipelineLogLevel22[HttpPipelineLogLevel22["ERROR"] = 1] = "ERROR"; + HttpPipelineLogLevel22[HttpPipelineLogLevel22["INFO"] = 3] = "INFO"; + HttpPipelineLogLevel22[HttpPipelineLogLevel22["OFF"] = 0] = "OFF"; + HttpPipelineLogLevel22[HttpPipelineLogLevel22["WARNING"] = 2] = "WARNING"; + return HttpPipelineLogLevel22; + })(HttpPipelineLogLevel2 || {}); + var mockRequestPolicyOptions = { + log(_logLevel, _message) { + }, + shouldLog(_logLevel) { + return false; + } + }; + var requestPolicyFactoryPolicyName2 = "RequestPolicyFactoryPolicy"; + function createRequestPolicyFactoryPolicy2(factories) { + const orderedFactories = factories.slice().reverse(); + return { + name: requestPolicyFactoryPolicyName2, + async sendRequest(request, next) { + let httpPipeline = { + async sendRequest(httpRequest) { + const response2 = await next((0, import_util.toPipelineRequest)(httpRequest)); + return (0, import_response.toCompatResponse)(response2, { createProxy: true }); + } + }; + for (const factory of orderedFactories) { + httpPipeline = factory.create(httpPipeline, mockRequestPolicyOptions); + } + const webResourceLike = (0, import_util.toWebResourceLike)(request, { createProxy: true }); + const response = await httpPipeline.sendRequest(webResourceLike); + return (0, import_response.toPipelineResponse)(response); + } + }; + } + } +}); + +// node_modules/@azure/core-http-compat/dist/commonjs/httpClientAdapter.js +var require_httpClientAdapter = __commonJS({ + "node_modules/@azure/core-http-compat/dist/commonjs/httpClientAdapter.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var httpClientAdapter_exports = {}; + __export2(httpClientAdapter_exports, { + convertHttpClient: () => convertHttpClient2 + }); + module2.exports = __toCommonJS2(httpClientAdapter_exports); + var import_response = require_response2(); + var import_util = require_util3(); + function convertHttpClient2(requestPolicyClient) { + return { + sendRequest: async (request) => { + const response = await requestPolicyClient.sendRequest( + (0, import_util.toWebResourceLike)(request, { createProxy: true }) + ); + return (0, import_response.toPipelineResponse)(response); + } + }; + } + } +}); + +// node_modules/@azure/core-http-compat/dist/commonjs/index.js +var require_commonjs9 = __commonJS({ + "node_modules/@azure/core-http-compat/dist/commonjs/index.js"(exports2, module2) { + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var src_exports = {}; + __export2(src_exports, { + ExtendedServiceClient: () => import_extendedClient.ExtendedServiceClient, + HttpPipelineLogLevel: () => import_requestPolicyFactoryPolicy.HttpPipelineLogLevel, + convertHttpClient: () => import_httpClientAdapter.convertHttpClient, + createRequestPolicyFactoryPolicy: () => import_requestPolicyFactoryPolicy.createRequestPolicyFactoryPolicy, + disableKeepAlivePolicyName: () => import_disableKeepAlivePolicy.disableKeepAlivePolicyName, + requestPolicyFactoryPolicyName: () => import_requestPolicyFactoryPolicy.requestPolicyFactoryPolicyName, + toCompatResponse: () => import_response.toCompatResponse, + toHttpHeadersLike: () => import_util.toHttpHeadersLike + }); + module2.exports = __toCommonJS2(src_exports); + var import_extendedClient = require_extendedClient(); + var import_response = require_response2(); + var import_requestPolicyFactoryPolicy = require_requestPolicyFactoryPolicy(); + var import_disableKeepAlivePolicy = require_disableKeepAlivePolicy(); + var import_httpClientAdapter = require_httpClientAdapter(); + var import_util = require_util3(); + } +}); + +// node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/response.js +var require_response3 = __commonJS({ + "node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/response.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.toPipelineResponse = exports2.toCompatResponse = void 0; + var core_rest_pipeline_1 = require_commonjs6(); + var util_js_1 = require_util2(); + var originalResponse = Symbol("Original FullOperationResponse"); + function toCompatResponse2(response, options) { + let request = (0, util_js_1.toWebResourceLike)(response.request); + let headers = (0, util_js_1.toHttpHeadersLike)(response.headers); + if (options === null || options === void 0 ? void 0 : options.createProxy) { + return new Proxy(response, { + get(target, prop, receiver) { + if (prop === "headers") { + return headers; + } else if (prop === "request") { + return request; + } else if (prop === originalResponse) { + return response; + } + return Reflect.get(target, prop, receiver); + }, + set(target, prop, value, receiver) { + if (prop === "headers") { + headers = value; + } else if (prop === "request") { + request = value; + } + return Reflect.set(target, prop, value, receiver); + } + }); + } else { + return Object.assign(Object.assign({}, response), { + request, + headers + }); + } + } + exports2.toCompatResponse = toCompatResponse2; + function toPipelineResponse(compatResponse) { + const extendedCompatResponse = compatResponse; + const response = extendedCompatResponse[originalResponse]; + const headers = (0, core_rest_pipeline_1.createHttpHeaders)(compatResponse.headers.toJson({ preserveCase: true })); + if (response) { + response.headers = headers; + return response; + } else { + return Object.assign(Object.assign({}, compatResponse), { headers, request: (0, util_js_1.toPipelineRequest)(compatResponse.request) }); + } + } + exports2.toPipelineResponse = toPipelineResponse; + } +}); + +// node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/serviceClientContext.js +var require_serviceClientContext = __commonJS({ + "node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat/serviceClientContext.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __rest2 = exports2 && exports2.__rest || function(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ServiceClientContext = void 0; + var core_client_1 = require_commonjs8(); + var core_http_compat_1 = require_commonjs9(); + var response_1 = require_response3(); + var core_rest_pipeline_1 = require_commonjs6(); + var compat_1 = require_compat(); + var ServiceClientContext = class { + /** + * Initializes a new instance of the ConnectorClientContext class. + * + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials, options = {}) { + var _a, _b, _c, _d; + this._requestPolicyFactories = []; + if (credentials === null || credentials === void 0) { + throw new Error("'credentials' cannot be null."); + } + if (!options) { + options = {}; + } + const requestContentType = ((_b = (_a = options.deserializationContentTypes) === null || _a === void 0 ? void 0 : _a.json) === null || _b === void 0 ? void 0 : _b.join(" ")) || ((_d = (_c = options.deserializationContentTypes) === null || _c === void 0 ? void 0 : _c.xml) === null || _d === void 0 ? void 0 : _d.join(" ")) || "application/json; charset=utf-8"; + const userAgentPrefix = (typeof options.userAgent === "function" ? options.userAgent("") : options.userAgent) || ""; + const { baseUri: endpoint, proxySettings: proxyOptions, httpClient, credentialScopes, requestPolicyFactories } = options; + this.client = new core_client_1.ServiceClient({ + endpoint, + requestContentType, + userAgentOptions: { userAgentPrefix }, + allowInsecureConnection: endpoint === null || endpoint === void 0 ? void 0 : endpoint.toLowerCase().startsWith("http:"), + proxyOptions, + httpClient: httpClient ? (0, core_http_compat_1.convertHttpClient)(httpClient) : void 0, + credentialScopes + }); + this.baseUri = endpoint; + this.requestContentType = requestContentType; + this.credentials = credentials; + this.options = options; + this._requestPolicyFactories = this.addPolicies(this.client, requestPolicyFactories); + } + // Protects against JSON.stringify leaking secrets + toJSON() { + return { name: this.constructor.name }; + } + /** + * Send the provided httpRequest. + * + * @param request The HTTP request to send. + * @returns The HTTP response. + */ + sendRequest(request) { + return __awaiter2(this, void 0, void 0, function* () { + if (!request) { + throw new Error("request cannot be null"); + } + const newRequest = yield this.addRequestSettings(request); + const response = yield this.client.sendRequest(newRequest); + return (0, response_1.toCompatResponse)(response); + }); + } + /** + * Send an HTTP request that is populated using the provided OperationSpec. + * + * @param operationArguments - The arguments that the HTTP request's templated values will be populated from. + * @param operationSpec - The OperationSpec to use to populate the httpRequest. + * @param callback - The callback to call when the response is received. + * @returns The response object. + */ + sendOperationRequest(operationArguments, operationSpec, callback) { + return __awaiter2(this, void 0, void 0, function* () { + if (!operationArguments) { + throw new Error("operationArguments cannot be null"); + } + const _a = operationArguments.options || {}, { customHeaders, timeout, onDownloadProgress, onUploadProgress, shouldDeserialize, serializerOptions, tracingContext } = _a, restOptions = __rest2(_a, ["customHeaders", "timeout", "onDownloadProgress", "onUploadProgress", "shouldDeserialize", "serializerOptions", "tracingContext"]); + let _response; + const requestOptions = {}; + const operationArgumentPipeline = Object.assign(Object.assign({}, operationArguments), { options: Object.assign(Object.assign({}, restOptions), { + requestOptions, + onResponse(rawResponse, flatResponse, error) { + _response = rawResponse; + const response = (0, response_1.toCompatResponse)(rawResponse); + callback === null || callback === void 0 ? void 0 : callback(error, flatResponse, response.request, response); + } + }) }); + if (customHeaders) { + requestOptions.customHeaders = customHeaders; + } + if (timeout) { + requestOptions.timeout = timeout; + } + if (onDownloadProgress) { + requestOptions.onDownloadProgress = onDownloadProgress; + } + if (onUploadProgress) { + requestOptions.onUploadProgress = onUploadProgress; + } + if (shouldDeserialize) { + requestOptions.shouldDeserialize = (response) => { + if (typeof shouldDeserialize === "function") { + return shouldDeserialize((0, response_1.toCompatResponse)(response)); + } else if (typeof shouldDeserialize === "boolean") { + return shouldDeserialize; + } + return true; + }; + } + if (serializerOptions) { + operationArgumentPipeline.options.serializerOptions = { + xml: serializerOptions + }; + } + if (tracingContext) { + operationArgumentPipeline.options.tracingOptions = { + tracingContext + }; + } + const result = yield this.client.sendOperationRequest(operationArgumentPipeline, operationSpec); + Object.defineProperty(result, "_response", { + value: _response + }); + return result; + }); + } + addRequestSettings(request) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + const webResource = (0, compat_1.createWebResource)(request); + yield this.credentials.signRequest(webResource); + const headers = (0, core_rest_pipeline_1.createHttpHeaders)(Object.assign(Object.assign({}, request.headers.toJSON({ preserveCase: true })), webResource.headers.toJson({ preserveCase: true }))); + request.withCredentials = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.withCredentials) === true; + request.headers = headers; + return request; + }); + } + addPolicies(client, policies) { + if (Array.isArray(policies)) { + const policy = (0, core_http_compat_1.createRequestPolicyFactoryPolicy)(policies); + policy.name = "ServiceClientContext_RequestPolicyFactories"; + client.pipeline.removePolicy(policy); + client.pipeline.addPolicy(policy); + } else if (typeof policies === "function") { + this.addPolicies(client, policies([]) || []); + } + this.client.pipeline.addPolicy({ + name: "ServiceClientContext_Credentials_SignRequest", + sendRequest: (request, next) => __awaiter2(this, void 0, void 0, function* () { + const newRequest = yield this.addRequestSettings(request); + return next(newRequest); + }) + }); + return client.pipeline.getOrderedPolicies(); + } + }; + exports2.ServiceClientContext = ServiceClientContext; + } +}); + +// node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat.js +var require_azureCoreHttpCompat = __commonJS({ + "node_modules/botbuilder-stdlib/lib/azureCoreHttpCompat.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_compat(), exports2); + __exportStar2(require_serviceClientContext(), exports2); + } +}); + +// node_modules/botbuilder-stdlib/lib/delay.js +var require_delay3 = __commonJS({ + "node_modules/botbuilder-stdlib/lib/delay.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.delay = void 0; + function delay(promiseOrmilliseconds, maybeMilliseconds) { + if (typeof promiseOrmilliseconds === "number") { + return new Promise((resolve) => setTimeout(resolve, promiseOrmilliseconds)); + } + return new Promise((resolve) => setTimeout(() => resolve(promiseOrmilliseconds), maybeMilliseconds)); + } + exports2.delay = delay; + } +}); + +// node_modules/botbuilder-stdlib/lib/maybeCast.js +var require_maybeCast = __commonJS({ + "node_modules/botbuilder-stdlib/lib/maybeCast.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.maybeCast = void 0; + function maybeCast(value, ctor) { + if (ctor != null && value instanceof ctor) { + return value; + } + return value; + } + exports2.maybeCast = maybeCast; + } +}); + +// node_modules/botbuilder-stdlib/lib/retry.js +var require_retry = __commonJS({ + "node_modules/botbuilder-stdlib/lib/retry.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.retry = void 0; + function retry(promise, maxRetries, initialDelay = 500) { + return __awaiter2(this, void 0, void 0, function* () { + let delay = initialDelay, n = 1, maybeError; + maxRetries = Math.max(maxRetries, 1); + while (n <= maxRetries) { + try { + return yield promise(n); + } catch (err) { + maybeError = err; + yield new Promise((resolve) => setTimeout(resolve, delay)); + delay *= n; + n++; + } + } + if (maybeError) { + throw maybeError; + } + }); + } + exports2.retry = retry; + } +}); + +// node_modules/botbuilder-stdlib/lib/stringify.js +var require_stringify2 = __commonJS({ + "node_modules/botbuilder-stdlib/lib/stringify.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.stringify = void 0; + function stringify4(value, replacer, space) { + if (!value) { + return ""; + } + try { + return JSON.stringify(value, stringifyReplacer(replacer), space); + } catch (error) { + if (!(error === null || error === void 0 ? void 0 : error.message.includes("circular structure"))) { + throw error; + } + const seen = /* @__PURE__ */ new WeakMap(); + return JSON.stringify(value, function stringifyCircularReplacer(key, val) { + var _a; + if (val === null || val === void 0 || typeof val !== "object") { + return val; + } + if (key) { + const path3 = seen.get(val); + if (path3) { + return `[Circular *.${path3.join(".")}]`; + } + const parent = (_a = seen.get(this)) !== null && _a !== void 0 ? _a : []; + seen.set(val, [...parent, key]); + } + const value2 = stringifyReplacer(replacer)(key, val); + return value2; + }, space); + } + } + exports2.stringify = stringify4; + function stringifyReplacer(replacer) { + return function stringifyReplacerInternal(key, val) { + const replacerValue = replacer ? replacer.call(this, key, val) : val; + if (replacerValue === null || replacerValue === void 0 || typeof replacerValue !== "object") { + return replacerValue; + } + const result = replacerValue._replacer ? replacerValue._replacer(key) : replacerValue; + return result; + }; + } + } +}); + +// node_modules/botbuilder-stdlib/lib/index.js +var require_lib5 = __commonJS({ + "node_modules/botbuilder-stdlib/lib/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.stringify = exports2.retry = exports2.maybeCast = exports2.delay = exports2.AzureCoreHttpCompat = exports2.stringExt = void 0; + __exportStar2(require_types3(), exports2); + exports2.stringExt = __importStar2(require_stringExt()); + exports2.AzureCoreHttpCompat = __importStar2(require_azureCoreHttpCompat()); + var delay_1 = require_delay3(); + Object.defineProperty(exports2, "delay", { enumerable: true, get: function() { + return delay_1.delay; + } }); + var maybeCast_1 = require_maybeCast(); + Object.defineProperty(exports2, "maybeCast", { enumerable: true, get: function() { + return maybeCast_1.maybeCast; + } }); + var retry_1 = require_retry(); + Object.defineProperty(exports2, "retry", { enumerable: true, get: function() { + return retry_1.retry; + } }); + var stringify_1 = require_stringify2(); + Object.defineProperty(exports2, "stringify", { enumerable: true, get: function() { + return stringify_1.stringify; + } }); + } +}); + +// node_modules/botbuilder-core/lib/storage.js +var require_storage = __commonJS({ + "node_modules/botbuilder-core/lib/storage.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __rest2 = exports2 && exports2.__rest || function(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.calculateChangeHash = exports2.assertStoreItems = void 0; + var z = __importStar2(require_zod()); + var crypto_1 = require("crypto"); + var botbuilder_stdlib_1 = require_lib5(); + var storeItems = z.record(z.unknown()); + function assertStoreItems(val, ..._args) { + storeItems.parse(val); + } + exports2.assertStoreItems = assertStoreItems; + function calculateChangeHash(item) { + const { eTag } = item, rest = __rest2(item, ["eTag"]); + const result = (0, botbuilder_stdlib_1.stringify)(rest); + const hash = (0, crypto_1.createHash)("sha256", { encoding: "utf-8" }); + const hashed = hash.update(result).digest("hex"); + return hashed; + } + exports2.calculateChangeHash = calculateChangeHash; + } +}); + +// node_modules/botbuilder-core/lib/botState.js +var require_botState = __commonJS({ + "node_modules/botbuilder-core/lib/botState.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotState = void 0; + var botStatePropertyAccessor_1 = require_botStatePropertyAccessor(); + var storage_1 = require_storage(); + var BotState = class { + /** + * Creates a new BotState instance. + * + * @param storage Storage provider to persist the state object to. + * @param storageKey Function called anytime the storage key for a given turn needs to be calculated. + */ + constructor(storage, storageKey) { + this.storage = storage; + this.storageKey = storageKey; + this.stateKey = Symbol("state"); + } + /** + * Creates a new property accessor for reading and writing an individual property to the bot + * states storage object. + * + * @template T The type of property to create. Defaults to `any` type. + * @param name Name of the property to add. + * @returns An accessor for the property. + */ + createProperty(name) { + const prop = new botStatePropertyAccessor_1.BotStatePropertyAccessor(this, name); + return prop; + } + /** + * Reads in and caches the backing state object for a turn. + * + * @remarks + * Subsequent reads will return the cached object unless the `force` flag is passed in which + * will force the state object to be re-read. + * + * This method is automatically called on first access of any of created property accessors. + * + * ```JavaScript + * const state = await botState.load(context); + * ``` + * @param context Context for current turn of conversation with the user. + * @param force (Optional) If `true` the cache will be bypassed and the state will always be read in directly from storage. Defaults to `false`. + * @returns {Promise} The cached state. + */ + load(context, force = false) { + const cached = context.turnState.get(this.stateKey); + if (force || !cached || !cached.state) { + return Promise.resolve(this.storageKey(context)).then((key) => { + return this.storage.read([key]).then((items) => { + const state = items[key] || {}; + const hash = (0, storage_1.calculateChangeHash)(state); + context.turnState.set(this.stateKey, { state, hash }); + return state; + }); + }); + } + return Promise.resolve(cached.state); + } + /** + * Saves the cached state object if it's been changed. + * + * @remarks + * If the `force` flag is passed in the cached state object will be saved regardless of + * whether its been changed or not and if no object has been cached, an empty object will be + * created and then saved. + * + * ```JavaScript + * await botState.saveChanges(context); + * ``` + * @param context Context for current turn of conversation with the user. + * @param force (Optional) if `true` the state will always be written out regardless of its change state. Defaults to `false`. + * @returns {Promise} A promise representing the async operation. + */ + saveChanges(context, force = false) { + let cached = context.turnState.get(this.stateKey); + if (force || cached && cached.hash !== (0, storage_1.calculateChangeHash)(cached === null || cached === void 0 ? void 0 : cached.state)) { + return Promise.resolve(this.storageKey(context)).then((key) => { + if (!cached) { + cached = { state: {}, hash: "" }; + } + cached.state.eTag = "*"; + const changes = {}; + changes[key] = cached.state; + return this.storage.write(changes).then(() => { + cached.hash = (0, storage_1.calculateChangeHash)(cached.state); + context.turnState.set(this.stateKey, cached); + }); + }); + } + return Promise.resolve(); + } + /** + * Clears the current state object for a turn. + * + * @remarks + * The cleared state object will not be persisted until [saveChanges()](#savechanges) has + * been called. + * + * ```JavaScript + * await botState.clear(context); + * await botState.saveChanges(context); + * ``` + * @param context Context for current turn of conversation with the user. + * @returns {Promise} A promise representing the async operation. + */ + clear(context) { + context.turnState.set(this.stateKey, { state: {}, hash: "" }); + return Promise.resolve(); + } + /** + * Delete the backing state object for the current turn. + * + * @remarks + * The state object will be removed from storage if it exists. If the state object has been + * read in and cached, the cache will be cleared. + * + * ```JavaScript + * await botState.delete(context); + * ``` + * @param context Context for current turn of conversation with the user. + * @returns {Promise} A promise representing the async operation. + */ + delete(context) { + if (context.turnState.has(this.stateKey)) { + context.turnState.delete(this.stateKey); + } + return Promise.resolve(this.storageKey(context)).then((key) => this.storage.delete([key])); + } + /** + * Returns a cached state object or undefined if not cached. + * + * @remarks + * This example shows how to synchronously get an already loaded and cached state object: + * + * ```JavaScript + * const state = botState.get(context); + * ``` + * @param context Context for current turn of conversation with the user. + * @returns A cached state object or undefined if not cached. + */ + get(context) { + const cached = context.turnState.get(this.stateKey); + return typeof cached === "object" && typeof cached.state === "object" ? cached.state : void 0; + } + }; + exports2.BotState = BotState; + } +}); + +// node_modules/botbuilder-core/lib/botTelemetryClient.js +var require_botTelemetryClient = __commonJS({ + "node_modules/botbuilder-core/lib/botTelemetryClient.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.telemetryTrackDialogView = exports2.NullTelemetryClient = exports2.BotTelemetryClientKey = exports2.Severity = void 0; + var Severity; + (function(Severity2) { + Severity2[Severity2["Verbose"] = 0] = "Verbose"; + Severity2[Severity2["Information"] = 1] = "Information"; + Severity2[Severity2["Warning"] = 2] = "Warning"; + Severity2[Severity2["Error"] = 3] = "Error"; + Severity2[Severity2["Critical"] = 4] = "Critical"; + })(Severity = exports2.Severity || (exports2.Severity = {})); + exports2.BotTelemetryClientKey = "BotTelemetryClient"; + var NullTelemetryClient = class { + /** + * Creates a new instance of the [NullTelemetryClient](xref:botbuilder-core.NullTelemetryClient) class. + * + * @param _settings Optional. Settings for the telemetry client. + */ + constructor(_settings) { + } + /** + * Logs an Application Insights page view. + * + * @param _telemetry An object implementing [TelemetryPageView](xref:botbuilder-core.TelemetryPageView). + */ + trackPageView(_telemetry) { + } + /** + * Sends information about an external dependency (outgoing call) in the application. + * + * @param _telemetry An object implementing [TelemetryDependency](xref:botbuilder-core.TelemetryDependency). + */ + trackDependency(_telemetry) { + } + /** + * Logs custom events with extensible named fields. + * + * @param _telemetry An object implementing [TelemetryEvent](xref:botbuilder-core.TelemetryEvent). + */ + trackEvent(_telemetry) { + } + /** + * Logs a system exception. + * + * @param _telemetry An object implementing [TelemetryException](xref:botbuilder-core.TelemetryException). + */ + trackException(_telemetry) { + } + /** + * Sends a trace message. + * + * @param _telemetry An object implementing [TelemetryTrace](xref:botbuilder-core.TelemetryTrace). + */ + trackTrace(_telemetry) { + } + /** + * Flushes the in-memory buffer and any metrics being pre-aggregated. + */ + flush() { + } + }; + exports2.NullTelemetryClient = NullTelemetryClient; + function telemetryTrackDialogView(telemetryClient, dialogName, properties, metrics) { + if (!clientSupportsTrackDialogView(telemetryClient)) { + throw new TypeError('"telemetryClient" parameter does not have methods trackPageView() or trackTrace()'); + } + if (instanceOfBotPageViewTelemetryClient(telemetryClient)) { + telemetryClient.trackPageView({ name: dialogName, properties, metrics }); + } else { + telemetryClient.trackTrace({ message: "Dialog View: " + dialogName, severityLevel: Severity.Information }); + } + } + exports2.telemetryTrackDialogView = telemetryTrackDialogView; + function instanceOfBotPageViewTelemetryClient(object) { + return "trackPageView" in object; + } + function clientSupportsTrackDialogView(client) { + if (!client) { + return false; + } + if (typeof client.trackPageView !== "function" && typeof client.trackTrace !== "function") { + return false; + } + return true; + } + } +}); + +// node_modules/botbuilder-core/lib/memoryStorage.js +var require_memoryStorage = __commonJS({ + "node_modules/botbuilder-core/lib/memoryStorage.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MemoryStorage = void 0; + var MemoryStorage = class { + /** + * Creates a new MemoryStorage instance. + * + * @param memory (Optional) memory to use for storing items. By default it will create an empty JSON object `{}`. + */ + constructor(memory = {}) { + this.memory = memory; + this.etag = 1; + } + /** + * Reads storage items from storage. + * + * @param keys Keys of the [StoreItems](xref:botbuilder-core.StoreItems) objects to read. + * @returns The read items. + */ + read(keys) { + return new Promise((resolve) => { + if (!keys) { + throw new ReferenceError("Keys are required when reading."); + } + const data = {}; + keys.forEach((key) => { + const item = this.memory[key]; + if (item) { + data[key] = JSON.parse(item); + } + }); + resolve(data); + }); + } + /** + * Writes storage items to storage. + * + * @param changes The [StoreItems](xref:botbuilder-core.StoreItems) to write, indexed by key. + * @returns {Promise} A promise representing the async operation. + */ + write(changes) { + const saveItem = (key, item) => { + const clone = Object.assign({}, item); + clone.eTag = (this.etag++).toString(); + this.memory[key] = JSON.stringify(clone); + }; + return new Promise((resolve, reject) => { + if (!changes) { + throw new ReferenceError("Changes are required when writing."); + } + Object.keys(changes).forEach((key) => { + const newItem = changes[key]; + const old = this.memory[key]; + if (!old || newItem.eTag === "*" || !newItem.eTag) { + saveItem(key, newItem); + } else { + const oldItem = JSON.parse(old); + if (newItem.eTag === oldItem.eTag) { + saveItem(key, newItem); + } else { + reject(new Error(`Storage: error writing "${key}" due to eTag conflict.`)); + } + } + }); + resolve(); + }); + } + /** + * Deletes storage items from storage. + * + * @param keys Keys of the [StoreItems](xref:botbuilder-core.StoreItems) objects to delete. + * @returns {Promise} A promise representing the async operation. + */ + delete(keys) { + return new Promise((resolve) => { + keys.forEach((key) => this.memory[key] = void 0); + resolve(); + }); + } + }; + exports2.MemoryStorage = MemoryStorage; + } +}); + +// node_modules/botbuilder-core/lib/browserStorage.js +var require_browserStorage = __commonJS({ + "node_modules/botbuilder-core/lib/browserStorage.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BrowserSessionStorage = exports2.BrowserLocalStorage = void 0; + var memoryStorage_1 = require_memoryStorage(); + var BrowserLocalStorage = class extends memoryStorage_1.MemoryStorage { + /** + * Creates a new [BrowserLocalStorage](xref:botbuilder-core.BrowserLocalStorage) instance. + */ + constructor() { + super(localStorage); + } + }; + exports2.BrowserLocalStorage = BrowserLocalStorage; + var BrowserSessionStorage = class extends memoryStorage_1.MemoryStorage { + /** + * Creates a new [BrowserSessionStorage](xref:botbuilder-core.BrowserSessionStorage) instance. + */ + constructor() { + super(sessionStorage); + } + }; + exports2.BrowserSessionStorage = BrowserSessionStorage; + } +}); + +// node_modules/botbuilder-core/lib/componentRegistration.js +var require_componentRegistration = __commonJS({ + "node_modules/botbuilder-core/lib/componentRegistration.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ComponentRegistration = void 0; + var ComponentRegistration = class _ComponentRegistration { + /** + * Gets list of all ComponentRegistration objects registered. + * + * @returns A list of ComponentRegistration objects. + */ + static get components() { + return Array.from(_ComponentRegistration._components.values()); + } + /** + * Add a component, only one instance per type is allowed for components. + * + * @param componentRegistration The component to be registered. + */ + static add(componentRegistration) { + const name = componentRegistration.constructor.name; + _ComponentRegistration._components.set(name, componentRegistration); + } + }; + exports2.ComponentRegistration = ComponentRegistration; + ComponentRegistration._components = /* @__PURE__ */ new Map(); + } +}); + +// node_modules/botframework-connector/lib/auth/authenticationError.js +var require_authenticationError = __commonJS({ + "node_modules/botframework-connector/lib/auth/authenticationError.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AuthenticationError = void 0; + var botframework_schema_1 = require_lib4(); + var AuthenticationError = class _AuthenticationError extends Error { + /** + * Initializes a new instance of the [AuthenticationError](xref:botframework-connector.AuthenticationError) class. + * + * @param message The Error message. + * @param statusCode The `StatusCode` number to use. + */ + constructor(message, statusCode) { + super(message); + this.statusCode = statusCode; + } + /** + * Corroborates that the error is of type [IStatusCodeError](xref:botframework-schema.IStatusCodeError). + * + * @param err The error to validate. + * @returns If `err` is an [IStatusCodeError](xref:botframework-schema.IStatusCodeError), the result is true; otherwise false. + */ + static isStatusCodeError(err) { + return !!(err && typeof err.statusCode === "number"); + } + /** + * Used to determine a status code from the error message for non-`IStatusCodeError`'s. + * + * @param err The error thrown, used to determine an appropriate status code. + * @returns The error message to be sent as a response. + */ + static determineStatusCodeAndBuildMessage(err) { + const errMessage = err && err.message ? err.message : "Internal Server Error"; + const code = _AuthenticationError.determineStatusCode(errMessage); + const connectionHeader = "Connection: 'close'\r\n"; + return `HTTP/1.1 ${code} ${botframework_schema_1.StatusCodes[code]}\r +${errMessage}\r +${connectionHeader}\r +`; + } + /** + * @private + */ + static determineStatusCode(message) { + if (typeof message === "string") { + if (message.toLowerCase().startsWith("unauthorized")) { + return botframework_schema_1.StatusCodes.UNAUTHORIZED; + } else if (message.toLowerCase().startsWith("'authheader'")) { + return botframework_schema_1.StatusCodes.BAD_REQUEST; + } + } + return botframework_schema_1.StatusCodes.INTERNAL_SERVER_ERROR; + } + }; + exports2.AuthenticationError = AuthenticationError; + } +}); + +// node_modules/botframework-connector/lib/auth/authenticationConfiguration.js +var require_authenticationConfiguration = __commonJS({ + "node_modules/botframework-connector/lib/auth/authenticationConfiguration.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AuthenticationConfiguration = void 0; + var AuthenticationConfiguration = class { + /** + * General configuration settings for authentication. + * + * @param {string[]} requiredEndorsements An array of JWT endorsements. + * @param {(claims: Claim[]) => Promise} validateClaims Function that validates a list of Claims + * and should throw an exception if the validation fails. + * @param {string[]} validTokenIssuers An array of valid JWT token issuers. + */ + constructor(requiredEndorsements = [], validateClaims, validTokenIssuers) { + this.requiredEndorsements = requiredEndorsements; + this.validateClaims = validateClaims; + this.validTokenIssuers = validTokenIssuers; + } + }; + exports2.AuthenticationConfiguration = AuthenticationConfiguration; + } +}); + +// node_modules/botframework-connector/lib/auth/authenticationConstants.js +var require_authenticationConstants = __commonJS({ + "node_modules/botframework-connector/lib/auth/authenticationConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AuthenticationConstants = void 0; + var AuthenticationConstants; + (function(AuthenticationConstants2) { + AuthenticationConstants2.ToChannelFromBotLoginUrl = "https://login.microsoftonline.com/botframework.com"; + AuthenticationConstants2.ToChannelFromBotLoginUrlPrefix = "https://login.microsoftonline.com/"; + AuthenticationConstants2.ToChannelFromBotTokenEndpointPath = "/oauth2/v2.0/token"; + AuthenticationConstants2.DefaultChannelAuthTenant = "botframework.com"; + AuthenticationConstants2.ToChannelFromBotOAuthScope = "https://api.botframework.com"; + AuthenticationConstants2.ToBotFromChannelTokenIssuer = "https://api.botframework.com"; + AuthenticationConstants2.OAuthUrl = "https://api.botframework.com"; + AuthenticationConstants2.BotOpenIdMetadataKey = "BotOpenIdMetadata"; + AuthenticationConstants2.ChannelService = "ChannelService"; + AuthenticationConstants2.OAuthUrlKey = "OAuthApiEndpoint"; + AuthenticationConstants2.EmulateOAuthCardsKey = "EmulateOAuthCards"; + AuthenticationConstants2.ToBotFromChannelOpenIdMetadataUrl = "https://login.botframework.com/v1/.well-known/openidconfiguration"; + AuthenticationConstants2.ToBotFromEnterpriseChannelOpenIdMetadataUrlFormat = "https://{channelService}.enterprisechannel.botframework.com/v1/.well-known/openidconfiguration"; + AuthenticationConstants2.ToBotFromEmulatorOpenIdMetadataUrl = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"; + AuthenticationConstants2.ValidTokenIssuerUrlTemplateV1 = "https://sts.windows.net/"; + AuthenticationConstants2.ValidTokenIssuerUrlTemplateV2 = "https://login.microsoftonline.com/"; + AuthenticationConstants2.ValidGovernmentTokenIssuerUrlTemplateV1 = "https://login.microsoftonline.us/"; + AuthenticationConstants2.ValidGovernmentTokenIssuerUrlTemplateV2 = "https://login.microsoftonline.us/"; + AuthenticationConstants2.AllowedSigningAlgorithms = ["RS256", "RS384", "RS512"]; + AuthenticationConstants2.AuthorizedParty = "azp"; + AuthenticationConstants2.AudienceClaim = "aud"; + AuthenticationConstants2.IssuerClaim = "iss"; + AuthenticationConstants2.KeyIdHeader = "kid"; + AuthenticationConstants2.VersionClaim = "ver"; + AuthenticationConstants2.AppIdClaim = "appid"; + AuthenticationConstants2.ServiceUrlClaim = "serviceurl"; + AuthenticationConstants2.TenantIdClaim = "tid"; + AuthenticationConstants2.AnonymousSkillAppId = "AnonymousSkill"; + AuthenticationConstants2.AnonymousAuthType = "anonymous"; + AuthenticationConstants2.CertificateThumbprint = "CertificateThumbprint"; + AuthenticationConstants2.CertificatePrivateKey = "CertificatePrivateKey"; + })(AuthenticationConstants = exports2.AuthenticationConstants || (exports2.AuthenticationConstants = {})); + } +}); + +// node_modules/jws/lib/data-stream.js +var require_data_stream = __commonJS({ + "node_modules/jws/lib/data-stream.js"(exports2, module2) { + var Buffer3 = require_safe_buffer().Buffer; + var Stream = require("stream"); + var util = require("util"); + function DataStream(data) { + this.buffer = null; + this.writable = true; + this.readable = true; + if (!data) { + this.buffer = Buffer3.alloc(0); + return this; + } + if (typeof data.pipe === "function") { + this.buffer = Buffer3.alloc(0); + data.pipe(this); + return this; + } + if (data.length || typeof data === "object") { + this.buffer = data; + this.writable = false; + process.nextTick(function() { + this.emit("end", data); + this.readable = false; + this.emit("close"); + }.bind(this)); + return this; + } + throw new TypeError("Unexpected data type (" + typeof data + ")"); + } + util.inherits(DataStream, Stream); + DataStream.prototype.write = function write(data) { + this.buffer = Buffer3.concat([this.buffer, Buffer3.from(data)]); + this.emit("data", data); + }; + DataStream.prototype.end = function end(data) { + if (data) + this.write(data); + this.emit("end", data); + this.emit("close"); + this.writable = false; + this.readable = false; + }; + module2.exports = DataStream; + } +}); + +// node_modules/ecdsa-sig-formatter/src/param-bytes-for-alg.js +var require_param_bytes_for_alg = __commonJS({ + "node_modules/ecdsa-sig-formatter/src/param-bytes-for-alg.js"(exports2, module2) { + "use strict"; + function getParamSize(keySize) { + var result = (keySize / 8 | 0) + (keySize % 8 === 0 ? 0 : 1); + return result; + } + var paramBytesForAlg = { + ES256: getParamSize(256), + ES384: getParamSize(384), + ES512: getParamSize(521) + }; + function getParamBytesForAlg(alg) { + var paramBytes = paramBytesForAlg[alg]; + if (paramBytes) { + return paramBytes; + } + throw new Error('Unknown algorithm "' + alg + '"'); + } + module2.exports = getParamBytesForAlg; + } +}); + +// node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.js +var require_ecdsa_sig_formatter = __commonJS({ + "node_modules/ecdsa-sig-formatter/src/ecdsa-sig-formatter.js"(exports2, module2) { + "use strict"; + var Buffer3 = require_safe_buffer().Buffer; + var getParamBytesForAlg = require_param_bytes_for_alg(); + var MAX_OCTET = 128; + var CLASS_UNIVERSAL = 0; + var PRIMITIVE_BIT = 32; + var TAG_SEQ = 16; + var TAG_INT = 2; + var ENCODED_TAG_SEQ = TAG_SEQ | PRIMITIVE_BIT | CLASS_UNIVERSAL << 6; + var ENCODED_TAG_INT = TAG_INT | CLASS_UNIVERSAL << 6; + function base64Url(base64) { + return base64.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_"); + } + function signatureAsBuffer(signature) { + if (Buffer3.isBuffer(signature)) { + return signature; + } else if ("string" === typeof signature) { + return Buffer3.from(signature, "base64"); + } + throw new TypeError("ECDSA signature must be a Base64 string or a Buffer"); + } + function derToJose(signature, alg) { + signature = signatureAsBuffer(signature); + var paramBytes = getParamBytesForAlg(alg); + var maxEncodedParamLength = paramBytes + 1; + var inputLength = signature.length; + var offset = 0; + if (signature[offset++] !== ENCODED_TAG_SEQ) { + throw new Error('Could not find expected "seq"'); + } + var seqLength = signature[offset++]; + if (seqLength === (MAX_OCTET | 1)) { + seqLength = signature[offset++]; + } + if (inputLength - offset < seqLength) { + throw new Error('"seq" specified length of "' + seqLength + '", only "' + (inputLength - offset) + '" remaining'); + } + if (signature[offset++] !== ENCODED_TAG_INT) { + throw new Error('Could not find expected "int" for "r"'); + } + var rLength = signature[offset++]; + if (inputLength - offset - 2 < rLength) { + throw new Error('"r" specified length of "' + rLength + '", only "' + (inputLength - offset - 2) + '" available'); + } + if (maxEncodedParamLength < rLength) { + throw new Error('"r" specified length of "' + rLength + '", max of "' + maxEncodedParamLength + '" is acceptable'); + } + var rOffset = offset; + offset += rLength; + if (signature[offset++] !== ENCODED_TAG_INT) { + throw new Error('Could not find expected "int" for "s"'); + } + var sLength = signature[offset++]; + if (inputLength - offset !== sLength) { + throw new Error('"s" specified length of "' + sLength + '", expected "' + (inputLength - offset) + '"'); + } + if (maxEncodedParamLength < sLength) { + throw new Error('"s" specified length of "' + sLength + '", max of "' + maxEncodedParamLength + '" is acceptable'); + } + var sOffset = offset; + offset += sLength; + if (offset !== inputLength) { + throw new Error('Expected to consume entire buffer, but "' + (inputLength - offset) + '" bytes remain'); + } + var rPadding = paramBytes - rLength, sPadding = paramBytes - sLength; + var dst = Buffer3.allocUnsafe(rPadding + rLength + sPadding + sLength); + for (offset = 0; offset < rPadding; ++offset) { + dst[offset] = 0; + } + signature.copy(dst, offset, rOffset + Math.max(-rPadding, 0), rOffset + rLength); + offset = paramBytes; + for (var o = offset; offset < o + sPadding; ++offset) { + dst[offset] = 0; + } + signature.copy(dst, offset, sOffset + Math.max(-sPadding, 0), sOffset + sLength); + dst = dst.toString("base64"); + dst = base64Url(dst); + return dst; + } + function countPadding(buf, start, stop) { + var padding = 0; + while (start + padding < stop && buf[start + padding] === 0) { + ++padding; + } + var needsSign = buf[start + padding] >= MAX_OCTET; + if (needsSign) { + --padding; + } + return padding; + } + function joseToDer(signature, alg) { + signature = signatureAsBuffer(signature); + var paramBytes = getParamBytesForAlg(alg); + var signatureBytes = signature.length; + if (signatureBytes !== paramBytes * 2) { + throw new TypeError('"' + alg + '" signatures must be "' + paramBytes * 2 + '" bytes, saw "' + signatureBytes + '"'); + } + var rPadding = countPadding(signature, 0, paramBytes); + var sPadding = countPadding(signature, paramBytes, signature.length); + var rLength = paramBytes - rPadding; + var sLength = paramBytes - sPadding; + var rsBytes = 1 + 1 + rLength + 1 + 1 + sLength; + var shortLength = rsBytes < MAX_OCTET; + var dst = Buffer3.allocUnsafe((shortLength ? 2 : 3) + rsBytes); + var offset = 0; + dst[offset++] = ENCODED_TAG_SEQ; + if (shortLength) { + dst[offset++] = rsBytes; + } else { + dst[offset++] = MAX_OCTET | 1; + dst[offset++] = rsBytes & 255; + } + dst[offset++] = ENCODED_TAG_INT; + dst[offset++] = rLength; + if (rPadding < 0) { + dst[offset++] = 0; + offset += signature.copy(dst, offset, 0, paramBytes); + } else { + offset += signature.copy(dst, offset, rPadding, paramBytes); + } + dst[offset++] = ENCODED_TAG_INT; + dst[offset++] = sLength; + if (sPadding < 0) { + dst[offset++] = 0; + signature.copy(dst, offset, paramBytes); + } else { + signature.copy(dst, offset, paramBytes + sPadding); + } + return dst; + } + module2.exports = { + derToJose, + joseToDer + }; + } +}); + +// node_modules/buffer-equal-constant-time/index.js +var require_buffer_equal_constant_time = __commonJS({ + "node_modules/buffer-equal-constant-time/index.js"(exports2, module2) { + "use strict"; + var Buffer3 = require("buffer").Buffer; + var SlowBuffer = require("buffer").SlowBuffer; + module2.exports = bufferEq; + function bufferEq(a, b) { + if (!Buffer3.isBuffer(a) || !Buffer3.isBuffer(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + var c = 0; + for (var i = 0; i < a.length; i++) { + c |= a[i] ^ b[i]; + } + return c === 0; + } + bufferEq.install = function() { + Buffer3.prototype.equal = SlowBuffer.prototype.equal = function equal(that) { + return bufferEq(this, that); + }; + }; + var origBufEqual = Buffer3.prototype.equal; + var origSlowBufEqual = SlowBuffer.prototype.equal; + bufferEq.restore = function() { + Buffer3.prototype.equal = origBufEqual; + SlowBuffer.prototype.equal = origSlowBufEqual; + }; + } +}); + +// node_modules/jwa/index.js +var require_jwa = __commonJS({ + "node_modules/jwa/index.js"(exports2, module2) { + var Buffer3 = require_safe_buffer().Buffer; + var crypto12 = require("crypto"); + var formatEcdsa = require_ecdsa_sig_formatter(); + var util = require("util"); + var MSG_INVALID_ALGORITHM = '"%s" is not a valid algorithm.\n Supported algorithms are:\n "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" and "none".'; + var MSG_INVALID_SECRET = "secret must be a string or buffer"; + var MSG_INVALID_VERIFIER_KEY = "key must be a string or a buffer"; + var MSG_INVALID_SIGNER_KEY = "key must be a string, a buffer or an object"; + var supportsKeyObjects = typeof crypto12.createPublicKey === "function"; + if (supportsKeyObjects) { + MSG_INVALID_VERIFIER_KEY += " or a KeyObject"; + MSG_INVALID_SECRET += "or a KeyObject"; + } + function checkIsPublicKey(key) { + if (Buffer3.isBuffer(key)) { + return; + } + if (typeof key === "string") { + return; + } + if (!supportsKeyObjects) { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + if (typeof key !== "object") { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + if (typeof key.type !== "string") { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + if (typeof key.asymmetricKeyType !== "string") { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + if (typeof key.export !== "function") { + throw typeError(MSG_INVALID_VERIFIER_KEY); + } + } + function checkIsPrivateKey(key) { + if (Buffer3.isBuffer(key)) { + return; + } + if (typeof key === "string") { + return; + } + if (typeof key === "object") { + return; + } + throw typeError(MSG_INVALID_SIGNER_KEY); + } + function checkIsSecretKey(key) { + if (Buffer3.isBuffer(key)) { + return; + } + if (typeof key === "string") { + return key; + } + if (!supportsKeyObjects) { + throw typeError(MSG_INVALID_SECRET); + } + if (typeof key !== "object") { + throw typeError(MSG_INVALID_SECRET); + } + if (key.type !== "secret") { + throw typeError(MSG_INVALID_SECRET); + } + if (typeof key.export !== "function") { + throw typeError(MSG_INVALID_SECRET); + } + } + function fromBase64(base64) { + return base64.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_"); + } + function toBase64(base64url) { + base64url = base64url.toString(); + var padding = 4 - base64url.length % 4; + if (padding !== 4) { + for (var i = 0; i < padding; ++i) { + base64url += "="; + } + } + return base64url.replace(/\-/g, "+").replace(/_/g, "/"); + } + function typeError(template) { + var args = [].slice.call(arguments, 1); + var errMsg = util.format.bind(util, template).apply(null, args); + return new TypeError(errMsg); + } + function bufferOrString(obj) { + return Buffer3.isBuffer(obj) || typeof obj === "string"; + } + function normalizeInput(thing) { + if (!bufferOrString(thing)) + thing = JSON.stringify(thing); + return thing; + } + function createHmacSigner(bits) { + return function sign(thing, secret) { + checkIsSecretKey(secret); + thing = normalizeInput(thing); + var hmac = crypto12.createHmac("sha" + bits, secret); + var sig = (hmac.update(thing), hmac.digest("base64")); + return fromBase64(sig); + }; + } + var bufferEqual; + var timingSafeEqual = "timingSafeEqual" in crypto12 ? function timingSafeEqual2(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + return crypto12.timingSafeEqual(a, b); + } : function timingSafeEqual2(a, b) { + if (!bufferEqual) { + bufferEqual = require_buffer_equal_constant_time(); + } + return bufferEqual(a, b); + }; + function createHmacVerifier(bits) { + return function verify(thing, signature, secret) { + var computedSig = createHmacSigner(bits)(thing, secret); + return timingSafeEqual(Buffer3.from(signature), Buffer3.from(computedSig)); + }; + } + function createKeySigner(bits) { + return function sign(thing, privateKey) { + checkIsPrivateKey(privateKey); + thing = normalizeInput(thing); + var signer = crypto12.createSign("RSA-SHA" + bits); + var sig = (signer.update(thing), signer.sign(privateKey, "base64")); + return fromBase64(sig); + }; + } + function createKeyVerifier(bits) { + return function verify(thing, signature, publicKey) { + checkIsPublicKey(publicKey); + thing = normalizeInput(thing); + signature = toBase64(signature); + var verifier = crypto12.createVerify("RSA-SHA" + bits); + verifier.update(thing); + return verifier.verify(publicKey, signature, "base64"); + }; + } + function createPSSKeySigner(bits) { + return function sign(thing, privateKey) { + checkIsPrivateKey(privateKey); + thing = normalizeInput(thing); + var signer = crypto12.createSign("RSA-SHA" + bits); + var sig = (signer.update(thing), signer.sign({ + key: privateKey, + padding: crypto12.constants.RSA_PKCS1_PSS_PADDING, + saltLength: crypto12.constants.RSA_PSS_SALTLEN_DIGEST + }, "base64")); + return fromBase64(sig); + }; + } + function createPSSKeyVerifier(bits) { + return function verify(thing, signature, publicKey) { + checkIsPublicKey(publicKey); + thing = normalizeInput(thing); + signature = toBase64(signature); + var verifier = crypto12.createVerify("RSA-SHA" + bits); + verifier.update(thing); + return verifier.verify({ + key: publicKey, + padding: crypto12.constants.RSA_PKCS1_PSS_PADDING, + saltLength: crypto12.constants.RSA_PSS_SALTLEN_DIGEST + }, signature, "base64"); + }; + } + function createECDSASigner(bits) { + var inner = createKeySigner(bits); + return function sign() { + var signature = inner.apply(null, arguments); + signature = formatEcdsa.derToJose(signature, "ES" + bits); + return signature; + }; + } + function createECDSAVerifer(bits) { + var inner = createKeyVerifier(bits); + return function verify(thing, signature, publicKey) { + signature = formatEcdsa.joseToDer(signature, "ES" + bits).toString("base64"); + var result = inner(thing, signature, publicKey); + return result; + }; + } + function createNoneSigner() { + return function sign() { + return ""; + }; + } + function createNoneVerifier() { + return function verify(thing, signature) { + return signature === ""; + }; + } + module2.exports = function jwa(algorithm) { + var signerFactories = { + hs: createHmacSigner, + rs: createKeySigner, + ps: createPSSKeySigner, + es: createECDSASigner, + none: createNoneSigner + }; + var verifierFactories = { + hs: createHmacVerifier, + rs: createKeyVerifier, + ps: createPSSKeyVerifier, + es: createECDSAVerifer, + none: createNoneVerifier + }; + var match = algorithm.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/); + if (!match) + throw typeError(MSG_INVALID_ALGORITHM, algorithm); + var algo = (match[1] || match[3]).toLowerCase(); + var bits = match[2]; + return { + sign: signerFactories[algo](bits), + verify: verifierFactories[algo](bits) + }; + }; + } +}); + +// node_modules/jws/lib/tostring.js +var require_tostring = __commonJS({ + "node_modules/jws/lib/tostring.js"(exports2, module2) { + var Buffer3 = require("buffer").Buffer; + module2.exports = function toString(obj) { + if (typeof obj === "string") + return obj; + if (typeof obj === "number" || Buffer3.isBuffer(obj)) + return obj.toString(); + return JSON.stringify(obj); + }; + } +}); + +// node_modules/jws/lib/sign-stream.js +var require_sign_stream = __commonJS({ + "node_modules/jws/lib/sign-stream.js"(exports2, module2) { + var Buffer3 = require_safe_buffer().Buffer; + var DataStream = require_data_stream(); + var jwa = require_jwa(); + var Stream = require("stream"); + var toString = require_tostring(); + var util = require("util"); + function base64url(string, encoding) { + return Buffer3.from(string, encoding).toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_"); + } + function jwsSecuredInput(header, payload, encoding) { + encoding = encoding || "utf8"; + var encodedHeader = base64url(toString(header), "binary"); + var encodedPayload = base64url(toString(payload), encoding); + return util.format("%s.%s", encodedHeader, encodedPayload); + } + function jwsSign(opts) { + var header = opts.header; + var payload = opts.payload; + var secretOrKey = opts.secret || opts.privateKey; + var encoding = opts.encoding; + var algo = jwa(header.alg); + var securedInput = jwsSecuredInput(header, payload, encoding); + var signature = algo.sign(securedInput, secretOrKey); + return util.format("%s.%s", securedInput, signature); + } + function SignStream(opts) { + var secret = opts.secret; + secret = secret == null ? opts.privateKey : secret; + secret = secret == null ? opts.key : secret; + if (/^hs/i.test(opts.header.alg) === true && secret == null) { + throw new TypeError("secret must be a string or buffer or a KeyObject"); + } + var secretStream = new DataStream(secret); + this.readable = true; + this.header = opts.header; + this.encoding = opts.encoding; + this.secret = this.privateKey = this.key = secretStream; + this.payload = new DataStream(opts.payload); + this.secret.once("close", function() { + if (!this.payload.writable && this.readable) + this.sign(); + }.bind(this)); + this.payload.once("close", function() { + if (!this.secret.writable && this.readable) + this.sign(); + }.bind(this)); + } + util.inherits(SignStream, Stream); + SignStream.prototype.sign = function sign() { + try { + var signature = jwsSign({ + header: this.header, + payload: this.payload.buffer, + secret: this.secret.buffer, + encoding: this.encoding + }); + this.emit("done", signature); + this.emit("data", signature); + this.emit("end"); + this.readable = false; + return signature; + } catch (e) { + this.readable = false; + this.emit("error", e); + this.emit("close"); + } + }; + SignStream.sign = jwsSign; + module2.exports = SignStream; + } +}); + +// node_modules/jws/lib/verify-stream.js +var require_verify_stream = __commonJS({ + "node_modules/jws/lib/verify-stream.js"(exports2, module2) { + var Buffer3 = require_safe_buffer().Buffer; + var DataStream = require_data_stream(); + var jwa = require_jwa(); + var Stream = require("stream"); + var toString = require_tostring(); + var util = require("util"); + var JWS_REGEX = /^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/; + function isObject2(thing) { + return Object.prototype.toString.call(thing) === "[object Object]"; + } + function safeJsonParse(thing) { + if (isObject2(thing)) + return thing; + try { + return JSON.parse(thing); + } catch (e) { + return void 0; + } + } + function headerFromJWS(jwsSig) { + var encodedHeader = jwsSig.split(".", 1)[0]; + return safeJsonParse(Buffer3.from(encodedHeader, "base64").toString("binary")); + } + function securedInputFromJWS(jwsSig) { + return jwsSig.split(".", 2).join("."); + } + function signatureFromJWS(jwsSig) { + return jwsSig.split(".")[2]; + } + function payloadFromJWS(jwsSig, encoding) { + encoding = encoding || "utf8"; + var payload = jwsSig.split(".")[1]; + return Buffer3.from(payload, "base64").toString(encoding); + } + function isValidJws(string) { + return JWS_REGEX.test(string) && !!headerFromJWS(string); + } + function jwsVerify(jwsSig, algorithm, secretOrKey) { + if (!algorithm) { + var err = new Error("Missing algorithm parameter for jws.verify"); + err.code = "MISSING_ALGORITHM"; + throw err; + } + jwsSig = toString(jwsSig); + var signature = signatureFromJWS(jwsSig); + var securedInput = securedInputFromJWS(jwsSig); + var algo = jwa(algorithm); + return algo.verify(securedInput, signature, secretOrKey); + } + function jwsDecode(jwsSig, opts) { + opts = opts || {}; + jwsSig = toString(jwsSig); + if (!isValidJws(jwsSig)) + return null; + var header = headerFromJWS(jwsSig); + if (!header) + return null; + var payload = payloadFromJWS(jwsSig); + if (header.typ === "JWT" || opts.json) + payload = JSON.parse(payload, opts.encoding); + return { + header, + payload, + signature: signatureFromJWS(jwsSig) + }; + } + function VerifyStream(opts) { + opts = opts || {}; + var secretOrKey = opts.secret; + secretOrKey = secretOrKey == null ? opts.publicKey : secretOrKey; + secretOrKey = secretOrKey == null ? opts.key : secretOrKey; + if (/^hs/i.test(opts.algorithm) === true && secretOrKey == null) { + throw new TypeError("secret must be a string or buffer or a KeyObject"); + } + var secretStream = new DataStream(secretOrKey); + this.readable = true; + this.algorithm = opts.algorithm; + this.encoding = opts.encoding; + this.secret = this.publicKey = this.key = secretStream; + this.signature = new DataStream(opts.signature); + this.secret.once("close", function() { + if (!this.signature.writable && this.readable) + this.verify(); + }.bind(this)); + this.signature.once("close", function() { + if (!this.secret.writable && this.readable) + this.verify(); + }.bind(this)); + } + util.inherits(VerifyStream, Stream); + VerifyStream.prototype.verify = function verify() { + try { + var valid = jwsVerify(this.signature.buffer, this.algorithm, this.key.buffer); + var obj = jwsDecode(this.signature.buffer, this.encoding); + this.emit("done", valid, obj); + this.emit("data", valid); + this.emit("end"); + this.readable = false; + return valid; + } catch (e) { + this.readable = false; + this.emit("error", e); + this.emit("close"); + } + }; + VerifyStream.decode = jwsDecode; + VerifyStream.isValid = isValidJws; + VerifyStream.verify = jwsVerify; + module2.exports = VerifyStream; + } +}); + +// node_modules/jws/index.js +var require_jws = __commonJS({ + "node_modules/jws/index.js"(exports2) { + var SignStream = require_sign_stream(); + var VerifyStream = require_verify_stream(); + var ALGORITHMS = [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "PS256", + "PS384", + "PS512", + "ES256", + "ES384", + "ES512" + ]; + exports2.ALGORITHMS = ALGORITHMS; + exports2.sign = SignStream.sign; + exports2.verify = VerifyStream.verify; + exports2.decode = VerifyStream.decode; + exports2.isValid = VerifyStream.isValid; + exports2.createSign = function createSign(opts) { + return new SignStream(opts); + }; + exports2.createVerify = function createVerify(opts) { + return new VerifyStream(opts); + }; + } +}); + +// node_modules/jsonwebtoken/decode.js +var require_decode = __commonJS({ + "node_modules/jsonwebtoken/decode.js"(exports2, module2) { + var jws = require_jws(); + module2.exports = function(jwt, options) { + options = options || {}; + var decoded = jws.decode(jwt, options); + if (!decoded) { + return null; + } + var payload = decoded.payload; + if (typeof payload === "string") { + try { + var obj = JSON.parse(payload); + if (obj !== null && typeof obj === "object") { + payload = obj; + } + } catch (e) { + } + } + if (options.complete === true) { + return { + header: decoded.header, + payload, + signature: decoded.signature + }; + } + return payload; + }; + } +}); + +// node_modules/jsonwebtoken/lib/JsonWebTokenError.js +var require_JsonWebTokenError = __commonJS({ + "node_modules/jsonwebtoken/lib/JsonWebTokenError.js"(exports2, module2) { + var JsonWebTokenError = function(message, error) { + Error.call(this, message); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + this.name = "JsonWebTokenError"; + this.message = message; + if (error) this.inner = error; + }; + JsonWebTokenError.prototype = Object.create(Error.prototype); + JsonWebTokenError.prototype.constructor = JsonWebTokenError; + module2.exports = JsonWebTokenError; + } +}); + +// node_modules/jsonwebtoken/lib/NotBeforeError.js +var require_NotBeforeError = __commonJS({ + "node_modules/jsonwebtoken/lib/NotBeforeError.js"(exports2, module2) { + var JsonWebTokenError = require_JsonWebTokenError(); + var NotBeforeError = function(message, date) { + JsonWebTokenError.call(this, message); + this.name = "NotBeforeError"; + this.date = date; + }; + NotBeforeError.prototype = Object.create(JsonWebTokenError.prototype); + NotBeforeError.prototype.constructor = NotBeforeError; + module2.exports = NotBeforeError; + } +}); + +// node_modules/jsonwebtoken/lib/TokenExpiredError.js +var require_TokenExpiredError = __commonJS({ + "node_modules/jsonwebtoken/lib/TokenExpiredError.js"(exports2, module2) { + var JsonWebTokenError = require_JsonWebTokenError(); + var TokenExpiredError = function(message, expiredAt) { + JsonWebTokenError.call(this, message); + this.name = "TokenExpiredError"; + this.expiredAt = expiredAt; + }; + TokenExpiredError.prototype = Object.create(JsonWebTokenError.prototype); + TokenExpiredError.prototype.constructor = TokenExpiredError; + module2.exports = TokenExpiredError; + } +}); + +// node_modules/jsonwebtoken/lib/timespan.js +var require_timespan = __commonJS({ + "node_modules/jsonwebtoken/lib/timespan.js"(exports2, module2) { + var ms = require_ms5(); + module2.exports = function(time, iat) { + var timestamp = iat || Math.floor(Date.now() / 1e3); + if (typeof time === "string") { + var milliseconds = ms(time); + if (typeof milliseconds === "undefined") { + return; + } + return Math.floor(timestamp + milliseconds / 1e3); + } else if (typeof time === "number") { + return timestamp + time; + } else { + return; + } + }; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/internal/constants.js +var require_constants3 = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/internal/constants.js"(exports2, module2) { + "use strict"; + var SEMVER_SPEC_VERSION = "2.0.0"; + var MAX_LENGTH = 256; + var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */ + 9007199254740991; + var MAX_SAFE_COMPONENT_LENGTH = 16; + var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6; + var RELEASE_TYPES = [ + "major", + "premajor", + "minor", + "preminor", + "patch", + "prepatch", + "prerelease" + ]; + module2.exports = { + MAX_LENGTH, + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_SAFE_INTEGER, + RELEASE_TYPES, + SEMVER_SPEC_VERSION, + FLAG_INCLUDE_PRERELEASE: 1, + FLAG_LOOSE: 2 + }; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/internal/debug.js +var require_debug6 = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/internal/debug.js"(exports2, module2) { + "use strict"; + var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => { + }; + module2.exports = debug; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/internal/re.js +var require_re = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/internal/re.js"(exports2, module2) { + "use strict"; + var { + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_LENGTH + } = require_constants3(); + var debug = require_debug6(); + exports2 = module2.exports = {}; + var re = exports2.re = []; + var safeRe = exports2.safeRe = []; + var src = exports2.src = []; + var safeSrc = exports2.safeSrc = []; + var t = exports2.t = {}; + var R = 0; + var LETTERDASHNUMBER = "[a-zA-Z0-9-]"; + var safeRegexReplacements = [ + ["\\s", 1], + ["\\d", MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH] + ]; + var makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value.split(`${token}*`).join(`${token}{0,${max}}`).split(`${token}+`).join(`${token}{1,${max}}`); + } + return value; + }; + var createToken = (name, value, isGlobal) => { + const safe = makeSafeRegex(value); + const index = R++; + debug(name, index, value); + t[name] = index; + src[index] = value; + safeSrc[index] = safe; + re[index] = new RegExp(value, isGlobal ? "g" : void 0); + safeRe[index] = new RegExp(safe, isGlobal ? "g" : void 0); + }; + createToken("NUMERICIDENTIFIER", "0|[1-9]\\d*"); + createToken("NUMERICIDENTIFIERLOOSE", "\\d+"); + createToken("NONNUMERICIDENTIFIER", `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`); + createToken("MAINVERSION", `(${src[t.NUMERICIDENTIFIER]})\\.(${src[t.NUMERICIDENTIFIER]})\\.(${src[t.NUMERICIDENTIFIER]})`); + createToken("MAINVERSIONLOOSE", `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.(${src[t.NUMERICIDENTIFIERLOOSE]})\\.(${src[t.NUMERICIDENTIFIERLOOSE]})`); + createToken("PRERELEASEIDENTIFIER", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIER]})`); + createToken("PRERELEASEIDENTIFIERLOOSE", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIERLOOSE]})`); + createToken("PRERELEASE", `(?:-(${src[t.PRERELEASEIDENTIFIER]}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`); + createToken("PRERELEASELOOSE", `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`); + createToken("BUILDIDENTIFIER", `${LETTERDASHNUMBER}+`); + createToken("BUILD", `(?:\\+(${src[t.BUILDIDENTIFIER]}(?:\\.${src[t.BUILDIDENTIFIER]})*))`); + createToken("FULLPLAIN", `v?${src[t.MAINVERSION]}${src[t.PRERELEASE]}?${src[t.BUILD]}?`); + createToken("FULL", `^${src[t.FULLPLAIN]}$`); + createToken("LOOSEPLAIN", `[v=\\s]*${src[t.MAINVERSIONLOOSE]}${src[t.PRERELEASELOOSE]}?${src[t.BUILD]}?`); + createToken("LOOSE", `^${src[t.LOOSEPLAIN]}$`); + createToken("GTLT", "((?:<|>)?=?)"); + createToken("XRANGEIDENTIFIERLOOSE", `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`); + createToken("XRANGEIDENTIFIER", `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`); + createToken("XRANGEPLAIN", `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})(?:\\.(${src[t.XRANGEIDENTIFIER]})(?:\\.(${src[t.XRANGEIDENTIFIER]})(?:${src[t.PRERELEASE]})?${src[t.BUILD]}?)?)?`); + createToken("XRANGEPLAINLOOSE", `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})(?:${src[t.PRERELEASELOOSE]})?${src[t.BUILD]}?)?)?`); + createToken("XRANGE", `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`); + createToken("XRANGELOOSE", `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`); + createToken("COERCEPLAIN", `${"(^|[^\\d])(\\d{1,"}${MAX_SAFE_COMPONENT_LENGTH}})(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`); + createToken("COERCE", `${src[t.COERCEPLAIN]}(?:$|[^\\d])`); + createToken("COERCEFULL", src[t.COERCEPLAIN] + `(?:${src[t.PRERELEASE]})?(?:${src[t.BUILD]})?(?:$|[^\\d])`); + createToken("COERCERTL", src[t.COERCE], true); + createToken("COERCERTLFULL", src[t.COERCEFULL], true); + createToken("LONETILDE", "(?:~>?)"); + createToken("TILDETRIM", `(\\s*)${src[t.LONETILDE]}\\s+`, true); + exports2.tildeTrimReplace = "$1~"; + createToken("TILDE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`); + createToken("TILDELOOSE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`); + createToken("LONECARET", "(?:\\^)"); + createToken("CARETTRIM", `(\\s*)${src[t.LONECARET]}\\s+`, true); + exports2.caretTrimReplace = "$1^"; + createToken("CARET", `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`); + createToken("CARETLOOSE", `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`); + createToken("COMPARATORLOOSE", `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`); + createToken("COMPARATOR", `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`); + createToken("COMPARATORTRIM", `(\\s*)${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true); + exports2.comparatorTrimReplace = "$1$2$3"; + createToken("HYPHENRANGE", `^\\s*(${src[t.XRANGEPLAIN]})\\s+-\\s+(${src[t.XRANGEPLAIN]})\\s*$`); + createToken("HYPHENRANGELOOSE", `^\\s*(${src[t.XRANGEPLAINLOOSE]})\\s+-\\s+(${src[t.XRANGEPLAINLOOSE]})\\s*$`); + createToken("STAR", "(<|>)?=?\\s*\\*"); + createToken("GTE0", "^\\s*>=\\s*0\\.0\\.0\\s*$"); + createToken("GTE0PRE", "^\\s*>=\\s*0\\.0\\.0-0\\s*$"); + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/internal/parse-options.js +var require_parse_options = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/internal/parse-options.js"(exports2, module2) { + "use strict"; + var looseOption = Object.freeze({ loose: true }); + var emptyOpts = Object.freeze({}); + var parseOptions = (options) => { + if (!options) { + return emptyOpts; + } + if (typeof options !== "object") { + return looseOption; + } + return options; + }; + module2.exports = parseOptions; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/internal/identifiers.js +var require_identifiers = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/internal/identifiers.js"(exports2, module2) { + "use strict"; + var numeric = /^[0-9]+$/; + var compareIdentifiers = (a, b) => { + if (typeof a === "number" && typeof b === "number") { + return a === b ? 0 : a < b ? -1 : 1; + } + const anum = numeric.test(a); + const bnum = numeric.test(b); + if (anum && bnum) { + a = +a; + b = +b; + } + return a === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : 1; + }; + var rcompareIdentifiers = (a, b) => compareIdentifiers(b, a); + module2.exports = { + compareIdentifiers, + rcompareIdentifiers + }; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/classes/semver.js +var require_semver = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/classes/semver.js"(exports2, module2) { + "use strict"; + var debug = require_debug6(); + var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants3(); + var { safeRe: re, t } = require_re(); + var parseOptions = require_parse_options(); + var { compareIdentifiers } = require_identifiers(); + var SemVer = class _SemVer { + constructor(version4, options) { + options = parseOptions(options); + if (version4 instanceof _SemVer) { + if (version4.loose === !!options.loose && version4.includePrerelease === !!options.includePrerelease) { + return version4; + } else { + version4 = version4.version; + } + } else if (typeof version4 !== "string") { + throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version4}".`); + } + if (version4.length > MAX_LENGTH) { + throw new TypeError( + `version is longer than ${MAX_LENGTH} characters` + ); + } + debug("SemVer", version4, options); + this.options = options; + this.loose = !!options.loose; + this.includePrerelease = !!options.includePrerelease; + const m = version4.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]); + if (!m) { + throw new TypeError(`Invalid Version: ${version4}`); + } + this.raw = version4; + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError("Invalid major version"); + } + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError("Invalid minor version"); + } + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError("Invalid patch version"); + } + if (!m[4]) { + this.prerelease = []; + } else { + this.prerelease = m[4].split(".").map((id) => { + if (/^[0-9]+$/.test(id)) { + const num = +id; + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num; + } + } + return id; + }); + } + this.build = m[5] ? m[5].split(".") : []; + this.format(); + } + format() { + this.version = `${this.major}.${this.minor}.${this.patch}`; + if (this.prerelease.length) { + this.version += `-${this.prerelease.join(".")}`; + } + return this.version; + } + toString() { + return this.version; + } + compare(other) { + debug("SemVer.compare", this.version, this.options, other); + if (!(other instanceof _SemVer)) { + if (typeof other === "string" && other === this.version) { + return 0; + } + other = new _SemVer(other, this.options); + } + if (other.version === this.version) { + return 0; + } + return this.compareMain(other) || this.comparePre(other); + } + compareMain(other) { + if (!(other instanceof _SemVer)) { + other = new _SemVer(other, this.options); + } + if (this.major < other.major) { + return -1; + } + if (this.major > other.major) { + return 1; + } + if (this.minor < other.minor) { + return -1; + } + if (this.minor > other.minor) { + return 1; + } + if (this.patch < other.patch) { + return -1; + } + if (this.patch > other.patch) { + return 1; + } + return 0; + } + comparePre(other) { + if (!(other instanceof _SemVer)) { + other = new _SemVer(other, this.options); + } + if (this.prerelease.length && !other.prerelease.length) { + return -1; + } else if (!this.prerelease.length && other.prerelease.length) { + return 1; + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0; + } + let i = 0; + do { + const a = this.prerelease[i]; + const b = other.prerelease[i]; + debug("prerelease compare", i, a, b); + if (a === void 0 && b === void 0) { + return 0; + } else if (b === void 0) { + return 1; + } else if (a === void 0) { + return -1; + } else if (a === b) { + continue; + } else { + return compareIdentifiers(a, b); + } + } while (++i); + } + compareBuild(other) { + if (!(other instanceof _SemVer)) { + other = new _SemVer(other, this.options); + } + let i = 0; + do { + const a = this.build[i]; + const b = other.build[i]; + debug("build compare", i, a, b); + if (a === void 0 && b === void 0) { + return 0; + } else if (b === void 0) { + return 1; + } else if (a === void 0) { + return -1; + } else if (a === b) { + continue; + } else { + return compareIdentifiers(a, b); + } + } while (++i); + } + // preminor will bump the version up to the next minor release, and immediately + // down to pre-release. premajor and prepatch work the same way. + inc(release, identifier, identifierBase) { + if (release.startsWith("pre")) { + if (!identifier && identifierBase === false) { + throw new Error("invalid increment argument: identifier is empty"); + } + if (identifier) { + const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE]); + if (!match || match[1] !== identifier) { + throw new Error(`invalid identifier: ${identifier}`); + } + } + } + switch (release) { + case "premajor": + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc("pre", identifier, identifierBase); + break; + case "preminor": + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc("pre", identifier, identifierBase); + break; + case "prepatch": + this.prerelease.length = 0; + this.inc("patch", identifier, identifierBase); + this.inc("pre", identifier, identifierBase); + break; + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case "prerelease": + if (this.prerelease.length === 0) { + this.inc("patch", identifier, identifierBase); + } + this.inc("pre", identifier, identifierBase); + break; + case "release": + if (this.prerelease.length === 0) { + throw new Error(`version ${this.raw} is not a prerelease`); + } + this.prerelease.length = 0; + break; + case "major": + if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) { + this.major++; + } + this.minor = 0; + this.patch = 0; + this.prerelease = []; + break; + case "minor": + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++; + } + this.patch = 0; + this.prerelease = []; + break; + case "patch": + if (this.prerelease.length === 0) { + this.patch++; + } + this.prerelease = []; + break; + // This probably shouldn't be used publicly. + // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. + case "pre": { + const base = Number(identifierBase) ? 1 : 0; + if (this.prerelease.length === 0) { + this.prerelease = [base]; + } else { + let i = this.prerelease.length; + while (--i >= 0) { + if (typeof this.prerelease[i] === "number") { + this.prerelease[i]++; + i = -2; + } + } + if (i === -1) { + if (identifier === this.prerelease.join(".") && identifierBase === false) { + throw new Error("invalid increment argument: identifier already exists"); + } + this.prerelease.push(base); + } + } + if (identifier) { + let prerelease = [identifier, base]; + if (identifierBase === false) { + prerelease = [identifier]; + } + if (compareIdentifiers(this.prerelease[0], identifier) === 0) { + if (isNaN(this.prerelease[1])) { + this.prerelease = prerelease; + } + } else { + this.prerelease = prerelease; + } + } + break; + } + default: + throw new Error(`invalid increment argument: ${release}`); + } + this.raw = this.format(); + if (this.build.length) { + this.raw += `+${this.build.join(".")}`; + } + return this; + } + }; + module2.exports = SemVer; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/parse.js +var require_parse2 = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/parse.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var parse4 = (version4, options, throwErrors = false) => { + if (version4 instanceof SemVer) { + return version4; + } + try { + return new SemVer(version4, options); + } catch (er) { + if (!throwErrors) { + return null; + } + throw er; + } + }; + module2.exports = parse4; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/valid.js +var require_valid = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/valid.js"(exports2, module2) { + "use strict"; + var parse4 = require_parse2(); + var valid = (version4, options) => { + const v = parse4(version4, options); + return v ? v.version : null; + }; + module2.exports = valid; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/clean.js +var require_clean = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/clean.js"(exports2, module2) { + "use strict"; + var parse4 = require_parse2(); + var clean = (version4, options) => { + const s = parse4(version4.trim().replace(/^[=v]+/, ""), options); + return s ? s.version : null; + }; + module2.exports = clean; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/inc.js +var require_inc = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/inc.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var inc = (version4, release, options, identifier, identifierBase) => { + if (typeof options === "string") { + identifierBase = identifier; + identifier = options; + options = void 0; + } + try { + return new SemVer( + version4 instanceof SemVer ? version4.version : version4, + options + ).inc(release, identifier, identifierBase).version; + } catch (er) { + return null; + } + }; + module2.exports = inc; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/diff.js +var require_diff = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/diff.js"(exports2, module2) { + "use strict"; + var parse4 = require_parse2(); + var diff = (version1, version22) => { + const v14 = parse4(version1, null, true); + const v2 = parse4(version22, null, true); + const comparison = v14.compare(v2); + if (comparison === 0) { + return null; + } + const v1Higher = comparison > 0; + const highVersion = v1Higher ? v14 : v2; + const lowVersion = v1Higher ? v2 : v14; + const highHasPre = !!highVersion.prerelease.length; + const lowHasPre = !!lowVersion.prerelease.length; + if (lowHasPre && !highHasPre) { + if (!lowVersion.patch && !lowVersion.minor) { + return "major"; + } + if (lowVersion.compareMain(highVersion) === 0) { + if (lowVersion.minor && !lowVersion.patch) { + return "minor"; + } + return "patch"; + } + } + const prefix = highHasPre ? "pre" : ""; + if (v14.major !== v2.major) { + return prefix + "major"; + } + if (v14.minor !== v2.minor) { + return prefix + "minor"; + } + if (v14.patch !== v2.patch) { + return prefix + "patch"; + } + return "prerelease"; + }; + module2.exports = diff; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/major.js +var require_major = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/major.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var major = (a, loose) => new SemVer(a, loose).major; + module2.exports = major; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/minor.js +var require_minor = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/minor.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var minor = (a, loose) => new SemVer(a, loose).minor; + module2.exports = minor; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/patch.js +var require_patch = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/patch.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var patch = (a, loose) => new SemVer(a, loose).patch; + module2.exports = patch; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/prerelease.js +var require_prerelease = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/prerelease.js"(exports2, module2) { + "use strict"; + var parse4 = require_parse2(); + var prerelease = (version4, options) => { + const parsed = parse4(version4, options); + return parsed && parsed.prerelease.length ? parsed.prerelease : null; + }; + module2.exports = prerelease; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/compare.js +var require_compare = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/compare.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var compare = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose)); + module2.exports = compare; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/rcompare.js +var require_rcompare = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/rcompare.js"(exports2, module2) { + "use strict"; + var compare = require_compare(); + var rcompare = (a, b, loose) => compare(b, a, loose); + module2.exports = rcompare; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/compare-loose.js +var require_compare_loose = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/compare-loose.js"(exports2, module2) { + "use strict"; + var compare = require_compare(); + var compareLoose = (a, b) => compare(a, b, true); + module2.exports = compareLoose; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/compare-build.js +var require_compare_build = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/compare-build.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var compareBuild = (a, b, loose) => { + const versionA = new SemVer(a, loose); + const versionB = new SemVer(b, loose); + return versionA.compare(versionB) || versionA.compareBuild(versionB); + }; + module2.exports = compareBuild; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/sort.js +var require_sort = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/sort.js"(exports2, module2) { + "use strict"; + var compareBuild = require_compare_build(); + var sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose)); + module2.exports = sort; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/rsort.js +var require_rsort = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/rsort.js"(exports2, module2) { + "use strict"; + var compareBuild = require_compare_build(); + var rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose)); + module2.exports = rsort; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/gt.js +var require_gt = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/gt.js"(exports2, module2) { + "use strict"; + var compare = require_compare(); + var gt = (a, b, loose) => compare(a, b, loose) > 0; + module2.exports = gt; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/lt.js +var require_lt = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/lt.js"(exports2, module2) { + "use strict"; + var compare = require_compare(); + var lt = (a, b, loose) => compare(a, b, loose) < 0; + module2.exports = lt; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/eq.js +var require_eq = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/eq.js"(exports2, module2) { + "use strict"; + var compare = require_compare(); + var eq = (a, b, loose) => compare(a, b, loose) === 0; + module2.exports = eq; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/neq.js +var require_neq = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/neq.js"(exports2, module2) { + "use strict"; + var compare = require_compare(); + var neq = (a, b, loose) => compare(a, b, loose) !== 0; + module2.exports = neq; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/gte.js +var require_gte = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/gte.js"(exports2, module2) { + "use strict"; + var compare = require_compare(); + var gte = (a, b, loose) => compare(a, b, loose) >= 0; + module2.exports = gte; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/lte.js +var require_lte = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/lte.js"(exports2, module2) { + "use strict"; + var compare = require_compare(); + var lte = (a, b, loose) => compare(a, b, loose) <= 0; + module2.exports = lte; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/cmp.js +var require_cmp = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/cmp.js"(exports2, module2) { + "use strict"; + var eq = require_eq(); + var neq = require_neq(); + var gt = require_gt(); + var gte = require_gte(); + var lt = require_lt(); + var lte = require_lte(); + var cmp = (a, op, b, loose) => { + switch (op) { + case "===": + if (typeof a === "object") { + a = a.version; + } + if (typeof b === "object") { + b = b.version; + } + return a === b; + case "!==": + if (typeof a === "object") { + a = a.version; + } + if (typeof b === "object") { + b = b.version; + } + return a !== b; + case "": + case "=": + case "==": + return eq(a, b, loose); + case "!=": + return neq(a, b, loose); + case ">": + return gt(a, b, loose); + case ">=": + return gte(a, b, loose); + case "<": + return lt(a, b, loose); + case "<=": + return lte(a, b, loose); + default: + throw new TypeError(`Invalid operator: ${op}`); + } + }; + module2.exports = cmp; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/coerce.js +var require_coerce = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/coerce.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var parse4 = require_parse2(); + var { safeRe: re, t } = require_re(); + var coerce = (version4, options) => { + if (version4 instanceof SemVer) { + return version4; + } + if (typeof version4 === "number") { + version4 = String(version4); + } + if (typeof version4 !== "string") { + return null; + } + options = options || {}; + let match = null; + if (!options.rtl) { + match = version4.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]); + } else { + const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL]; + let next; + while ((next = coerceRtlRegex.exec(version4)) && (!match || match.index + match[0].length !== version4.length)) { + if (!match || next.index + next[0].length !== match.index + match[0].length) { + match = next; + } + coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length; + } + coerceRtlRegex.lastIndex = -1; + } + if (match === null) { + return null; + } + const major = match[2]; + const minor = match[3] || "0"; + const patch = match[4] || "0"; + const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : ""; + const build = options.includePrerelease && match[6] ? `+${match[6]}` : ""; + return parse4(`${major}.${minor}.${patch}${prerelease}${build}`, options); + }; + module2.exports = coerce; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/internal/lrucache.js +var require_lrucache = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/internal/lrucache.js"(exports2, module2) { + "use strict"; + var LRUCache = class { + constructor() { + this.max = 1e3; + this.map = /* @__PURE__ */ new Map(); + } + get(key) { + const value = this.map.get(key); + if (value === void 0) { + return void 0; + } else { + this.map.delete(key); + this.map.set(key, value); + return value; + } + } + delete(key) { + return this.map.delete(key); + } + set(key, value) { + const deleted = this.delete(key); + if (!deleted && value !== void 0) { + if (this.map.size >= this.max) { + const firstKey = this.map.keys().next().value; + this.delete(firstKey); + } + this.map.set(key, value); + } + return this; + } + }; + module2.exports = LRUCache; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/classes/range.js +var require_range2 = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/classes/range.js"(exports2, module2) { + "use strict"; + var SPACE_CHARACTERS = /\s+/g; + var Range = class _Range { + constructor(range, options) { + options = parseOptions(options); + if (range instanceof _Range) { + if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) { + return range; + } else { + return new _Range(range.raw, options); + } + } + if (range instanceof Comparator) { + this.raw = range.value; + this.set = [[range]]; + this.formatted = void 0; + return this; + } + this.options = options; + this.loose = !!options.loose; + this.includePrerelease = !!options.includePrerelease; + this.raw = range.trim().replace(SPACE_CHARACTERS, " "); + this.set = this.raw.split("||").map((r) => this.parseRange(r.trim())).filter((c) => c.length); + if (!this.set.length) { + throw new TypeError(`Invalid SemVer Range: ${this.raw}`); + } + if (this.set.length > 1) { + const first = this.set[0]; + this.set = this.set.filter((c) => !isNullSet(c[0])); + if (this.set.length === 0) { + this.set = [first]; + } else if (this.set.length > 1) { + for (const c of this.set) { + if (c.length === 1 && isAny(c[0])) { + this.set = [c]; + break; + } + } + } + } + this.formatted = void 0; + } + get range() { + if (this.formatted === void 0) { + this.formatted = ""; + for (let i = 0; i < this.set.length; i++) { + if (i > 0) { + this.formatted += "||"; + } + const comps = this.set[i]; + for (let k = 0; k < comps.length; k++) { + if (k > 0) { + this.formatted += " "; + } + this.formatted += comps[k].toString().trim(); + } + } + } + return this.formatted; + } + format() { + return this.range; + } + toString() { + return this.range; + } + parseRange(range) { + const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE); + const memoKey = memoOpts + ":" + range; + const cached = cache.get(memoKey); + if (cached) { + return cached; + } + const loose = this.options.loose; + const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]; + range = range.replace(hr, hyphenReplace(this.options.includePrerelease)); + debug("hyphen replace", range); + range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace); + debug("comparator trim", range); + range = range.replace(re[t.TILDETRIM], tildeTrimReplace); + debug("tilde trim", range); + range = range.replace(re[t.CARETTRIM], caretTrimReplace); + debug("caret trim", range); + let rangeList = range.split(" ").map((comp) => parseComparator(comp, this.options)).join(" ").split(/\s+/).map((comp) => replaceGTE0(comp, this.options)); + if (loose) { + rangeList = rangeList.filter((comp) => { + debug("loose invalid filter", comp, this.options); + return !!comp.match(re[t.COMPARATORLOOSE]); + }); + } + debug("range list", rangeList); + const rangeMap = /* @__PURE__ */ new Map(); + const comparators = rangeList.map((comp) => new Comparator(comp, this.options)); + for (const comp of comparators) { + if (isNullSet(comp)) { + return [comp]; + } + rangeMap.set(comp.value, comp); + } + if (rangeMap.size > 1 && rangeMap.has("")) { + rangeMap.delete(""); + } + const result = [...rangeMap.values()]; + cache.set(memoKey, result); + return result; + } + intersects(range, options) { + if (!(range instanceof _Range)) { + throw new TypeError("a Range is required"); + } + return this.set.some((thisComparators) => { + return isSatisfiable(thisComparators, options) && range.set.some((rangeComparators) => { + return isSatisfiable(rangeComparators, options) && thisComparators.every((thisComparator) => { + return rangeComparators.every((rangeComparator) => { + return thisComparator.intersects(rangeComparator, options); + }); + }); + }); + }); + } + // if ANY of the sets match ALL of its comparators, then pass + test(version4) { + if (!version4) { + return false; + } + if (typeof version4 === "string") { + try { + version4 = new SemVer(version4, this.options); + } catch (er) { + return false; + } + } + for (let i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version4, this.options)) { + return true; + } + } + return false; + } + }; + module2.exports = Range; + var LRU = require_lrucache(); + var cache = new LRU(); + var parseOptions = require_parse_options(); + var Comparator = require_comparator(); + var debug = require_debug6(); + var SemVer = require_semver(); + var { + safeRe: re, + t, + comparatorTrimReplace, + tildeTrimReplace, + caretTrimReplace + } = require_re(); + var { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require_constants3(); + var isNullSet = (c) => c.value === "<0.0.0-0"; + var isAny = (c) => c.value === ""; + var isSatisfiable = (comparators, options) => { + let result = true; + const remainingComparators = comparators.slice(); + let testComparator = remainingComparators.pop(); + while (result && remainingComparators.length) { + result = remainingComparators.every((otherComparator) => { + return testComparator.intersects(otherComparator, options); + }); + testComparator = remainingComparators.pop(); + } + return result; + }; + var parseComparator = (comp, options) => { + comp = comp.replace(re[t.BUILD], ""); + debug("comp", comp, options); + comp = replaceCarets(comp, options); + debug("caret", comp); + comp = replaceTildes(comp, options); + debug("tildes", comp); + comp = replaceXRanges(comp, options); + debug("xrange", comp); + comp = replaceStars(comp, options); + debug("stars", comp); + return comp; + }; + var isX = (id) => !id || id.toLowerCase() === "x" || id === "*"; + var replaceTildes = (comp, options) => { + return comp.trim().split(/\s+/).map((c) => replaceTilde(c, options)).join(" "); + }; + var replaceTilde = (comp, options) => { + const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]; + return comp.replace(r, (_, M, m, p, pr) => { + debug("tilde", comp, _, M, m, p, pr); + let ret; + if (isX(M)) { + ret = ""; + } else if (isX(m)) { + ret = `>=${M}.0.0 <${+M + 1}.0.0-0`; + } else if (isX(p)) { + ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`; + } else if (pr) { + debug("replaceTilde pr", pr); + ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`; + } else { + ret = `>=${M}.${m}.${p} <${M}.${+m + 1}.0-0`; + } + debug("tilde return", ret); + return ret; + }); + }; + var replaceCarets = (comp, options) => { + return comp.trim().split(/\s+/).map((c) => replaceCaret(c, options)).join(" "); + }; + var replaceCaret = (comp, options) => { + debug("caret", comp, options); + const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET]; + const z = options.includePrerelease ? "-0" : ""; + return comp.replace(r, (_, M, m, p, pr) => { + debug("caret", comp, _, M, m, p, pr); + let ret; + if (isX(M)) { + ret = ""; + } else if (isX(m)) { + ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`; + } else if (isX(p)) { + if (M === "0") { + ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`; + } else { + ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`; + } + } else if (pr) { + debug("replaceCaret pr", pr); + if (M === "0") { + if (m === "0") { + ret = `>=${M}.${m}.${p}-${pr} <${M}.${m}.${+p + 1}-0`; + } else { + ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`; + } + } else { + ret = `>=${M}.${m}.${p}-${pr} <${+M + 1}.0.0-0`; + } + } else { + debug("no pr"); + if (M === "0") { + if (m === "0") { + ret = `>=${M}.${m}.${p}${z} <${M}.${m}.${+p + 1}-0`; + } else { + ret = `>=${M}.${m}.${p}${z} <${M}.${+m + 1}.0-0`; + } + } else { + ret = `>=${M}.${m}.${p} <${+M + 1}.0.0-0`; + } + } + debug("caret return", ret); + return ret; + }); + }; + var replaceXRanges = (comp, options) => { + debug("replaceXRanges", comp, options); + return comp.split(/\s+/).map((c) => replaceXRange(c, options)).join(" "); + }; + var replaceXRange = (comp, options) => { + comp = comp.trim(); + const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]; + return comp.replace(r, (ret, gtlt, M, m, p, pr) => { + debug("xRange", comp, ret, gtlt, M, m, p, pr); + const xM = isX(M); + const xm = xM || isX(m); + const xp = xm || isX(p); + const anyX = xp; + if (gtlt === "=" && anyX) { + gtlt = ""; + } + pr = options.includePrerelease ? "-0" : ""; + if (xM) { + if (gtlt === ">" || gtlt === "<") { + ret = "<0.0.0-0"; + } else { + ret = "*"; + } + } else if (gtlt && anyX) { + if (xm) { + m = 0; + } + p = 0; + if (gtlt === ">") { + gtlt = ">="; + if (xm) { + M = +M + 1; + m = 0; + p = 0; + } else { + m = +m + 1; + p = 0; + } + } else if (gtlt === "<=") { + gtlt = "<"; + if (xm) { + M = +M + 1; + } else { + m = +m + 1; + } + } + if (gtlt === "<") { + pr = "-0"; + } + ret = `${gtlt + M}.${m}.${p}${pr}`; + } else if (xm) { + ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`; + } else if (xp) { + ret = `>=${M}.${m}.0${pr} <${M}.${+m + 1}.0-0`; + } + debug("xRange return", ret); + return ret; + }); + }; + var replaceStars = (comp, options) => { + debug("replaceStars", comp, options); + return comp.trim().replace(re[t.STAR], ""); + }; + var replaceGTE0 = (comp, options) => { + debug("replaceGTE0", comp, options); + return comp.trim().replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], ""); + }; + var hyphenReplace = (incPr) => ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr) => { + if (isX(fM)) { + from = ""; + } else if (isX(fm)) { + from = `>=${fM}.0.0${incPr ? "-0" : ""}`; + } else if (isX(fp)) { + from = `>=${fM}.${fm}.0${incPr ? "-0" : ""}`; + } else if (fpr) { + from = `>=${from}`; + } else { + from = `>=${from}${incPr ? "-0" : ""}`; + } + if (isX(tM)) { + to = ""; + } else if (isX(tm)) { + to = `<${+tM + 1}.0.0-0`; + } else if (isX(tp)) { + to = `<${tM}.${+tm + 1}.0-0`; + } else if (tpr) { + to = `<=${tM}.${tm}.${tp}-${tpr}`; + } else if (incPr) { + to = `<${tM}.${tm}.${+tp + 1}-0`; + } else { + to = `<=${to}`; + } + return `${from} ${to}`.trim(); + }; + var testSet = (set, version4, options) => { + for (let i = 0; i < set.length; i++) { + if (!set[i].test(version4)) { + return false; + } + } + if (version4.prerelease.length && !options.includePrerelease) { + for (let i = 0; i < set.length; i++) { + debug(set[i].semver); + if (set[i].semver === Comparator.ANY) { + continue; + } + if (set[i].semver.prerelease.length > 0) { + const allowed = set[i].semver; + if (allowed.major === version4.major && allowed.minor === version4.minor && allowed.patch === version4.patch) { + return true; + } + } + } + return false; + } + return true; + }; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/classes/comparator.js +var require_comparator = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/classes/comparator.js"(exports2, module2) { + "use strict"; + var ANY = Symbol("SemVer ANY"); + var Comparator = class _Comparator { + static get ANY() { + return ANY; + } + constructor(comp, options) { + options = parseOptions(options); + if (comp instanceof _Comparator) { + if (comp.loose === !!options.loose) { + return comp; + } else { + comp = comp.value; + } + } + comp = comp.trim().split(/\s+/).join(" "); + debug("comparator", comp, options); + this.options = options; + this.loose = !!options.loose; + this.parse(comp); + if (this.semver === ANY) { + this.value = ""; + } else { + this.value = this.operator + this.semver.version; + } + debug("comp", this); + } + parse(comp) { + const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]; + const m = comp.match(r); + if (!m) { + throw new TypeError(`Invalid comparator: ${comp}`); + } + this.operator = m[1] !== void 0 ? m[1] : ""; + if (this.operator === "=") { + this.operator = ""; + } + if (!m[2]) { + this.semver = ANY; + } else { + this.semver = new SemVer(m[2], this.options.loose); + } + } + toString() { + return this.value; + } + test(version4) { + debug("Comparator.test", version4, this.options.loose); + if (this.semver === ANY || version4 === ANY) { + return true; + } + if (typeof version4 === "string") { + try { + version4 = new SemVer(version4, this.options); + } catch (er) { + return false; + } + } + return cmp(version4, this.operator, this.semver, this.options); + } + intersects(comp, options) { + if (!(comp instanceof _Comparator)) { + throw new TypeError("a Comparator is required"); + } + if (this.operator === "") { + if (this.value === "") { + return true; + } + return new Range(comp.value, options).test(this.value); + } else if (comp.operator === "") { + if (comp.value === "") { + return true; + } + return new Range(this.value, options).test(comp.semver); + } + options = parseOptions(options); + if (options.includePrerelease && (this.value === "<0.0.0-0" || comp.value === "<0.0.0-0")) { + return false; + } + if (!options.includePrerelease && (this.value.startsWith("<0.0.0") || comp.value.startsWith("<0.0.0"))) { + return false; + } + if (this.operator.startsWith(">") && comp.operator.startsWith(">")) { + return true; + } + if (this.operator.startsWith("<") && comp.operator.startsWith("<")) { + return true; + } + if (this.semver.version === comp.semver.version && this.operator.includes("=") && comp.operator.includes("=")) { + return true; + } + if (cmp(this.semver, "<", comp.semver, options) && this.operator.startsWith(">") && comp.operator.startsWith("<")) { + return true; + } + if (cmp(this.semver, ">", comp.semver, options) && this.operator.startsWith("<") && comp.operator.startsWith(">")) { + return true; + } + return false; + } + }; + module2.exports = Comparator; + var parseOptions = require_parse_options(); + var { safeRe: re, t } = require_re(); + var cmp = require_cmp(); + var debug = require_debug6(); + var SemVer = require_semver(); + var Range = require_range2(); + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/functions/satisfies.js +var require_satisfies = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/functions/satisfies.js"(exports2, module2) { + "use strict"; + var Range = require_range2(); + var satisfies = (version4, range, options) => { + try { + range = new Range(range, options); + } catch (er) { + return false; + } + return range.test(version4); + }; + module2.exports = satisfies; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/to-comparators.js +var require_to_comparators = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/to-comparators.js"(exports2, module2) { + "use strict"; + var Range = require_range2(); + var toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c) => c.value).join(" ").trim().split(" ")); + module2.exports = toComparators; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/max-satisfying.js +var require_max_satisfying = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/max-satisfying.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var Range = require_range2(); + var maxSatisfying = (versions, range, options) => { + let max = null; + let maxSV = null; + let rangeObj = null; + try { + rangeObj = new Range(range, options); + } catch (er) { + return null; + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + if (!max || maxSV.compare(v) === -1) { + max = v; + maxSV = new SemVer(max, options); + } + } + }); + return max; + }; + module2.exports = maxSatisfying; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/min-satisfying.js +var require_min_satisfying = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/min-satisfying.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var Range = require_range2(); + var minSatisfying = (versions, range, options) => { + let min = null; + let minSV = null; + let rangeObj = null; + try { + rangeObj = new Range(range, options); + } catch (er) { + return null; + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + if (!min || minSV.compare(v) === 1) { + min = v; + minSV = new SemVer(min, options); + } + } + }); + return min; + }; + module2.exports = minSatisfying; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/min-version.js +var require_min_version = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/min-version.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var Range = require_range2(); + var gt = require_gt(); + var minVersion = (range, loose) => { + range = new Range(range, loose); + let minver = new SemVer("0.0.0"); + if (range.test(minver)) { + return minver; + } + minver = new SemVer("0.0.0-0"); + if (range.test(minver)) { + return minver; + } + minver = null; + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i]; + let setMin = null; + comparators.forEach((comparator) => { + const compver = new SemVer(comparator.semver.version); + switch (comparator.operator) { + case ">": + if (compver.prerelease.length === 0) { + compver.patch++; + } else { + compver.prerelease.push(0); + } + compver.raw = compver.format(); + /* fallthrough */ + case "": + case ">=": + if (!setMin || gt(compver, setMin)) { + setMin = compver; + } + break; + case "<": + case "<=": + break; + /* istanbul ignore next */ + default: + throw new Error(`Unexpected operation: ${comparator.operator}`); + } + }); + if (setMin && (!minver || gt(minver, setMin))) { + minver = setMin; + } + } + if (minver && range.test(minver)) { + return minver; + } + return null; + }; + module2.exports = minVersion; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/valid.js +var require_valid2 = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/valid.js"(exports2, module2) { + "use strict"; + var Range = require_range2(); + var validRange = (range, options) => { + try { + return new Range(range, options).range || "*"; + } catch (er) { + return null; + } + }; + module2.exports = validRange; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/outside.js +var require_outside = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/outside.js"(exports2, module2) { + "use strict"; + var SemVer = require_semver(); + var Comparator = require_comparator(); + var { ANY } = Comparator; + var Range = require_range2(); + var satisfies = require_satisfies(); + var gt = require_gt(); + var lt = require_lt(); + var lte = require_lte(); + var gte = require_gte(); + var outside = (version4, range, hilo, options) => { + version4 = new SemVer(version4, options); + range = new Range(range, options); + let gtfn, ltefn, ltfn, comp, ecomp; + switch (hilo) { + case ">": + gtfn = gt; + ltefn = lte; + ltfn = lt; + comp = ">"; + ecomp = ">="; + break; + case "<": + gtfn = lt; + ltefn = gte; + ltfn = gt; + comp = "<"; + ecomp = "<="; + break; + default: + throw new TypeError('Must provide a hilo val of "<" or ">"'); + } + if (satisfies(version4, range, options)) { + return false; + } + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i]; + let high = null; + let low = null; + comparators.forEach((comparator) => { + if (comparator.semver === ANY) { + comparator = new Comparator(">=0.0.0"); + } + high = high || comparator; + low = low || comparator; + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator; + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator; + } + }); + if (high.operator === comp || high.operator === ecomp) { + return false; + } + if ((!low.operator || low.operator === comp) && ltefn(version4, low.semver)) { + return false; + } else if (low.operator === ecomp && ltfn(version4, low.semver)) { + return false; + } + } + return true; + }; + module2.exports = outside; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/gtr.js +var require_gtr = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/gtr.js"(exports2, module2) { + "use strict"; + var outside = require_outside(); + var gtr = (version4, range, options) => outside(version4, range, ">", options); + module2.exports = gtr; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/ltr.js +var require_ltr = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/ltr.js"(exports2, module2) { + "use strict"; + var outside = require_outside(); + var ltr = (version4, range, options) => outside(version4, range, "<", options); + module2.exports = ltr; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/intersects.js +var require_intersects = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/intersects.js"(exports2, module2) { + "use strict"; + var Range = require_range2(); + var intersects = (r1, r2, options) => { + r1 = new Range(r1, options); + r2 = new Range(r2, options); + return r1.intersects(r2, options); + }; + module2.exports = intersects; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/simplify.js +var require_simplify = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/simplify.js"(exports2, module2) { + "use strict"; + var satisfies = require_satisfies(); + var compare = require_compare(); + module2.exports = (versions, range, options) => { + const set = []; + let first = null; + let prev = null; + const v = versions.sort((a, b) => compare(a, b, options)); + for (const version4 of v) { + const included = satisfies(version4, range, options); + if (included) { + prev = version4; + if (!first) { + first = version4; + } + } else { + if (prev) { + set.push([first, prev]); + } + prev = null; + first = null; + } + } + if (first) { + set.push([first, null]); + } + const ranges = []; + for (const [min, max] of set) { + if (min === max) { + ranges.push(min); + } else if (!max && min === v[0]) { + ranges.push("*"); + } else if (!max) { + ranges.push(`>=${min}`); + } else if (min === v[0]) { + ranges.push(`<=${max}`); + } else { + ranges.push(`${min} - ${max}`); + } + } + const simplified = ranges.join(" || "); + const original = typeof range.raw === "string" ? range.raw : String(range); + return simplified.length < original.length ? simplified : range; + }; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/ranges/subset.js +var require_subset = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/ranges/subset.js"(exports2, module2) { + "use strict"; + var Range = require_range2(); + var Comparator = require_comparator(); + var { ANY } = Comparator; + var satisfies = require_satisfies(); + var compare = require_compare(); + var subset = (sub, dom, options = {}) => { + if (sub === dom) { + return true; + } + sub = new Range(sub, options); + dom = new Range(dom, options); + let sawNonNull = false; + OUTER: for (const simpleSub of sub.set) { + for (const simpleDom of dom.set) { + const isSub = simpleSubset(simpleSub, simpleDom, options); + sawNonNull = sawNonNull || isSub !== null; + if (isSub) { + continue OUTER; + } + } + if (sawNonNull) { + return false; + } + } + return true; + }; + var minimumVersionWithPreRelease = [new Comparator(">=0.0.0-0")]; + var minimumVersion = [new Comparator(">=0.0.0")]; + var simpleSubset = (sub, dom, options) => { + if (sub === dom) { + return true; + } + if (sub.length === 1 && sub[0].semver === ANY) { + if (dom.length === 1 && dom[0].semver === ANY) { + return true; + } else if (options.includePrerelease) { + sub = minimumVersionWithPreRelease; + } else { + sub = minimumVersion; + } + } + if (dom.length === 1 && dom[0].semver === ANY) { + if (options.includePrerelease) { + return true; + } else { + dom = minimumVersion; + } + } + const eqSet = /* @__PURE__ */ new Set(); + let gt, lt; + for (const c of sub) { + if (c.operator === ">" || c.operator === ">=") { + gt = higherGT(gt, c, options); + } else if (c.operator === "<" || c.operator === "<=") { + lt = lowerLT(lt, c, options); + } else { + eqSet.add(c.semver); + } + } + if (eqSet.size > 1) { + return null; + } + let gtltComp; + if (gt && lt) { + gtltComp = compare(gt.semver, lt.semver, options); + if (gtltComp > 0) { + return null; + } else if (gtltComp === 0 && (gt.operator !== ">=" || lt.operator !== "<=")) { + return null; + } + } + for (const eq of eqSet) { + if (gt && !satisfies(eq, String(gt), options)) { + return null; + } + if (lt && !satisfies(eq, String(lt), options)) { + return null; + } + for (const c of dom) { + if (!satisfies(eq, String(c), options)) { + return false; + } + } + return true; + } + let higher, lower; + let hasDomLT, hasDomGT; + let needDomLTPre = lt && !options.includePrerelease && lt.semver.prerelease.length ? lt.semver : false; + let needDomGTPre = gt && !options.includePrerelease && gt.semver.prerelease.length ? gt.semver : false; + if (needDomLTPre && needDomLTPre.prerelease.length === 1 && lt.operator === "<" && needDomLTPre.prerelease[0] === 0) { + needDomLTPre = false; + } + for (const c of dom) { + hasDomGT = hasDomGT || c.operator === ">" || c.operator === ">="; + hasDomLT = hasDomLT || c.operator === "<" || c.operator === "<="; + if (gt) { + if (needDomGTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && c.semver.major === needDomGTPre.major && c.semver.minor === needDomGTPre.minor && c.semver.patch === needDomGTPre.patch) { + needDomGTPre = false; + } + } + if (c.operator === ">" || c.operator === ">=") { + higher = higherGT(gt, c, options); + if (higher === c && higher !== gt) { + return false; + } + } else if (gt.operator === ">=" && !satisfies(gt.semver, String(c), options)) { + return false; + } + } + if (lt) { + if (needDomLTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && c.semver.major === needDomLTPre.major && c.semver.minor === needDomLTPre.minor && c.semver.patch === needDomLTPre.patch) { + needDomLTPre = false; + } + } + if (c.operator === "<" || c.operator === "<=") { + lower = lowerLT(lt, c, options); + if (lower === c && lower !== lt) { + return false; + } + } else if (lt.operator === "<=" && !satisfies(lt.semver, String(c), options)) { + return false; + } + } + if (!c.operator && (lt || gt) && gtltComp !== 0) { + return false; + } + } + if (gt && hasDomLT && !lt && gtltComp !== 0) { + return false; + } + if (lt && hasDomGT && !gt && gtltComp !== 0) { + return false; + } + if (needDomGTPre || needDomLTPre) { + return false; + } + return true; + }; + var higherGT = (a, b, options) => { + if (!a) { + return b; + } + const comp = compare(a.semver, b.semver, options); + return comp > 0 ? a : comp < 0 ? b : b.operator === ">" && a.operator === ">=" ? b : a; + }; + var lowerLT = (a, b, options) => { + if (!a) { + return b; + } + const comp = compare(a.semver, b.semver, options); + return comp < 0 ? a : comp > 0 ? b : b.operator === "<" && a.operator === "<=" ? b : a; + }; + module2.exports = subset; + } +}); + +// node_modules/jsonwebtoken/node_modules/semver/index.js +var require_semver2 = __commonJS({ + "node_modules/jsonwebtoken/node_modules/semver/index.js"(exports2, module2) { + "use strict"; + var internalRe = require_re(); + var constants = require_constants3(); + var SemVer = require_semver(); + var identifiers = require_identifiers(); + var parse4 = require_parse2(); + var valid = require_valid(); + var clean = require_clean(); + var inc = require_inc(); + var diff = require_diff(); + var major = require_major(); + var minor = require_minor(); + var patch = require_patch(); + var prerelease = require_prerelease(); + var compare = require_compare(); + var rcompare = require_rcompare(); + var compareLoose = require_compare_loose(); + var compareBuild = require_compare_build(); + var sort = require_sort(); + var rsort = require_rsort(); + var gt = require_gt(); + var lt = require_lt(); + var eq = require_eq(); + var neq = require_neq(); + var gte = require_gte(); + var lte = require_lte(); + var cmp = require_cmp(); + var coerce = require_coerce(); + var Comparator = require_comparator(); + var Range = require_range2(); + var satisfies = require_satisfies(); + var toComparators = require_to_comparators(); + var maxSatisfying = require_max_satisfying(); + var minSatisfying = require_min_satisfying(); + var minVersion = require_min_version(); + var validRange = require_valid2(); + var outside = require_outside(); + var gtr = require_gtr(); + var ltr = require_ltr(); + var intersects = require_intersects(); + var simplifyRange = require_simplify(); + var subset = require_subset(); + module2.exports = { + parse: parse4, + valid, + clean, + inc, + diff, + major, + minor, + patch, + prerelease, + compare, + rcompare, + compareLoose, + compareBuild, + sort, + rsort, + gt, + lt, + eq, + neq, + gte, + lte, + cmp, + coerce, + Comparator, + Range, + satisfies, + toComparators, + maxSatisfying, + minSatisfying, + minVersion, + validRange, + outside, + gtr, + ltr, + intersects, + simplifyRange, + subset, + SemVer, + re: internalRe.re, + src: internalRe.src, + tokens: internalRe.t, + SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, + RELEASE_TYPES: constants.RELEASE_TYPES, + compareIdentifiers: identifiers.compareIdentifiers, + rcompareIdentifiers: identifiers.rcompareIdentifiers + }; + } +}); + +// node_modules/jsonwebtoken/lib/asymmetricKeyDetailsSupported.js +var require_asymmetricKeyDetailsSupported = __commonJS({ + "node_modules/jsonwebtoken/lib/asymmetricKeyDetailsSupported.js"(exports2, module2) { + var semver = require_semver2(); + module2.exports = semver.satisfies(process.version, ">=15.7.0"); + } +}); + +// node_modules/jsonwebtoken/lib/rsaPssKeyDetailsSupported.js +var require_rsaPssKeyDetailsSupported = __commonJS({ + "node_modules/jsonwebtoken/lib/rsaPssKeyDetailsSupported.js"(exports2, module2) { + var semver = require_semver2(); + module2.exports = semver.satisfies(process.version, ">=16.9.0"); + } +}); + +// node_modules/jsonwebtoken/lib/validateAsymmetricKey.js +var require_validateAsymmetricKey = __commonJS({ + "node_modules/jsonwebtoken/lib/validateAsymmetricKey.js"(exports2, module2) { + var ASYMMETRIC_KEY_DETAILS_SUPPORTED = require_asymmetricKeyDetailsSupported(); + var RSA_PSS_KEY_DETAILS_SUPPORTED = require_rsaPssKeyDetailsSupported(); + var allowedAlgorithmsForKeys = { + "ec": ["ES256", "ES384", "ES512"], + "rsa": ["RS256", "PS256", "RS384", "PS384", "RS512", "PS512"], + "rsa-pss": ["PS256", "PS384", "PS512"] + }; + var allowedCurves = { + ES256: "prime256v1", + ES384: "secp384r1", + ES512: "secp521r1" + }; + module2.exports = function(algorithm, key) { + if (!algorithm || !key) return; + const keyType = key.asymmetricKeyType; + if (!keyType) return; + const allowedAlgorithms = allowedAlgorithmsForKeys[keyType]; + if (!allowedAlgorithms) { + throw new Error(`Unknown key type "${keyType}".`); + } + if (!allowedAlgorithms.includes(algorithm)) { + throw new Error(`"alg" parameter for "${keyType}" key type must be one of: ${allowedAlgorithms.join(", ")}.`); + } + if (ASYMMETRIC_KEY_DETAILS_SUPPORTED) { + switch (keyType) { + case "ec": + const keyCurve = key.asymmetricKeyDetails.namedCurve; + const allowedCurve = allowedCurves[algorithm]; + if (keyCurve !== allowedCurve) { + throw new Error(`"alg" parameter "${algorithm}" requires curve "${allowedCurve}".`); + } + break; + case "rsa-pss": + if (RSA_PSS_KEY_DETAILS_SUPPORTED) { + const length = parseInt(algorithm.slice(-3), 10); + const { hashAlgorithm, mgf1HashAlgorithm, saltLength } = key.asymmetricKeyDetails; + if (hashAlgorithm !== `sha${length}` || mgf1HashAlgorithm !== hashAlgorithm) { + throw new Error(`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${algorithm}.`); + } + if (saltLength !== void 0 && saltLength > length >> 3) { + throw new Error(`Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" ${algorithm}.`); + } + } + break; + } + } + }; + } +}); + +// node_modules/jsonwebtoken/lib/psSupported.js +var require_psSupported = __commonJS({ + "node_modules/jsonwebtoken/lib/psSupported.js"(exports2, module2) { + var semver = require_semver2(); + module2.exports = semver.satisfies(process.version, "^6.12.0 || >=8.0.0"); + } +}); + +// node_modules/jsonwebtoken/verify.js +var require_verify = __commonJS({ + "node_modules/jsonwebtoken/verify.js"(exports2, module2) { + var JsonWebTokenError = require_JsonWebTokenError(); + var NotBeforeError = require_NotBeforeError(); + var TokenExpiredError = require_TokenExpiredError(); + var decode = require_decode(); + var timespan = require_timespan(); + var validateAsymmetricKey = require_validateAsymmetricKey(); + var PS_SUPPORTED = require_psSupported(); + var jws = require_jws(); + var { KeyObject, createSecretKey, createPublicKey } = require("crypto"); + var PUB_KEY_ALGS = ["RS256", "RS384", "RS512"]; + var EC_KEY_ALGS = ["ES256", "ES384", "ES512"]; + var RSA_KEY_ALGS = ["RS256", "RS384", "RS512"]; + var HS_ALGS = ["HS256", "HS384", "HS512"]; + if (PS_SUPPORTED) { + PUB_KEY_ALGS.splice(PUB_KEY_ALGS.length, 0, "PS256", "PS384", "PS512"); + RSA_KEY_ALGS.splice(RSA_KEY_ALGS.length, 0, "PS256", "PS384", "PS512"); + } + module2.exports = function(jwtString, secretOrPublicKey, options, callback) { + if (typeof options === "function" && !callback) { + callback = options; + options = {}; + } + if (!options) { + options = {}; + } + options = Object.assign({}, options); + let done; + if (callback) { + done = callback; + } else { + done = function(err, data) { + if (err) throw err; + return data; + }; + } + if (options.clockTimestamp && typeof options.clockTimestamp !== "number") { + return done(new JsonWebTokenError("clockTimestamp must be a number")); + } + if (options.nonce !== void 0 && (typeof options.nonce !== "string" || options.nonce.trim() === "")) { + return done(new JsonWebTokenError("nonce must be a non-empty string")); + } + if (options.allowInvalidAsymmetricKeyTypes !== void 0 && typeof options.allowInvalidAsymmetricKeyTypes !== "boolean") { + return done(new JsonWebTokenError("allowInvalidAsymmetricKeyTypes must be a boolean")); + } + const clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1e3); + if (!jwtString) { + return done(new JsonWebTokenError("jwt must be provided")); + } + if (typeof jwtString !== "string") { + return done(new JsonWebTokenError("jwt must be a string")); + } + const parts = jwtString.split("."); + if (parts.length !== 3) { + return done(new JsonWebTokenError("jwt malformed")); + } + let decodedToken; + try { + decodedToken = decode(jwtString, { complete: true }); + } catch (err) { + return done(err); + } + if (!decodedToken) { + return done(new JsonWebTokenError("invalid token")); + } + const header = decodedToken.header; + let getSecret; + if (typeof secretOrPublicKey === "function") { + if (!callback) { + return done(new JsonWebTokenError("verify must be called asynchronous if secret or public key is provided as a callback")); + } + getSecret = secretOrPublicKey; + } else { + getSecret = function(header2, secretCallback) { + return secretCallback(null, secretOrPublicKey); + }; + } + return getSecret(header, function(err, secretOrPublicKey2) { + if (err) { + return done(new JsonWebTokenError("error in secret or public key callback: " + err.message)); + } + const hasSignature = parts[2].trim() !== ""; + if (!hasSignature && secretOrPublicKey2) { + return done(new JsonWebTokenError("jwt signature is required")); + } + if (hasSignature && !secretOrPublicKey2) { + return done(new JsonWebTokenError("secret or public key must be provided")); + } + if (!hasSignature && !options.algorithms) { + return done(new JsonWebTokenError('please specify "none" in "algorithms" to verify unsigned tokens')); + } + if (secretOrPublicKey2 != null && !(secretOrPublicKey2 instanceof KeyObject)) { + try { + secretOrPublicKey2 = createPublicKey(secretOrPublicKey2); + } catch (_) { + try { + secretOrPublicKey2 = createSecretKey(typeof secretOrPublicKey2 === "string" ? Buffer.from(secretOrPublicKey2) : secretOrPublicKey2); + } catch (_2) { + return done(new JsonWebTokenError("secretOrPublicKey is not valid key material")); + } + } + } + if (!options.algorithms) { + if (secretOrPublicKey2.type === "secret") { + options.algorithms = HS_ALGS; + } else if (["rsa", "rsa-pss"].includes(secretOrPublicKey2.asymmetricKeyType)) { + options.algorithms = RSA_KEY_ALGS; + } else if (secretOrPublicKey2.asymmetricKeyType === "ec") { + options.algorithms = EC_KEY_ALGS; + } else { + options.algorithms = PUB_KEY_ALGS; + } + } + if (options.algorithms.indexOf(decodedToken.header.alg) === -1) { + return done(new JsonWebTokenError("invalid algorithm")); + } + if (header.alg.startsWith("HS") && secretOrPublicKey2.type !== "secret") { + return done(new JsonWebTokenError(`secretOrPublicKey must be a symmetric key when using ${header.alg}`)); + } else if (/^(?:RS|PS|ES)/.test(header.alg) && secretOrPublicKey2.type !== "public") { + return done(new JsonWebTokenError(`secretOrPublicKey must be an asymmetric key when using ${header.alg}`)); + } + if (!options.allowInvalidAsymmetricKeyTypes) { + try { + validateAsymmetricKey(header.alg, secretOrPublicKey2); + } catch (e) { + return done(e); + } + } + let valid; + try { + valid = jws.verify(jwtString, decodedToken.header.alg, secretOrPublicKey2); + } catch (e) { + return done(e); + } + if (!valid) { + return done(new JsonWebTokenError("invalid signature")); + } + const payload = decodedToken.payload; + if (typeof payload.nbf !== "undefined" && !options.ignoreNotBefore) { + if (typeof payload.nbf !== "number") { + return done(new JsonWebTokenError("invalid nbf value")); + } + if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) { + return done(new NotBeforeError("jwt not active", new Date(payload.nbf * 1e3))); + } + } + if (typeof payload.exp !== "undefined" && !options.ignoreExpiration) { + if (typeof payload.exp !== "number") { + return done(new JsonWebTokenError("invalid exp value")); + } + if (clockTimestamp >= payload.exp + (options.clockTolerance || 0)) { + return done(new TokenExpiredError("jwt expired", new Date(payload.exp * 1e3))); + } + } + if (options.audience) { + const audiences = Array.isArray(options.audience) ? options.audience : [options.audience]; + const target = Array.isArray(payload.aud) ? payload.aud : [payload.aud]; + const match = target.some(function(targetAudience) { + return audiences.some(function(audience) { + return audience instanceof RegExp ? audience.test(targetAudience) : audience === targetAudience; + }); + }); + if (!match) { + return done(new JsonWebTokenError("jwt audience invalid. expected: " + audiences.join(" or "))); + } + } + if (options.issuer) { + const invalid_issuer = typeof options.issuer === "string" && payload.iss !== options.issuer || Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1; + if (invalid_issuer) { + return done(new JsonWebTokenError("jwt issuer invalid. expected: " + options.issuer)); + } + } + if (options.subject) { + if (payload.sub !== options.subject) { + return done(new JsonWebTokenError("jwt subject invalid. expected: " + options.subject)); + } + } + if (options.jwtid) { + if (payload.jti !== options.jwtid) { + return done(new JsonWebTokenError("jwt jwtid invalid. expected: " + options.jwtid)); + } + } + if (options.nonce) { + if (payload.nonce !== options.nonce) { + return done(new JsonWebTokenError("jwt nonce invalid. expected: " + options.nonce)); + } + } + if (options.maxAge) { + if (typeof payload.iat !== "number") { + return done(new JsonWebTokenError("iat required when maxAge is specified")); + } + const maxAgeTimestamp = timespan(options.maxAge, payload.iat); + if (typeof maxAgeTimestamp === "undefined") { + return done(new JsonWebTokenError('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); + } + if (clockTimestamp >= maxAgeTimestamp + (options.clockTolerance || 0)) { + return done(new TokenExpiredError("maxAge exceeded", new Date(maxAgeTimestamp * 1e3))); + } + } + if (options.complete === true) { + const signature = decodedToken.signature; + return done(null, { + header, + payload, + signature + }); + } + return done(null, payload); + }); + }; + } +}); + +// node_modules/lodash.includes/index.js +var require_lodash = __commonJS({ + "node_modules/lodash.includes/index.js"(exports2, module2) { + var INFINITY = 1 / 0; + var MAX_SAFE_INTEGER = 9007199254740991; + var MAX_INTEGER = 17976931348623157e292; + var NAN = 0 / 0; + var argsTag = "[object Arguments]"; + var funcTag = "[object Function]"; + var genTag = "[object GeneratorFunction]"; + var stringTag = "[object String]"; + var symbolTag = "[object Symbol]"; + var reTrim = /^\s+|\s+$/g; + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + var reIsBinary = /^0b[01]+$/i; + var reIsOctal = /^0o[0-7]+$/i; + var reIsUint = /^(?:0|[1-9]\d*)$/; + var freeParseInt = parseInt; + function arrayMap(array, iteratee) { + var index = -1, length = array ? array.length : 0, result = Array(length); + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, index = fromIndex + (fromRight ? 1 : -1); + while (fromRight ? index-- : ++index < length) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return baseFindIndex(array, baseIsNaN, fromIndex); + } + var index = fromIndex - 1, length = array.length; + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + function baseIsNaN(value) { + return value !== value; + } + function baseTimes(n, iteratee) { + var index = -1, result = Array(n); + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); + } + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + var objectProto = Object.prototype; + var hasOwnProperty = objectProto.hasOwnProperty; + var objectToString = objectProto.toString; + var propertyIsEnumerable = objectProto.propertyIsEnumerable; + var nativeKeys = overArg(Object.keys, Object); + var nativeMax = Math.max; + function arrayLikeKeys(value, inherited) { + var result = isArray(value) || isArguments(value) ? baseTimes(value.length, String) : []; + var length = result.length, skipIndexes = !!length; + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && (key == "length" || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != "constructor") { + result.push(key); + } + } + return result; + } + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && (typeof value == "number" || reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length); + } + function isPrototype(value) { + var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto; + return value === proto; + } + function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = fromIndex && !guard ? toInteger(fromIndex) : 0; + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1; + } + function isArguments(value) { + return isArrayLikeObject(value) && hasOwnProperty.call(value, "callee") && (!propertyIsEnumerable.call(value, "callee") || objectToString.call(value) == argsTag); + } + var isArray = Array.isArray; + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + function isFunction(value) { + var tag = isObject2(value) ? objectToString.call(value) : ""; + return tag == funcTag || tag == genTag; + } + function isLength(value) { + return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + function isObject2(value) { + var type = typeof value; + return !!value && (type == "object" || type == "function"); + } + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + function isString(value) { + return typeof value == "string" || !isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag; + } + function isSymbol(value) { + return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag; + } + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = value < 0 ? -1 : 1; + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + function toInteger(value) { + var result = toFinite(value), remainder = result % 1; + return result === result ? remainder ? result - remainder : result : 0; + } + function toNumber(value) { + if (typeof value == "number") { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject2(value)) { + var other = typeof value.valueOf == "function" ? value.valueOf() : value; + value = isObject2(other) ? other + "" : other; + } + if (typeof value != "string") { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ""); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; + } + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + function values(object) { + return object ? baseValues(object, keys(object)) : []; + } + module2.exports = includes; + } +}); + +// node_modules/lodash.isboolean/index.js +var require_lodash2 = __commonJS({ + "node_modules/lodash.isboolean/index.js"(exports2, module2) { + var boolTag = "[object Boolean]"; + var objectProto = Object.prototype; + var objectToString = objectProto.toString; + function isBoolean(value) { + return value === true || value === false || isObjectLike(value) && objectToString.call(value) == boolTag; + } + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + module2.exports = isBoolean; + } +}); + +// node_modules/lodash.isinteger/index.js +var require_lodash3 = __commonJS({ + "node_modules/lodash.isinteger/index.js"(exports2, module2) { + var INFINITY = 1 / 0; + var MAX_INTEGER = 17976931348623157e292; + var NAN = 0 / 0; + var symbolTag = "[object Symbol]"; + var reTrim = /^\s+|\s+$/g; + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + var reIsBinary = /^0b[01]+$/i; + var reIsOctal = /^0o[0-7]+$/i; + var freeParseInt = parseInt; + var objectProto = Object.prototype; + var objectToString = objectProto.toString; + function isInteger(value) { + return typeof value == "number" && value == toInteger(value); + } + function isObject2(value) { + var type = typeof value; + return !!value && (type == "object" || type == "function"); + } + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + function isSymbol(value) { + return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag; + } + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = value < 0 ? -1 : 1; + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + function toInteger(value) { + var result = toFinite(value), remainder = result % 1; + return result === result ? remainder ? result - remainder : result : 0; + } + function toNumber(value) { + if (typeof value == "number") { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject2(value)) { + var other = typeof value.valueOf == "function" ? value.valueOf() : value; + value = isObject2(other) ? other + "" : other; + } + if (typeof value != "string") { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ""); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; + } + module2.exports = isInteger; + } +}); + +// node_modules/lodash.isnumber/index.js +var require_lodash4 = __commonJS({ + "node_modules/lodash.isnumber/index.js"(exports2, module2) { + var numberTag = "[object Number]"; + var objectProto = Object.prototype; + var objectToString = objectProto.toString; + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + function isNumber(value) { + return typeof value == "number" || isObjectLike(value) && objectToString.call(value) == numberTag; + } + module2.exports = isNumber; + } +}); + +// node_modules/lodash.isplainobject/index.js +var require_lodash5 = __commonJS({ + "node_modules/lodash.isplainobject/index.js"(exports2, module2) { + var objectTag = "[object Object]"; + function isHostObject(value) { + var result = false; + if (value != null && typeof value.toString != "function") { + try { + result = !!(value + ""); + } catch (e) { + } + } + return result; + } + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + var funcProto = Function.prototype; + var objectProto = Object.prototype; + var funcToString = funcProto.toString; + var hasOwnProperty = objectProto.hasOwnProperty; + var objectCtorString = funcToString.call(Object); + var objectToString = objectProto.toString; + var getPrototype = overArg(Object.getPrototypeOf, Object); + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + function isPlainObject(value) { + if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, "constructor") && proto.constructor; + return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString; + } + module2.exports = isPlainObject; + } +}); + +// node_modules/lodash.isstring/index.js +var require_lodash6 = __commonJS({ + "node_modules/lodash.isstring/index.js"(exports2, module2) { + var stringTag = "[object String]"; + var objectProto = Object.prototype; + var objectToString = objectProto.toString; + var isArray = Array.isArray; + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + function isString(value) { + return typeof value == "string" || !isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag; + } + module2.exports = isString; + } +}); + +// node_modules/lodash.once/index.js +var require_lodash7 = __commonJS({ + "node_modules/lodash.once/index.js"(exports2, module2) { + var FUNC_ERROR_TEXT = "Expected a function"; + var INFINITY = 1 / 0; + var MAX_INTEGER = 17976931348623157e292; + var NAN = 0 / 0; + var symbolTag = "[object Symbol]"; + var reTrim = /^\s+|\s+$/g; + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + var reIsBinary = /^0b[01]+$/i; + var reIsOctal = /^0o[0-7]+$/i; + var freeParseInt = parseInt; + var objectProto = Object.prototype; + var objectToString = objectProto.toString; + function before(n, func) { + var result; + if (typeof func != "function") { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = void 0; + } + return result; + }; + } + function once(func) { + return before(2, func); + } + function isObject2(value) { + var type = typeof value; + return !!value && (type == "object" || type == "function"); + } + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + function isSymbol(value) { + return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag; + } + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = value < 0 ? -1 : 1; + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + function toInteger(value) { + var result = toFinite(value), remainder = result % 1; + return result === result ? remainder ? result - remainder : result : 0; + } + function toNumber(value) { + if (typeof value == "number") { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject2(value)) { + var other = typeof value.valueOf == "function" ? value.valueOf() : value; + value = isObject2(other) ? other + "" : other; + } + if (typeof value != "string") { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ""); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; + } + module2.exports = once; + } +}); + +// node_modules/jsonwebtoken/sign.js +var require_sign2 = __commonJS({ + "node_modules/jsonwebtoken/sign.js"(exports2, module2) { + var timespan = require_timespan(); + var PS_SUPPORTED = require_psSupported(); + var validateAsymmetricKey = require_validateAsymmetricKey(); + var jws = require_jws(); + var includes = require_lodash(); + var isBoolean = require_lodash2(); + var isInteger = require_lodash3(); + var isNumber = require_lodash4(); + var isPlainObject = require_lodash5(); + var isString = require_lodash6(); + var once = require_lodash7(); + var { KeyObject, createSecretKey, createPrivateKey } = require("crypto"); + var SUPPORTED_ALGS = ["RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256", "HS384", "HS512", "none"]; + if (PS_SUPPORTED) { + SUPPORTED_ALGS.splice(3, 0, "PS256", "PS384", "PS512"); + } + var sign_options_schema = { + expiresIn: { isValid: function(value) { + return isInteger(value) || isString(value) && value; + }, message: '"expiresIn" should be a number of seconds or string representing a timespan' }, + notBefore: { isValid: function(value) { + return isInteger(value) || isString(value) && value; + }, message: '"notBefore" should be a number of seconds or string representing a timespan' }, + audience: { isValid: function(value) { + return isString(value) || Array.isArray(value); + }, message: '"audience" must be a string or array' }, + algorithm: { isValid: includes.bind(null, SUPPORTED_ALGS), message: '"algorithm" must be a valid string enum value' }, + header: { isValid: isPlainObject, message: '"header" must be an object' }, + encoding: { isValid: isString, message: '"encoding" must be a string' }, + issuer: { isValid: isString, message: '"issuer" must be a string' }, + subject: { isValid: isString, message: '"subject" must be a string' }, + jwtid: { isValid: isString, message: '"jwtid" must be a string' }, + noTimestamp: { isValid: isBoolean, message: '"noTimestamp" must be a boolean' }, + keyid: { isValid: isString, message: '"keyid" must be a string' }, + mutatePayload: { isValid: isBoolean, message: '"mutatePayload" must be a boolean' }, + allowInsecureKeySizes: { isValid: isBoolean, message: '"allowInsecureKeySizes" must be a boolean' }, + allowInvalidAsymmetricKeyTypes: { isValid: isBoolean, message: '"allowInvalidAsymmetricKeyTypes" must be a boolean' } + }; + var registered_claims_schema = { + iat: { isValid: isNumber, message: '"iat" should be a number of seconds' }, + exp: { isValid: isNumber, message: '"exp" should be a number of seconds' }, + nbf: { isValid: isNumber, message: '"nbf" should be a number of seconds' } + }; + function validate4(schema, allowUnknown, object, parameterName) { + if (!isPlainObject(object)) { + throw new Error('Expected "' + parameterName + '" to be a plain object.'); + } + Object.keys(object).forEach(function(key) { + const validator = schema[key]; + if (!validator) { + if (!allowUnknown) { + throw new Error('"' + key + '" is not allowed in "' + parameterName + '"'); + } + return; + } + if (!validator.isValid(object[key])) { + throw new Error(validator.message); + } + }); + } + function validateOptions(options) { + return validate4(sign_options_schema, false, options, "options"); + } + function validatePayload(payload) { + return validate4(registered_claims_schema, true, payload, "payload"); + } + var options_to_payload = { + "audience": "aud", + "issuer": "iss", + "subject": "sub", + "jwtid": "jti" + }; + var options_for_objects = [ + "expiresIn", + "notBefore", + "noTimestamp", + "audience", + "issuer", + "subject", + "jwtid" + ]; + module2.exports = function(payload, secretOrPrivateKey, options, callback) { + if (typeof options === "function") { + callback = options; + options = {}; + } else { + options = options || {}; + } + const isObjectPayload = typeof payload === "object" && !Buffer.isBuffer(payload); + const header = Object.assign({ + alg: options.algorithm || "HS256", + typ: isObjectPayload ? "JWT" : void 0, + kid: options.keyid + }, options.header); + function failure(err) { + if (callback) { + return callback(err); + } + throw err; + } + if (!secretOrPrivateKey && options.algorithm !== "none") { + return failure(new Error("secretOrPrivateKey must have a value")); + } + if (secretOrPrivateKey != null && !(secretOrPrivateKey instanceof KeyObject)) { + try { + secretOrPrivateKey = createPrivateKey(secretOrPrivateKey); + } catch (_) { + try { + secretOrPrivateKey = createSecretKey(typeof secretOrPrivateKey === "string" ? Buffer.from(secretOrPrivateKey) : secretOrPrivateKey); + } catch (_2) { + return failure(new Error("secretOrPrivateKey is not valid key material")); + } + } + } + if (header.alg.startsWith("HS") && secretOrPrivateKey.type !== "secret") { + return failure(new Error(`secretOrPrivateKey must be a symmetric key when using ${header.alg}`)); + } else if (/^(?:RS|PS|ES)/.test(header.alg)) { + if (secretOrPrivateKey.type !== "private") { + return failure(new Error(`secretOrPrivateKey must be an asymmetric key when using ${header.alg}`)); + } + if (!options.allowInsecureKeySizes && !header.alg.startsWith("ES") && secretOrPrivateKey.asymmetricKeyDetails !== void 0 && //KeyObject.asymmetricKeyDetails is supported in Node 15+ + secretOrPrivateKey.asymmetricKeyDetails.modulusLength < 2048) { + return failure(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`)); + } + } + if (typeof payload === "undefined") { + return failure(new Error("payload is required")); + } else if (isObjectPayload) { + try { + validatePayload(payload); + } catch (error) { + return failure(error); + } + if (!options.mutatePayload) { + payload = Object.assign({}, payload); + } + } else { + const invalid_options = options_for_objects.filter(function(opt) { + return typeof options[opt] !== "undefined"; + }); + if (invalid_options.length > 0) { + return failure(new Error("invalid " + invalid_options.join(",") + " option for " + typeof payload + " payload")); + } + } + if (typeof payload.exp !== "undefined" && typeof options.expiresIn !== "undefined") { + return failure(new Error('Bad "options.expiresIn" option the payload already has an "exp" property.')); + } + if (typeof payload.nbf !== "undefined" && typeof options.notBefore !== "undefined") { + return failure(new Error('Bad "options.notBefore" option the payload already has an "nbf" property.')); + } + try { + validateOptions(options); + } catch (error) { + return failure(error); + } + if (!options.allowInvalidAsymmetricKeyTypes) { + try { + validateAsymmetricKey(header.alg, secretOrPrivateKey); + } catch (error) { + return failure(error); + } + } + const timestamp = payload.iat || Math.floor(Date.now() / 1e3); + if (options.noTimestamp) { + delete payload.iat; + } else if (isObjectPayload) { + payload.iat = timestamp; + } + if (typeof options.notBefore !== "undefined") { + try { + payload.nbf = timespan(options.notBefore, timestamp); + } catch (err) { + return failure(err); + } + if (typeof payload.nbf === "undefined") { + return failure(new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); + } + } + if (typeof options.expiresIn !== "undefined" && typeof payload === "object") { + try { + payload.exp = timespan(options.expiresIn, timestamp); + } catch (err) { + return failure(err); + } + if (typeof payload.exp === "undefined") { + return failure(new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); + } + } + Object.keys(options_to_payload).forEach(function(key) { + const claim = options_to_payload[key]; + if (typeof options[key] !== "undefined") { + if (typeof payload[claim] !== "undefined") { + return failure(new Error('Bad "options.' + key + '" option. The payload already has an "' + claim + '" property.')); + } + payload[claim] = options[key]; + } + }); + const encoding = options.encoding || "utf8"; + if (typeof callback === "function") { + callback = callback && once(callback); + jws.createSign({ + header, + privateKey: secretOrPrivateKey, + payload, + encoding + }).once("error", callback).once("done", function(signature) { + if (!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) { + return callback(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`)); + } + callback(null, signature); + }); + } else { + let signature = jws.sign({ header, payload, secret: secretOrPrivateKey, encoding }); + if (!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) { + throw new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`); + } + return signature; + } + }; + } +}); + +// node_modules/jsonwebtoken/index.js +var require_jsonwebtoken = __commonJS({ + "node_modules/jsonwebtoken/index.js"(exports2, module2) { + module2.exports = { + decode: require_decode(), + verify: require_verify(), + sign: require_sign2(), + JsonWebTokenError: require_JsonWebTokenError(), + NotBeforeError: require_NotBeforeError(), + TokenExpiredError: require_TokenExpiredError() + }; + } +}); + +// node_modules/botframework-connector/lib/auth/claimsIdentity.js +var require_claimsIdentity = __commonJS({ + "node_modules/botframework-connector/lib/auth/claimsIdentity.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ClaimsIdentity = void 0; + var ClaimsIdentity = class { + /** + * Initializes a new instance of the [ClaimsIdentity](xref:botframework-connector.ClaimsIdentity) class. + * + * @param {Claim[]} claims An array of [Claim](xref:botframework-connector.Claim). + * @param {string | boolean} authenticationType The type of auth for this set of claims, or boolean to override isAuthenticated + */ + constructor(claims, authenticationType) { + this.claims = claims; + this.authenticationType = authenticationType; + } + /** + * Returns authentication status. + * + * @returns True if is authenticated. + */ + get isAuthenticated() { + if (typeof this.authenticationType === "boolean") { + return this.authenticationType; + } + return this.authenticationType != null; + } + /** + * Returns a claim value (if its present) + * + * @param {string} claimType The claim type to look for + * @returns {string|null} The claim value or null if not found + */ + getClaimValue(claimType) { + var _a; + const claim = this.claims.find((c) => c.type === claimType); + return (_a = claim === null || claim === void 0 ? void 0 : claim.value) !== null && _a !== void 0 ? _a : null; + } + }; + exports2.ClaimsIdentity = ClaimsIdentity; + } +}); + +// node_modules/botframework-connector/lib/auth/endorsementsValidator.js +var require_endorsementsValidator = __commonJS({ + "node_modules/botframework-connector/lib/auth/endorsementsValidator.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.EndorsementsValidator = void 0; + var authenticationError_1 = require_authenticationError(); + var botframework_schema_1 = require_lib4(); + var EndorsementsValidator = class { + /** + * Verify that the set of ChannelIds, which come from the incoming activities, + * all match the endorsements found on the JWT Token. + * For example, if an Activity comes from webchat, that channelId says + * says "webchat" and the jwt token endorsement MUST match that. + * + * @param channelId The channel name, typically extracted from the activity.ChannelId field, that to which the Activity is affinitized. + * @param endorsements Whoever signed the JWT token is permitted to send activities only for + * some specific channels. That list is the endorsement list, and is validated here against the channelId. + * @returns {boolean} True is the channelId is found in the Endorsement set. False if the channelId is not found. + */ + static validate(channelId, endorsements) { + if (channelId === null || channelId.trim() === "") { + return true; + } + if (endorsements === null) { + throw new authenticationError_1.AuthenticationError("endorsements required", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return new Set(endorsements).has(channelId); + } + }; + exports2.EndorsementsValidator = EndorsementsValidator; + } +}); + +// node_modules/rsa-pem-from-mod-exp/index.js +var require_rsa_pem_from_mod_exp = __commonJS({ + "node_modules/rsa-pem-from-mod-exp/index.js"(exports2, module2) { + module2.exports = rsaPublicKeyPem; + function rsaPublicKeyPem(modulus_b64, exponent_b64) { + var modulus = Buffer.from(modulus_b64, "base64"); + var exponent = Buffer.from(exponent_b64, "base64"); + var modulus_hex = modulus.toString("hex"); + var exponent_hex = exponent.toString("hex"); + modulus_hex = prepadSigned(modulus_hex); + exponent_hex = prepadSigned(exponent_hex); + var modlen = modulus_hex.length / 2; + var explen = exponent_hex.length / 2; + var encoded_modlen = encodeLengthHex(modlen); + var encoded_explen = encodeLengthHex(explen); + var encoded_pubkey = "30" + encodeLengthHex( + modlen + explen + encoded_modlen.length / 2 + encoded_explen.length / 2 + 2 + ) + "02" + encoded_modlen + modulus_hex + "02" + encoded_explen + exponent_hex; + var der_b64 = Buffer.from(encoded_pubkey, "hex").toString("base64"); + var pem = "-----BEGIN RSA PUBLIC KEY-----\n" + der_b64.match(/.{1,64}/g).join("\n") + "\n-----END RSA PUBLIC KEY-----\n"; + return pem; + } + function prepadSigned(hexStr) { + var msb = hexStr[0]; + if (msb < "0" || msb > "7") { + return "00" + hexStr; + } else { + return hexStr; + } + } + function toHex(number) { + var nstr = number.toString(16); + if (nstr.length % 2) return "0" + nstr; + return nstr; + } + function encodeLengthHex(n) { + if (n <= 127) return toHex(n); + else { + var n_hex = toHex(n); + var length_of_length_byte = 128 + n_hex.length / 2; + return toHex(length_of_length_byte) + n_hex; + } + } + } +}); + +// node_modules/base64url/dist/pad-string.js +var require_pad_string = __commonJS({ + "node_modules/base64url/dist/pad-string.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + function padString(input) { + var segmentLength = 4; + var stringLength = input.length; + var diff = stringLength % segmentLength; + if (!diff) { + return input; + } + var position = stringLength; + var padLength = segmentLength - diff; + var paddedStringLength = stringLength + padLength; + var buffer = Buffer.alloc(paddedStringLength); + buffer.write(input); + while (padLength--) { + buffer.write("=", position++); + } + return buffer.toString(); + } + exports2.default = padString; + } +}); + +// node_modules/base64url/dist/base64url.js +var require_base64url = __commonJS({ + "node_modules/base64url/dist/base64url.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + var pad_string_1 = require_pad_string(); + function encode(input, encoding) { + if (encoding === void 0) { + encoding = "utf8"; + } + if (Buffer.isBuffer(input)) { + return fromBase64(input.toString("base64")); + } + return fromBase64(Buffer.from(input, encoding).toString("base64")); + } + function decode(base64url2, encoding) { + if (encoding === void 0) { + encoding = "utf8"; + } + return Buffer.from(toBase64(base64url2), "base64").toString(encoding); + } + function toBase64(base64url2) { + base64url2 = base64url2.toString(); + return pad_string_1.default(base64url2).replace(/\-/g, "+").replace(/_/g, "/"); + } + function fromBase64(base64) { + return base64.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_"); + } + function toBuffer(base64url2) { + return Buffer.from(toBase64(base64url2), "base64"); + } + var base64url = encode; + base64url.encode = encode; + base64url.decode = decode; + base64url.toBase64 = toBase64; + base64url.fromBase64 = fromBase64; + base64url.toBuffer = toBuffer; + exports2.default = base64url; + } +}); + +// node_modules/base64url/index.js +var require_base64url2 = __commonJS({ + "node_modules/base64url/index.js"(exports2, module2) { + module2.exports = require_base64url().default; + module2.exports.default = module2.exports; + } +}); + +// node_modules/webidl-conversions/lib/index.js +var require_lib6 = __commonJS({ + "node_modules/webidl-conversions/lib/index.js"(exports2, module2) { + "use strict"; + var conversions = {}; + module2.exports = conversions; + function sign(x) { + return x < 0 ? -1 : 1; + } + function evenRound(x) { + if (x % 1 === 0.5 && (x & 1) === 0) { + return Math.floor(x); + } else { + return Math.round(x); + } + } + function createNumberConversion(bitLength, typeOpts) { + if (!typeOpts.unsigned) { + --bitLength; + } + const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); + const upperBound = Math.pow(2, bitLength) - 1; + const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); + const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); + return function(V, opts) { + if (!opts) opts = {}; + let x = +V; + if (opts.enforceRange) { + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite number"); + } + x = sign(x) * Math.floor(Math.abs(x)); + if (x < lowerBound || x > upperBound) { + throw new TypeError("Argument is not in byte range"); + } + return x; + } + if (!isNaN(x) && opts.clamp) { + x = evenRound(x); + if (x < lowerBound) x = lowerBound; + if (x > upperBound) x = upperBound; + return x; + } + if (!Number.isFinite(x) || x === 0) { + return 0; + } + x = sign(x) * Math.floor(Math.abs(x)); + x = x % moduloVal; + if (!typeOpts.unsigned && x >= moduloBound) { + return x - moduloVal; + } else if (typeOpts.unsigned) { + if (x < 0) { + x += moduloVal; + } else if (x === -0) { + return 0; + } + } + return x; + }; + } + conversions["void"] = function() { + return void 0; + }; + conversions["boolean"] = function(val) { + return !!val; + }; + conversions["byte"] = createNumberConversion(8, { unsigned: false }); + conversions["octet"] = createNumberConversion(8, { unsigned: true }); + conversions["short"] = createNumberConversion(16, { unsigned: false }); + conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); + conversions["long"] = createNumberConversion(32, { unsigned: false }); + conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); + conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); + conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); + conversions["double"] = function(V) { + const x = +V; + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite floating-point value"); + } + return x; + }; + conversions["unrestricted double"] = function(V) { + const x = +V; + if (isNaN(x)) { + throw new TypeError("Argument is NaN"); + } + return x; + }; + conversions["float"] = conversions["double"]; + conversions["unrestricted float"] = conversions["unrestricted double"]; + conversions["DOMString"] = function(V, opts) { + if (!opts) opts = {}; + if (opts.treatNullAsEmptyString && V === null) { + return ""; + } + return String(V); + }; + conversions["ByteString"] = function(V, opts) { + const x = String(V); + let c = void 0; + for (let i = 0; (c = x.codePointAt(i)) !== void 0; ++i) { + if (c > 255) { + throw new TypeError("Argument is not a valid bytestring"); + } + } + return x; + }; + conversions["USVString"] = function(V) { + const S = String(V); + const n = S.length; + const U = []; + for (let i = 0; i < n; ++i) { + const c = S.charCodeAt(i); + if (c < 55296 || c > 57343) { + U.push(String.fromCodePoint(c)); + } else if (56320 <= c && c <= 57343) { + U.push(String.fromCodePoint(65533)); + } else { + if (i === n - 1) { + U.push(String.fromCodePoint(65533)); + } else { + const d = S.charCodeAt(i + 1); + if (56320 <= d && d <= 57343) { + const a = c & 1023; + const b = d & 1023; + U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); + ++i; + } else { + U.push(String.fromCodePoint(65533)); + } + } + } + } + return U.join(""); + }; + conversions["Date"] = function(V, opts) { + if (!(V instanceof Date)) { + throw new TypeError("Argument is not a Date object"); + } + if (isNaN(V)) { + return void 0; + } + return V; + }; + conversions["RegExp"] = function(V, opts) { + if (!(V instanceof RegExp)) { + V = new RegExp(V); + } + return V; + }; + } +}); + +// node_modules/whatwg-url/lib/utils.js +var require_utils5 = __commonJS({ + "node_modules/whatwg-url/lib/utils.js"(exports2, module2) { + "use strict"; + module2.exports.mixin = function mixin(target, source) { + const keys = Object.getOwnPropertyNames(source); + for (let i = 0; i < keys.length; ++i) { + Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i])); + } + }; + module2.exports.wrapperSymbol = Symbol("wrapper"); + module2.exports.implSymbol = Symbol("impl"); + module2.exports.wrapperForImpl = function(impl) { + return impl[module2.exports.wrapperSymbol]; + }; + module2.exports.implForWrapper = function(wrapper) { + return wrapper[module2.exports.implSymbol]; + }; + } +}); + +// node_modules/tr46/lib/mappingTable.json +var require_mappingTable = __commonJS({ + "node_modules/tr46/lib/mappingTable.json"(exports2, module2) { + module2.exports = [[[0, 44], "disallowed_STD3_valid"], [[45, 46], "valid"], [[47, 47], "disallowed_STD3_valid"], [[48, 57], "valid"], [[58, 64], "disallowed_STD3_valid"], [[65, 65], "mapped", [97]], [[66, 66], "mapped", [98]], [[67, 67], "mapped", [99]], [[68, 68], "mapped", [100]], [[69, 69], "mapped", [101]], [[70, 70], "mapped", [102]], [[71, 71], "mapped", [103]], [[72, 72], "mapped", [104]], [[73, 73], "mapped", [105]], [[74, 74], "mapped", [106]], [[75, 75], "mapped", [107]], [[76, 76], "mapped", [108]], [[77, 77], "mapped", [109]], [[78, 78], "mapped", [110]], [[79, 79], "mapped", [111]], [[80, 80], "mapped", [112]], [[81, 81], "mapped", [113]], [[82, 82], "mapped", [114]], [[83, 83], "mapped", [115]], [[84, 84], "mapped", [116]], [[85, 85], "mapped", [117]], [[86, 86], "mapped", [118]], [[87, 87], "mapped", [119]], [[88, 88], "mapped", [120]], [[89, 89], "mapped", [121]], [[90, 90], "mapped", [122]], [[91, 96], "disallowed_STD3_valid"], [[97, 122], "valid"], [[123, 127], "disallowed_STD3_valid"], [[128, 159], "disallowed"], [[160, 160], "disallowed_STD3_mapped", [32]], [[161, 167], "valid", [], "NV8"], [[168, 168], "disallowed_STD3_mapped", [32, 776]], [[169, 169], "valid", [], "NV8"], [[170, 170], "mapped", [97]], [[171, 172], "valid", [], "NV8"], [[173, 173], "ignored"], [[174, 174], "valid", [], "NV8"], [[175, 175], "disallowed_STD3_mapped", [32, 772]], [[176, 177], "valid", [], "NV8"], [[178, 178], "mapped", [50]], [[179, 179], "mapped", [51]], [[180, 180], "disallowed_STD3_mapped", [32, 769]], [[181, 181], "mapped", [956]], [[182, 182], "valid", [], "NV8"], [[183, 183], "valid"], [[184, 184], "disallowed_STD3_mapped", [32, 807]], [[185, 185], "mapped", [49]], [[186, 186], "mapped", [111]], [[187, 187], "valid", [], "NV8"], [[188, 188], "mapped", [49, 8260, 52]], [[189, 189], "mapped", [49, 8260, 50]], [[190, 190], "mapped", [51, 8260, 52]], [[191, 191], "valid", [], "NV8"], [[192, 192], "mapped", [224]], [[193, 193], "mapped", [225]], [[194, 194], "mapped", [226]], [[195, 195], "mapped", [227]], [[196, 196], "mapped", [228]], [[197, 197], "mapped", [229]], [[198, 198], "mapped", [230]], [[199, 199], "mapped", [231]], [[200, 200], "mapped", [232]], [[201, 201], "mapped", [233]], [[202, 202], "mapped", [234]], [[203, 203], "mapped", [235]], [[204, 204], "mapped", [236]], [[205, 205], "mapped", [237]], [[206, 206], "mapped", [238]], [[207, 207], "mapped", [239]], [[208, 208], "mapped", [240]], [[209, 209], "mapped", [241]], [[210, 210], "mapped", [242]], [[211, 211], "mapped", [243]], [[212, 212], "mapped", [244]], [[213, 213], "mapped", [245]], [[214, 214], "mapped", [246]], [[215, 215], "valid", [], "NV8"], [[216, 216], "mapped", [248]], [[217, 217], "mapped", [249]], [[218, 218], "mapped", [250]], [[219, 219], "mapped", [251]], [[220, 220], "mapped", [252]], [[221, 221], "mapped", [253]], [[222, 222], "mapped", [254]], [[223, 223], "deviation", [115, 115]], [[224, 246], "valid"], [[247, 247], "valid", [], "NV8"], [[248, 255], "valid"], [[256, 256], "mapped", [257]], [[257, 257], "valid"], [[258, 258], "mapped", [259]], [[259, 259], "valid"], [[260, 260], "mapped", [261]], [[261, 261], "valid"], [[262, 262], "mapped", [263]], [[263, 263], "valid"], [[264, 264], "mapped", [265]], [[265, 265], "valid"], [[266, 266], "mapped", [267]], [[267, 267], "valid"], [[268, 268], "mapped", [269]], [[269, 269], "valid"], [[270, 270], "mapped", [271]], [[271, 271], "valid"], [[272, 272], "mapped", [273]], [[273, 273], "valid"], [[274, 274], "mapped", [275]], [[275, 275], "valid"], [[276, 276], "mapped", [277]], [[277, 277], "valid"], [[278, 278], "mapped", [279]], [[279, 279], "valid"], [[280, 280], "mapped", [281]], [[281, 281], "valid"], [[282, 282], "mapped", [283]], [[283, 283], "valid"], [[284, 284], "mapped", [285]], [[285, 285], "valid"], [[286, 286], "mapped", [287]], [[287, 287], "valid"], [[288, 288], "mapped", [289]], [[289, 289], "valid"], [[290, 290], "mapped", [291]], [[291, 291], "valid"], [[292, 292], "mapped", [293]], [[293, 293], "valid"], [[294, 294], "mapped", [295]], [[295, 295], "valid"], [[296, 296], "mapped", [297]], [[297, 297], "valid"], [[298, 298], "mapped", [299]], [[299, 299], "valid"], [[300, 300], "mapped", [301]], [[301, 301], "valid"], [[302, 302], "mapped", [303]], [[303, 303], "valid"], [[304, 304], "mapped", [105, 775]], [[305, 305], "valid"], [[306, 307], "mapped", [105, 106]], [[308, 308], "mapped", [309]], [[309, 309], "valid"], [[310, 310], "mapped", [311]], [[311, 312], "valid"], [[313, 313], "mapped", [314]], [[314, 314], "valid"], [[315, 315], "mapped", [316]], [[316, 316], "valid"], [[317, 317], "mapped", [318]], [[318, 318], "valid"], [[319, 320], "mapped", [108, 183]], [[321, 321], "mapped", [322]], [[322, 322], "valid"], [[323, 323], "mapped", [324]], [[324, 324], "valid"], [[325, 325], "mapped", [326]], [[326, 326], "valid"], [[327, 327], "mapped", [328]], [[328, 328], "valid"], [[329, 329], "mapped", [700, 110]], [[330, 330], "mapped", [331]], [[331, 331], "valid"], [[332, 332], "mapped", [333]], [[333, 333], "valid"], [[334, 334], "mapped", [335]], [[335, 335], "valid"], [[336, 336], "mapped", [337]], [[337, 337], "valid"], [[338, 338], "mapped", [339]], [[339, 339], "valid"], [[340, 340], "mapped", [341]], [[341, 341], "valid"], [[342, 342], "mapped", [343]], [[343, 343], "valid"], [[344, 344], "mapped", [345]], [[345, 345], "valid"], [[346, 346], "mapped", [347]], [[347, 347], "valid"], [[348, 348], "mapped", [349]], [[349, 349], "valid"], [[350, 350], "mapped", [351]], [[351, 351], "valid"], [[352, 352], "mapped", [353]], [[353, 353], "valid"], [[354, 354], "mapped", [355]], [[355, 355], "valid"], [[356, 356], "mapped", [357]], [[357, 357], "valid"], [[358, 358], "mapped", [359]], [[359, 359], "valid"], [[360, 360], "mapped", [361]], [[361, 361], "valid"], [[362, 362], "mapped", [363]], [[363, 363], "valid"], [[364, 364], "mapped", [365]], [[365, 365], "valid"], [[366, 366], "mapped", [367]], [[367, 367], "valid"], [[368, 368], "mapped", [369]], [[369, 369], "valid"], [[370, 370], "mapped", [371]], [[371, 371], "valid"], [[372, 372], "mapped", [373]], [[373, 373], "valid"], [[374, 374], "mapped", [375]], [[375, 375], "valid"], [[376, 376], "mapped", [255]], [[377, 377], "mapped", [378]], [[378, 378], "valid"], [[379, 379], "mapped", [380]], [[380, 380], "valid"], [[381, 381], "mapped", [382]], [[382, 382], "valid"], [[383, 383], "mapped", [115]], [[384, 384], "valid"], [[385, 385], "mapped", [595]], [[386, 386], "mapped", [387]], [[387, 387], "valid"], [[388, 388], "mapped", [389]], [[389, 389], "valid"], [[390, 390], "mapped", [596]], [[391, 391], "mapped", [392]], [[392, 392], "valid"], [[393, 393], "mapped", [598]], [[394, 394], "mapped", [599]], [[395, 395], "mapped", [396]], [[396, 397], "valid"], [[398, 398], "mapped", [477]], [[399, 399], "mapped", [601]], [[400, 400], "mapped", [603]], [[401, 401], "mapped", [402]], [[402, 402], "valid"], [[403, 403], "mapped", [608]], [[404, 404], "mapped", [611]], [[405, 405], "valid"], [[406, 406], "mapped", [617]], [[407, 407], "mapped", [616]], [[408, 408], "mapped", [409]], [[409, 411], "valid"], [[412, 412], "mapped", [623]], [[413, 413], "mapped", [626]], [[414, 414], "valid"], [[415, 415], "mapped", [629]], [[416, 416], "mapped", [417]], [[417, 417], "valid"], [[418, 418], "mapped", [419]], [[419, 419], "valid"], [[420, 420], "mapped", [421]], [[421, 421], "valid"], [[422, 422], "mapped", [640]], [[423, 423], "mapped", [424]], [[424, 424], "valid"], [[425, 425], "mapped", [643]], [[426, 427], "valid"], [[428, 428], "mapped", [429]], [[429, 429], "valid"], [[430, 430], "mapped", [648]], [[431, 431], "mapped", [432]], [[432, 432], "valid"], [[433, 433], "mapped", [650]], [[434, 434], "mapped", [651]], [[435, 435], "mapped", [436]], [[436, 436], "valid"], [[437, 437], "mapped", [438]], [[438, 438], "valid"], [[439, 439], "mapped", [658]], [[440, 440], "mapped", [441]], [[441, 443], "valid"], [[444, 444], "mapped", [445]], [[445, 451], "valid"], [[452, 454], "mapped", [100, 382]], [[455, 457], "mapped", [108, 106]], [[458, 460], "mapped", [110, 106]], [[461, 461], "mapped", [462]], [[462, 462], "valid"], [[463, 463], "mapped", [464]], [[464, 464], "valid"], [[465, 465], "mapped", [466]], [[466, 466], "valid"], [[467, 467], "mapped", [468]], [[468, 468], "valid"], [[469, 469], "mapped", [470]], [[470, 470], "valid"], [[471, 471], "mapped", [472]], [[472, 472], "valid"], [[473, 473], "mapped", [474]], [[474, 474], "valid"], [[475, 475], "mapped", [476]], [[476, 477], "valid"], [[478, 478], "mapped", [479]], [[479, 479], "valid"], [[480, 480], "mapped", [481]], [[481, 481], "valid"], [[482, 482], "mapped", [483]], [[483, 483], "valid"], [[484, 484], "mapped", [485]], [[485, 485], "valid"], [[486, 486], "mapped", [487]], [[487, 487], "valid"], [[488, 488], "mapped", [489]], [[489, 489], "valid"], [[490, 490], "mapped", [491]], [[491, 491], "valid"], [[492, 492], "mapped", [493]], [[493, 493], "valid"], [[494, 494], "mapped", [495]], [[495, 496], "valid"], [[497, 499], "mapped", [100, 122]], [[500, 500], "mapped", [501]], [[501, 501], "valid"], [[502, 502], "mapped", [405]], [[503, 503], "mapped", [447]], [[504, 504], "mapped", [505]], [[505, 505], "valid"], [[506, 506], "mapped", [507]], [[507, 507], "valid"], [[508, 508], "mapped", [509]], [[509, 509], "valid"], [[510, 510], "mapped", [511]], [[511, 511], "valid"], [[512, 512], "mapped", [513]], [[513, 513], "valid"], [[514, 514], "mapped", [515]], [[515, 515], "valid"], [[516, 516], "mapped", [517]], [[517, 517], "valid"], [[518, 518], "mapped", [519]], [[519, 519], "valid"], [[520, 520], "mapped", [521]], [[521, 521], "valid"], [[522, 522], "mapped", [523]], [[523, 523], "valid"], [[524, 524], "mapped", [525]], [[525, 525], "valid"], [[526, 526], "mapped", [527]], [[527, 527], "valid"], [[528, 528], "mapped", [529]], [[529, 529], "valid"], [[530, 530], "mapped", [531]], [[531, 531], "valid"], [[532, 532], "mapped", [533]], [[533, 533], "valid"], [[534, 534], "mapped", [535]], [[535, 535], "valid"], [[536, 536], "mapped", [537]], [[537, 537], "valid"], [[538, 538], "mapped", [539]], [[539, 539], "valid"], [[540, 540], "mapped", [541]], [[541, 541], "valid"], [[542, 542], "mapped", [543]], [[543, 543], "valid"], [[544, 544], "mapped", [414]], [[545, 545], "valid"], [[546, 546], "mapped", [547]], [[547, 547], "valid"], [[548, 548], "mapped", [549]], [[549, 549], "valid"], [[550, 550], "mapped", [551]], [[551, 551], "valid"], [[552, 552], "mapped", [553]], [[553, 553], "valid"], [[554, 554], "mapped", [555]], [[555, 555], "valid"], [[556, 556], "mapped", [557]], [[557, 557], "valid"], [[558, 558], "mapped", [559]], [[559, 559], "valid"], [[560, 560], "mapped", [561]], [[561, 561], "valid"], [[562, 562], "mapped", [563]], [[563, 563], "valid"], [[564, 566], "valid"], [[567, 569], "valid"], [[570, 570], "mapped", [11365]], [[571, 571], "mapped", [572]], [[572, 572], "valid"], [[573, 573], "mapped", [410]], [[574, 574], "mapped", [11366]], [[575, 576], "valid"], [[577, 577], "mapped", [578]], [[578, 578], "valid"], [[579, 579], "mapped", [384]], [[580, 580], "mapped", [649]], [[581, 581], "mapped", [652]], [[582, 582], "mapped", [583]], [[583, 583], "valid"], [[584, 584], "mapped", [585]], [[585, 585], "valid"], [[586, 586], "mapped", [587]], [[587, 587], "valid"], [[588, 588], "mapped", [589]], [[589, 589], "valid"], [[590, 590], "mapped", [591]], [[591, 591], "valid"], [[592, 680], "valid"], [[681, 685], "valid"], [[686, 687], "valid"], [[688, 688], "mapped", [104]], [[689, 689], "mapped", [614]], [[690, 690], "mapped", [106]], [[691, 691], "mapped", [114]], [[692, 692], "mapped", [633]], [[693, 693], "mapped", [635]], [[694, 694], "mapped", [641]], [[695, 695], "mapped", [119]], [[696, 696], "mapped", [121]], [[697, 705], "valid"], [[706, 709], "valid", [], "NV8"], [[710, 721], "valid"], [[722, 727], "valid", [], "NV8"], [[728, 728], "disallowed_STD3_mapped", [32, 774]], [[729, 729], "disallowed_STD3_mapped", [32, 775]], [[730, 730], "disallowed_STD3_mapped", [32, 778]], [[731, 731], "disallowed_STD3_mapped", [32, 808]], [[732, 732], "disallowed_STD3_mapped", [32, 771]], [[733, 733], "disallowed_STD3_mapped", [32, 779]], [[734, 734], "valid", [], "NV8"], [[735, 735], "valid", [], "NV8"], [[736, 736], "mapped", [611]], [[737, 737], "mapped", [108]], [[738, 738], "mapped", [115]], [[739, 739], "mapped", [120]], [[740, 740], "mapped", [661]], [[741, 745], "valid", [], "NV8"], [[746, 747], "valid", [], "NV8"], [[748, 748], "valid"], [[749, 749], "valid", [], "NV8"], [[750, 750], "valid"], [[751, 767], "valid", [], "NV8"], [[768, 831], "valid"], [[832, 832], "mapped", [768]], [[833, 833], "mapped", [769]], [[834, 834], "valid"], [[835, 835], "mapped", [787]], [[836, 836], "mapped", [776, 769]], [[837, 837], "mapped", [953]], [[838, 846], "valid"], [[847, 847], "ignored"], [[848, 855], "valid"], [[856, 860], "valid"], [[861, 863], "valid"], [[864, 865], "valid"], [[866, 866], "valid"], [[867, 879], "valid"], [[880, 880], "mapped", [881]], [[881, 881], "valid"], [[882, 882], "mapped", [883]], [[883, 883], "valid"], [[884, 884], "mapped", [697]], [[885, 885], "valid"], [[886, 886], "mapped", [887]], [[887, 887], "valid"], [[888, 889], "disallowed"], [[890, 890], "disallowed_STD3_mapped", [32, 953]], [[891, 893], "valid"], [[894, 894], "disallowed_STD3_mapped", [59]], [[895, 895], "mapped", [1011]], [[896, 899], "disallowed"], [[900, 900], "disallowed_STD3_mapped", [32, 769]], [[901, 901], "disallowed_STD3_mapped", [32, 776, 769]], [[902, 902], "mapped", [940]], [[903, 903], "mapped", [183]], [[904, 904], "mapped", [941]], [[905, 905], "mapped", [942]], [[906, 906], "mapped", [943]], [[907, 907], "disallowed"], [[908, 908], "mapped", [972]], [[909, 909], "disallowed"], [[910, 910], "mapped", [973]], [[911, 911], "mapped", [974]], [[912, 912], "valid"], [[913, 913], "mapped", [945]], [[914, 914], "mapped", [946]], [[915, 915], "mapped", [947]], [[916, 916], "mapped", [948]], [[917, 917], "mapped", [949]], [[918, 918], "mapped", [950]], [[919, 919], "mapped", [951]], [[920, 920], "mapped", [952]], [[921, 921], "mapped", [953]], [[922, 922], "mapped", [954]], [[923, 923], "mapped", [955]], [[924, 924], "mapped", [956]], [[925, 925], "mapped", [957]], [[926, 926], "mapped", [958]], [[927, 927], "mapped", [959]], [[928, 928], "mapped", [960]], [[929, 929], "mapped", [961]], [[930, 930], "disallowed"], [[931, 931], "mapped", [963]], [[932, 932], "mapped", [964]], [[933, 933], "mapped", [965]], [[934, 934], "mapped", [966]], [[935, 935], "mapped", [967]], [[936, 936], "mapped", [968]], [[937, 937], "mapped", [969]], [[938, 938], "mapped", [970]], [[939, 939], "mapped", [971]], [[940, 961], "valid"], [[962, 962], "deviation", [963]], [[963, 974], "valid"], [[975, 975], "mapped", [983]], [[976, 976], "mapped", [946]], [[977, 977], "mapped", [952]], [[978, 978], "mapped", [965]], [[979, 979], "mapped", [973]], [[980, 980], "mapped", [971]], [[981, 981], "mapped", [966]], [[982, 982], "mapped", [960]], [[983, 983], "valid"], [[984, 984], "mapped", [985]], [[985, 985], "valid"], [[986, 986], "mapped", [987]], [[987, 987], "valid"], [[988, 988], "mapped", [989]], [[989, 989], "valid"], [[990, 990], "mapped", [991]], [[991, 991], "valid"], [[992, 992], "mapped", [993]], [[993, 993], "valid"], [[994, 994], "mapped", [995]], [[995, 995], "valid"], [[996, 996], "mapped", [997]], [[997, 997], "valid"], [[998, 998], "mapped", [999]], [[999, 999], "valid"], [[1e3, 1e3], "mapped", [1001]], [[1001, 1001], "valid"], [[1002, 1002], "mapped", [1003]], [[1003, 1003], "valid"], [[1004, 1004], "mapped", [1005]], [[1005, 1005], "valid"], [[1006, 1006], "mapped", [1007]], [[1007, 1007], "valid"], [[1008, 1008], "mapped", [954]], [[1009, 1009], "mapped", [961]], [[1010, 1010], "mapped", [963]], [[1011, 1011], "valid"], [[1012, 1012], "mapped", [952]], [[1013, 1013], "mapped", [949]], [[1014, 1014], "valid", [], "NV8"], [[1015, 1015], "mapped", [1016]], [[1016, 1016], "valid"], [[1017, 1017], "mapped", [963]], [[1018, 1018], "mapped", [1019]], [[1019, 1019], "valid"], [[1020, 1020], "valid"], [[1021, 1021], "mapped", [891]], [[1022, 1022], "mapped", [892]], [[1023, 1023], "mapped", [893]], [[1024, 1024], "mapped", [1104]], [[1025, 1025], "mapped", [1105]], [[1026, 1026], "mapped", [1106]], [[1027, 1027], "mapped", [1107]], [[1028, 1028], "mapped", [1108]], [[1029, 1029], "mapped", [1109]], [[1030, 1030], "mapped", [1110]], [[1031, 1031], "mapped", [1111]], [[1032, 1032], "mapped", [1112]], [[1033, 1033], "mapped", [1113]], [[1034, 1034], "mapped", [1114]], [[1035, 1035], "mapped", [1115]], [[1036, 1036], "mapped", [1116]], [[1037, 1037], "mapped", [1117]], [[1038, 1038], "mapped", [1118]], [[1039, 1039], "mapped", [1119]], [[1040, 1040], "mapped", [1072]], [[1041, 1041], "mapped", [1073]], [[1042, 1042], "mapped", [1074]], [[1043, 1043], "mapped", [1075]], [[1044, 1044], "mapped", [1076]], [[1045, 1045], "mapped", [1077]], [[1046, 1046], "mapped", [1078]], [[1047, 1047], "mapped", [1079]], [[1048, 1048], "mapped", [1080]], [[1049, 1049], "mapped", [1081]], [[1050, 1050], "mapped", [1082]], [[1051, 1051], "mapped", [1083]], [[1052, 1052], "mapped", [1084]], [[1053, 1053], "mapped", [1085]], [[1054, 1054], "mapped", [1086]], [[1055, 1055], "mapped", [1087]], [[1056, 1056], "mapped", [1088]], [[1057, 1057], "mapped", [1089]], [[1058, 1058], "mapped", [1090]], [[1059, 1059], "mapped", [1091]], [[1060, 1060], "mapped", [1092]], [[1061, 1061], "mapped", [1093]], [[1062, 1062], "mapped", [1094]], [[1063, 1063], "mapped", [1095]], [[1064, 1064], "mapped", [1096]], [[1065, 1065], "mapped", [1097]], [[1066, 1066], "mapped", [1098]], [[1067, 1067], "mapped", [1099]], [[1068, 1068], "mapped", [1100]], [[1069, 1069], "mapped", [1101]], [[1070, 1070], "mapped", [1102]], [[1071, 1071], "mapped", [1103]], [[1072, 1103], "valid"], [[1104, 1104], "valid"], [[1105, 1116], "valid"], [[1117, 1117], "valid"], [[1118, 1119], "valid"], [[1120, 1120], "mapped", [1121]], [[1121, 1121], "valid"], [[1122, 1122], "mapped", [1123]], [[1123, 1123], "valid"], [[1124, 1124], "mapped", [1125]], [[1125, 1125], "valid"], [[1126, 1126], "mapped", [1127]], [[1127, 1127], "valid"], [[1128, 1128], "mapped", [1129]], [[1129, 1129], "valid"], [[1130, 1130], "mapped", [1131]], [[1131, 1131], "valid"], [[1132, 1132], "mapped", [1133]], [[1133, 1133], "valid"], [[1134, 1134], "mapped", [1135]], [[1135, 1135], "valid"], [[1136, 1136], "mapped", [1137]], [[1137, 1137], "valid"], [[1138, 1138], "mapped", [1139]], [[1139, 1139], "valid"], [[1140, 1140], "mapped", [1141]], [[1141, 1141], "valid"], [[1142, 1142], "mapped", [1143]], [[1143, 1143], "valid"], [[1144, 1144], "mapped", [1145]], [[1145, 1145], "valid"], [[1146, 1146], "mapped", [1147]], [[1147, 1147], "valid"], [[1148, 1148], "mapped", [1149]], [[1149, 1149], "valid"], [[1150, 1150], "mapped", [1151]], [[1151, 1151], "valid"], [[1152, 1152], "mapped", [1153]], [[1153, 1153], "valid"], [[1154, 1154], "valid", [], "NV8"], [[1155, 1158], "valid"], [[1159, 1159], "valid"], [[1160, 1161], "valid", [], "NV8"], [[1162, 1162], "mapped", [1163]], [[1163, 1163], "valid"], [[1164, 1164], "mapped", [1165]], [[1165, 1165], "valid"], [[1166, 1166], "mapped", [1167]], [[1167, 1167], "valid"], [[1168, 1168], "mapped", [1169]], [[1169, 1169], "valid"], [[1170, 1170], "mapped", [1171]], [[1171, 1171], "valid"], [[1172, 1172], "mapped", [1173]], [[1173, 1173], "valid"], [[1174, 1174], "mapped", [1175]], [[1175, 1175], "valid"], [[1176, 1176], "mapped", [1177]], [[1177, 1177], "valid"], [[1178, 1178], "mapped", [1179]], [[1179, 1179], "valid"], [[1180, 1180], "mapped", [1181]], [[1181, 1181], "valid"], [[1182, 1182], "mapped", [1183]], [[1183, 1183], "valid"], [[1184, 1184], "mapped", [1185]], [[1185, 1185], "valid"], [[1186, 1186], "mapped", [1187]], [[1187, 1187], "valid"], [[1188, 1188], "mapped", [1189]], [[1189, 1189], "valid"], [[1190, 1190], "mapped", [1191]], [[1191, 1191], "valid"], [[1192, 1192], "mapped", [1193]], [[1193, 1193], "valid"], [[1194, 1194], "mapped", [1195]], [[1195, 1195], "valid"], [[1196, 1196], "mapped", [1197]], [[1197, 1197], "valid"], [[1198, 1198], "mapped", [1199]], [[1199, 1199], "valid"], [[1200, 1200], "mapped", [1201]], [[1201, 1201], "valid"], [[1202, 1202], "mapped", [1203]], [[1203, 1203], "valid"], [[1204, 1204], "mapped", [1205]], [[1205, 1205], "valid"], [[1206, 1206], "mapped", [1207]], [[1207, 1207], "valid"], [[1208, 1208], "mapped", [1209]], [[1209, 1209], "valid"], [[1210, 1210], "mapped", [1211]], [[1211, 1211], "valid"], [[1212, 1212], "mapped", [1213]], [[1213, 1213], "valid"], [[1214, 1214], "mapped", [1215]], [[1215, 1215], "valid"], [[1216, 1216], "disallowed"], [[1217, 1217], "mapped", [1218]], [[1218, 1218], "valid"], [[1219, 1219], "mapped", [1220]], [[1220, 1220], "valid"], [[1221, 1221], "mapped", [1222]], [[1222, 1222], "valid"], [[1223, 1223], "mapped", [1224]], [[1224, 1224], "valid"], [[1225, 1225], "mapped", [1226]], [[1226, 1226], "valid"], [[1227, 1227], "mapped", [1228]], [[1228, 1228], "valid"], [[1229, 1229], "mapped", [1230]], [[1230, 1230], "valid"], [[1231, 1231], "valid"], [[1232, 1232], "mapped", [1233]], [[1233, 1233], "valid"], [[1234, 1234], "mapped", [1235]], [[1235, 1235], "valid"], [[1236, 1236], "mapped", [1237]], [[1237, 1237], "valid"], [[1238, 1238], "mapped", [1239]], [[1239, 1239], "valid"], [[1240, 1240], "mapped", [1241]], [[1241, 1241], "valid"], [[1242, 1242], "mapped", [1243]], [[1243, 1243], "valid"], [[1244, 1244], "mapped", [1245]], [[1245, 1245], "valid"], [[1246, 1246], "mapped", [1247]], [[1247, 1247], "valid"], [[1248, 1248], "mapped", [1249]], [[1249, 1249], "valid"], [[1250, 1250], "mapped", [1251]], [[1251, 1251], "valid"], [[1252, 1252], "mapped", [1253]], [[1253, 1253], "valid"], [[1254, 1254], "mapped", [1255]], [[1255, 1255], "valid"], [[1256, 1256], "mapped", [1257]], [[1257, 1257], "valid"], [[1258, 1258], "mapped", [1259]], [[1259, 1259], "valid"], [[1260, 1260], "mapped", [1261]], [[1261, 1261], "valid"], [[1262, 1262], "mapped", [1263]], [[1263, 1263], "valid"], [[1264, 1264], "mapped", [1265]], [[1265, 1265], "valid"], [[1266, 1266], "mapped", [1267]], [[1267, 1267], "valid"], [[1268, 1268], "mapped", [1269]], [[1269, 1269], "valid"], [[1270, 1270], "mapped", [1271]], [[1271, 1271], "valid"], [[1272, 1272], "mapped", [1273]], [[1273, 1273], "valid"], [[1274, 1274], "mapped", [1275]], [[1275, 1275], "valid"], [[1276, 1276], "mapped", [1277]], [[1277, 1277], "valid"], [[1278, 1278], "mapped", [1279]], [[1279, 1279], "valid"], [[1280, 1280], "mapped", [1281]], [[1281, 1281], "valid"], [[1282, 1282], "mapped", [1283]], [[1283, 1283], "valid"], [[1284, 1284], "mapped", [1285]], [[1285, 1285], "valid"], [[1286, 1286], "mapped", [1287]], [[1287, 1287], "valid"], [[1288, 1288], "mapped", [1289]], [[1289, 1289], "valid"], [[1290, 1290], "mapped", [1291]], [[1291, 1291], "valid"], [[1292, 1292], "mapped", [1293]], [[1293, 1293], "valid"], [[1294, 1294], "mapped", [1295]], [[1295, 1295], "valid"], [[1296, 1296], "mapped", [1297]], [[1297, 1297], "valid"], [[1298, 1298], "mapped", [1299]], [[1299, 1299], "valid"], [[1300, 1300], "mapped", [1301]], [[1301, 1301], "valid"], [[1302, 1302], "mapped", [1303]], [[1303, 1303], "valid"], [[1304, 1304], "mapped", [1305]], [[1305, 1305], "valid"], [[1306, 1306], "mapped", [1307]], [[1307, 1307], "valid"], [[1308, 1308], "mapped", [1309]], [[1309, 1309], "valid"], [[1310, 1310], "mapped", [1311]], [[1311, 1311], "valid"], [[1312, 1312], "mapped", [1313]], [[1313, 1313], "valid"], [[1314, 1314], "mapped", [1315]], [[1315, 1315], "valid"], [[1316, 1316], "mapped", [1317]], [[1317, 1317], "valid"], [[1318, 1318], "mapped", [1319]], [[1319, 1319], "valid"], [[1320, 1320], "mapped", [1321]], [[1321, 1321], "valid"], [[1322, 1322], "mapped", [1323]], [[1323, 1323], "valid"], [[1324, 1324], "mapped", [1325]], [[1325, 1325], "valid"], [[1326, 1326], "mapped", [1327]], [[1327, 1327], "valid"], [[1328, 1328], "disallowed"], [[1329, 1329], "mapped", [1377]], [[1330, 1330], "mapped", [1378]], [[1331, 1331], "mapped", [1379]], [[1332, 1332], "mapped", [1380]], [[1333, 1333], "mapped", [1381]], [[1334, 1334], "mapped", [1382]], [[1335, 1335], "mapped", [1383]], [[1336, 1336], "mapped", [1384]], [[1337, 1337], "mapped", [1385]], [[1338, 1338], "mapped", [1386]], [[1339, 1339], "mapped", [1387]], [[1340, 1340], "mapped", [1388]], [[1341, 1341], "mapped", [1389]], [[1342, 1342], "mapped", [1390]], [[1343, 1343], "mapped", [1391]], [[1344, 1344], "mapped", [1392]], [[1345, 1345], "mapped", [1393]], [[1346, 1346], "mapped", [1394]], [[1347, 1347], "mapped", [1395]], [[1348, 1348], "mapped", [1396]], [[1349, 1349], "mapped", [1397]], [[1350, 1350], "mapped", [1398]], [[1351, 1351], "mapped", [1399]], [[1352, 1352], "mapped", [1400]], [[1353, 1353], "mapped", [1401]], [[1354, 1354], "mapped", [1402]], [[1355, 1355], "mapped", [1403]], [[1356, 1356], "mapped", [1404]], [[1357, 1357], "mapped", [1405]], [[1358, 1358], "mapped", [1406]], [[1359, 1359], "mapped", [1407]], [[1360, 1360], "mapped", [1408]], [[1361, 1361], "mapped", [1409]], [[1362, 1362], "mapped", [1410]], [[1363, 1363], "mapped", [1411]], [[1364, 1364], "mapped", [1412]], [[1365, 1365], "mapped", [1413]], [[1366, 1366], "mapped", [1414]], [[1367, 1368], "disallowed"], [[1369, 1369], "valid"], [[1370, 1375], "valid", [], "NV8"], [[1376, 1376], "disallowed"], [[1377, 1414], "valid"], [[1415, 1415], "mapped", [1381, 1410]], [[1416, 1416], "disallowed"], [[1417, 1417], "valid", [], "NV8"], [[1418, 1418], "valid", [], "NV8"], [[1419, 1420], "disallowed"], [[1421, 1422], "valid", [], "NV8"], [[1423, 1423], "valid", [], "NV8"], [[1424, 1424], "disallowed"], [[1425, 1441], "valid"], [[1442, 1442], "valid"], [[1443, 1455], "valid"], [[1456, 1465], "valid"], [[1466, 1466], "valid"], [[1467, 1469], "valid"], [[1470, 1470], "valid", [], "NV8"], [[1471, 1471], "valid"], [[1472, 1472], "valid", [], "NV8"], [[1473, 1474], "valid"], [[1475, 1475], "valid", [], "NV8"], [[1476, 1476], "valid"], [[1477, 1477], "valid"], [[1478, 1478], "valid", [], "NV8"], [[1479, 1479], "valid"], [[1480, 1487], "disallowed"], [[1488, 1514], "valid"], [[1515, 1519], "disallowed"], [[1520, 1524], "valid"], [[1525, 1535], "disallowed"], [[1536, 1539], "disallowed"], [[1540, 1540], "disallowed"], [[1541, 1541], "disallowed"], [[1542, 1546], "valid", [], "NV8"], [[1547, 1547], "valid", [], "NV8"], [[1548, 1548], "valid", [], "NV8"], [[1549, 1551], "valid", [], "NV8"], [[1552, 1557], "valid"], [[1558, 1562], "valid"], [[1563, 1563], "valid", [], "NV8"], [[1564, 1564], "disallowed"], [[1565, 1565], "disallowed"], [[1566, 1566], "valid", [], "NV8"], [[1567, 1567], "valid", [], "NV8"], [[1568, 1568], "valid"], [[1569, 1594], "valid"], [[1595, 1599], "valid"], [[1600, 1600], "valid", [], "NV8"], [[1601, 1618], "valid"], [[1619, 1621], "valid"], [[1622, 1624], "valid"], [[1625, 1630], "valid"], [[1631, 1631], "valid"], [[1632, 1641], "valid"], [[1642, 1645], "valid", [], "NV8"], [[1646, 1647], "valid"], [[1648, 1652], "valid"], [[1653, 1653], "mapped", [1575, 1652]], [[1654, 1654], "mapped", [1608, 1652]], [[1655, 1655], "mapped", [1735, 1652]], [[1656, 1656], "mapped", [1610, 1652]], [[1657, 1719], "valid"], [[1720, 1721], "valid"], [[1722, 1726], "valid"], [[1727, 1727], "valid"], [[1728, 1742], "valid"], [[1743, 1743], "valid"], [[1744, 1747], "valid"], [[1748, 1748], "valid", [], "NV8"], [[1749, 1756], "valid"], [[1757, 1757], "disallowed"], [[1758, 1758], "valid", [], "NV8"], [[1759, 1768], "valid"], [[1769, 1769], "valid", [], "NV8"], [[1770, 1773], "valid"], [[1774, 1775], "valid"], [[1776, 1785], "valid"], [[1786, 1790], "valid"], [[1791, 1791], "valid"], [[1792, 1805], "valid", [], "NV8"], [[1806, 1806], "disallowed"], [[1807, 1807], "disallowed"], [[1808, 1836], "valid"], [[1837, 1839], "valid"], [[1840, 1866], "valid"], [[1867, 1868], "disallowed"], [[1869, 1871], "valid"], [[1872, 1901], "valid"], [[1902, 1919], "valid"], [[1920, 1968], "valid"], [[1969, 1969], "valid"], [[1970, 1983], "disallowed"], [[1984, 2037], "valid"], [[2038, 2042], "valid", [], "NV8"], [[2043, 2047], "disallowed"], [[2048, 2093], "valid"], [[2094, 2095], "disallowed"], [[2096, 2110], "valid", [], "NV8"], [[2111, 2111], "disallowed"], [[2112, 2139], "valid"], [[2140, 2141], "disallowed"], [[2142, 2142], "valid", [], "NV8"], [[2143, 2207], "disallowed"], [[2208, 2208], "valid"], [[2209, 2209], "valid"], [[2210, 2220], "valid"], [[2221, 2226], "valid"], [[2227, 2228], "valid"], [[2229, 2274], "disallowed"], [[2275, 2275], "valid"], [[2276, 2302], "valid"], [[2303, 2303], "valid"], [[2304, 2304], "valid"], [[2305, 2307], "valid"], [[2308, 2308], "valid"], [[2309, 2361], "valid"], [[2362, 2363], "valid"], [[2364, 2381], "valid"], [[2382, 2382], "valid"], [[2383, 2383], "valid"], [[2384, 2388], "valid"], [[2389, 2389], "valid"], [[2390, 2391], "valid"], [[2392, 2392], "mapped", [2325, 2364]], [[2393, 2393], "mapped", [2326, 2364]], [[2394, 2394], "mapped", [2327, 2364]], [[2395, 2395], "mapped", [2332, 2364]], [[2396, 2396], "mapped", [2337, 2364]], [[2397, 2397], "mapped", [2338, 2364]], [[2398, 2398], "mapped", [2347, 2364]], [[2399, 2399], "mapped", [2351, 2364]], [[2400, 2403], "valid"], [[2404, 2405], "valid", [], "NV8"], [[2406, 2415], "valid"], [[2416, 2416], "valid", [], "NV8"], [[2417, 2418], "valid"], [[2419, 2423], "valid"], [[2424, 2424], "valid"], [[2425, 2426], "valid"], [[2427, 2428], "valid"], [[2429, 2429], "valid"], [[2430, 2431], "valid"], [[2432, 2432], "valid"], [[2433, 2435], "valid"], [[2436, 2436], "disallowed"], [[2437, 2444], "valid"], [[2445, 2446], "disallowed"], [[2447, 2448], "valid"], [[2449, 2450], "disallowed"], [[2451, 2472], "valid"], [[2473, 2473], "disallowed"], [[2474, 2480], "valid"], [[2481, 2481], "disallowed"], [[2482, 2482], "valid"], [[2483, 2485], "disallowed"], [[2486, 2489], "valid"], [[2490, 2491], "disallowed"], [[2492, 2492], "valid"], [[2493, 2493], "valid"], [[2494, 2500], "valid"], [[2501, 2502], "disallowed"], [[2503, 2504], "valid"], [[2505, 2506], "disallowed"], [[2507, 2509], "valid"], [[2510, 2510], "valid"], [[2511, 2518], "disallowed"], [[2519, 2519], "valid"], [[2520, 2523], "disallowed"], [[2524, 2524], "mapped", [2465, 2492]], [[2525, 2525], "mapped", [2466, 2492]], [[2526, 2526], "disallowed"], [[2527, 2527], "mapped", [2479, 2492]], [[2528, 2531], "valid"], [[2532, 2533], "disallowed"], [[2534, 2545], "valid"], [[2546, 2554], "valid", [], "NV8"], [[2555, 2555], "valid", [], "NV8"], [[2556, 2560], "disallowed"], [[2561, 2561], "valid"], [[2562, 2562], "valid"], [[2563, 2563], "valid"], [[2564, 2564], "disallowed"], [[2565, 2570], "valid"], [[2571, 2574], "disallowed"], [[2575, 2576], "valid"], [[2577, 2578], "disallowed"], [[2579, 2600], "valid"], [[2601, 2601], "disallowed"], [[2602, 2608], "valid"], [[2609, 2609], "disallowed"], [[2610, 2610], "valid"], [[2611, 2611], "mapped", [2610, 2620]], [[2612, 2612], "disallowed"], [[2613, 2613], "valid"], [[2614, 2614], "mapped", [2616, 2620]], [[2615, 2615], "disallowed"], [[2616, 2617], "valid"], [[2618, 2619], "disallowed"], [[2620, 2620], "valid"], [[2621, 2621], "disallowed"], [[2622, 2626], "valid"], [[2627, 2630], "disallowed"], [[2631, 2632], "valid"], [[2633, 2634], "disallowed"], [[2635, 2637], "valid"], [[2638, 2640], "disallowed"], [[2641, 2641], "valid"], [[2642, 2648], "disallowed"], [[2649, 2649], "mapped", [2582, 2620]], [[2650, 2650], "mapped", [2583, 2620]], [[2651, 2651], "mapped", [2588, 2620]], [[2652, 2652], "valid"], [[2653, 2653], "disallowed"], [[2654, 2654], "mapped", [2603, 2620]], [[2655, 2661], "disallowed"], [[2662, 2676], "valid"], [[2677, 2677], "valid"], [[2678, 2688], "disallowed"], [[2689, 2691], "valid"], [[2692, 2692], "disallowed"], [[2693, 2699], "valid"], [[2700, 2700], "valid"], [[2701, 2701], "valid"], [[2702, 2702], "disallowed"], [[2703, 2705], "valid"], [[2706, 2706], "disallowed"], [[2707, 2728], "valid"], [[2729, 2729], "disallowed"], [[2730, 2736], "valid"], [[2737, 2737], "disallowed"], [[2738, 2739], "valid"], [[2740, 2740], "disallowed"], [[2741, 2745], "valid"], [[2746, 2747], "disallowed"], [[2748, 2757], "valid"], [[2758, 2758], "disallowed"], [[2759, 2761], "valid"], [[2762, 2762], "disallowed"], [[2763, 2765], "valid"], [[2766, 2767], "disallowed"], [[2768, 2768], "valid"], [[2769, 2783], "disallowed"], [[2784, 2784], "valid"], [[2785, 2787], "valid"], [[2788, 2789], "disallowed"], [[2790, 2799], "valid"], [[2800, 2800], "valid", [], "NV8"], [[2801, 2801], "valid", [], "NV8"], [[2802, 2808], "disallowed"], [[2809, 2809], "valid"], [[2810, 2816], "disallowed"], [[2817, 2819], "valid"], [[2820, 2820], "disallowed"], [[2821, 2828], "valid"], [[2829, 2830], "disallowed"], [[2831, 2832], "valid"], [[2833, 2834], "disallowed"], [[2835, 2856], "valid"], [[2857, 2857], "disallowed"], [[2858, 2864], "valid"], [[2865, 2865], "disallowed"], [[2866, 2867], "valid"], [[2868, 2868], "disallowed"], [[2869, 2869], "valid"], [[2870, 2873], "valid"], [[2874, 2875], "disallowed"], [[2876, 2883], "valid"], [[2884, 2884], "valid"], [[2885, 2886], "disallowed"], [[2887, 2888], "valid"], [[2889, 2890], "disallowed"], [[2891, 2893], "valid"], [[2894, 2901], "disallowed"], [[2902, 2903], "valid"], [[2904, 2907], "disallowed"], [[2908, 2908], "mapped", [2849, 2876]], [[2909, 2909], "mapped", [2850, 2876]], [[2910, 2910], "disallowed"], [[2911, 2913], "valid"], [[2914, 2915], "valid"], [[2916, 2917], "disallowed"], [[2918, 2927], "valid"], [[2928, 2928], "valid", [], "NV8"], [[2929, 2929], "valid"], [[2930, 2935], "valid", [], "NV8"], [[2936, 2945], "disallowed"], [[2946, 2947], "valid"], [[2948, 2948], "disallowed"], [[2949, 2954], "valid"], [[2955, 2957], "disallowed"], [[2958, 2960], "valid"], [[2961, 2961], "disallowed"], [[2962, 2965], "valid"], [[2966, 2968], "disallowed"], [[2969, 2970], "valid"], [[2971, 2971], "disallowed"], [[2972, 2972], "valid"], [[2973, 2973], "disallowed"], [[2974, 2975], "valid"], [[2976, 2978], "disallowed"], [[2979, 2980], "valid"], [[2981, 2983], "disallowed"], [[2984, 2986], "valid"], [[2987, 2989], "disallowed"], [[2990, 2997], "valid"], [[2998, 2998], "valid"], [[2999, 3001], "valid"], [[3002, 3005], "disallowed"], [[3006, 3010], "valid"], [[3011, 3013], "disallowed"], [[3014, 3016], "valid"], [[3017, 3017], "disallowed"], [[3018, 3021], "valid"], [[3022, 3023], "disallowed"], [[3024, 3024], "valid"], [[3025, 3030], "disallowed"], [[3031, 3031], "valid"], [[3032, 3045], "disallowed"], [[3046, 3046], "valid"], [[3047, 3055], "valid"], [[3056, 3058], "valid", [], "NV8"], [[3059, 3066], "valid", [], "NV8"], [[3067, 3071], "disallowed"], [[3072, 3072], "valid"], [[3073, 3075], "valid"], [[3076, 3076], "disallowed"], [[3077, 3084], "valid"], [[3085, 3085], "disallowed"], [[3086, 3088], "valid"], [[3089, 3089], "disallowed"], [[3090, 3112], "valid"], [[3113, 3113], "disallowed"], [[3114, 3123], "valid"], [[3124, 3124], "valid"], [[3125, 3129], "valid"], [[3130, 3132], "disallowed"], [[3133, 3133], "valid"], [[3134, 3140], "valid"], [[3141, 3141], "disallowed"], [[3142, 3144], "valid"], [[3145, 3145], "disallowed"], [[3146, 3149], "valid"], [[3150, 3156], "disallowed"], [[3157, 3158], "valid"], [[3159, 3159], "disallowed"], [[3160, 3161], "valid"], [[3162, 3162], "valid"], [[3163, 3167], "disallowed"], [[3168, 3169], "valid"], [[3170, 3171], "valid"], [[3172, 3173], "disallowed"], [[3174, 3183], "valid"], [[3184, 3191], "disallowed"], [[3192, 3199], "valid", [], "NV8"], [[3200, 3200], "disallowed"], [[3201, 3201], "valid"], [[3202, 3203], "valid"], [[3204, 3204], "disallowed"], [[3205, 3212], "valid"], [[3213, 3213], "disallowed"], [[3214, 3216], "valid"], [[3217, 3217], "disallowed"], [[3218, 3240], "valid"], [[3241, 3241], "disallowed"], [[3242, 3251], "valid"], [[3252, 3252], "disallowed"], [[3253, 3257], "valid"], [[3258, 3259], "disallowed"], [[3260, 3261], "valid"], [[3262, 3268], "valid"], [[3269, 3269], "disallowed"], [[3270, 3272], "valid"], [[3273, 3273], "disallowed"], [[3274, 3277], "valid"], [[3278, 3284], "disallowed"], [[3285, 3286], "valid"], [[3287, 3293], "disallowed"], [[3294, 3294], "valid"], [[3295, 3295], "disallowed"], [[3296, 3297], "valid"], [[3298, 3299], "valid"], [[3300, 3301], "disallowed"], [[3302, 3311], "valid"], [[3312, 3312], "disallowed"], [[3313, 3314], "valid"], [[3315, 3328], "disallowed"], [[3329, 3329], "valid"], [[3330, 3331], "valid"], [[3332, 3332], "disallowed"], [[3333, 3340], "valid"], [[3341, 3341], "disallowed"], [[3342, 3344], "valid"], [[3345, 3345], "disallowed"], [[3346, 3368], "valid"], [[3369, 3369], "valid"], [[3370, 3385], "valid"], [[3386, 3386], "valid"], [[3387, 3388], "disallowed"], [[3389, 3389], "valid"], [[3390, 3395], "valid"], [[3396, 3396], "valid"], [[3397, 3397], "disallowed"], [[3398, 3400], "valid"], [[3401, 3401], "disallowed"], [[3402, 3405], "valid"], [[3406, 3406], "valid"], [[3407, 3414], "disallowed"], [[3415, 3415], "valid"], [[3416, 3422], "disallowed"], [[3423, 3423], "valid"], [[3424, 3425], "valid"], [[3426, 3427], "valid"], [[3428, 3429], "disallowed"], [[3430, 3439], "valid"], [[3440, 3445], "valid", [], "NV8"], [[3446, 3448], "disallowed"], [[3449, 3449], "valid", [], "NV8"], [[3450, 3455], "valid"], [[3456, 3457], "disallowed"], [[3458, 3459], "valid"], [[3460, 3460], "disallowed"], [[3461, 3478], "valid"], [[3479, 3481], "disallowed"], [[3482, 3505], "valid"], [[3506, 3506], "disallowed"], [[3507, 3515], "valid"], [[3516, 3516], "disallowed"], [[3517, 3517], "valid"], [[3518, 3519], "disallowed"], [[3520, 3526], "valid"], [[3527, 3529], "disallowed"], [[3530, 3530], "valid"], [[3531, 3534], "disallowed"], [[3535, 3540], "valid"], [[3541, 3541], "disallowed"], [[3542, 3542], "valid"], [[3543, 3543], "disallowed"], [[3544, 3551], "valid"], [[3552, 3557], "disallowed"], [[3558, 3567], "valid"], [[3568, 3569], "disallowed"], [[3570, 3571], "valid"], [[3572, 3572], "valid", [], "NV8"], [[3573, 3584], "disallowed"], [[3585, 3634], "valid"], [[3635, 3635], "mapped", [3661, 3634]], [[3636, 3642], "valid"], [[3643, 3646], "disallowed"], [[3647, 3647], "valid", [], "NV8"], [[3648, 3662], "valid"], [[3663, 3663], "valid", [], "NV8"], [[3664, 3673], "valid"], [[3674, 3675], "valid", [], "NV8"], [[3676, 3712], "disallowed"], [[3713, 3714], "valid"], [[3715, 3715], "disallowed"], [[3716, 3716], "valid"], [[3717, 3718], "disallowed"], [[3719, 3720], "valid"], [[3721, 3721], "disallowed"], [[3722, 3722], "valid"], [[3723, 3724], "disallowed"], [[3725, 3725], "valid"], [[3726, 3731], "disallowed"], [[3732, 3735], "valid"], [[3736, 3736], "disallowed"], [[3737, 3743], "valid"], [[3744, 3744], "disallowed"], [[3745, 3747], "valid"], [[3748, 3748], "disallowed"], [[3749, 3749], "valid"], [[3750, 3750], "disallowed"], [[3751, 3751], "valid"], [[3752, 3753], "disallowed"], [[3754, 3755], "valid"], [[3756, 3756], "disallowed"], [[3757, 3762], "valid"], [[3763, 3763], "mapped", [3789, 3762]], [[3764, 3769], "valid"], [[3770, 3770], "disallowed"], [[3771, 3773], "valid"], [[3774, 3775], "disallowed"], [[3776, 3780], "valid"], [[3781, 3781], "disallowed"], [[3782, 3782], "valid"], [[3783, 3783], "disallowed"], [[3784, 3789], "valid"], [[3790, 3791], "disallowed"], [[3792, 3801], "valid"], [[3802, 3803], "disallowed"], [[3804, 3804], "mapped", [3755, 3737]], [[3805, 3805], "mapped", [3755, 3745]], [[3806, 3807], "valid"], [[3808, 3839], "disallowed"], [[3840, 3840], "valid"], [[3841, 3850], "valid", [], "NV8"], [[3851, 3851], "valid"], [[3852, 3852], "mapped", [3851]], [[3853, 3863], "valid", [], "NV8"], [[3864, 3865], "valid"], [[3866, 3871], "valid", [], "NV8"], [[3872, 3881], "valid"], [[3882, 3892], "valid", [], "NV8"], [[3893, 3893], "valid"], [[3894, 3894], "valid", [], "NV8"], [[3895, 3895], "valid"], [[3896, 3896], "valid", [], "NV8"], [[3897, 3897], "valid"], [[3898, 3901], "valid", [], "NV8"], [[3902, 3906], "valid"], [[3907, 3907], "mapped", [3906, 4023]], [[3908, 3911], "valid"], [[3912, 3912], "disallowed"], [[3913, 3916], "valid"], [[3917, 3917], "mapped", [3916, 4023]], [[3918, 3921], "valid"], [[3922, 3922], "mapped", [3921, 4023]], [[3923, 3926], "valid"], [[3927, 3927], "mapped", [3926, 4023]], [[3928, 3931], "valid"], [[3932, 3932], "mapped", [3931, 4023]], [[3933, 3944], "valid"], [[3945, 3945], "mapped", [3904, 4021]], [[3946, 3946], "valid"], [[3947, 3948], "valid"], [[3949, 3952], "disallowed"], [[3953, 3954], "valid"], [[3955, 3955], "mapped", [3953, 3954]], [[3956, 3956], "valid"], [[3957, 3957], "mapped", [3953, 3956]], [[3958, 3958], "mapped", [4018, 3968]], [[3959, 3959], "mapped", [4018, 3953, 3968]], [[3960, 3960], "mapped", [4019, 3968]], [[3961, 3961], "mapped", [4019, 3953, 3968]], [[3962, 3968], "valid"], [[3969, 3969], "mapped", [3953, 3968]], [[3970, 3972], "valid"], [[3973, 3973], "valid", [], "NV8"], [[3974, 3979], "valid"], [[3980, 3983], "valid"], [[3984, 3986], "valid"], [[3987, 3987], "mapped", [3986, 4023]], [[3988, 3989], "valid"], [[3990, 3990], "valid"], [[3991, 3991], "valid"], [[3992, 3992], "disallowed"], [[3993, 3996], "valid"], [[3997, 3997], "mapped", [3996, 4023]], [[3998, 4001], "valid"], [[4002, 4002], "mapped", [4001, 4023]], [[4003, 4006], "valid"], [[4007, 4007], "mapped", [4006, 4023]], [[4008, 4011], "valid"], [[4012, 4012], "mapped", [4011, 4023]], [[4013, 4013], "valid"], [[4014, 4016], "valid"], [[4017, 4023], "valid"], [[4024, 4024], "valid"], [[4025, 4025], "mapped", [3984, 4021]], [[4026, 4028], "valid"], [[4029, 4029], "disallowed"], [[4030, 4037], "valid", [], "NV8"], [[4038, 4038], "valid"], [[4039, 4044], "valid", [], "NV8"], [[4045, 4045], "disallowed"], [[4046, 4046], "valid", [], "NV8"], [[4047, 4047], "valid", [], "NV8"], [[4048, 4049], "valid", [], "NV8"], [[4050, 4052], "valid", [], "NV8"], [[4053, 4056], "valid", [], "NV8"], [[4057, 4058], "valid", [], "NV8"], [[4059, 4095], "disallowed"], [[4096, 4129], "valid"], [[4130, 4130], "valid"], [[4131, 4135], "valid"], [[4136, 4136], "valid"], [[4137, 4138], "valid"], [[4139, 4139], "valid"], [[4140, 4146], "valid"], [[4147, 4149], "valid"], [[4150, 4153], "valid"], [[4154, 4159], "valid"], [[4160, 4169], "valid"], [[4170, 4175], "valid", [], "NV8"], [[4176, 4185], "valid"], [[4186, 4249], "valid"], [[4250, 4253], "valid"], [[4254, 4255], "valid", [], "NV8"], [[4256, 4293], "disallowed"], [[4294, 4294], "disallowed"], [[4295, 4295], "mapped", [11559]], [[4296, 4300], "disallowed"], [[4301, 4301], "mapped", [11565]], [[4302, 4303], "disallowed"], [[4304, 4342], "valid"], [[4343, 4344], "valid"], [[4345, 4346], "valid"], [[4347, 4347], "valid", [], "NV8"], [[4348, 4348], "mapped", [4316]], [[4349, 4351], "valid"], [[4352, 4441], "valid", [], "NV8"], [[4442, 4446], "valid", [], "NV8"], [[4447, 4448], "disallowed"], [[4449, 4514], "valid", [], "NV8"], [[4515, 4519], "valid", [], "NV8"], [[4520, 4601], "valid", [], "NV8"], [[4602, 4607], "valid", [], "NV8"], [[4608, 4614], "valid"], [[4615, 4615], "valid"], [[4616, 4678], "valid"], [[4679, 4679], "valid"], [[4680, 4680], "valid"], [[4681, 4681], "disallowed"], [[4682, 4685], "valid"], [[4686, 4687], "disallowed"], [[4688, 4694], "valid"], [[4695, 4695], "disallowed"], [[4696, 4696], "valid"], [[4697, 4697], "disallowed"], [[4698, 4701], "valid"], [[4702, 4703], "disallowed"], [[4704, 4742], "valid"], [[4743, 4743], "valid"], [[4744, 4744], "valid"], [[4745, 4745], "disallowed"], [[4746, 4749], "valid"], [[4750, 4751], "disallowed"], [[4752, 4782], "valid"], [[4783, 4783], "valid"], [[4784, 4784], "valid"], [[4785, 4785], "disallowed"], [[4786, 4789], "valid"], [[4790, 4791], "disallowed"], [[4792, 4798], "valid"], [[4799, 4799], "disallowed"], [[4800, 4800], "valid"], [[4801, 4801], "disallowed"], [[4802, 4805], "valid"], [[4806, 4807], "disallowed"], [[4808, 4814], "valid"], [[4815, 4815], "valid"], [[4816, 4822], "valid"], [[4823, 4823], "disallowed"], [[4824, 4846], "valid"], [[4847, 4847], "valid"], [[4848, 4878], "valid"], [[4879, 4879], "valid"], [[4880, 4880], "valid"], [[4881, 4881], "disallowed"], [[4882, 4885], "valid"], [[4886, 4887], "disallowed"], [[4888, 4894], "valid"], [[4895, 4895], "valid"], [[4896, 4934], "valid"], [[4935, 4935], "valid"], [[4936, 4954], "valid"], [[4955, 4956], "disallowed"], [[4957, 4958], "valid"], [[4959, 4959], "valid"], [[4960, 4960], "valid", [], "NV8"], [[4961, 4988], "valid", [], "NV8"], [[4989, 4991], "disallowed"], [[4992, 5007], "valid"], [[5008, 5017], "valid", [], "NV8"], [[5018, 5023], "disallowed"], [[5024, 5108], "valid"], [[5109, 5109], "valid"], [[5110, 5111], "disallowed"], [[5112, 5112], "mapped", [5104]], [[5113, 5113], "mapped", [5105]], [[5114, 5114], "mapped", [5106]], [[5115, 5115], "mapped", [5107]], [[5116, 5116], "mapped", [5108]], [[5117, 5117], "mapped", [5109]], [[5118, 5119], "disallowed"], [[5120, 5120], "valid", [], "NV8"], [[5121, 5740], "valid"], [[5741, 5742], "valid", [], "NV8"], [[5743, 5750], "valid"], [[5751, 5759], "valid"], [[5760, 5760], "disallowed"], [[5761, 5786], "valid"], [[5787, 5788], "valid", [], "NV8"], [[5789, 5791], "disallowed"], [[5792, 5866], "valid"], [[5867, 5872], "valid", [], "NV8"], [[5873, 5880], "valid"], [[5881, 5887], "disallowed"], [[5888, 5900], "valid"], [[5901, 5901], "disallowed"], [[5902, 5908], "valid"], [[5909, 5919], "disallowed"], [[5920, 5940], "valid"], [[5941, 5942], "valid", [], "NV8"], [[5943, 5951], "disallowed"], [[5952, 5971], "valid"], [[5972, 5983], "disallowed"], [[5984, 5996], "valid"], [[5997, 5997], "disallowed"], [[5998, 6e3], "valid"], [[6001, 6001], "disallowed"], [[6002, 6003], "valid"], [[6004, 6015], "disallowed"], [[6016, 6067], "valid"], [[6068, 6069], "disallowed"], [[6070, 6099], "valid"], [[6100, 6102], "valid", [], "NV8"], [[6103, 6103], "valid"], [[6104, 6107], "valid", [], "NV8"], [[6108, 6108], "valid"], [[6109, 6109], "valid"], [[6110, 6111], "disallowed"], [[6112, 6121], "valid"], [[6122, 6127], "disallowed"], [[6128, 6137], "valid", [], "NV8"], [[6138, 6143], "disallowed"], [[6144, 6149], "valid", [], "NV8"], [[6150, 6150], "disallowed"], [[6151, 6154], "valid", [], "NV8"], [[6155, 6157], "ignored"], [[6158, 6158], "disallowed"], [[6159, 6159], "disallowed"], [[6160, 6169], "valid"], [[6170, 6175], "disallowed"], [[6176, 6263], "valid"], [[6264, 6271], "disallowed"], [[6272, 6313], "valid"], [[6314, 6314], "valid"], [[6315, 6319], "disallowed"], [[6320, 6389], "valid"], [[6390, 6399], "disallowed"], [[6400, 6428], "valid"], [[6429, 6430], "valid"], [[6431, 6431], "disallowed"], [[6432, 6443], "valid"], [[6444, 6447], "disallowed"], [[6448, 6459], "valid"], [[6460, 6463], "disallowed"], [[6464, 6464], "valid", [], "NV8"], [[6465, 6467], "disallowed"], [[6468, 6469], "valid", [], "NV8"], [[6470, 6509], "valid"], [[6510, 6511], "disallowed"], [[6512, 6516], "valid"], [[6517, 6527], "disallowed"], [[6528, 6569], "valid"], [[6570, 6571], "valid"], [[6572, 6575], "disallowed"], [[6576, 6601], "valid"], [[6602, 6607], "disallowed"], [[6608, 6617], "valid"], [[6618, 6618], "valid", [], "XV8"], [[6619, 6621], "disallowed"], [[6622, 6623], "valid", [], "NV8"], [[6624, 6655], "valid", [], "NV8"], [[6656, 6683], "valid"], [[6684, 6685], "disallowed"], [[6686, 6687], "valid", [], "NV8"], [[6688, 6750], "valid"], [[6751, 6751], "disallowed"], [[6752, 6780], "valid"], [[6781, 6782], "disallowed"], [[6783, 6793], "valid"], [[6794, 6799], "disallowed"], [[6800, 6809], "valid"], [[6810, 6815], "disallowed"], [[6816, 6822], "valid", [], "NV8"], [[6823, 6823], "valid"], [[6824, 6829], "valid", [], "NV8"], [[6830, 6831], "disallowed"], [[6832, 6845], "valid"], [[6846, 6846], "valid", [], "NV8"], [[6847, 6911], "disallowed"], [[6912, 6987], "valid"], [[6988, 6991], "disallowed"], [[6992, 7001], "valid"], [[7002, 7018], "valid", [], "NV8"], [[7019, 7027], "valid"], [[7028, 7036], "valid", [], "NV8"], [[7037, 7039], "disallowed"], [[7040, 7082], "valid"], [[7083, 7085], "valid"], [[7086, 7097], "valid"], [[7098, 7103], "valid"], [[7104, 7155], "valid"], [[7156, 7163], "disallowed"], [[7164, 7167], "valid", [], "NV8"], [[7168, 7223], "valid"], [[7224, 7226], "disallowed"], [[7227, 7231], "valid", [], "NV8"], [[7232, 7241], "valid"], [[7242, 7244], "disallowed"], [[7245, 7293], "valid"], [[7294, 7295], "valid", [], "NV8"], [[7296, 7359], "disallowed"], [[7360, 7367], "valid", [], "NV8"], [[7368, 7375], "disallowed"], [[7376, 7378], "valid"], [[7379, 7379], "valid", [], "NV8"], [[7380, 7410], "valid"], [[7411, 7414], "valid"], [[7415, 7415], "disallowed"], [[7416, 7417], "valid"], [[7418, 7423], "disallowed"], [[7424, 7467], "valid"], [[7468, 7468], "mapped", [97]], [[7469, 7469], "mapped", [230]], [[7470, 7470], "mapped", [98]], [[7471, 7471], "valid"], [[7472, 7472], "mapped", [100]], [[7473, 7473], "mapped", [101]], [[7474, 7474], "mapped", [477]], [[7475, 7475], "mapped", [103]], [[7476, 7476], "mapped", [104]], [[7477, 7477], "mapped", [105]], [[7478, 7478], "mapped", [106]], [[7479, 7479], "mapped", [107]], [[7480, 7480], "mapped", [108]], [[7481, 7481], "mapped", [109]], [[7482, 7482], "mapped", [110]], [[7483, 7483], "valid"], [[7484, 7484], "mapped", [111]], [[7485, 7485], "mapped", [547]], [[7486, 7486], "mapped", [112]], [[7487, 7487], "mapped", [114]], [[7488, 7488], "mapped", [116]], [[7489, 7489], "mapped", [117]], [[7490, 7490], "mapped", [119]], [[7491, 7491], "mapped", [97]], [[7492, 7492], "mapped", [592]], [[7493, 7493], "mapped", [593]], [[7494, 7494], "mapped", [7426]], [[7495, 7495], "mapped", [98]], [[7496, 7496], "mapped", [100]], [[7497, 7497], "mapped", [101]], [[7498, 7498], "mapped", [601]], [[7499, 7499], "mapped", [603]], [[7500, 7500], "mapped", [604]], [[7501, 7501], "mapped", [103]], [[7502, 7502], "valid"], [[7503, 7503], "mapped", [107]], [[7504, 7504], "mapped", [109]], [[7505, 7505], "mapped", [331]], [[7506, 7506], "mapped", [111]], [[7507, 7507], "mapped", [596]], [[7508, 7508], "mapped", [7446]], [[7509, 7509], "mapped", [7447]], [[7510, 7510], "mapped", [112]], [[7511, 7511], "mapped", [116]], [[7512, 7512], "mapped", [117]], [[7513, 7513], "mapped", [7453]], [[7514, 7514], "mapped", [623]], [[7515, 7515], "mapped", [118]], [[7516, 7516], "mapped", [7461]], [[7517, 7517], "mapped", [946]], [[7518, 7518], "mapped", [947]], [[7519, 7519], "mapped", [948]], [[7520, 7520], "mapped", [966]], [[7521, 7521], "mapped", [967]], [[7522, 7522], "mapped", [105]], [[7523, 7523], "mapped", [114]], [[7524, 7524], "mapped", [117]], [[7525, 7525], "mapped", [118]], [[7526, 7526], "mapped", [946]], [[7527, 7527], "mapped", [947]], [[7528, 7528], "mapped", [961]], [[7529, 7529], "mapped", [966]], [[7530, 7530], "mapped", [967]], [[7531, 7531], "valid"], [[7532, 7543], "valid"], [[7544, 7544], "mapped", [1085]], [[7545, 7578], "valid"], [[7579, 7579], "mapped", [594]], [[7580, 7580], "mapped", [99]], [[7581, 7581], "mapped", [597]], [[7582, 7582], "mapped", [240]], [[7583, 7583], "mapped", [604]], [[7584, 7584], "mapped", [102]], [[7585, 7585], "mapped", [607]], [[7586, 7586], "mapped", [609]], [[7587, 7587], "mapped", [613]], [[7588, 7588], "mapped", [616]], [[7589, 7589], "mapped", [617]], [[7590, 7590], "mapped", [618]], [[7591, 7591], "mapped", [7547]], [[7592, 7592], "mapped", [669]], [[7593, 7593], "mapped", [621]], [[7594, 7594], "mapped", [7557]], [[7595, 7595], "mapped", [671]], [[7596, 7596], "mapped", [625]], [[7597, 7597], "mapped", [624]], [[7598, 7598], "mapped", [626]], [[7599, 7599], "mapped", [627]], [[7600, 7600], "mapped", [628]], [[7601, 7601], "mapped", [629]], [[7602, 7602], "mapped", [632]], [[7603, 7603], "mapped", [642]], [[7604, 7604], "mapped", [643]], [[7605, 7605], "mapped", [427]], [[7606, 7606], "mapped", [649]], [[7607, 7607], "mapped", [650]], [[7608, 7608], "mapped", [7452]], [[7609, 7609], "mapped", [651]], [[7610, 7610], "mapped", [652]], [[7611, 7611], "mapped", [122]], [[7612, 7612], "mapped", [656]], [[7613, 7613], "mapped", [657]], [[7614, 7614], "mapped", [658]], [[7615, 7615], "mapped", [952]], [[7616, 7619], "valid"], [[7620, 7626], "valid"], [[7627, 7654], "valid"], [[7655, 7669], "valid"], [[7670, 7675], "disallowed"], [[7676, 7676], "valid"], [[7677, 7677], "valid"], [[7678, 7679], "valid"], [[7680, 7680], "mapped", [7681]], [[7681, 7681], "valid"], [[7682, 7682], "mapped", [7683]], [[7683, 7683], "valid"], [[7684, 7684], "mapped", [7685]], [[7685, 7685], "valid"], [[7686, 7686], "mapped", [7687]], [[7687, 7687], "valid"], [[7688, 7688], "mapped", [7689]], [[7689, 7689], "valid"], [[7690, 7690], "mapped", [7691]], [[7691, 7691], "valid"], [[7692, 7692], "mapped", [7693]], [[7693, 7693], "valid"], [[7694, 7694], "mapped", [7695]], [[7695, 7695], "valid"], [[7696, 7696], "mapped", [7697]], [[7697, 7697], "valid"], [[7698, 7698], "mapped", [7699]], [[7699, 7699], "valid"], [[7700, 7700], "mapped", [7701]], [[7701, 7701], "valid"], [[7702, 7702], "mapped", [7703]], [[7703, 7703], "valid"], [[7704, 7704], "mapped", [7705]], [[7705, 7705], "valid"], [[7706, 7706], "mapped", [7707]], [[7707, 7707], "valid"], [[7708, 7708], "mapped", [7709]], [[7709, 7709], "valid"], [[7710, 7710], "mapped", [7711]], [[7711, 7711], "valid"], [[7712, 7712], "mapped", [7713]], [[7713, 7713], "valid"], [[7714, 7714], "mapped", [7715]], [[7715, 7715], "valid"], [[7716, 7716], "mapped", [7717]], [[7717, 7717], "valid"], [[7718, 7718], "mapped", [7719]], [[7719, 7719], "valid"], [[7720, 7720], "mapped", [7721]], [[7721, 7721], "valid"], [[7722, 7722], "mapped", [7723]], [[7723, 7723], "valid"], [[7724, 7724], "mapped", [7725]], [[7725, 7725], "valid"], [[7726, 7726], "mapped", [7727]], [[7727, 7727], "valid"], [[7728, 7728], "mapped", [7729]], [[7729, 7729], "valid"], [[7730, 7730], "mapped", [7731]], [[7731, 7731], "valid"], [[7732, 7732], "mapped", [7733]], [[7733, 7733], "valid"], [[7734, 7734], "mapped", [7735]], [[7735, 7735], "valid"], [[7736, 7736], "mapped", [7737]], [[7737, 7737], "valid"], [[7738, 7738], "mapped", [7739]], [[7739, 7739], "valid"], [[7740, 7740], "mapped", [7741]], [[7741, 7741], "valid"], [[7742, 7742], "mapped", [7743]], [[7743, 7743], "valid"], [[7744, 7744], "mapped", [7745]], [[7745, 7745], "valid"], [[7746, 7746], "mapped", [7747]], [[7747, 7747], "valid"], [[7748, 7748], "mapped", [7749]], [[7749, 7749], "valid"], [[7750, 7750], "mapped", [7751]], [[7751, 7751], "valid"], [[7752, 7752], "mapped", [7753]], [[7753, 7753], "valid"], [[7754, 7754], "mapped", [7755]], [[7755, 7755], "valid"], [[7756, 7756], "mapped", [7757]], [[7757, 7757], "valid"], [[7758, 7758], "mapped", [7759]], [[7759, 7759], "valid"], [[7760, 7760], "mapped", [7761]], [[7761, 7761], "valid"], [[7762, 7762], "mapped", [7763]], [[7763, 7763], "valid"], [[7764, 7764], "mapped", [7765]], [[7765, 7765], "valid"], [[7766, 7766], "mapped", [7767]], [[7767, 7767], "valid"], [[7768, 7768], "mapped", [7769]], [[7769, 7769], "valid"], [[7770, 7770], "mapped", [7771]], [[7771, 7771], "valid"], [[7772, 7772], "mapped", [7773]], [[7773, 7773], "valid"], [[7774, 7774], "mapped", [7775]], [[7775, 7775], "valid"], [[7776, 7776], "mapped", [7777]], [[7777, 7777], "valid"], [[7778, 7778], "mapped", [7779]], [[7779, 7779], "valid"], [[7780, 7780], "mapped", [7781]], [[7781, 7781], "valid"], [[7782, 7782], "mapped", [7783]], [[7783, 7783], "valid"], [[7784, 7784], "mapped", [7785]], [[7785, 7785], "valid"], [[7786, 7786], "mapped", [7787]], [[7787, 7787], "valid"], [[7788, 7788], "mapped", [7789]], [[7789, 7789], "valid"], [[7790, 7790], "mapped", [7791]], [[7791, 7791], "valid"], [[7792, 7792], "mapped", [7793]], [[7793, 7793], "valid"], [[7794, 7794], "mapped", [7795]], [[7795, 7795], "valid"], [[7796, 7796], "mapped", [7797]], [[7797, 7797], "valid"], [[7798, 7798], "mapped", [7799]], [[7799, 7799], "valid"], [[7800, 7800], "mapped", [7801]], [[7801, 7801], "valid"], [[7802, 7802], "mapped", [7803]], [[7803, 7803], "valid"], [[7804, 7804], "mapped", [7805]], [[7805, 7805], "valid"], [[7806, 7806], "mapped", [7807]], [[7807, 7807], "valid"], [[7808, 7808], "mapped", [7809]], [[7809, 7809], "valid"], [[7810, 7810], "mapped", [7811]], [[7811, 7811], "valid"], [[7812, 7812], "mapped", [7813]], [[7813, 7813], "valid"], [[7814, 7814], "mapped", [7815]], [[7815, 7815], "valid"], [[7816, 7816], "mapped", [7817]], [[7817, 7817], "valid"], [[7818, 7818], "mapped", [7819]], [[7819, 7819], "valid"], [[7820, 7820], "mapped", [7821]], [[7821, 7821], "valid"], [[7822, 7822], "mapped", [7823]], [[7823, 7823], "valid"], [[7824, 7824], "mapped", [7825]], [[7825, 7825], "valid"], [[7826, 7826], "mapped", [7827]], [[7827, 7827], "valid"], [[7828, 7828], "mapped", [7829]], [[7829, 7833], "valid"], [[7834, 7834], "mapped", [97, 702]], [[7835, 7835], "mapped", [7777]], [[7836, 7837], "valid"], [[7838, 7838], "mapped", [115, 115]], [[7839, 7839], "valid"], [[7840, 7840], "mapped", [7841]], [[7841, 7841], "valid"], [[7842, 7842], "mapped", [7843]], [[7843, 7843], "valid"], [[7844, 7844], "mapped", [7845]], [[7845, 7845], "valid"], [[7846, 7846], "mapped", [7847]], [[7847, 7847], "valid"], [[7848, 7848], "mapped", [7849]], [[7849, 7849], "valid"], [[7850, 7850], "mapped", [7851]], [[7851, 7851], "valid"], [[7852, 7852], "mapped", [7853]], [[7853, 7853], "valid"], [[7854, 7854], "mapped", [7855]], [[7855, 7855], "valid"], [[7856, 7856], "mapped", [7857]], [[7857, 7857], "valid"], [[7858, 7858], "mapped", [7859]], [[7859, 7859], "valid"], [[7860, 7860], "mapped", [7861]], [[7861, 7861], "valid"], [[7862, 7862], "mapped", [7863]], [[7863, 7863], "valid"], [[7864, 7864], "mapped", [7865]], [[7865, 7865], "valid"], [[7866, 7866], "mapped", [7867]], [[7867, 7867], "valid"], [[7868, 7868], "mapped", [7869]], [[7869, 7869], "valid"], [[7870, 7870], "mapped", [7871]], [[7871, 7871], "valid"], [[7872, 7872], "mapped", [7873]], [[7873, 7873], "valid"], [[7874, 7874], "mapped", [7875]], [[7875, 7875], "valid"], [[7876, 7876], "mapped", [7877]], [[7877, 7877], "valid"], [[7878, 7878], "mapped", [7879]], [[7879, 7879], "valid"], [[7880, 7880], "mapped", [7881]], [[7881, 7881], "valid"], [[7882, 7882], "mapped", [7883]], [[7883, 7883], "valid"], [[7884, 7884], "mapped", [7885]], [[7885, 7885], "valid"], [[7886, 7886], "mapped", [7887]], [[7887, 7887], "valid"], [[7888, 7888], "mapped", [7889]], [[7889, 7889], "valid"], [[7890, 7890], "mapped", [7891]], [[7891, 7891], "valid"], [[7892, 7892], "mapped", [7893]], [[7893, 7893], "valid"], [[7894, 7894], "mapped", [7895]], [[7895, 7895], "valid"], [[7896, 7896], "mapped", [7897]], [[7897, 7897], "valid"], [[7898, 7898], "mapped", [7899]], [[7899, 7899], "valid"], [[7900, 7900], "mapped", [7901]], [[7901, 7901], "valid"], [[7902, 7902], "mapped", [7903]], [[7903, 7903], "valid"], [[7904, 7904], "mapped", [7905]], [[7905, 7905], "valid"], [[7906, 7906], "mapped", [7907]], [[7907, 7907], "valid"], [[7908, 7908], "mapped", [7909]], [[7909, 7909], "valid"], [[7910, 7910], "mapped", [7911]], [[7911, 7911], "valid"], [[7912, 7912], "mapped", [7913]], [[7913, 7913], "valid"], [[7914, 7914], "mapped", [7915]], [[7915, 7915], "valid"], [[7916, 7916], "mapped", [7917]], [[7917, 7917], "valid"], [[7918, 7918], "mapped", [7919]], [[7919, 7919], "valid"], [[7920, 7920], "mapped", [7921]], [[7921, 7921], "valid"], [[7922, 7922], "mapped", [7923]], [[7923, 7923], "valid"], [[7924, 7924], "mapped", [7925]], [[7925, 7925], "valid"], [[7926, 7926], "mapped", [7927]], [[7927, 7927], "valid"], [[7928, 7928], "mapped", [7929]], [[7929, 7929], "valid"], [[7930, 7930], "mapped", [7931]], [[7931, 7931], "valid"], [[7932, 7932], "mapped", [7933]], [[7933, 7933], "valid"], [[7934, 7934], "mapped", [7935]], [[7935, 7935], "valid"], [[7936, 7943], "valid"], [[7944, 7944], "mapped", [7936]], [[7945, 7945], "mapped", [7937]], [[7946, 7946], "mapped", [7938]], [[7947, 7947], "mapped", [7939]], [[7948, 7948], "mapped", [7940]], [[7949, 7949], "mapped", [7941]], [[7950, 7950], "mapped", [7942]], [[7951, 7951], "mapped", [7943]], [[7952, 7957], "valid"], [[7958, 7959], "disallowed"], [[7960, 7960], "mapped", [7952]], [[7961, 7961], "mapped", [7953]], [[7962, 7962], "mapped", [7954]], [[7963, 7963], "mapped", [7955]], [[7964, 7964], "mapped", [7956]], [[7965, 7965], "mapped", [7957]], [[7966, 7967], "disallowed"], [[7968, 7975], "valid"], [[7976, 7976], "mapped", [7968]], [[7977, 7977], "mapped", [7969]], [[7978, 7978], "mapped", [7970]], [[7979, 7979], "mapped", [7971]], [[7980, 7980], "mapped", [7972]], [[7981, 7981], "mapped", [7973]], [[7982, 7982], "mapped", [7974]], [[7983, 7983], "mapped", [7975]], [[7984, 7991], "valid"], [[7992, 7992], "mapped", [7984]], [[7993, 7993], "mapped", [7985]], [[7994, 7994], "mapped", [7986]], [[7995, 7995], "mapped", [7987]], [[7996, 7996], "mapped", [7988]], [[7997, 7997], "mapped", [7989]], [[7998, 7998], "mapped", [7990]], [[7999, 7999], "mapped", [7991]], [[8e3, 8005], "valid"], [[8006, 8007], "disallowed"], [[8008, 8008], "mapped", [8e3]], [[8009, 8009], "mapped", [8001]], [[8010, 8010], "mapped", [8002]], [[8011, 8011], "mapped", [8003]], [[8012, 8012], "mapped", [8004]], [[8013, 8013], "mapped", [8005]], [[8014, 8015], "disallowed"], [[8016, 8023], "valid"], [[8024, 8024], "disallowed"], [[8025, 8025], "mapped", [8017]], [[8026, 8026], "disallowed"], [[8027, 8027], "mapped", [8019]], [[8028, 8028], "disallowed"], [[8029, 8029], "mapped", [8021]], [[8030, 8030], "disallowed"], [[8031, 8031], "mapped", [8023]], [[8032, 8039], "valid"], [[8040, 8040], "mapped", [8032]], [[8041, 8041], "mapped", [8033]], [[8042, 8042], "mapped", [8034]], [[8043, 8043], "mapped", [8035]], [[8044, 8044], "mapped", [8036]], [[8045, 8045], "mapped", [8037]], [[8046, 8046], "mapped", [8038]], [[8047, 8047], "mapped", [8039]], [[8048, 8048], "valid"], [[8049, 8049], "mapped", [940]], [[8050, 8050], "valid"], [[8051, 8051], "mapped", [941]], [[8052, 8052], "valid"], [[8053, 8053], "mapped", [942]], [[8054, 8054], "valid"], [[8055, 8055], "mapped", [943]], [[8056, 8056], "valid"], [[8057, 8057], "mapped", [972]], [[8058, 8058], "valid"], [[8059, 8059], "mapped", [973]], [[8060, 8060], "valid"], [[8061, 8061], "mapped", [974]], [[8062, 8063], "disallowed"], [[8064, 8064], "mapped", [7936, 953]], [[8065, 8065], "mapped", [7937, 953]], [[8066, 8066], "mapped", [7938, 953]], [[8067, 8067], "mapped", [7939, 953]], [[8068, 8068], "mapped", [7940, 953]], [[8069, 8069], "mapped", [7941, 953]], [[8070, 8070], "mapped", [7942, 953]], [[8071, 8071], "mapped", [7943, 953]], [[8072, 8072], "mapped", [7936, 953]], [[8073, 8073], "mapped", [7937, 953]], [[8074, 8074], "mapped", [7938, 953]], [[8075, 8075], "mapped", [7939, 953]], [[8076, 8076], "mapped", [7940, 953]], [[8077, 8077], "mapped", [7941, 953]], [[8078, 8078], "mapped", [7942, 953]], [[8079, 8079], "mapped", [7943, 953]], [[8080, 8080], "mapped", [7968, 953]], [[8081, 8081], "mapped", [7969, 953]], [[8082, 8082], "mapped", [7970, 953]], [[8083, 8083], "mapped", [7971, 953]], [[8084, 8084], "mapped", [7972, 953]], [[8085, 8085], "mapped", [7973, 953]], [[8086, 8086], "mapped", [7974, 953]], [[8087, 8087], "mapped", [7975, 953]], [[8088, 8088], "mapped", [7968, 953]], [[8089, 8089], "mapped", [7969, 953]], [[8090, 8090], "mapped", [7970, 953]], [[8091, 8091], "mapped", [7971, 953]], [[8092, 8092], "mapped", [7972, 953]], [[8093, 8093], "mapped", [7973, 953]], [[8094, 8094], "mapped", [7974, 953]], [[8095, 8095], "mapped", [7975, 953]], [[8096, 8096], "mapped", [8032, 953]], [[8097, 8097], "mapped", [8033, 953]], [[8098, 8098], "mapped", [8034, 953]], [[8099, 8099], "mapped", [8035, 953]], [[8100, 8100], "mapped", [8036, 953]], [[8101, 8101], "mapped", [8037, 953]], [[8102, 8102], "mapped", [8038, 953]], [[8103, 8103], "mapped", [8039, 953]], [[8104, 8104], "mapped", [8032, 953]], [[8105, 8105], "mapped", [8033, 953]], [[8106, 8106], "mapped", [8034, 953]], [[8107, 8107], "mapped", [8035, 953]], [[8108, 8108], "mapped", [8036, 953]], [[8109, 8109], "mapped", [8037, 953]], [[8110, 8110], "mapped", [8038, 953]], [[8111, 8111], "mapped", [8039, 953]], [[8112, 8113], "valid"], [[8114, 8114], "mapped", [8048, 953]], [[8115, 8115], "mapped", [945, 953]], [[8116, 8116], "mapped", [940, 953]], [[8117, 8117], "disallowed"], [[8118, 8118], "valid"], [[8119, 8119], "mapped", [8118, 953]], [[8120, 8120], "mapped", [8112]], [[8121, 8121], "mapped", [8113]], [[8122, 8122], "mapped", [8048]], [[8123, 8123], "mapped", [940]], [[8124, 8124], "mapped", [945, 953]], [[8125, 8125], "disallowed_STD3_mapped", [32, 787]], [[8126, 8126], "mapped", [953]], [[8127, 8127], "disallowed_STD3_mapped", [32, 787]], [[8128, 8128], "disallowed_STD3_mapped", [32, 834]], [[8129, 8129], "disallowed_STD3_mapped", [32, 776, 834]], [[8130, 8130], "mapped", [8052, 953]], [[8131, 8131], "mapped", [951, 953]], [[8132, 8132], "mapped", [942, 953]], [[8133, 8133], "disallowed"], [[8134, 8134], "valid"], [[8135, 8135], "mapped", [8134, 953]], [[8136, 8136], "mapped", [8050]], [[8137, 8137], "mapped", [941]], [[8138, 8138], "mapped", [8052]], [[8139, 8139], "mapped", [942]], [[8140, 8140], "mapped", [951, 953]], [[8141, 8141], "disallowed_STD3_mapped", [32, 787, 768]], [[8142, 8142], "disallowed_STD3_mapped", [32, 787, 769]], [[8143, 8143], "disallowed_STD3_mapped", [32, 787, 834]], [[8144, 8146], "valid"], [[8147, 8147], "mapped", [912]], [[8148, 8149], "disallowed"], [[8150, 8151], "valid"], [[8152, 8152], "mapped", [8144]], [[8153, 8153], "mapped", [8145]], [[8154, 8154], "mapped", [8054]], [[8155, 8155], "mapped", [943]], [[8156, 8156], "disallowed"], [[8157, 8157], "disallowed_STD3_mapped", [32, 788, 768]], [[8158, 8158], "disallowed_STD3_mapped", [32, 788, 769]], [[8159, 8159], "disallowed_STD3_mapped", [32, 788, 834]], [[8160, 8162], "valid"], [[8163, 8163], "mapped", [944]], [[8164, 8167], "valid"], [[8168, 8168], "mapped", [8160]], [[8169, 8169], "mapped", [8161]], [[8170, 8170], "mapped", [8058]], [[8171, 8171], "mapped", [973]], [[8172, 8172], "mapped", [8165]], [[8173, 8173], "disallowed_STD3_mapped", [32, 776, 768]], [[8174, 8174], "disallowed_STD3_mapped", [32, 776, 769]], [[8175, 8175], "disallowed_STD3_mapped", [96]], [[8176, 8177], "disallowed"], [[8178, 8178], "mapped", [8060, 953]], [[8179, 8179], "mapped", [969, 953]], [[8180, 8180], "mapped", [974, 953]], [[8181, 8181], "disallowed"], [[8182, 8182], "valid"], [[8183, 8183], "mapped", [8182, 953]], [[8184, 8184], "mapped", [8056]], [[8185, 8185], "mapped", [972]], [[8186, 8186], "mapped", [8060]], [[8187, 8187], "mapped", [974]], [[8188, 8188], "mapped", [969, 953]], [[8189, 8189], "disallowed_STD3_mapped", [32, 769]], [[8190, 8190], "disallowed_STD3_mapped", [32, 788]], [[8191, 8191], "disallowed"], [[8192, 8202], "disallowed_STD3_mapped", [32]], [[8203, 8203], "ignored"], [[8204, 8205], "deviation", []], [[8206, 8207], "disallowed"], [[8208, 8208], "valid", [], "NV8"], [[8209, 8209], "mapped", [8208]], [[8210, 8214], "valid", [], "NV8"], [[8215, 8215], "disallowed_STD3_mapped", [32, 819]], [[8216, 8227], "valid", [], "NV8"], [[8228, 8230], "disallowed"], [[8231, 8231], "valid", [], "NV8"], [[8232, 8238], "disallowed"], [[8239, 8239], "disallowed_STD3_mapped", [32]], [[8240, 8242], "valid", [], "NV8"], [[8243, 8243], "mapped", [8242, 8242]], [[8244, 8244], "mapped", [8242, 8242, 8242]], [[8245, 8245], "valid", [], "NV8"], [[8246, 8246], "mapped", [8245, 8245]], [[8247, 8247], "mapped", [8245, 8245, 8245]], [[8248, 8251], "valid", [], "NV8"], [[8252, 8252], "disallowed_STD3_mapped", [33, 33]], [[8253, 8253], "valid", [], "NV8"], [[8254, 8254], "disallowed_STD3_mapped", [32, 773]], [[8255, 8262], "valid", [], "NV8"], [[8263, 8263], "disallowed_STD3_mapped", [63, 63]], [[8264, 8264], "disallowed_STD3_mapped", [63, 33]], [[8265, 8265], "disallowed_STD3_mapped", [33, 63]], [[8266, 8269], "valid", [], "NV8"], [[8270, 8274], "valid", [], "NV8"], [[8275, 8276], "valid", [], "NV8"], [[8277, 8278], "valid", [], "NV8"], [[8279, 8279], "mapped", [8242, 8242, 8242, 8242]], [[8280, 8286], "valid", [], "NV8"], [[8287, 8287], "disallowed_STD3_mapped", [32]], [[8288, 8288], "ignored"], [[8289, 8291], "disallowed"], [[8292, 8292], "ignored"], [[8293, 8293], "disallowed"], [[8294, 8297], "disallowed"], [[8298, 8303], "disallowed"], [[8304, 8304], "mapped", [48]], [[8305, 8305], "mapped", [105]], [[8306, 8307], "disallowed"], [[8308, 8308], "mapped", [52]], [[8309, 8309], "mapped", [53]], [[8310, 8310], "mapped", [54]], [[8311, 8311], "mapped", [55]], [[8312, 8312], "mapped", [56]], [[8313, 8313], "mapped", [57]], [[8314, 8314], "disallowed_STD3_mapped", [43]], [[8315, 8315], "mapped", [8722]], [[8316, 8316], "disallowed_STD3_mapped", [61]], [[8317, 8317], "disallowed_STD3_mapped", [40]], [[8318, 8318], "disallowed_STD3_mapped", [41]], [[8319, 8319], "mapped", [110]], [[8320, 8320], "mapped", [48]], [[8321, 8321], "mapped", [49]], [[8322, 8322], "mapped", [50]], [[8323, 8323], "mapped", [51]], [[8324, 8324], "mapped", [52]], [[8325, 8325], "mapped", [53]], [[8326, 8326], "mapped", [54]], [[8327, 8327], "mapped", [55]], [[8328, 8328], "mapped", [56]], [[8329, 8329], "mapped", [57]], [[8330, 8330], "disallowed_STD3_mapped", [43]], [[8331, 8331], "mapped", [8722]], [[8332, 8332], "disallowed_STD3_mapped", [61]], [[8333, 8333], "disallowed_STD3_mapped", [40]], [[8334, 8334], "disallowed_STD3_mapped", [41]], [[8335, 8335], "disallowed"], [[8336, 8336], "mapped", [97]], [[8337, 8337], "mapped", [101]], [[8338, 8338], "mapped", [111]], [[8339, 8339], "mapped", [120]], [[8340, 8340], "mapped", [601]], [[8341, 8341], "mapped", [104]], [[8342, 8342], "mapped", [107]], [[8343, 8343], "mapped", [108]], [[8344, 8344], "mapped", [109]], [[8345, 8345], "mapped", [110]], [[8346, 8346], "mapped", [112]], [[8347, 8347], "mapped", [115]], [[8348, 8348], "mapped", [116]], [[8349, 8351], "disallowed"], [[8352, 8359], "valid", [], "NV8"], [[8360, 8360], "mapped", [114, 115]], [[8361, 8362], "valid", [], "NV8"], [[8363, 8363], "valid", [], "NV8"], [[8364, 8364], "valid", [], "NV8"], [[8365, 8367], "valid", [], "NV8"], [[8368, 8369], "valid", [], "NV8"], [[8370, 8373], "valid", [], "NV8"], [[8374, 8376], "valid", [], "NV8"], [[8377, 8377], "valid", [], "NV8"], [[8378, 8378], "valid", [], "NV8"], [[8379, 8381], "valid", [], "NV8"], [[8382, 8382], "valid", [], "NV8"], [[8383, 8399], "disallowed"], [[8400, 8417], "valid", [], "NV8"], [[8418, 8419], "valid", [], "NV8"], [[8420, 8426], "valid", [], "NV8"], [[8427, 8427], "valid", [], "NV8"], [[8428, 8431], "valid", [], "NV8"], [[8432, 8432], "valid", [], "NV8"], [[8433, 8447], "disallowed"], [[8448, 8448], "disallowed_STD3_mapped", [97, 47, 99]], [[8449, 8449], "disallowed_STD3_mapped", [97, 47, 115]], [[8450, 8450], "mapped", [99]], [[8451, 8451], "mapped", [176, 99]], [[8452, 8452], "valid", [], "NV8"], [[8453, 8453], "disallowed_STD3_mapped", [99, 47, 111]], [[8454, 8454], "disallowed_STD3_mapped", [99, 47, 117]], [[8455, 8455], "mapped", [603]], [[8456, 8456], "valid", [], "NV8"], [[8457, 8457], "mapped", [176, 102]], [[8458, 8458], "mapped", [103]], [[8459, 8462], "mapped", [104]], [[8463, 8463], "mapped", [295]], [[8464, 8465], "mapped", [105]], [[8466, 8467], "mapped", [108]], [[8468, 8468], "valid", [], "NV8"], [[8469, 8469], "mapped", [110]], [[8470, 8470], "mapped", [110, 111]], [[8471, 8472], "valid", [], "NV8"], [[8473, 8473], "mapped", [112]], [[8474, 8474], "mapped", [113]], [[8475, 8477], "mapped", [114]], [[8478, 8479], "valid", [], "NV8"], [[8480, 8480], "mapped", [115, 109]], [[8481, 8481], "mapped", [116, 101, 108]], [[8482, 8482], "mapped", [116, 109]], [[8483, 8483], "valid", [], "NV8"], [[8484, 8484], "mapped", [122]], [[8485, 8485], "valid", [], "NV8"], [[8486, 8486], "mapped", [969]], [[8487, 8487], "valid", [], "NV8"], [[8488, 8488], "mapped", [122]], [[8489, 8489], "valid", [], "NV8"], [[8490, 8490], "mapped", [107]], [[8491, 8491], "mapped", [229]], [[8492, 8492], "mapped", [98]], [[8493, 8493], "mapped", [99]], [[8494, 8494], "valid", [], "NV8"], [[8495, 8496], "mapped", [101]], [[8497, 8497], "mapped", [102]], [[8498, 8498], "disallowed"], [[8499, 8499], "mapped", [109]], [[8500, 8500], "mapped", [111]], [[8501, 8501], "mapped", [1488]], [[8502, 8502], "mapped", [1489]], [[8503, 8503], "mapped", [1490]], [[8504, 8504], "mapped", [1491]], [[8505, 8505], "mapped", [105]], [[8506, 8506], "valid", [], "NV8"], [[8507, 8507], "mapped", [102, 97, 120]], [[8508, 8508], "mapped", [960]], [[8509, 8510], "mapped", [947]], [[8511, 8511], "mapped", [960]], [[8512, 8512], "mapped", [8721]], [[8513, 8516], "valid", [], "NV8"], [[8517, 8518], "mapped", [100]], [[8519, 8519], "mapped", [101]], [[8520, 8520], "mapped", [105]], [[8521, 8521], "mapped", [106]], [[8522, 8523], "valid", [], "NV8"], [[8524, 8524], "valid", [], "NV8"], [[8525, 8525], "valid", [], "NV8"], [[8526, 8526], "valid"], [[8527, 8527], "valid", [], "NV8"], [[8528, 8528], "mapped", [49, 8260, 55]], [[8529, 8529], "mapped", [49, 8260, 57]], [[8530, 8530], "mapped", [49, 8260, 49, 48]], [[8531, 8531], "mapped", [49, 8260, 51]], [[8532, 8532], "mapped", [50, 8260, 51]], [[8533, 8533], "mapped", [49, 8260, 53]], [[8534, 8534], "mapped", [50, 8260, 53]], [[8535, 8535], "mapped", [51, 8260, 53]], [[8536, 8536], "mapped", [52, 8260, 53]], [[8537, 8537], "mapped", [49, 8260, 54]], [[8538, 8538], "mapped", [53, 8260, 54]], [[8539, 8539], "mapped", [49, 8260, 56]], [[8540, 8540], "mapped", [51, 8260, 56]], [[8541, 8541], "mapped", [53, 8260, 56]], [[8542, 8542], "mapped", [55, 8260, 56]], [[8543, 8543], "mapped", [49, 8260]], [[8544, 8544], "mapped", [105]], [[8545, 8545], "mapped", [105, 105]], [[8546, 8546], "mapped", [105, 105, 105]], [[8547, 8547], "mapped", [105, 118]], [[8548, 8548], "mapped", [118]], [[8549, 8549], "mapped", [118, 105]], [[8550, 8550], "mapped", [118, 105, 105]], [[8551, 8551], "mapped", [118, 105, 105, 105]], [[8552, 8552], "mapped", [105, 120]], [[8553, 8553], "mapped", [120]], [[8554, 8554], "mapped", [120, 105]], [[8555, 8555], "mapped", [120, 105, 105]], [[8556, 8556], "mapped", [108]], [[8557, 8557], "mapped", [99]], [[8558, 8558], "mapped", [100]], [[8559, 8559], "mapped", [109]], [[8560, 8560], "mapped", [105]], [[8561, 8561], "mapped", [105, 105]], [[8562, 8562], "mapped", [105, 105, 105]], [[8563, 8563], "mapped", [105, 118]], [[8564, 8564], "mapped", [118]], [[8565, 8565], "mapped", [118, 105]], [[8566, 8566], "mapped", [118, 105, 105]], [[8567, 8567], "mapped", [118, 105, 105, 105]], [[8568, 8568], "mapped", [105, 120]], [[8569, 8569], "mapped", [120]], [[8570, 8570], "mapped", [120, 105]], [[8571, 8571], "mapped", [120, 105, 105]], [[8572, 8572], "mapped", [108]], [[8573, 8573], "mapped", [99]], [[8574, 8574], "mapped", [100]], [[8575, 8575], "mapped", [109]], [[8576, 8578], "valid", [], "NV8"], [[8579, 8579], "disallowed"], [[8580, 8580], "valid"], [[8581, 8584], "valid", [], "NV8"], [[8585, 8585], "mapped", [48, 8260, 51]], [[8586, 8587], "valid", [], "NV8"], [[8588, 8591], "disallowed"], [[8592, 8682], "valid", [], "NV8"], [[8683, 8691], "valid", [], "NV8"], [[8692, 8703], "valid", [], "NV8"], [[8704, 8747], "valid", [], "NV8"], [[8748, 8748], "mapped", [8747, 8747]], [[8749, 8749], "mapped", [8747, 8747, 8747]], [[8750, 8750], "valid", [], "NV8"], [[8751, 8751], "mapped", [8750, 8750]], [[8752, 8752], "mapped", [8750, 8750, 8750]], [[8753, 8799], "valid", [], "NV8"], [[8800, 8800], "disallowed_STD3_valid"], [[8801, 8813], "valid", [], "NV8"], [[8814, 8815], "disallowed_STD3_valid"], [[8816, 8945], "valid", [], "NV8"], [[8946, 8959], "valid", [], "NV8"], [[8960, 8960], "valid", [], "NV8"], [[8961, 8961], "valid", [], "NV8"], [[8962, 9e3], "valid", [], "NV8"], [[9001, 9001], "mapped", [12296]], [[9002, 9002], "mapped", [12297]], [[9003, 9082], "valid", [], "NV8"], [[9083, 9083], "valid", [], "NV8"], [[9084, 9084], "valid", [], "NV8"], [[9085, 9114], "valid", [], "NV8"], [[9115, 9166], "valid", [], "NV8"], [[9167, 9168], "valid", [], "NV8"], [[9169, 9179], "valid", [], "NV8"], [[9180, 9191], "valid", [], "NV8"], [[9192, 9192], "valid", [], "NV8"], [[9193, 9203], "valid", [], "NV8"], [[9204, 9210], "valid", [], "NV8"], [[9211, 9215], "disallowed"], [[9216, 9252], "valid", [], "NV8"], [[9253, 9254], "valid", [], "NV8"], [[9255, 9279], "disallowed"], [[9280, 9290], "valid", [], "NV8"], [[9291, 9311], "disallowed"], [[9312, 9312], "mapped", [49]], [[9313, 9313], "mapped", [50]], [[9314, 9314], "mapped", [51]], [[9315, 9315], "mapped", [52]], [[9316, 9316], "mapped", [53]], [[9317, 9317], "mapped", [54]], [[9318, 9318], "mapped", [55]], [[9319, 9319], "mapped", [56]], [[9320, 9320], "mapped", [57]], [[9321, 9321], "mapped", [49, 48]], [[9322, 9322], "mapped", [49, 49]], [[9323, 9323], "mapped", [49, 50]], [[9324, 9324], "mapped", [49, 51]], [[9325, 9325], "mapped", [49, 52]], [[9326, 9326], "mapped", [49, 53]], [[9327, 9327], "mapped", [49, 54]], [[9328, 9328], "mapped", [49, 55]], [[9329, 9329], "mapped", [49, 56]], [[9330, 9330], "mapped", [49, 57]], [[9331, 9331], "mapped", [50, 48]], [[9332, 9332], "disallowed_STD3_mapped", [40, 49, 41]], [[9333, 9333], "disallowed_STD3_mapped", [40, 50, 41]], [[9334, 9334], "disallowed_STD3_mapped", [40, 51, 41]], [[9335, 9335], "disallowed_STD3_mapped", [40, 52, 41]], [[9336, 9336], "disallowed_STD3_mapped", [40, 53, 41]], [[9337, 9337], "disallowed_STD3_mapped", [40, 54, 41]], [[9338, 9338], "disallowed_STD3_mapped", [40, 55, 41]], [[9339, 9339], "disallowed_STD3_mapped", [40, 56, 41]], [[9340, 9340], "disallowed_STD3_mapped", [40, 57, 41]], [[9341, 9341], "disallowed_STD3_mapped", [40, 49, 48, 41]], [[9342, 9342], "disallowed_STD3_mapped", [40, 49, 49, 41]], [[9343, 9343], "disallowed_STD3_mapped", [40, 49, 50, 41]], [[9344, 9344], "disallowed_STD3_mapped", [40, 49, 51, 41]], [[9345, 9345], "disallowed_STD3_mapped", [40, 49, 52, 41]], [[9346, 9346], "disallowed_STD3_mapped", [40, 49, 53, 41]], [[9347, 9347], "disallowed_STD3_mapped", [40, 49, 54, 41]], [[9348, 9348], "disallowed_STD3_mapped", [40, 49, 55, 41]], [[9349, 9349], "disallowed_STD3_mapped", [40, 49, 56, 41]], [[9350, 9350], "disallowed_STD3_mapped", [40, 49, 57, 41]], [[9351, 9351], "disallowed_STD3_mapped", [40, 50, 48, 41]], [[9352, 9371], "disallowed"], [[9372, 9372], "disallowed_STD3_mapped", [40, 97, 41]], [[9373, 9373], "disallowed_STD3_mapped", [40, 98, 41]], [[9374, 9374], "disallowed_STD3_mapped", [40, 99, 41]], [[9375, 9375], "disallowed_STD3_mapped", [40, 100, 41]], [[9376, 9376], "disallowed_STD3_mapped", [40, 101, 41]], [[9377, 9377], "disallowed_STD3_mapped", [40, 102, 41]], [[9378, 9378], "disallowed_STD3_mapped", [40, 103, 41]], [[9379, 9379], "disallowed_STD3_mapped", [40, 104, 41]], [[9380, 9380], "disallowed_STD3_mapped", [40, 105, 41]], [[9381, 9381], "disallowed_STD3_mapped", [40, 106, 41]], [[9382, 9382], "disallowed_STD3_mapped", [40, 107, 41]], [[9383, 9383], "disallowed_STD3_mapped", [40, 108, 41]], [[9384, 9384], "disallowed_STD3_mapped", [40, 109, 41]], [[9385, 9385], "disallowed_STD3_mapped", [40, 110, 41]], [[9386, 9386], "disallowed_STD3_mapped", [40, 111, 41]], [[9387, 9387], "disallowed_STD3_mapped", [40, 112, 41]], [[9388, 9388], "disallowed_STD3_mapped", [40, 113, 41]], [[9389, 9389], "disallowed_STD3_mapped", [40, 114, 41]], [[9390, 9390], "disallowed_STD3_mapped", [40, 115, 41]], [[9391, 9391], "disallowed_STD3_mapped", [40, 116, 41]], [[9392, 9392], "disallowed_STD3_mapped", [40, 117, 41]], [[9393, 9393], "disallowed_STD3_mapped", [40, 118, 41]], [[9394, 9394], "disallowed_STD3_mapped", [40, 119, 41]], [[9395, 9395], "disallowed_STD3_mapped", [40, 120, 41]], [[9396, 9396], "disallowed_STD3_mapped", [40, 121, 41]], [[9397, 9397], "disallowed_STD3_mapped", [40, 122, 41]], [[9398, 9398], "mapped", [97]], [[9399, 9399], "mapped", [98]], [[9400, 9400], "mapped", [99]], [[9401, 9401], "mapped", [100]], [[9402, 9402], "mapped", [101]], [[9403, 9403], "mapped", [102]], [[9404, 9404], "mapped", [103]], [[9405, 9405], "mapped", [104]], [[9406, 9406], "mapped", [105]], [[9407, 9407], "mapped", [106]], [[9408, 9408], "mapped", [107]], [[9409, 9409], "mapped", [108]], [[9410, 9410], "mapped", [109]], [[9411, 9411], "mapped", [110]], [[9412, 9412], "mapped", [111]], [[9413, 9413], "mapped", [112]], [[9414, 9414], "mapped", [113]], [[9415, 9415], "mapped", [114]], [[9416, 9416], "mapped", [115]], [[9417, 9417], "mapped", [116]], [[9418, 9418], "mapped", [117]], [[9419, 9419], "mapped", [118]], [[9420, 9420], "mapped", [119]], [[9421, 9421], "mapped", [120]], [[9422, 9422], "mapped", [121]], [[9423, 9423], "mapped", [122]], [[9424, 9424], "mapped", [97]], [[9425, 9425], "mapped", [98]], [[9426, 9426], "mapped", [99]], [[9427, 9427], "mapped", [100]], [[9428, 9428], "mapped", [101]], [[9429, 9429], "mapped", [102]], [[9430, 9430], "mapped", [103]], [[9431, 9431], "mapped", [104]], [[9432, 9432], "mapped", [105]], [[9433, 9433], "mapped", [106]], [[9434, 9434], "mapped", [107]], [[9435, 9435], "mapped", [108]], [[9436, 9436], "mapped", [109]], [[9437, 9437], "mapped", [110]], [[9438, 9438], "mapped", [111]], [[9439, 9439], "mapped", [112]], [[9440, 9440], "mapped", [113]], [[9441, 9441], "mapped", [114]], [[9442, 9442], "mapped", [115]], [[9443, 9443], "mapped", [116]], [[9444, 9444], "mapped", [117]], [[9445, 9445], "mapped", [118]], [[9446, 9446], "mapped", [119]], [[9447, 9447], "mapped", [120]], [[9448, 9448], "mapped", [121]], [[9449, 9449], "mapped", [122]], [[9450, 9450], "mapped", [48]], [[9451, 9470], "valid", [], "NV8"], [[9471, 9471], "valid", [], "NV8"], [[9472, 9621], "valid", [], "NV8"], [[9622, 9631], "valid", [], "NV8"], [[9632, 9711], "valid", [], "NV8"], [[9712, 9719], "valid", [], "NV8"], [[9720, 9727], "valid", [], "NV8"], [[9728, 9747], "valid", [], "NV8"], [[9748, 9749], "valid", [], "NV8"], [[9750, 9751], "valid", [], "NV8"], [[9752, 9752], "valid", [], "NV8"], [[9753, 9753], "valid", [], "NV8"], [[9754, 9839], "valid", [], "NV8"], [[9840, 9841], "valid", [], "NV8"], [[9842, 9853], "valid", [], "NV8"], [[9854, 9855], "valid", [], "NV8"], [[9856, 9865], "valid", [], "NV8"], [[9866, 9873], "valid", [], "NV8"], [[9874, 9884], "valid", [], "NV8"], [[9885, 9885], "valid", [], "NV8"], [[9886, 9887], "valid", [], "NV8"], [[9888, 9889], "valid", [], "NV8"], [[9890, 9905], "valid", [], "NV8"], [[9906, 9906], "valid", [], "NV8"], [[9907, 9916], "valid", [], "NV8"], [[9917, 9919], "valid", [], "NV8"], [[9920, 9923], "valid", [], "NV8"], [[9924, 9933], "valid", [], "NV8"], [[9934, 9934], "valid", [], "NV8"], [[9935, 9953], "valid", [], "NV8"], [[9954, 9954], "valid", [], "NV8"], [[9955, 9955], "valid", [], "NV8"], [[9956, 9959], "valid", [], "NV8"], [[9960, 9983], "valid", [], "NV8"], [[9984, 9984], "valid", [], "NV8"], [[9985, 9988], "valid", [], "NV8"], [[9989, 9989], "valid", [], "NV8"], [[9990, 9993], "valid", [], "NV8"], [[9994, 9995], "valid", [], "NV8"], [[9996, 10023], "valid", [], "NV8"], [[10024, 10024], "valid", [], "NV8"], [[10025, 10059], "valid", [], "NV8"], [[10060, 10060], "valid", [], "NV8"], [[10061, 10061], "valid", [], "NV8"], [[10062, 10062], "valid", [], "NV8"], [[10063, 10066], "valid", [], "NV8"], [[10067, 10069], "valid", [], "NV8"], [[10070, 10070], "valid", [], "NV8"], [[10071, 10071], "valid", [], "NV8"], [[10072, 10078], "valid", [], "NV8"], [[10079, 10080], "valid", [], "NV8"], [[10081, 10087], "valid", [], "NV8"], [[10088, 10101], "valid", [], "NV8"], [[10102, 10132], "valid", [], "NV8"], [[10133, 10135], "valid", [], "NV8"], [[10136, 10159], "valid", [], "NV8"], [[10160, 10160], "valid", [], "NV8"], [[10161, 10174], "valid", [], "NV8"], [[10175, 10175], "valid", [], "NV8"], [[10176, 10182], "valid", [], "NV8"], [[10183, 10186], "valid", [], "NV8"], [[10187, 10187], "valid", [], "NV8"], [[10188, 10188], "valid", [], "NV8"], [[10189, 10189], "valid", [], "NV8"], [[10190, 10191], "valid", [], "NV8"], [[10192, 10219], "valid", [], "NV8"], [[10220, 10223], "valid", [], "NV8"], [[10224, 10239], "valid", [], "NV8"], [[10240, 10495], "valid", [], "NV8"], [[10496, 10763], "valid", [], "NV8"], [[10764, 10764], "mapped", [8747, 8747, 8747, 8747]], [[10765, 10867], "valid", [], "NV8"], [[10868, 10868], "disallowed_STD3_mapped", [58, 58, 61]], [[10869, 10869], "disallowed_STD3_mapped", [61, 61]], [[10870, 10870], "disallowed_STD3_mapped", [61, 61, 61]], [[10871, 10971], "valid", [], "NV8"], [[10972, 10972], "mapped", [10973, 824]], [[10973, 11007], "valid", [], "NV8"], [[11008, 11021], "valid", [], "NV8"], [[11022, 11027], "valid", [], "NV8"], [[11028, 11034], "valid", [], "NV8"], [[11035, 11039], "valid", [], "NV8"], [[11040, 11043], "valid", [], "NV8"], [[11044, 11084], "valid", [], "NV8"], [[11085, 11087], "valid", [], "NV8"], [[11088, 11092], "valid", [], "NV8"], [[11093, 11097], "valid", [], "NV8"], [[11098, 11123], "valid", [], "NV8"], [[11124, 11125], "disallowed"], [[11126, 11157], "valid", [], "NV8"], [[11158, 11159], "disallowed"], [[11160, 11193], "valid", [], "NV8"], [[11194, 11196], "disallowed"], [[11197, 11208], "valid", [], "NV8"], [[11209, 11209], "disallowed"], [[11210, 11217], "valid", [], "NV8"], [[11218, 11243], "disallowed"], [[11244, 11247], "valid", [], "NV8"], [[11248, 11263], "disallowed"], [[11264, 11264], "mapped", [11312]], [[11265, 11265], "mapped", [11313]], [[11266, 11266], "mapped", [11314]], [[11267, 11267], "mapped", [11315]], [[11268, 11268], "mapped", [11316]], [[11269, 11269], "mapped", [11317]], [[11270, 11270], "mapped", [11318]], [[11271, 11271], "mapped", [11319]], [[11272, 11272], "mapped", [11320]], [[11273, 11273], "mapped", [11321]], [[11274, 11274], "mapped", [11322]], [[11275, 11275], "mapped", [11323]], [[11276, 11276], "mapped", [11324]], [[11277, 11277], "mapped", [11325]], [[11278, 11278], "mapped", [11326]], [[11279, 11279], "mapped", [11327]], [[11280, 11280], "mapped", [11328]], [[11281, 11281], "mapped", [11329]], [[11282, 11282], "mapped", [11330]], [[11283, 11283], "mapped", [11331]], [[11284, 11284], "mapped", [11332]], [[11285, 11285], "mapped", [11333]], [[11286, 11286], "mapped", [11334]], [[11287, 11287], "mapped", [11335]], [[11288, 11288], "mapped", [11336]], [[11289, 11289], "mapped", [11337]], [[11290, 11290], "mapped", [11338]], [[11291, 11291], "mapped", [11339]], [[11292, 11292], "mapped", [11340]], [[11293, 11293], "mapped", [11341]], [[11294, 11294], "mapped", [11342]], [[11295, 11295], "mapped", [11343]], [[11296, 11296], "mapped", [11344]], [[11297, 11297], "mapped", [11345]], [[11298, 11298], "mapped", [11346]], [[11299, 11299], "mapped", [11347]], [[11300, 11300], "mapped", [11348]], [[11301, 11301], "mapped", [11349]], [[11302, 11302], "mapped", [11350]], [[11303, 11303], "mapped", [11351]], [[11304, 11304], "mapped", [11352]], [[11305, 11305], "mapped", [11353]], [[11306, 11306], "mapped", [11354]], [[11307, 11307], "mapped", [11355]], [[11308, 11308], "mapped", [11356]], [[11309, 11309], "mapped", [11357]], [[11310, 11310], "mapped", [11358]], [[11311, 11311], "disallowed"], [[11312, 11358], "valid"], [[11359, 11359], "disallowed"], [[11360, 11360], "mapped", [11361]], [[11361, 11361], "valid"], [[11362, 11362], "mapped", [619]], [[11363, 11363], "mapped", [7549]], [[11364, 11364], "mapped", [637]], [[11365, 11366], "valid"], [[11367, 11367], "mapped", [11368]], [[11368, 11368], "valid"], [[11369, 11369], "mapped", [11370]], [[11370, 11370], "valid"], [[11371, 11371], "mapped", [11372]], [[11372, 11372], "valid"], [[11373, 11373], "mapped", [593]], [[11374, 11374], "mapped", [625]], [[11375, 11375], "mapped", [592]], [[11376, 11376], "mapped", [594]], [[11377, 11377], "valid"], [[11378, 11378], "mapped", [11379]], [[11379, 11379], "valid"], [[11380, 11380], "valid"], [[11381, 11381], "mapped", [11382]], [[11382, 11383], "valid"], [[11384, 11387], "valid"], [[11388, 11388], "mapped", [106]], [[11389, 11389], "mapped", [118]], [[11390, 11390], "mapped", [575]], [[11391, 11391], "mapped", [576]], [[11392, 11392], "mapped", [11393]], [[11393, 11393], "valid"], [[11394, 11394], "mapped", [11395]], [[11395, 11395], "valid"], [[11396, 11396], "mapped", [11397]], [[11397, 11397], "valid"], [[11398, 11398], "mapped", [11399]], [[11399, 11399], "valid"], [[11400, 11400], "mapped", [11401]], [[11401, 11401], "valid"], [[11402, 11402], "mapped", [11403]], [[11403, 11403], "valid"], [[11404, 11404], "mapped", [11405]], [[11405, 11405], "valid"], [[11406, 11406], "mapped", [11407]], [[11407, 11407], "valid"], [[11408, 11408], "mapped", [11409]], [[11409, 11409], "valid"], [[11410, 11410], "mapped", [11411]], [[11411, 11411], "valid"], [[11412, 11412], "mapped", [11413]], [[11413, 11413], "valid"], [[11414, 11414], "mapped", [11415]], [[11415, 11415], "valid"], [[11416, 11416], "mapped", [11417]], [[11417, 11417], "valid"], [[11418, 11418], "mapped", [11419]], [[11419, 11419], "valid"], [[11420, 11420], "mapped", [11421]], [[11421, 11421], "valid"], [[11422, 11422], "mapped", [11423]], [[11423, 11423], "valid"], [[11424, 11424], "mapped", [11425]], [[11425, 11425], "valid"], [[11426, 11426], "mapped", [11427]], [[11427, 11427], "valid"], [[11428, 11428], "mapped", [11429]], [[11429, 11429], "valid"], [[11430, 11430], "mapped", [11431]], [[11431, 11431], "valid"], [[11432, 11432], "mapped", [11433]], [[11433, 11433], "valid"], [[11434, 11434], "mapped", [11435]], [[11435, 11435], "valid"], [[11436, 11436], "mapped", [11437]], [[11437, 11437], "valid"], [[11438, 11438], "mapped", [11439]], [[11439, 11439], "valid"], [[11440, 11440], "mapped", [11441]], [[11441, 11441], "valid"], [[11442, 11442], "mapped", [11443]], [[11443, 11443], "valid"], [[11444, 11444], "mapped", [11445]], [[11445, 11445], "valid"], [[11446, 11446], "mapped", [11447]], [[11447, 11447], "valid"], [[11448, 11448], "mapped", [11449]], [[11449, 11449], "valid"], [[11450, 11450], "mapped", [11451]], [[11451, 11451], "valid"], [[11452, 11452], "mapped", [11453]], [[11453, 11453], "valid"], [[11454, 11454], "mapped", [11455]], [[11455, 11455], "valid"], [[11456, 11456], "mapped", [11457]], [[11457, 11457], "valid"], [[11458, 11458], "mapped", [11459]], [[11459, 11459], "valid"], [[11460, 11460], "mapped", [11461]], [[11461, 11461], "valid"], [[11462, 11462], "mapped", [11463]], [[11463, 11463], "valid"], [[11464, 11464], "mapped", [11465]], [[11465, 11465], "valid"], [[11466, 11466], "mapped", [11467]], [[11467, 11467], "valid"], [[11468, 11468], "mapped", [11469]], [[11469, 11469], "valid"], [[11470, 11470], "mapped", [11471]], [[11471, 11471], "valid"], [[11472, 11472], "mapped", [11473]], [[11473, 11473], "valid"], [[11474, 11474], "mapped", [11475]], [[11475, 11475], "valid"], [[11476, 11476], "mapped", [11477]], [[11477, 11477], "valid"], [[11478, 11478], "mapped", [11479]], [[11479, 11479], "valid"], [[11480, 11480], "mapped", [11481]], [[11481, 11481], "valid"], [[11482, 11482], "mapped", [11483]], [[11483, 11483], "valid"], [[11484, 11484], "mapped", [11485]], [[11485, 11485], "valid"], [[11486, 11486], "mapped", [11487]], [[11487, 11487], "valid"], [[11488, 11488], "mapped", [11489]], [[11489, 11489], "valid"], [[11490, 11490], "mapped", [11491]], [[11491, 11492], "valid"], [[11493, 11498], "valid", [], "NV8"], [[11499, 11499], "mapped", [11500]], [[11500, 11500], "valid"], [[11501, 11501], "mapped", [11502]], [[11502, 11505], "valid"], [[11506, 11506], "mapped", [11507]], [[11507, 11507], "valid"], [[11508, 11512], "disallowed"], [[11513, 11519], "valid", [], "NV8"], [[11520, 11557], "valid"], [[11558, 11558], "disallowed"], [[11559, 11559], "valid"], [[11560, 11564], "disallowed"], [[11565, 11565], "valid"], [[11566, 11567], "disallowed"], [[11568, 11621], "valid"], [[11622, 11623], "valid"], [[11624, 11630], "disallowed"], [[11631, 11631], "mapped", [11617]], [[11632, 11632], "valid", [], "NV8"], [[11633, 11646], "disallowed"], [[11647, 11647], "valid"], [[11648, 11670], "valid"], [[11671, 11679], "disallowed"], [[11680, 11686], "valid"], [[11687, 11687], "disallowed"], [[11688, 11694], "valid"], [[11695, 11695], "disallowed"], [[11696, 11702], "valid"], [[11703, 11703], "disallowed"], [[11704, 11710], "valid"], [[11711, 11711], "disallowed"], [[11712, 11718], "valid"], [[11719, 11719], "disallowed"], [[11720, 11726], "valid"], [[11727, 11727], "disallowed"], [[11728, 11734], "valid"], [[11735, 11735], "disallowed"], [[11736, 11742], "valid"], [[11743, 11743], "disallowed"], [[11744, 11775], "valid"], [[11776, 11799], "valid", [], "NV8"], [[11800, 11803], "valid", [], "NV8"], [[11804, 11805], "valid", [], "NV8"], [[11806, 11822], "valid", [], "NV8"], [[11823, 11823], "valid"], [[11824, 11824], "valid", [], "NV8"], [[11825, 11825], "valid", [], "NV8"], [[11826, 11835], "valid", [], "NV8"], [[11836, 11842], "valid", [], "NV8"], [[11843, 11903], "disallowed"], [[11904, 11929], "valid", [], "NV8"], [[11930, 11930], "disallowed"], [[11931, 11934], "valid", [], "NV8"], [[11935, 11935], "mapped", [27597]], [[11936, 12018], "valid", [], "NV8"], [[12019, 12019], "mapped", [40863]], [[12020, 12031], "disallowed"], [[12032, 12032], "mapped", [19968]], [[12033, 12033], "mapped", [20008]], [[12034, 12034], "mapped", [20022]], [[12035, 12035], "mapped", [20031]], [[12036, 12036], "mapped", [20057]], [[12037, 12037], "mapped", [20101]], [[12038, 12038], "mapped", [20108]], [[12039, 12039], "mapped", [20128]], [[12040, 12040], "mapped", [20154]], [[12041, 12041], "mapped", [20799]], [[12042, 12042], "mapped", [20837]], [[12043, 12043], "mapped", [20843]], [[12044, 12044], "mapped", [20866]], [[12045, 12045], "mapped", [20886]], [[12046, 12046], "mapped", [20907]], [[12047, 12047], "mapped", [20960]], [[12048, 12048], "mapped", [20981]], [[12049, 12049], "mapped", [20992]], [[12050, 12050], "mapped", [21147]], [[12051, 12051], "mapped", [21241]], [[12052, 12052], "mapped", [21269]], [[12053, 12053], "mapped", [21274]], [[12054, 12054], "mapped", [21304]], [[12055, 12055], "mapped", [21313]], [[12056, 12056], "mapped", [21340]], [[12057, 12057], "mapped", [21353]], [[12058, 12058], "mapped", [21378]], [[12059, 12059], "mapped", [21430]], [[12060, 12060], "mapped", [21448]], [[12061, 12061], "mapped", [21475]], [[12062, 12062], "mapped", [22231]], [[12063, 12063], "mapped", [22303]], [[12064, 12064], "mapped", [22763]], [[12065, 12065], "mapped", [22786]], [[12066, 12066], "mapped", [22794]], [[12067, 12067], "mapped", [22805]], [[12068, 12068], "mapped", [22823]], [[12069, 12069], "mapped", [22899]], [[12070, 12070], "mapped", [23376]], [[12071, 12071], "mapped", [23424]], [[12072, 12072], "mapped", [23544]], [[12073, 12073], "mapped", [23567]], [[12074, 12074], "mapped", [23586]], [[12075, 12075], "mapped", [23608]], [[12076, 12076], "mapped", [23662]], [[12077, 12077], "mapped", [23665]], [[12078, 12078], "mapped", [24027]], [[12079, 12079], "mapped", [24037]], [[12080, 12080], "mapped", [24049]], [[12081, 12081], "mapped", [24062]], [[12082, 12082], "mapped", [24178]], [[12083, 12083], "mapped", [24186]], [[12084, 12084], "mapped", [24191]], [[12085, 12085], "mapped", [24308]], [[12086, 12086], "mapped", [24318]], [[12087, 12087], "mapped", [24331]], [[12088, 12088], "mapped", [24339]], [[12089, 12089], "mapped", [24400]], [[12090, 12090], "mapped", [24417]], [[12091, 12091], "mapped", [24435]], [[12092, 12092], "mapped", [24515]], [[12093, 12093], "mapped", [25096]], [[12094, 12094], "mapped", [25142]], [[12095, 12095], "mapped", [25163]], [[12096, 12096], "mapped", [25903]], [[12097, 12097], "mapped", [25908]], [[12098, 12098], "mapped", [25991]], [[12099, 12099], "mapped", [26007]], [[12100, 12100], "mapped", [26020]], [[12101, 12101], "mapped", [26041]], [[12102, 12102], "mapped", [26080]], [[12103, 12103], "mapped", [26085]], [[12104, 12104], "mapped", [26352]], [[12105, 12105], "mapped", [26376]], [[12106, 12106], "mapped", [26408]], [[12107, 12107], "mapped", [27424]], [[12108, 12108], "mapped", [27490]], [[12109, 12109], "mapped", [27513]], [[12110, 12110], "mapped", [27571]], [[12111, 12111], "mapped", [27595]], [[12112, 12112], "mapped", [27604]], [[12113, 12113], "mapped", [27611]], [[12114, 12114], "mapped", [27663]], [[12115, 12115], "mapped", [27668]], [[12116, 12116], "mapped", [27700]], [[12117, 12117], "mapped", [28779]], [[12118, 12118], "mapped", [29226]], [[12119, 12119], "mapped", [29238]], [[12120, 12120], "mapped", [29243]], [[12121, 12121], "mapped", [29247]], [[12122, 12122], "mapped", [29255]], [[12123, 12123], "mapped", [29273]], [[12124, 12124], "mapped", [29275]], [[12125, 12125], "mapped", [29356]], [[12126, 12126], "mapped", [29572]], [[12127, 12127], "mapped", [29577]], [[12128, 12128], "mapped", [29916]], [[12129, 12129], "mapped", [29926]], [[12130, 12130], "mapped", [29976]], [[12131, 12131], "mapped", [29983]], [[12132, 12132], "mapped", [29992]], [[12133, 12133], "mapped", [3e4]], [[12134, 12134], "mapped", [30091]], [[12135, 12135], "mapped", [30098]], [[12136, 12136], "mapped", [30326]], [[12137, 12137], "mapped", [30333]], [[12138, 12138], "mapped", [30382]], [[12139, 12139], "mapped", [30399]], [[12140, 12140], "mapped", [30446]], [[12141, 12141], "mapped", [30683]], [[12142, 12142], "mapped", [30690]], [[12143, 12143], "mapped", [30707]], [[12144, 12144], "mapped", [31034]], [[12145, 12145], "mapped", [31160]], [[12146, 12146], "mapped", [31166]], [[12147, 12147], "mapped", [31348]], [[12148, 12148], "mapped", [31435]], [[12149, 12149], "mapped", [31481]], [[12150, 12150], "mapped", [31859]], [[12151, 12151], "mapped", [31992]], [[12152, 12152], "mapped", [32566]], [[12153, 12153], "mapped", [32593]], [[12154, 12154], "mapped", [32650]], [[12155, 12155], "mapped", [32701]], [[12156, 12156], "mapped", [32769]], [[12157, 12157], "mapped", [32780]], [[12158, 12158], "mapped", [32786]], [[12159, 12159], "mapped", [32819]], [[12160, 12160], "mapped", [32895]], [[12161, 12161], "mapped", [32905]], [[12162, 12162], "mapped", [33251]], [[12163, 12163], "mapped", [33258]], [[12164, 12164], "mapped", [33267]], [[12165, 12165], "mapped", [33276]], [[12166, 12166], "mapped", [33292]], [[12167, 12167], "mapped", [33307]], [[12168, 12168], "mapped", [33311]], [[12169, 12169], "mapped", [33390]], [[12170, 12170], "mapped", [33394]], [[12171, 12171], "mapped", [33400]], [[12172, 12172], "mapped", [34381]], [[12173, 12173], "mapped", [34411]], [[12174, 12174], "mapped", [34880]], [[12175, 12175], "mapped", [34892]], [[12176, 12176], "mapped", [34915]], [[12177, 12177], "mapped", [35198]], [[12178, 12178], "mapped", [35211]], [[12179, 12179], "mapped", [35282]], [[12180, 12180], "mapped", [35328]], [[12181, 12181], "mapped", [35895]], [[12182, 12182], "mapped", [35910]], [[12183, 12183], "mapped", [35925]], [[12184, 12184], "mapped", [35960]], [[12185, 12185], "mapped", [35997]], [[12186, 12186], "mapped", [36196]], [[12187, 12187], "mapped", [36208]], [[12188, 12188], "mapped", [36275]], [[12189, 12189], "mapped", [36523]], [[12190, 12190], "mapped", [36554]], [[12191, 12191], "mapped", [36763]], [[12192, 12192], "mapped", [36784]], [[12193, 12193], "mapped", [36789]], [[12194, 12194], "mapped", [37009]], [[12195, 12195], "mapped", [37193]], [[12196, 12196], "mapped", [37318]], [[12197, 12197], "mapped", [37324]], [[12198, 12198], "mapped", [37329]], [[12199, 12199], "mapped", [38263]], [[12200, 12200], "mapped", [38272]], [[12201, 12201], "mapped", [38428]], [[12202, 12202], "mapped", [38582]], [[12203, 12203], "mapped", [38585]], [[12204, 12204], "mapped", [38632]], [[12205, 12205], "mapped", [38737]], [[12206, 12206], "mapped", [38750]], [[12207, 12207], "mapped", [38754]], [[12208, 12208], "mapped", [38761]], [[12209, 12209], "mapped", [38859]], [[12210, 12210], "mapped", [38893]], [[12211, 12211], "mapped", [38899]], [[12212, 12212], "mapped", [38913]], [[12213, 12213], "mapped", [39080]], [[12214, 12214], "mapped", [39131]], [[12215, 12215], "mapped", [39135]], [[12216, 12216], "mapped", [39318]], [[12217, 12217], "mapped", [39321]], [[12218, 12218], "mapped", [39340]], [[12219, 12219], "mapped", [39592]], [[12220, 12220], "mapped", [39640]], [[12221, 12221], "mapped", [39647]], [[12222, 12222], "mapped", [39717]], [[12223, 12223], "mapped", [39727]], [[12224, 12224], "mapped", [39730]], [[12225, 12225], "mapped", [39740]], [[12226, 12226], "mapped", [39770]], [[12227, 12227], "mapped", [40165]], [[12228, 12228], "mapped", [40565]], [[12229, 12229], "mapped", [40575]], [[12230, 12230], "mapped", [40613]], [[12231, 12231], "mapped", [40635]], [[12232, 12232], "mapped", [40643]], [[12233, 12233], "mapped", [40653]], [[12234, 12234], "mapped", [40657]], [[12235, 12235], "mapped", [40697]], [[12236, 12236], "mapped", [40701]], [[12237, 12237], "mapped", [40718]], [[12238, 12238], "mapped", [40723]], [[12239, 12239], "mapped", [40736]], [[12240, 12240], "mapped", [40763]], [[12241, 12241], "mapped", [40778]], [[12242, 12242], "mapped", [40786]], [[12243, 12243], "mapped", [40845]], [[12244, 12244], "mapped", [40860]], [[12245, 12245], "mapped", [40864]], [[12246, 12271], "disallowed"], [[12272, 12283], "disallowed"], [[12284, 12287], "disallowed"], [[12288, 12288], "disallowed_STD3_mapped", [32]], [[12289, 12289], "valid", [], "NV8"], [[12290, 12290], "mapped", [46]], [[12291, 12292], "valid", [], "NV8"], [[12293, 12295], "valid"], [[12296, 12329], "valid", [], "NV8"], [[12330, 12333], "valid"], [[12334, 12341], "valid", [], "NV8"], [[12342, 12342], "mapped", [12306]], [[12343, 12343], "valid", [], "NV8"], [[12344, 12344], "mapped", [21313]], [[12345, 12345], "mapped", [21316]], [[12346, 12346], "mapped", [21317]], [[12347, 12347], "valid", [], "NV8"], [[12348, 12348], "valid"], [[12349, 12349], "valid", [], "NV8"], [[12350, 12350], "valid", [], "NV8"], [[12351, 12351], "valid", [], "NV8"], [[12352, 12352], "disallowed"], [[12353, 12436], "valid"], [[12437, 12438], "valid"], [[12439, 12440], "disallowed"], [[12441, 12442], "valid"], [[12443, 12443], "disallowed_STD3_mapped", [32, 12441]], [[12444, 12444], "disallowed_STD3_mapped", [32, 12442]], [[12445, 12446], "valid"], [[12447, 12447], "mapped", [12424, 12426]], [[12448, 12448], "valid", [], "NV8"], [[12449, 12542], "valid"], [[12543, 12543], "mapped", [12467, 12488]], [[12544, 12548], "disallowed"], [[12549, 12588], "valid"], [[12589, 12589], "valid"], [[12590, 12592], "disallowed"], [[12593, 12593], "mapped", [4352]], [[12594, 12594], "mapped", [4353]], [[12595, 12595], "mapped", [4522]], [[12596, 12596], "mapped", [4354]], [[12597, 12597], "mapped", [4524]], [[12598, 12598], "mapped", [4525]], [[12599, 12599], "mapped", [4355]], [[12600, 12600], "mapped", [4356]], [[12601, 12601], "mapped", [4357]], [[12602, 12602], "mapped", [4528]], [[12603, 12603], "mapped", [4529]], [[12604, 12604], "mapped", [4530]], [[12605, 12605], "mapped", [4531]], [[12606, 12606], "mapped", [4532]], [[12607, 12607], "mapped", [4533]], [[12608, 12608], "mapped", [4378]], [[12609, 12609], "mapped", [4358]], [[12610, 12610], "mapped", [4359]], [[12611, 12611], "mapped", [4360]], [[12612, 12612], "mapped", [4385]], [[12613, 12613], "mapped", [4361]], [[12614, 12614], "mapped", [4362]], [[12615, 12615], "mapped", [4363]], [[12616, 12616], "mapped", [4364]], [[12617, 12617], "mapped", [4365]], [[12618, 12618], "mapped", [4366]], [[12619, 12619], "mapped", [4367]], [[12620, 12620], "mapped", [4368]], [[12621, 12621], "mapped", [4369]], [[12622, 12622], "mapped", [4370]], [[12623, 12623], "mapped", [4449]], [[12624, 12624], "mapped", [4450]], [[12625, 12625], "mapped", [4451]], [[12626, 12626], "mapped", [4452]], [[12627, 12627], "mapped", [4453]], [[12628, 12628], "mapped", [4454]], [[12629, 12629], "mapped", [4455]], [[12630, 12630], "mapped", [4456]], [[12631, 12631], "mapped", [4457]], [[12632, 12632], "mapped", [4458]], [[12633, 12633], "mapped", [4459]], [[12634, 12634], "mapped", [4460]], [[12635, 12635], "mapped", [4461]], [[12636, 12636], "mapped", [4462]], [[12637, 12637], "mapped", [4463]], [[12638, 12638], "mapped", [4464]], [[12639, 12639], "mapped", [4465]], [[12640, 12640], "mapped", [4466]], [[12641, 12641], "mapped", [4467]], [[12642, 12642], "mapped", [4468]], [[12643, 12643], "mapped", [4469]], [[12644, 12644], "disallowed"], [[12645, 12645], "mapped", [4372]], [[12646, 12646], "mapped", [4373]], [[12647, 12647], "mapped", [4551]], [[12648, 12648], "mapped", [4552]], [[12649, 12649], "mapped", [4556]], [[12650, 12650], "mapped", [4558]], [[12651, 12651], "mapped", [4563]], [[12652, 12652], "mapped", [4567]], [[12653, 12653], "mapped", [4569]], [[12654, 12654], "mapped", [4380]], [[12655, 12655], "mapped", [4573]], [[12656, 12656], "mapped", [4575]], [[12657, 12657], "mapped", [4381]], [[12658, 12658], "mapped", [4382]], [[12659, 12659], "mapped", [4384]], [[12660, 12660], "mapped", [4386]], [[12661, 12661], "mapped", [4387]], [[12662, 12662], "mapped", [4391]], [[12663, 12663], "mapped", [4393]], [[12664, 12664], "mapped", [4395]], [[12665, 12665], "mapped", [4396]], [[12666, 12666], "mapped", [4397]], [[12667, 12667], "mapped", [4398]], [[12668, 12668], "mapped", [4399]], [[12669, 12669], "mapped", [4402]], [[12670, 12670], "mapped", [4406]], [[12671, 12671], "mapped", [4416]], [[12672, 12672], "mapped", [4423]], [[12673, 12673], "mapped", [4428]], [[12674, 12674], "mapped", [4593]], [[12675, 12675], "mapped", [4594]], [[12676, 12676], "mapped", [4439]], [[12677, 12677], "mapped", [4440]], [[12678, 12678], "mapped", [4441]], [[12679, 12679], "mapped", [4484]], [[12680, 12680], "mapped", [4485]], [[12681, 12681], "mapped", [4488]], [[12682, 12682], "mapped", [4497]], [[12683, 12683], "mapped", [4498]], [[12684, 12684], "mapped", [4500]], [[12685, 12685], "mapped", [4510]], [[12686, 12686], "mapped", [4513]], [[12687, 12687], "disallowed"], [[12688, 12689], "valid", [], "NV8"], [[12690, 12690], "mapped", [19968]], [[12691, 12691], "mapped", [20108]], [[12692, 12692], "mapped", [19977]], [[12693, 12693], "mapped", [22235]], [[12694, 12694], "mapped", [19978]], [[12695, 12695], "mapped", [20013]], [[12696, 12696], "mapped", [19979]], [[12697, 12697], "mapped", [30002]], [[12698, 12698], "mapped", [20057]], [[12699, 12699], "mapped", [19993]], [[12700, 12700], "mapped", [19969]], [[12701, 12701], "mapped", [22825]], [[12702, 12702], "mapped", [22320]], [[12703, 12703], "mapped", [20154]], [[12704, 12727], "valid"], [[12728, 12730], "valid"], [[12731, 12735], "disallowed"], [[12736, 12751], "valid", [], "NV8"], [[12752, 12771], "valid", [], "NV8"], [[12772, 12783], "disallowed"], [[12784, 12799], "valid"], [[12800, 12800], "disallowed_STD3_mapped", [40, 4352, 41]], [[12801, 12801], "disallowed_STD3_mapped", [40, 4354, 41]], [[12802, 12802], "disallowed_STD3_mapped", [40, 4355, 41]], [[12803, 12803], "disallowed_STD3_mapped", [40, 4357, 41]], [[12804, 12804], "disallowed_STD3_mapped", [40, 4358, 41]], [[12805, 12805], "disallowed_STD3_mapped", [40, 4359, 41]], [[12806, 12806], "disallowed_STD3_mapped", [40, 4361, 41]], [[12807, 12807], "disallowed_STD3_mapped", [40, 4363, 41]], [[12808, 12808], "disallowed_STD3_mapped", [40, 4364, 41]], [[12809, 12809], "disallowed_STD3_mapped", [40, 4366, 41]], [[12810, 12810], "disallowed_STD3_mapped", [40, 4367, 41]], [[12811, 12811], "disallowed_STD3_mapped", [40, 4368, 41]], [[12812, 12812], "disallowed_STD3_mapped", [40, 4369, 41]], [[12813, 12813], "disallowed_STD3_mapped", [40, 4370, 41]], [[12814, 12814], "disallowed_STD3_mapped", [40, 44032, 41]], [[12815, 12815], "disallowed_STD3_mapped", [40, 45208, 41]], [[12816, 12816], "disallowed_STD3_mapped", [40, 45796, 41]], [[12817, 12817], "disallowed_STD3_mapped", [40, 46972, 41]], [[12818, 12818], "disallowed_STD3_mapped", [40, 47560, 41]], [[12819, 12819], "disallowed_STD3_mapped", [40, 48148, 41]], [[12820, 12820], "disallowed_STD3_mapped", [40, 49324, 41]], [[12821, 12821], "disallowed_STD3_mapped", [40, 50500, 41]], [[12822, 12822], "disallowed_STD3_mapped", [40, 51088, 41]], [[12823, 12823], "disallowed_STD3_mapped", [40, 52264, 41]], [[12824, 12824], "disallowed_STD3_mapped", [40, 52852, 41]], [[12825, 12825], "disallowed_STD3_mapped", [40, 53440, 41]], [[12826, 12826], "disallowed_STD3_mapped", [40, 54028, 41]], [[12827, 12827], "disallowed_STD3_mapped", [40, 54616, 41]], [[12828, 12828], "disallowed_STD3_mapped", [40, 51452, 41]], [[12829, 12829], "disallowed_STD3_mapped", [40, 50724, 51204, 41]], [[12830, 12830], "disallowed_STD3_mapped", [40, 50724, 54980, 41]], [[12831, 12831], "disallowed"], [[12832, 12832], "disallowed_STD3_mapped", [40, 19968, 41]], [[12833, 12833], "disallowed_STD3_mapped", [40, 20108, 41]], [[12834, 12834], "disallowed_STD3_mapped", [40, 19977, 41]], [[12835, 12835], "disallowed_STD3_mapped", [40, 22235, 41]], [[12836, 12836], "disallowed_STD3_mapped", [40, 20116, 41]], [[12837, 12837], "disallowed_STD3_mapped", [40, 20845, 41]], [[12838, 12838], "disallowed_STD3_mapped", [40, 19971, 41]], [[12839, 12839], "disallowed_STD3_mapped", [40, 20843, 41]], [[12840, 12840], "disallowed_STD3_mapped", [40, 20061, 41]], [[12841, 12841], "disallowed_STD3_mapped", [40, 21313, 41]], [[12842, 12842], "disallowed_STD3_mapped", [40, 26376, 41]], [[12843, 12843], "disallowed_STD3_mapped", [40, 28779, 41]], [[12844, 12844], "disallowed_STD3_mapped", [40, 27700, 41]], [[12845, 12845], "disallowed_STD3_mapped", [40, 26408, 41]], [[12846, 12846], "disallowed_STD3_mapped", [40, 37329, 41]], [[12847, 12847], "disallowed_STD3_mapped", [40, 22303, 41]], [[12848, 12848], "disallowed_STD3_mapped", [40, 26085, 41]], [[12849, 12849], "disallowed_STD3_mapped", [40, 26666, 41]], [[12850, 12850], "disallowed_STD3_mapped", [40, 26377, 41]], [[12851, 12851], "disallowed_STD3_mapped", [40, 31038, 41]], [[12852, 12852], "disallowed_STD3_mapped", [40, 21517, 41]], [[12853, 12853], "disallowed_STD3_mapped", [40, 29305, 41]], [[12854, 12854], "disallowed_STD3_mapped", [40, 36001, 41]], [[12855, 12855], "disallowed_STD3_mapped", [40, 31069, 41]], [[12856, 12856], "disallowed_STD3_mapped", [40, 21172, 41]], [[12857, 12857], "disallowed_STD3_mapped", [40, 20195, 41]], [[12858, 12858], "disallowed_STD3_mapped", [40, 21628, 41]], [[12859, 12859], "disallowed_STD3_mapped", [40, 23398, 41]], [[12860, 12860], "disallowed_STD3_mapped", [40, 30435, 41]], [[12861, 12861], "disallowed_STD3_mapped", [40, 20225, 41]], [[12862, 12862], "disallowed_STD3_mapped", [40, 36039, 41]], [[12863, 12863], "disallowed_STD3_mapped", [40, 21332, 41]], [[12864, 12864], "disallowed_STD3_mapped", [40, 31085, 41]], [[12865, 12865], "disallowed_STD3_mapped", [40, 20241, 41]], [[12866, 12866], "disallowed_STD3_mapped", [40, 33258, 41]], [[12867, 12867], "disallowed_STD3_mapped", [40, 33267, 41]], [[12868, 12868], "mapped", [21839]], [[12869, 12869], "mapped", [24188]], [[12870, 12870], "mapped", [25991]], [[12871, 12871], "mapped", [31631]], [[12872, 12879], "valid", [], "NV8"], [[12880, 12880], "mapped", [112, 116, 101]], [[12881, 12881], "mapped", [50, 49]], [[12882, 12882], "mapped", [50, 50]], [[12883, 12883], "mapped", [50, 51]], [[12884, 12884], "mapped", [50, 52]], [[12885, 12885], "mapped", [50, 53]], [[12886, 12886], "mapped", [50, 54]], [[12887, 12887], "mapped", [50, 55]], [[12888, 12888], "mapped", [50, 56]], [[12889, 12889], "mapped", [50, 57]], [[12890, 12890], "mapped", [51, 48]], [[12891, 12891], "mapped", [51, 49]], [[12892, 12892], "mapped", [51, 50]], [[12893, 12893], "mapped", [51, 51]], [[12894, 12894], "mapped", [51, 52]], [[12895, 12895], "mapped", [51, 53]], [[12896, 12896], "mapped", [4352]], [[12897, 12897], "mapped", [4354]], [[12898, 12898], "mapped", [4355]], [[12899, 12899], "mapped", [4357]], [[12900, 12900], "mapped", [4358]], [[12901, 12901], "mapped", [4359]], [[12902, 12902], "mapped", [4361]], [[12903, 12903], "mapped", [4363]], [[12904, 12904], "mapped", [4364]], [[12905, 12905], "mapped", [4366]], [[12906, 12906], "mapped", [4367]], [[12907, 12907], "mapped", [4368]], [[12908, 12908], "mapped", [4369]], [[12909, 12909], "mapped", [4370]], [[12910, 12910], "mapped", [44032]], [[12911, 12911], "mapped", [45208]], [[12912, 12912], "mapped", [45796]], [[12913, 12913], "mapped", [46972]], [[12914, 12914], "mapped", [47560]], [[12915, 12915], "mapped", [48148]], [[12916, 12916], "mapped", [49324]], [[12917, 12917], "mapped", [50500]], [[12918, 12918], "mapped", [51088]], [[12919, 12919], "mapped", [52264]], [[12920, 12920], "mapped", [52852]], [[12921, 12921], "mapped", [53440]], [[12922, 12922], "mapped", [54028]], [[12923, 12923], "mapped", [54616]], [[12924, 12924], "mapped", [52280, 44256]], [[12925, 12925], "mapped", [51452, 51032]], [[12926, 12926], "mapped", [50864]], [[12927, 12927], "valid", [], "NV8"], [[12928, 12928], "mapped", [19968]], [[12929, 12929], "mapped", [20108]], [[12930, 12930], "mapped", [19977]], [[12931, 12931], "mapped", [22235]], [[12932, 12932], "mapped", [20116]], [[12933, 12933], "mapped", [20845]], [[12934, 12934], "mapped", [19971]], [[12935, 12935], "mapped", [20843]], [[12936, 12936], "mapped", [20061]], [[12937, 12937], "mapped", [21313]], [[12938, 12938], "mapped", [26376]], [[12939, 12939], "mapped", [28779]], [[12940, 12940], "mapped", [27700]], [[12941, 12941], "mapped", [26408]], [[12942, 12942], "mapped", [37329]], [[12943, 12943], "mapped", [22303]], [[12944, 12944], "mapped", [26085]], [[12945, 12945], "mapped", [26666]], [[12946, 12946], "mapped", [26377]], [[12947, 12947], "mapped", [31038]], [[12948, 12948], "mapped", [21517]], [[12949, 12949], "mapped", [29305]], [[12950, 12950], "mapped", [36001]], [[12951, 12951], "mapped", [31069]], [[12952, 12952], "mapped", [21172]], [[12953, 12953], "mapped", [31192]], [[12954, 12954], "mapped", [30007]], [[12955, 12955], "mapped", [22899]], [[12956, 12956], "mapped", [36969]], [[12957, 12957], "mapped", [20778]], [[12958, 12958], "mapped", [21360]], [[12959, 12959], "mapped", [27880]], [[12960, 12960], "mapped", [38917]], [[12961, 12961], "mapped", [20241]], [[12962, 12962], "mapped", [20889]], [[12963, 12963], "mapped", [27491]], [[12964, 12964], "mapped", [19978]], [[12965, 12965], "mapped", [20013]], [[12966, 12966], "mapped", [19979]], [[12967, 12967], "mapped", [24038]], [[12968, 12968], "mapped", [21491]], [[12969, 12969], "mapped", [21307]], [[12970, 12970], "mapped", [23447]], [[12971, 12971], "mapped", [23398]], [[12972, 12972], "mapped", [30435]], [[12973, 12973], "mapped", [20225]], [[12974, 12974], "mapped", [36039]], [[12975, 12975], "mapped", [21332]], [[12976, 12976], "mapped", [22812]], [[12977, 12977], "mapped", [51, 54]], [[12978, 12978], "mapped", [51, 55]], [[12979, 12979], "mapped", [51, 56]], [[12980, 12980], "mapped", [51, 57]], [[12981, 12981], "mapped", [52, 48]], [[12982, 12982], "mapped", [52, 49]], [[12983, 12983], "mapped", [52, 50]], [[12984, 12984], "mapped", [52, 51]], [[12985, 12985], "mapped", [52, 52]], [[12986, 12986], "mapped", [52, 53]], [[12987, 12987], "mapped", [52, 54]], [[12988, 12988], "mapped", [52, 55]], [[12989, 12989], "mapped", [52, 56]], [[12990, 12990], "mapped", [52, 57]], [[12991, 12991], "mapped", [53, 48]], [[12992, 12992], "mapped", [49, 26376]], [[12993, 12993], "mapped", [50, 26376]], [[12994, 12994], "mapped", [51, 26376]], [[12995, 12995], "mapped", [52, 26376]], [[12996, 12996], "mapped", [53, 26376]], [[12997, 12997], "mapped", [54, 26376]], [[12998, 12998], "mapped", [55, 26376]], [[12999, 12999], "mapped", [56, 26376]], [[13e3, 13e3], "mapped", [57, 26376]], [[13001, 13001], "mapped", [49, 48, 26376]], [[13002, 13002], "mapped", [49, 49, 26376]], [[13003, 13003], "mapped", [49, 50, 26376]], [[13004, 13004], "mapped", [104, 103]], [[13005, 13005], "mapped", [101, 114, 103]], [[13006, 13006], "mapped", [101, 118]], [[13007, 13007], "mapped", [108, 116, 100]], [[13008, 13008], "mapped", [12450]], [[13009, 13009], "mapped", [12452]], [[13010, 13010], "mapped", [12454]], [[13011, 13011], "mapped", [12456]], [[13012, 13012], "mapped", [12458]], [[13013, 13013], "mapped", [12459]], [[13014, 13014], "mapped", [12461]], [[13015, 13015], "mapped", [12463]], [[13016, 13016], "mapped", [12465]], [[13017, 13017], "mapped", [12467]], [[13018, 13018], "mapped", [12469]], [[13019, 13019], "mapped", [12471]], [[13020, 13020], "mapped", [12473]], [[13021, 13021], "mapped", [12475]], [[13022, 13022], "mapped", [12477]], [[13023, 13023], "mapped", [12479]], [[13024, 13024], "mapped", [12481]], [[13025, 13025], "mapped", [12484]], [[13026, 13026], "mapped", [12486]], [[13027, 13027], "mapped", [12488]], [[13028, 13028], "mapped", [12490]], [[13029, 13029], "mapped", [12491]], [[13030, 13030], "mapped", [12492]], [[13031, 13031], "mapped", [12493]], [[13032, 13032], "mapped", [12494]], [[13033, 13033], "mapped", [12495]], [[13034, 13034], "mapped", [12498]], [[13035, 13035], "mapped", [12501]], [[13036, 13036], "mapped", [12504]], [[13037, 13037], "mapped", [12507]], [[13038, 13038], "mapped", [12510]], [[13039, 13039], "mapped", [12511]], [[13040, 13040], "mapped", [12512]], [[13041, 13041], "mapped", [12513]], [[13042, 13042], "mapped", [12514]], [[13043, 13043], "mapped", [12516]], [[13044, 13044], "mapped", [12518]], [[13045, 13045], "mapped", [12520]], [[13046, 13046], "mapped", [12521]], [[13047, 13047], "mapped", [12522]], [[13048, 13048], "mapped", [12523]], [[13049, 13049], "mapped", [12524]], [[13050, 13050], "mapped", [12525]], [[13051, 13051], "mapped", [12527]], [[13052, 13052], "mapped", [12528]], [[13053, 13053], "mapped", [12529]], [[13054, 13054], "mapped", [12530]], [[13055, 13055], "disallowed"], [[13056, 13056], "mapped", [12450, 12497, 12540, 12488]], [[13057, 13057], "mapped", [12450, 12523, 12501, 12449]], [[13058, 13058], "mapped", [12450, 12531, 12506, 12450]], [[13059, 13059], "mapped", [12450, 12540, 12523]], [[13060, 13060], "mapped", [12452, 12491, 12531, 12464]], [[13061, 13061], "mapped", [12452, 12531, 12481]], [[13062, 13062], "mapped", [12454, 12457, 12531]], [[13063, 13063], "mapped", [12456, 12473, 12463, 12540, 12489]], [[13064, 13064], "mapped", [12456, 12540, 12459, 12540]], [[13065, 13065], "mapped", [12458, 12531, 12473]], [[13066, 13066], "mapped", [12458, 12540, 12512]], [[13067, 13067], "mapped", [12459, 12452, 12522]], [[13068, 13068], "mapped", [12459, 12521, 12483, 12488]], [[13069, 13069], "mapped", [12459, 12525, 12522, 12540]], [[13070, 13070], "mapped", [12460, 12525, 12531]], [[13071, 13071], "mapped", [12460, 12531, 12510]], [[13072, 13072], "mapped", [12462, 12460]], [[13073, 13073], "mapped", [12462, 12491, 12540]], [[13074, 13074], "mapped", [12461, 12517, 12522, 12540]], [[13075, 13075], "mapped", [12462, 12523, 12480, 12540]], [[13076, 13076], "mapped", [12461, 12525]], [[13077, 13077], "mapped", [12461, 12525, 12464, 12521, 12512]], [[13078, 13078], "mapped", [12461, 12525, 12513, 12540, 12488, 12523]], [[13079, 13079], "mapped", [12461, 12525, 12527, 12483, 12488]], [[13080, 13080], "mapped", [12464, 12521, 12512]], [[13081, 13081], "mapped", [12464, 12521, 12512, 12488, 12531]], [[13082, 13082], "mapped", [12463, 12523, 12476, 12452, 12525]], [[13083, 13083], "mapped", [12463, 12525, 12540, 12493]], [[13084, 13084], "mapped", [12465, 12540, 12473]], [[13085, 13085], "mapped", [12467, 12523, 12490]], [[13086, 13086], "mapped", [12467, 12540, 12509]], [[13087, 13087], "mapped", [12469, 12452, 12463, 12523]], [[13088, 13088], "mapped", [12469, 12531, 12481, 12540, 12512]], [[13089, 13089], "mapped", [12471, 12522, 12531, 12464]], [[13090, 13090], "mapped", [12475, 12531, 12481]], [[13091, 13091], "mapped", [12475, 12531, 12488]], [[13092, 13092], "mapped", [12480, 12540, 12473]], [[13093, 13093], "mapped", [12487, 12471]], [[13094, 13094], "mapped", [12489, 12523]], [[13095, 13095], "mapped", [12488, 12531]], [[13096, 13096], "mapped", [12490, 12494]], [[13097, 13097], "mapped", [12494, 12483, 12488]], [[13098, 13098], "mapped", [12495, 12452, 12484]], [[13099, 13099], "mapped", [12497, 12540, 12475, 12531, 12488]], [[13100, 13100], "mapped", [12497, 12540, 12484]], [[13101, 13101], "mapped", [12496, 12540, 12524, 12523]], [[13102, 13102], "mapped", [12500, 12450, 12473, 12488, 12523]], [[13103, 13103], "mapped", [12500, 12463, 12523]], [[13104, 13104], "mapped", [12500, 12467]], [[13105, 13105], "mapped", [12499, 12523]], [[13106, 13106], "mapped", [12501, 12449, 12521, 12483, 12489]], [[13107, 13107], "mapped", [12501, 12451, 12540, 12488]], [[13108, 13108], "mapped", [12502, 12483, 12471, 12455, 12523]], [[13109, 13109], "mapped", [12501, 12521, 12531]], [[13110, 13110], "mapped", [12504, 12463, 12479, 12540, 12523]], [[13111, 13111], "mapped", [12506, 12477]], [[13112, 13112], "mapped", [12506, 12491, 12498]], [[13113, 13113], "mapped", [12504, 12523, 12484]], [[13114, 13114], "mapped", [12506, 12531, 12473]], [[13115, 13115], "mapped", [12506, 12540, 12472]], [[13116, 13116], "mapped", [12505, 12540, 12479]], [[13117, 13117], "mapped", [12509, 12452, 12531, 12488]], [[13118, 13118], "mapped", [12508, 12523, 12488]], [[13119, 13119], "mapped", [12507, 12531]], [[13120, 13120], "mapped", [12509, 12531, 12489]], [[13121, 13121], "mapped", [12507, 12540, 12523]], [[13122, 13122], "mapped", [12507, 12540, 12531]], [[13123, 13123], "mapped", [12510, 12452, 12463, 12525]], [[13124, 13124], "mapped", [12510, 12452, 12523]], [[13125, 13125], "mapped", [12510, 12483, 12495]], [[13126, 13126], "mapped", [12510, 12523, 12463]], [[13127, 13127], "mapped", [12510, 12531, 12471, 12519, 12531]], [[13128, 13128], "mapped", [12511, 12463, 12525, 12531]], [[13129, 13129], "mapped", [12511, 12522]], [[13130, 13130], "mapped", [12511, 12522, 12496, 12540, 12523]], [[13131, 13131], "mapped", [12513, 12460]], [[13132, 13132], "mapped", [12513, 12460, 12488, 12531]], [[13133, 13133], "mapped", [12513, 12540, 12488, 12523]], [[13134, 13134], "mapped", [12516, 12540, 12489]], [[13135, 13135], "mapped", [12516, 12540, 12523]], [[13136, 13136], "mapped", [12518, 12450, 12531]], [[13137, 13137], "mapped", [12522, 12483, 12488, 12523]], [[13138, 13138], "mapped", [12522, 12521]], [[13139, 13139], "mapped", [12523, 12500, 12540]], [[13140, 13140], "mapped", [12523, 12540, 12502, 12523]], [[13141, 13141], "mapped", [12524, 12512]], [[13142, 13142], "mapped", [12524, 12531, 12488, 12466, 12531]], [[13143, 13143], "mapped", [12527, 12483, 12488]], [[13144, 13144], "mapped", [48, 28857]], [[13145, 13145], "mapped", [49, 28857]], [[13146, 13146], "mapped", [50, 28857]], [[13147, 13147], "mapped", [51, 28857]], [[13148, 13148], "mapped", [52, 28857]], [[13149, 13149], "mapped", [53, 28857]], [[13150, 13150], "mapped", [54, 28857]], [[13151, 13151], "mapped", [55, 28857]], [[13152, 13152], "mapped", [56, 28857]], [[13153, 13153], "mapped", [57, 28857]], [[13154, 13154], "mapped", [49, 48, 28857]], [[13155, 13155], "mapped", [49, 49, 28857]], [[13156, 13156], "mapped", [49, 50, 28857]], [[13157, 13157], "mapped", [49, 51, 28857]], [[13158, 13158], "mapped", [49, 52, 28857]], [[13159, 13159], "mapped", [49, 53, 28857]], [[13160, 13160], "mapped", [49, 54, 28857]], [[13161, 13161], "mapped", [49, 55, 28857]], [[13162, 13162], "mapped", [49, 56, 28857]], [[13163, 13163], "mapped", [49, 57, 28857]], [[13164, 13164], "mapped", [50, 48, 28857]], [[13165, 13165], "mapped", [50, 49, 28857]], [[13166, 13166], "mapped", [50, 50, 28857]], [[13167, 13167], "mapped", [50, 51, 28857]], [[13168, 13168], "mapped", [50, 52, 28857]], [[13169, 13169], "mapped", [104, 112, 97]], [[13170, 13170], "mapped", [100, 97]], [[13171, 13171], "mapped", [97, 117]], [[13172, 13172], "mapped", [98, 97, 114]], [[13173, 13173], "mapped", [111, 118]], [[13174, 13174], "mapped", [112, 99]], [[13175, 13175], "mapped", [100, 109]], [[13176, 13176], "mapped", [100, 109, 50]], [[13177, 13177], "mapped", [100, 109, 51]], [[13178, 13178], "mapped", [105, 117]], [[13179, 13179], "mapped", [24179, 25104]], [[13180, 13180], "mapped", [26157, 21644]], [[13181, 13181], "mapped", [22823, 27491]], [[13182, 13182], "mapped", [26126, 27835]], [[13183, 13183], "mapped", [26666, 24335, 20250, 31038]], [[13184, 13184], "mapped", [112, 97]], [[13185, 13185], "mapped", [110, 97]], [[13186, 13186], "mapped", [956, 97]], [[13187, 13187], "mapped", [109, 97]], [[13188, 13188], "mapped", [107, 97]], [[13189, 13189], "mapped", [107, 98]], [[13190, 13190], "mapped", [109, 98]], [[13191, 13191], "mapped", [103, 98]], [[13192, 13192], "mapped", [99, 97, 108]], [[13193, 13193], "mapped", [107, 99, 97, 108]], [[13194, 13194], "mapped", [112, 102]], [[13195, 13195], "mapped", [110, 102]], [[13196, 13196], "mapped", [956, 102]], [[13197, 13197], "mapped", [956, 103]], [[13198, 13198], "mapped", [109, 103]], [[13199, 13199], "mapped", [107, 103]], [[13200, 13200], "mapped", [104, 122]], [[13201, 13201], "mapped", [107, 104, 122]], [[13202, 13202], "mapped", [109, 104, 122]], [[13203, 13203], "mapped", [103, 104, 122]], [[13204, 13204], "mapped", [116, 104, 122]], [[13205, 13205], "mapped", [956, 108]], [[13206, 13206], "mapped", [109, 108]], [[13207, 13207], "mapped", [100, 108]], [[13208, 13208], "mapped", [107, 108]], [[13209, 13209], "mapped", [102, 109]], [[13210, 13210], "mapped", [110, 109]], [[13211, 13211], "mapped", [956, 109]], [[13212, 13212], "mapped", [109, 109]], [[13213, 13213], "mapped", [99, 109]], [[13214, 13214], "mapped", [107, 109]], [[13215, 13215], "mapped", [109, 109, 50]], [[13216, 13216], "mapped", [99, 109, 50]], [[13217, 13217], "mapped", [109, 50]], [[13218, 13218], "mapped", [107, 109, 50]], [[13219, 13219], "mapped", [109, 109, 51]], [[13220, 13220], "mapped", [99, 109, 51]], [[13221, 13221], "mapped", [109, 51]], [[13222, 13222], "mapped", [107, 109, 51]], [[13223, 13223], "mapped", [109, 8725, 115]], [[13224, 13224], "mapped", [109, 8725, 115, 50]], [[13225, 13225], "mapped", [112, 97]], [[13226, 13226], "mapped", [107, 112, 97]], [[13227, 13227], "mapped", [109, 112, 97]], [[13228, 13228], "mapped", [103, 112, 97]], [[13229, 13229], "mapped", [114, 97, 100]], [[13230, 13230], "mapped", [114, 97, 100, 8725, 115]], [[13231, 13231], "mapped", [114, 97, 100, 8725, 115, 50]], [[13232, 13232], "mapped", [112, 115]], [[13233, 13233], "mapped", [110, 115]], [[13234, 13234], "mapped", [956, 115]], [[13235, 13235], "mapped", [109, 115]], [[13236, 13236], "mapped", [112, 118]], [[13237, 13237], "mapped", [110, 118]], [[13238, 13238], "mapped", [956, 118]], [[13239, 13239], "mapped", [109, 118]], [[13240, 13240], "mapped", [107, 118]], [[13241, 13241], "mapped", [109, 118]], [[13242, 13242], "mapped", [112, 119]], [[13243, 13243], "mapped", [110, 119]], [[13244, 13244], "mapped", [956, 119]], [[13245, 13245], "mapped", [109, 119]], [[13246, 13246], "mapped", [107, 119]], [[13247, 13247], "mapped", [109, 119]], [[13248, 13248], "mapped", [107, 969]], [[13249, 13249], "mapped", [109, 969]], [[13250, 13250], "disallowed"], [[13251, 13251], "mapped", [98, 113]], [[13252, 13252], "mapped", [99, 99]], [[13253, 13253], "mapped", [99, 100]], [[13254, 13254], "mapped", [99, 8725, 107, 103]], [[13255, 13255], "disallowed"], [[13256, 13256], "mapped", [100, 98]], [[13257, 13257], "mapped", [103, 121]], [[13258, 13258], "mapped", [104, 97]], [[13259, 13259], "mapped", [104, 112]], [[13260, 13260], "mapped", [105, 110]], [[13261, 13261], "mapped", [107, 107]], [[13262, 13262], "mapped", [107, 109]], [[13263, 13263], "mapped", [107, 116]], [[13264, 13264], "mapped", [108, 109]], [[13265, 13265], "mapped", [108, 110]], [[13266, 13266], "mapped", [108, 111, 103]], [[13267, 13267], "mapped", [108, 120]], [[13268, 13268], "mapped", [109, 98]], [[13269, 13269], "mapped", [109, 105, 108]], [[13270, 13270], "mapped", [109, 111, 108]], [[13271, 13271], "mapped", [112, 104]], [[13272, 13272], "disallowed"], [[13273, 13273], "mapped", [112, 112, 109]], [[13274, 13274], "mapped", [112, 114]], [[13275, 13275], "mapped", [115, 114]], [[13276, 13276], "mapped", [115, 118]], [[13277, 13277], "mapped", [119, 98]], [[13278, 13278], "mapped", [118, 8725, 109]], [[13279, 13279], "mapped", [97, 8725, 109]], [[13280, 13280], "mapped", [49, 26085]], [[13281, 13281], "mapped", [50, 26085]], [[13282, 13282], "mapped", [51, 26085]], [[13283, 13283], "mapped", [52, 26085]], [[13284, 13284], "mapped", [53, 26085]], [[13285, 13285], "mapped", [54, 26085]], [[13286, 13286], "mapped", [55, 26085]], [[13287, 13287], "mapped", [56, 26085]], [[13288, 13288], "mapped", [57, 26085]], [[13289, 13289], "mapped", [49, 48, 26085]], [[13290, 13290], "mapped", [49, 49, 26085]], [[13291, 13291], "mapped", [49, 50, 26085]], [[13292, 13292], "mapped", [49, 51, 26085]], [[13293, 13293], "mapped", [49, 52, 26085]], [[13294, 13294], "mapped", [49, 53, 26085]], [[13295, 13295], "mapped", [49, 54, 26085]], [[13296, 13296], "mapped", [49, 55, 26085]], [[13297, 13297], "mapped", [49, 56, 26085]], [[13298, 13298], "mapped", [49, 57, 26085]], [[13299, 13299], "mapped", [50, 48, 26085]], [[13300, 13300], "mapped", [50, 49, 26085]], [[13301, 13301], "mapped", [50, 50, 26085]], [[13302, 13302], "mapped", [50, 51, 26085]], [[13303, 13303], "mapped", [50, 52, 26085]], [[13304, 13304], "mapped", [50, 53, 26085]], [[13305, 13305], "mapped", [50, 54, 26085]], [[13306, 13306], "mapped", [50, 55, 26085]], [[13307, 13307], "mapped", [50, 56, 26085]], [[13308, 13308], "mapped", [50, 57, 26085]], [[13309, 13309], "mapped", [51, 48, 26085]], [[13310, 13310], "mapped", [51, 49, 26085]], [[13311, 13311], "mapped", [103, 97, 108]], [[13312, 19893], "valid"], [[19894, 19903], "disallowed"], [[19904, 19967], "valid", [], "NV8"], [[19968, 40869], "valid"], [[40870, 40891], "valid"], [[40892, 40899], "valid"], [[40900, 40907], "valid"], [[40908, 40908], "valid"], [[40909, 40917], "valid"], [[40918, 40959], "disallowed"], [[40960, 42124], "valid"], [[42125, 42127], "disallowed"], [[42128, 42145], "valid", [], "NV8"], [[42146, 42147], "valid", [], "NV8"], [[42148, 42163], "valid", [], "NV8"], [[42164, 42164], "valid", [], "NV8"], [[42165, 42176], "valid", [], "NV8"], [[42177, 42177], "valid", [], "NV8"], [[42178, 42180], "valid", [], "NV8"], [[42181, 42181], "valid", [], "NV8"], [[42182, 42182], "valid", [], "NV8"], [[42183, 42191], "disallowed"], [[42192, 42237], "valid"], [[42238, 42239], "valid", [], "NV8"], [[42240, 42508], "valid"], [[42509, 42511], "valid", [], "NV8"], [[42512, 42539], "valid"], [[42540, 42559], "disallowed"], [[42560, 42560], "mapped", [42561]], [[42561, 42561], "valid"], [[42562, 42562], "mapped", [42563]], [[42563, 42563], "valid"], [[42564, 42564], "mapped", [42565]], [[42565, 42565], "valid"], [[42566, 42566], "mapped", [42567]], [[42567, 42567], "valid"], [[42568, 42568], "mapped", [42569]], [[42569, 42569], "valid"], [[42570, 42570], "mapped", [42571]], [[42571, 42571], "valid"], [[42572, 42572], "mapped", [42573]], [[42573, 42573], "valid"], [[42574, 42574], "mapped", [42575]], [[42575, 42575], "valid"], [[42576, 42576], "mapped", [42577]], [[42577, 42577], "valid"], [[42578, 42578], "mapped", [42579]], [[42579, 42579], "valid"], [[42580, 42580], "mapped", [42581]], [[42581, 42581], "valid"], [[42582, 42582], "mapped", [42583]], [[42583, 42583], "valid"], [[42584, 42584], "mapped", [42585]], [[42585, 42585], "valid"], [[42586, 42586], "mapped", [42587]], [[42587, 42587], "valid"], [[42588, 42588], "mapped", [42589]], [[42589, 42589], "valid"], [[42590, 42590], "mapped", [42591]], [[42591, 42591], "valid"], [[42592, 42592], "mapped", [42593]], [[42593, 42593], "valid"], [[42594, 42594], "mapped", [42595]], [[42595, 42595], "valid"], [[42596, 42596], "mapped", [42597]], [[42597, 42597], "valid"], [[42598, 42598], "mapped", [42599]], [[42599, 42599], "valid"], [[42600, 42600], "mapped", [42601]], [[42601, 42601], "valid"], [[42602, 42602], "mapped", [42603]], [[42603, 42603], "valid"], [[42604, 42604], "mapped", [42605]], [[42605, 42607], "valid"], [[42608, 42611], "valid", [], "NV8"], [[42612, 42619], "valid"], [[42620, 42621], "valid"], [[42622, 42622], "valid", [], "NV8"], [[42623, 42623], "valid"], [[42624, 42624], "mapped", [42625]], [[42625, 42625], "valid"], [[42626, 42626], "mapped", [42627]], [[42627, 42627], "valid"], [[42628, 42628], "mapped", [42629]], [[42629, 42629], "valid"], [[42630, 42630], "mapped", [42631]], [[42631, 42631], "valid"], [[42632, 42632], "mapped", [42633]], [[42633, 42633], "valid"], [[42634, 42634], "mapped", [42635]], [[42635, 42635], "valid"], [[42636, 42636], "mapped", [42637]], [[42637, 42637], "valid"], [[42638, 42638], "mapped", [42639]], [[42639, 42639], "valid"], [[42640, 42640], "mapped", [42641]], [[42641, 42641], "valid"], [[42642, 42642], "mapped", [42643]], [[42643, 42643], "valid"], [[42644, 42644], "mapped", [42645]], [[42645, 42645], "valid"], [[42646, 42646], "mapped", [42647]], [[42647, 42647], "valid"], [[42648, 42648], "mapped", [42649]], [[42649, 42649], "valid"], [[42650, 42650], "mapped", [42651]], [[42651, 42651], "valid"], [[42652, 42652], "mapped", [1098]], [[42653, 42653], "mapped", [1100]], [[42654, 42654], "valid"], [[42655, 42655], "valid"], [[42656, 42725], "valid"], [[42726, 42735], "valid", [], "NV8"], [[42736, 42737], "valid"], [[42738, 42743], "valid", [], "NV8"], [[42744, 42751], "disallowed"], [[42752, 42774], "valid", [], "NV8"], [[42775, 42778], "valid"], [[42779, 42783], "valid"], [[42784, 42785], "valid", [], "NV8"], [[42786, 42786], "mapped", [42787]], [[42787, 42787], "valid"], [[42788, 42788], "mapped", [42789]], [[42789, 42789], "valid"], [[42790, 42790], "mapped", [42791]], [[42791, 42791], "valid"], [[42792, 42792], "mapped", [42793]], [[42793, 42793], "valid"], [[42794, 42794], "mapped", [42795]], [[42795, 42795], "valid"], [[42796, 42796], "mapped", [42797]], [[42797, 42797], "valid"], [[42798, 42798], "mapped", [42799]], [[42799, 42801], "valid"], [[42802, 42802], "mapped", [42803]], [[42803, 42803], "valid"], [[42804, 42804], "mapped", [42805]], [[42805, 42805], "valid"], [[42806, 42806], "mapped", [42807]], [[42807, 42807], "valid"], [[42808, 42808], "mapped", [42809]], [[42809, 42809], "valid"], [[42810, 42810], "mapped", [42811]], [[42811, 42811], "valid"], [[42812, 42812], "mapped", [42813]], [[42813, 42813], "valid"], [[42814, 42814], "mapped", [42815]], [[42815, 42815], "valid"], [[42816, 42816], "mapped", [42817]], [[42817, 42817], "valid"], [[42818, 42818], "mapped", [42819]], [[42819, 42819], "valid"], [[42820, 42820], "mapped", [42821]], [[42821, 42821], "valid"], [[42822, 42822], "mapped", [42823]], [[42823, 42823], "valid"], [[42824, 42824], "mapped", [42825]], [[42825, 42825], "valid"], [[42826, 42826], "mapped", [42827]], [[42827, 42827], "valid"], [[42828, 42828], "mapped", [42829]], [[42829, 42829], "valid"], [[42830, 42830], "mapped", [42831]], [[42831, 42831], "valid"], [[42832, 42832], "mapped", [42833]], [[42833, 42833], "valid"], [[42834, 42834], "mapped", [42835]], [[42835, 42835], "valid"], [[42836, 42836], "mapped", [42837]], [[42837, 42837], "valid"], [[42838, 42838], "mapped", [42839]], [[42839, 42839], "valid"], [[42840, 42840], "mapped", [42841]], [[42841, 42841], "valid"], [[42842, 42842], "mapped", [42843]], [[42843, 42843], "valid"], [[42844, 42844], "mapped", [42845]], [[42845, 42845], "valid"], [[42846, 42846], "mapped", [42847]], [[42847, 42847], "valid"], [[42848, 42848], "mapped", [42849]], [[42849, 42849], "valid"], [[42850, 42850], "mapped", [42851]], [[42851, 42851], "valid"], [[42852, 42852], "mapped", [42853]], [[42853, 42853], "valid"], [[42854, 42854], "mapped", [42855]], [[42855, 42855], "valid"], [[42856, 42856], "mapped", [42857]], [[42857, 42857], "valid"], [[42858, 42858], "mapped", [42859]], [[42859, 42859], "valid"], [[42860, 42860], "mapped", [42861]], [[42861, 42861], "valid"], [[42862, 42862], "mapped", [42863]], [[42863, 42863], "valid"], [[42864, 42864], "mapped", [42863]], [[42865, 42872], "valid"], [[42873, 42873], "mapped", [42874]], [[42874, 42874], "valid"], [[42875, 42875], "mapped", [42876]], [[42876, 42876], "valid"], [[42877, 42877], "mapped", [7545]], [[42878, 42878], "mapped", [42879]], [[42879, 42879], "valid"], [[42880, 42880], "mapped", [42881]], [[42881, 42881], "valid"], [[42882, 42882], "mapped", [42883]], [[42883, 42883], "valid"], [[42884, 42884], "mapped", [42885]], [[42885, 42885], "valid"], [[42886, 42886], "mapped", [42887]], [[42887, 42888], "valid"], [[42889, 42890], "valid", [], "NV8"], [[42891, 42891], "mapped", [42892]], [[42892, 42892], "valid"], [[42893, 42893], "mapped", [613]], [[42894, 42894], "valid"], [[42895, 42895], "valid"], [[42896, 42896], "mapped", [42897]], [[42897, 42897], "valid"], [[42898, 42898], "mapped", [42899]], [[42899, 42899], "valid"], [[42900, 42901], "valid"], [[42902, 42902], "mapped", [42903]], [[42903, 42903], "valid"], [[42904, 42904], "mapped", [42905]], [[42905, 42905], "valid"], [[42906, 42906], "mapped", [42907]], [[42907, 42907], "valid"], [[42908, 42908], "mapped", [42909]], [[42909, 42909], "valid"], [[42910, 42910], "mapped", [42911]], [[42911, 42911], "valid"], [[42912, 42912], "mapped", [42913]], [[42913, 42913], "valid"], [[42914, 42914], "mapped", [42915]], [[42915, 42915], "valid"], [[42916, 42916], "mapped", [42917]], [[42917, 42917], "valid"], [[42918, 42918], "mapped", [42919]], [[42919, 42919], "valid"], [[42920, 42920], "mapped", [42921]], [[42921, 42921], "valid"], [[42922, 42922], "mapped", [614]], [[42923, 42923], "mapped", [604]], [[42924, 42924], "mapped", [609]], [[42925, 42925], "mapped", [620]], [[42926, 42927], "disallowed"], [[42928, 42928], "mapped", [670]], [[42929, 42929], "mapped", [647]], [[42930, 42930], "mapped", [669]], [[42931, 42931], "mapped", [43859]], [[42932, 42932], "mapped", [42933]], [[42933, 42933], "valid"], [[42934, 42934], "mapped", [42935]], [[42935, 42935], "valid"], [[42936, 42998], "disallowed"], [[42999, 42999], "valid"], [[43e3, 43e3], "mapped", [295]], [[43001, 43001], "mapped", [339]], [[43002, 43002], "valid"], [[43003, 43007], "valid"], [[43008, 43047], "valid"], [[43048, 43051], "valid", [], "NV8"], [[43052, 43055], "disallowed"], [[43056, 43065], "valid", [], "NV8"], [[43066, 43071], "disallowed"], [[43072, 43123], "valid"], [[43124, 43127], "valid", [], "NV8"], [[43128, 43135], "disallowed"], [[43136, 43204], "valid"], [[43205, 43213], "disallowed"], [[43214, 43215], "valid", [], "NV8"], [[43216, 43225], "valid"], [[43226, 43231], "disallowed"], [[43232, 43255], "valid"], [[43256, 43258], "valid", [], "NV8"], [[43259, 43259], "valid"], [[43260, 43260], "valid", [], "NV8"], [[43261, 43261], "valid"], [[43262, 43263], "disallowed"], [[43264, 43309], "valid"], [[43310, 43311], "valid", [], "NV8"], [[43312, 43347], "valid"], [[43348, 43358], "disallowed"], [[43359, 43359], "valid", [], "NV8"], [[43360, 43388], "valid", [], "NV8"], [[43389, 43391], "disallowed"], [[43392, 43456], "valid"], [[43457, 43469], "valid", [], "NV8"], [[43470, 43470], "disallowed"], [[43471, 43481], "valid"], [[43482, 43485], "disallowed"], [[43486, 43487], "valid", [], "NV8"], [[43488, 43518], "valid"], [[43519, 43519], "disallowed"], [[43520, 43574], "valid"], [[43575, 43583], "disallowed"], [[43584, 43597], "valid"], [[43598, 43599], "disallowed"], [[43600, 43609], "valid"], [[43610, 43611], "disallowed"], [[43612, 43615], "valid", [], "NV8"], [[43616, 43638], "valid"], [[43639, 43641], "valid", [], "NV8"], [[43642, 43643], "valid"], [[43644, 43647], "valid"], [[43648, 43714], "valid"], [[43715, 43738], "disallowed"], [[43739, 43741], "valid"], [[43742, 43743], "valid", [], "NV8"], [[43744, 43759], "valid"], [[43760, 43761], "valid", [], "NV8"], [[43762, 43766], "valid"], [[43767, 43776], "disallowed"], [[43777, 43782], "valid"], [[43783, 43784], "disallowed"], [[43785, 43790], "valid"], [[43791, 43792], "disallowed"], [[43793, 43798], "valid"], [[43799, 43807], "disallowed"], [[43808, 43814], "valid"], [[43815, 43815], "disallowed"], [[43816, 43822], "valid"], [[43823, 43823], "disallowed"], [[43824, 43866], "valid"], [[43867, 43867], "valid", [], "NV8"], [[43868, 43868], "mapped", [42791]], [[43869, 43869], "mapped", [43831]], [[43870, 43870], "mapped", [619]], [[43871, 43871], "mapped", [43858]], [[43872, 43875], "valid"], [[43876, 43877], "valid"], [[43878, 43887], "disallowed"], [[43888, 43888], "mapped", [5024]], [[43889, 43889], "mapped", [5025]], [[43890, 43890], "mapped", [5026]], [[43891, 43891], "mapped", [5027]], [[43892, 43892], "mapped", [5028]], [[43893, 43893], "mapped", [5029]], [[43894, 43894], "mapped", [5030]], [[43895, 43895], "mapped", [5031]], [[43896, 43896], "mapped", [5032]], [[43897, 43897], "mapped", [5033]], [[43898, 43898], "mapped", [5034]], [[43899, 43899], "mapped", [5035]], [[43900, 43900], "mapped", [5036]], [[43901, 43901], "mapped", [5037]], [[43902, 43902], "mapped", [5038]], [[43903, 43903], "mapped", [5039]], [[43904, 43904], "mapped", [5040]], [[43905, 43905], "mapped", [5041]], [[43906, 43906], "mapped", [5042]], [[43907, 43907], "mapped", [5043]], [[43908, 43908], "mapped", [5044]], [[43909, 43909], "mapped", [5045]], [[43910, 43910], "mapped", [5046]], [[43911, 43911], "mapped", [5047]], [[43912, 43912], "mapped", [5048]], [[43913, 43913], "mapped", [5049]], [[43914, 43914], "mapped", [5050]], [[43915, 43915], "mapped", [5051]], [[43916, 43916], "mapped", [5052]], [[43917, 43917], "mapped", [5053]], [[43918, 43918], "mapped", [5054]], [[43919, 43919], "mapped", [5055]], [[43920, 43920], "mapped", [5056]], [[43921, 43921], "mapped", [5057]], [[43922, 43922], "mapped", [5058]], [[43923, 43923], "mapped", [5059]], [[43924, 43924], "mapped", [5060]], [[43925, 43925], "mapped", [5061]], [[43926, 43926], "mapped", [5062]], [[43927, 43927], "mapped", [5063]], [[43928, 43928], "mapped", [5064]], [[43929, 43929], "mapped", [5065]], [[43930, 43930], "mapped", [5066]], [[43931, 43931], "mapped", [5067]], [[43932, 43932], "mapped", [5068]], [[43933, 43933], "mapped", [5069]], [[43934, 43934], "mapped", [5070]], [[43935, 43935], "mapped", [5071]], [[43936, 43936], "mapped", [5072]], [[43937, 43937], "mapped", [5073]], [[43938, 43938], "mapped", [5074]], [[43939, 43939], "mapped", [5075]], [[43940, 43940], "mapped", [5076]], [[43941, 43941], "mapped", [5077]], [[43942, 43942], "mapped", [5078]], [[43943, 43943], "mapped", [5079]], [[43944, 43944], "mapped", [5080]], [[43945, 43945], "mapped", [5081]], [[43946, 43946], "mapped", [5082]], [[43947, 43947], "mapped", [5083]], [[43948, 43948], "mapped", [5084]], [[43949, 43949], "mapped", [5085]], [[43950, 43950], "mapped", [5086]], [[43951, 43951], "mapped", [5087]], [[43952, 43952], "mapped", [5088]], [[43953, 43953], "mapped", [5089]], [[43954, 43954], "mapped", [5090]], [[43955, 43955], "mapped", [5091]], [[43956, 43956], "mapped", [5092]], [[43957, 43957], "mapped", [5093]], [[43958, 43958], "mapped", [5094]], [[43959, 43959], "mapped", [5095]], [[43960, 43960], "mapped", [5096]], [[43961, 43961], "mapped", [5097]], [[43962, 43962], "mapped", [5098]], [[43963, 43963], "mapped", [5099]], [[43964, 43964], "mapped", [5100]], [[43965, 43965], "mapped", [5101]], [[43966, 43966], "mapped", [5102]], [[43967, 43967], "mapped", [5103]], [[43968, 44010], "valid"], [[44011, 44011], "valid", [], "NV8"], [[44012, 44013], "valid"], [[44014, 44015], "disallowed"], [[44016, 44025], "valid"], [[44026, 44031], "disallowed"], [[44032, 55203], "valid"], [[55204, 55215], "disallowed"], [[55216, 55238], "valid", [], "NV8"], [[55239, 55242], "disallowed"], [[55243, 55291], "valid", [], "NV8"], [[55292, 55295], "disallowed"], [[55296, 57343], "disallowed"], [[57344, 63743], "disallowed"], [[63744, 63744], "mapped", [35912]], [[63745, 63745], "mapped", [26356]], [[63746, 63746], "mapped", [36554]], [[63747, 63747], "mapped", [36040]], [[63748, 63748], "mapped", [28369]], [[63749, 63749], "mapped", [20018]], [[63750, 63750], "mapped", [21477]], [[63751, 63752], "mapped", [40860]], [[63753, 63753], "mapped", [22865]], [[63754, 63754], "mapped", [37329]], [[63755, 63755], "mapped", [21895]], [[63756, 63756], "mapped", [22856]], [[63757, 63757], "mapped", [25078]], [[63758, 63758], "mapped", [30313]], [[63759, 63759], "mapped", [32645]], [[63760, 63760], "mapped", [34367]], [[63761, 63761], "mapped", [34746]], [[63762, 63762], "mapped", [35064]], [[63763, 63763], "mapped", [37007]], [[63764, 63764], "mapped", [27138]], [[63765, 63765], "mapped", [27931]], [[63766, 63766], "mapped", [28889]], [[63767, 63767], "mapped", [29662]], [[63768, 63768], "mapped", [33853]], [[63769, 63769], "mapped", [37226]], [[63770, 63770], "mapped", [39409]], [[63771, 63771], "mapped", [20098]], [[63772, 63772], "mapped", [21365]], [[63773, 63773], "mapped", [27396]], [[63774, 63774], "mapped", [29211]], [[63775, 63775], "mapped", [34349]], [[63776, 63776], "mapped", [40478]], [[63777, 63777], "mapped", [23888]], [[63778, 63778], "mapped", [28651]], [[63779, 63779], "mapped", [34253]], [[63780, 63780], "mapped", [35172]], [[63781, 63781], "mapped", [25289]], [[63782, 63782], "mapped", [33240]], [[63783, 63783], "mapped", [34847]], [[63784, 63784], "mapped", [24266]], [[63785, 63785], "mapped", [26391]], [[63786, 63786], "mapped", [28010]], [[63787, 63787], "mapped", [29436]], [[63788, 63788], "mapped", [37070]], [[63789, 63789], "mapped", [20358]], [[63790, 63790], "mapped", [20919]], [[63791, 63791], "mapped", [21214]], [[63792, 63792], "mapped", [25796]], [[63793, 63793], "mapped", [27347]], [[63794, 63794], "mapped", [29200]], [[63795, 63795], "mapped", [30439]], [[63796, 63796], "mapped", [32769]], [[63797, 63797], "mapped", [34310]], [[63798, 63798], "mapped", [34396]], [[63799, 63799], "mapped", [36335]], [[63800, 63800], "mapped", [38706]], [[63801, 63801], "mapped", [39791]], [[63802, 63802], "mapped", [40442]], [[63803, 63803], "mapped", [30860]], [[63804, 63804], "mapped", [31103]], [[63805, 63805], "mapped", [32160]], [[63806, 63806], "mapped", [33737]], [[63807, 63807], "mapped", [37636]], [[63808, 63808], "mapped", [40575]], [[63809, 63809], "mapped", [35542]], [[63810, 63810], "mapped", [22751]], [[63811, 63811], "mapped", [24324]], [[63812, 63812], "mapped", [31840]], [[63813, 63813], "mapped", [32894]], [[63814, 63814], "mapped", [29282]], [[63815, 63815], "mapped", [30922]], [[63816, 63816], "mapped", [36034]], [[63817, 63817], "mapped", [38647]], [[63818, 63818], "mapped", [22744]], [[63819, 63819], "mapped", [23650]], [[63820, 63820], "mapped", [27155]], [[63821, 63821], "mapped", [28122]], [[63822, 63822], "mapped", [28431]], [[63823, 63823], "mapped", [32047]], [[63824, 63824], "mapped", [32311]], [[63825, 63825], "mapped", [38475]], [[63826, 63826], "mapped", [21202]], [[63827, 63827], "mapped", [32907]], [[63828, 63828], "mapped", [20956]], [[63829, 63829], "mapped", [20940]], [[63830, 63830], "mapped", [31260]], [[63831, 63831], "mapped", [32190]], [[63832, 63832], "mapped", [33777]], [[63833, 63833], "mapped", [38517]], [[63834, 63834], "mapped", [35712]], [[63835, 63835], "mapped", [25295]], [[63836, 63836], "mapped", [27138]], [[63837, 63837], "mapped", [35582]], [[63838, 63838], "mapped", [20025]], [[63839, 63839], "mapped", [23527]], [[63840, 63840], "mapped", [24594]], [[63841, 63841], "mapped", [29575]], [[63842, 63842], "mapped", [30064]], [[63843, 63843], "mapped", [21271]], [[63844, 63844], "mapped", [30971]], [[63845, 63845], "mapped", [20415]], [[63846, 63846], "mapped", [24489]], [[63847, 63847], "mapped", [19981]], [[63848, 63848], "mapped", [27852]], [[63849, 63849], "mapped", [25976]], [[63850, 63850], "mapped", [32034]], [[63851, 63851], "mapped", [21443]], [[63852, 63852], "mapped", [22622]], [[63853, 63853], "mapped", [30465]], [[63854, 63854], "mapped", [33865]], [[63855, 63855], "mapped", [35498]], [[63856, 63856], "mapped", [27578]], [[63857, 63857], "mapped", [36784]], [[63858, 63858], "mapped", [27784]], [[63859, 63859], "mapped", [25342]], [[63860, 63860], "mapped", [33509]], [[63861, 63861], "mapped", [25504]], [[63862, 63862], "mapped", [30053]], [[63863, 63863], "mapped", [20142]], [[63864, 63864], "mapped", [20841]], [[63865, 63865], "mapped", [20937]], [[63866, 63866], "mapped", [26753]], [[63867, 63867], "mapped", [31975]], [[63868, 63868], "mapped", [33391]], [[63869, 63869], "mapped", [35538]], [[63870, 63870], "mapped", [37327]], [[63871, 63871], "mapped", [21237]], [[63872, 63872], "mapped", [21570]], [[63873, 63873], "mapped", [22899]], [[63874, 63874], "mapped", [24300]], [[63875, 63875], "mapped", [26053]], [[63876, 63876], "mapped", [28670]], [[63877, 63877], "mapped", [31018]], [[63878, 63878], "mapped", [38317]], [[63879, 63879], "mapped", [39530]], [[63880, 63880], "mapped", [40599]], [[63881, 63881], "mapped", [40654]], [[63882, 63882], "mapped", [21147]], [[63883, 63883], "mapped", [26310]], [[63884, 63884], "mapped", [27511]], [[63885, 63885], "mapped", [36706]], [[63886, 63886], "mapped", [24180]], [[63887, 63887], "mapped", [24976]], [[63888, 63888], "mapped", [25088]], [[63889, 63889], "mapped", [25754]], [[63890, 63890], "mapped", [28451]], [[63891, 63891], "mapped", [29001]], [[63892, 63892], "mapped", [29833]], [[63893, 63893], "mapped", [31178]], [[63894, 63894], "mapped", [32244]], [[63895, 63895], "mapped", [32879]], [[63896, 63896], "mapped", [36646]], [[63897, 63897], "mapped", [34030]], [[63898, 63898], "mapped", [36899]], [[63899, 63899], "mapped", [37706]], [[63900, 63900], "mapped", [21015]], [[63901, 63901], "mapped", [21155]], [[63902, 63902], "mapped", [21693]], [[63903, 63903], "mapped", [28872]], [[63904, 63904], "mapped", [35010]], [[63905, 63905], "mapped", [35498]], [[63906, 63906], "mapped", [24265]], [[63907, 63907], "mapped", [24565]], [[63908, 63908], "mapped", [25467]], [[63909, 63909], "mapped", [27566]], [[63910, 63910], "mapped", [31806]], [[63911, 63911], "mapped", [29557]], [[63912, 63912], "mapped", [20196]], [[63913, 63913], "mapped", [22265]], [[63914, 63914], "mapped", [23527]], [[63915, 63915], "mapped", [23994]], [[63916, 63916], "mapped", [24604]], [[63917, 63917], "mapped", [29618]], [[63918, 63918], "mapped", [29801]], [[63919, 63919], "mapped", [32666]], [[63920, 63920], "mapped", [32838]], [[63921, 63921], "mapped", [37428]], [[63922, 63922], "mapped", [38646]], [[63923, 63923], "mapped", [38728]], [[63924, 63924], "mapped", [38936]], [[63925, 63925], "mapped", [20363]], [[63926, 63926], "mapped", [31150]], [[63927, 63927], "mapped", [37300]], [[63928, 63928], "mapped", [38584]], [[63929, 63929], "mapped", [24801]], [[63930, 63930], "mapped", [20102]], [[63931, 63931], "mapped", [20698]], [[63932, 63932], "mapped", [23534]], [[63933, 63933], "mapped", [23615]], [[63934, 63934], "mapped", [26009]], [[63935, 63935], "mapped", [27138]], [[63936, 63936], "mapped", [29134]], [[63937, 63937], "mapped", [30274]], [[63938, 63938], "mapped", [34044]], [[63939, 63939], "mapped", [36988]], [[63940, 63940], "mapped", [40845]], [[63941, 63941], "mapped", [26248]], [[63942, 63942], "mapped", [38446]], [[63943, 63943], "mapped", [21129]], [[63944, 63944], "mapped", [26491]], [[63945, 63945], "mapped", [26611]], [[63946, 63946], "mapped", [27969]], [[63947, 63947], "mapped", [28316]], [[63948, 63948], "mapped", [29705]], [[63949, 63949], "mapped", [30041]], [[63950, 63950], "mapped", [30827]], [[63951, 63951], "mapped", [32016]], [[63952, 63952], "mapped", [39006]], [[63953, 63953], "mapped", [20845]], [[63954, 63954], "mapped", [25134]], [[63955, 63955], "mapped", [38520]], [[63956, 63956], "mapped", [20523]], [[63957, 63957], "mapped", [23833]], [[63958, 63958], "mapped", [28138]], [[63959, 63959], "mapped", [36650]], [[63960, 63960], "mapped", [24459]], [[63961, 63961], "mapped", [24900]], [[63962, 63962], "mapped", [26647]], [[63963, 63963], "mapped", [29575]], [[63964, 63964], "mapped", [38534]], [[63965, 63965], "mapped", [21033]], [[63966, 63966], "mapped", [21519]], [[63967, 63967], "mapped", [23653]], [[63968, 63968], "mapped", [26131]], [[63969, 63969], "mapped", [26446]], [[63970, 63970], "mapped", [26792]], [[63971, 63971], "mapped", [27877]], [[63972, 63972], "mapped", [29702]], [[63973, 63973], "mapped", [30178]], [[63974, 63974], "mapped", [32633]], [[63975, 63975], "mapped", [35023]], [[63976, 63976], "mapped", [35041]], [[63977, 63977], "mapped", [37324]], [[63978, 63978], "mapped", [38626]], [[63979, 63979], "mapped", [21311]], [[63980, 63980], "mapped", [28346]], [[63981, 63981], "mapped", [21533]], [[63982, 63982], "mapped", [29136]], [[63983, 63983], "mapped", [29848]], [[63984, 63984], "mapped", [34298]], [[63985, 63985], "mapped", [38563]], [[63986, 63986], "mapped", [40023]], [[63987, 63987], "mapped", [40607]], [[63988, 63988], "mapped", [26519]], [[63989, 63989], "mapped", [28107]], [[63990, 63990], "mapped", [33256]], [[63991, 63991], "mapped", [31435]], [[63992, 63992], "mapped", [31520]], [[63993, 63993], "mapped", [31890]], [[63994, 63994], "mapped", [29376]], [[63995, 63995], "mapped", [28825]], [[63996, 63996], "mapped", [35672]], [[63997, 63997], "mapped", [20160]], [[63998, 63998], "mapped", [33590]], [[63999, 63999], "mapped", [21050]], [[64e3, 64e3], "mapped", [20999]], [[64001, 64001], "mapped", [24230]], [[64002, 64002], "mapped", [25299]], [[64003, 64003], "mapped", [31958]], [[64004, 64004], "mapped", [23429]], [[64005, 64005], "mapped", [27934]], [[64006, 64006], "mapped", [26292]], [[64007, 64007], "mapped", [36667]], [[64008, 64008], "mapped", [34892]], [[64009, 64009], "mapped", [38477]], [[64010, 64010], "mapped", [35211]], [[64011, 64011], "mapped", [24275]], [[64012, 64012], "mapped", [20800]], [[64013, 64013], "mapped", [21952]], [[64014, 64015], "valid"], [[64016, 64016], "mapped", [22618]], [[64017, 64017], "valid"], [[64018, 64018], "mapped", [26228]], [[64019, 64020], "valid"], [[64021, 64021], "mapped", [20958]], [[64022, 64022], "mapped", [29482]], [[64023, 64023], "mapped", [30410]], [[64024, 64024], "mapped", [31036]], [[64025, 64025], "mapped", [31070]], [[64026, 64026], "mapped", [31077]], [[64027, 64027], "mapped", [31119]], [[64028, 64028], "mapped", [38742]], [[64029, 64029], "mapped", [31934]], [[64030, 64030], "mapped", [32701]], [[64031, 64031], "valid"], [[64032, 64032], "mapped", [34322]], [[64033, 64033], "valid"], [[64034, 64034], "mapped", [35576]], [[64035, 64036], "valid"], [[64037, 64037], "mapped", [36920]], [[64038, 64038], "mapped", [37117]], [[64039, 64041], "valid"], [[64042, 64042], "mapped", [39151]], [[64043, 64043], "mapped", [39164]], [[64044, 64044], "mapped", [39208]], [[64045, 64045], "mapped", [40372]], [[64046, 64046], "mapped", [37086]], [[64047, 64047], "mapped", [38583]], [[64048, 64048], "mapped", [20398]], [[64049, 64049], "mapped", [20711]], [[64050, 64050], "mapped", [20813]], [[64051, 64051], "mapped", [21193]], [[64052, 64052], "mapped", [21220]], [[64053, 64053], "mapped", [21329]], [[64054, 64054], "mapped", [21917]], [[64055, 64055], "mapped", [22022]], [[64056, 64056], "mapped", [22120]], [[64057, 64057], "mapped", [22592]], [[64058, 64058], "mapped", [22696]], [[64059, 64059], "mapped", [23652]], [[64060, 64060], "mapped", [23662]], [[64061, 64061], "mapped", [24724]], [[64062, 64062], "mapped", [24936]], [[64063, 64063], "mapped", [24974]], [[64064, 64064], "mapped", [25074]], [[64065, 64065], "mapped", [25935]], [[64066, 64066], "mapped", [26082]], [[64067, 64067], "mapped", [26257]], [[64068, 64068], "mapped", [26757]], [[64069, 64069], "mapped", [28023]], [[64070, 64070], "mapped", [28186]], [[64071, 64071], "mapped", [28450]], [[64072, 64072], "mapped", [29038]], [[64073, 64073], "mapped", [29227]], [[64074, 64074], "mapped", [29730]], [[64075, 64075], "mapped", [30865]], [[64076, 64076], "mapped", [31038]], [[64077, 64077], "mapped", [31049]], [[64078, 64078], "mapped", [31048]], [[64079, 64079], "mapped", [31056]], [[64080, 64080], "mapped", [31062]], [[64081, 64081], "mapped", [31069]], [[64082, 64082], "mapped", [31117]], [[64083, 64083], "mapped", [31118]], [[64084, 64084], "mapped", [31296]], [[64085, 64085], "mapped", [31361]], [[64086, 64086], "mapped", [31680]], [[64087, 64087], "mapped", [32244]], [[64088, 64088], "mapped", [32265]], [[64089, 64089], "mapped", [32321]], [[64090, 64090], "mapped", [32626]], [[64091, 64091], "mapped", [32773]], [[64092, 64092], "mapped", [33261]], [[64093, 64094], "mapped", [33401]], [[64095, 64095], "mapped", [33879]], [[64096, 64096], "mapped", [35088]], [[64097, 64097], "mapped", [35222]], [[64098, 64098], "mapped", [35585]], [[64099, 64099], "mapped", [35641]], [[64100, 64100], "mapped", [36051]], [[64101, 64101], "mapped", [36104]], [[64102, 64102], "mapped", [36790]], [[64103, 64103], "mapped", [36920]], [[64104, 64104], "mapped", [38627]], [[64105, 64105], "mapped", [38911]], [[64106, 64106], "mapped", [38971]], [[64107, 64107], "mapped", [24693]], [[64108, 64108], "mapped", [148206]], [[64109, 64109], "mapped", [33304]], [[64110, 64111], "disallowed"], [[64112, 64112], "mapped", [20006]], [[64113, 64113], "mapped", [20917]], [[64114, 64114], "mapped", [20840]], [[64115, 64115], "mapped", [20352]], [[64116, 64116], "mapped", [20805]], [[64117, 64117], "mapped", [20864]], [[64118, 64118], "mapped", [21191]], [[64119, 64119], "mapped", [21242]], [[64120, 64120], "mapped", [21917]], [[64121, 64121], "mapped", [21845]], [[64122, 64122], "mapped", [21913]], [[64123, 64123], "mapped", [21986]], [[64124, 64124], "mapped", [22618]], [[64125, 64125], "mapped", [22707]], [[64126, 64126], "mapped", [22852]], [[64127, 64127], "mapped", [22868]], [[64128, 64128], "mapped", [23138]], [[64129, 64129], "mapped", [23336]], [[64130, 64130], "mapped", [24274]], [[64131, 64131], "mapped", [24281]], [[64132, 64132], "mapped", [24425]], [[64133, 64133], "mapped", [24493]], [[64134, 64134], "mapped", [24792]], [[64135, 64135], "mapped", [24910]], [[64136, 64136], "mapped", [24840]], [[64137, 64137], "mapped", [24974]], [[64138, 64138], "mapped", [24928]], [[64139, 64139], "mapped", [25074]], [[64140, 64140], "mapped", [25140]], [[64141, 64141], "mapped", [25540]], [[64142, 64142], "mapped", [25628]], [[64143, 64143], "mapped", [25682]], [[64144, 64144], "mapped", [25942]], [[64145, 64145], "mapped", [26228]], [[64146, 64146], "mapped", [26391]], [[64147, 64147], "mapped", [26395]], [[64148, 64148], "mapped", [26454]], [[64149, 64149], "mapped", [27513]], [[64150, 64150], "mapped", [27578]], [[64151, 64151], "mapped", [27969]], [[64152, 64152], "mapped", [28379]], [[64153, 64153], "mapped", [28363]], [[64154, 64154], "mapped", [28450]], [[64155, 64155], "mapped", [28702]], [[64156, 64156], "mapped", [29038]], [[64157, 64157], "mapped", [30631]], [[64158, 64158], "mapped", [29237]], [[64159, 64159], "mapped", [29359]], [[64160, 64160], "mapped", [29482]], [[64161, 64161], "mapped", [29809]], [[64162, 64162], "mapped", [29958]], [[64163, 64163], "mapped", [30011]], [[64164, 64164], "mapped", [30237]], [[64165, 64165], "mapped", [30239]], [[64166, 64166], "mapped", [30410]], [[64167, 64167], "mapped", [30427]], [[64168, 64168], "mapped", [30452]], [[64169, 64169], "mapped", [30538]], [[64170, 64170], "mapped", [30528]], [[64171, 64171], "mapped", [30924]], [[64172, 64172], "mapped", [31409]], [[64173, 64173], "mapped", [31680]], [[64174, 64174], "mapped", [31867]], [[64175, 64175], "mapped", [32091]], [[64176, 64176], "mapped", [32244]], [[64177, 64177], "mapped", [32574]], [[64178, 64178], "mapped", [32773]], [[64179, 64179], "mapped", [33618]], [[64180, 64180], "mapped", [33775]], [[64181, 64181], "mapped", [34681]], [[64182, 64182], "mapped", [35137]], [[64183, 64183], "mapped", [35206]], [[64184, 64184], "mapped", [35222]], [[64185, 64185], "mapped", [35519]], [[64186, 64186], "mapped", [35576]], [[64187, 64187], "mapped", [35531]], [[64188, 64188], "mapped", [35585]], [[64189, 64189], "mapped", [35582]], [[64190, 64190], "mapped", [35565]], [[64191, 64191], "mapped", [35641]], [[64192, 64192], "mapped", [35722]], [[64193, 64193], "mapped", [36104]], [[64194, 64194], "mapped", [36664]], [[64195, 64195], "mapped", [36978]], [[64196, 64196], "mapped", [37273]], [[64197, 64197], "mapped", [37494]], [[64198, 64198], "mapped", [38524]], [[64199, 64199], "mapped", [38627]], [[64200, 64200], "mapped", [38742]], [[64201, 64201], "mapped", [38875]], [[64202, 64202], "mapped", [38911]], [[64203, 64203], "mapped", [38923]], [[64204, 64204], "mapped", [38971]], [[64205, 64205], "mapped", [39698]], [[64206, 64206], "mapped", [40860]], [[64207, 64207], "mapped", [141386]], [[64208, 64208], "mapped", [141380]], [[64209, 64209], "mapped", [144341]], [[64210, 64210], "mapped", [15261]], [[64211, 64211], "mapped", [16408]], [[64212, 64212], "mapped", [16441]], [[64213, 64213], "mapped", [152137]], [[64214, 64214], "mapped", [154832]], [[64215, 64215], "mapped", [163539]], [[64216, 64216], "mapped", [40771]], [[64217, 64217], "mapped", [40846]], [[64218, 64255], "disallowed"], [[64256, 64256], "mapped", [102, 102]], [[64257, 64257], "mapped", [102, 105]], [[64258, 64258], "mapped", [102, 108]], [[64259, 64259], "mapped", [102, 102, 105]], [[64260, 64260], "mapped", [102, 102, 108]], [[64261, 64262], "mapped", [115, 116]], [[64263, 64274], "disallowed"], [[64275, 64275], "mapped", [1396, 1398]], [[64276, 64276], "mapped", [1396, 1381]], [[64277, 64277], "mapped", [1396, 1387]], [[64278, 64278], "mapped", [1406, 1398]], [[64279, 64279], "mapped", [1396, 1389]], [[64280, 64284], "disallowed"], [[64285, 64285], "mapped", [1497, 1460]], [[64286, 64286], "valid"], [[64287, 64287], "mapped", [1522, 1463]], [[64288, 64288], "mapped", [1506]], [[64289, 64289], "mapped", [1488]], [[64290, 64290], "mapped", [1491]], [[64291, 64291], "mapped", [1492]], [[64292, 64292], "mapped", [1499]], [[64293, 64293], "mapped", [1500]], [[64294, 64294], "mapped", [1501]], [[64295, 64295], "mapped", [1512]], [[64296, 64296], "mapped", [1514]], [[64297, 64297], "disallowed_STD3_mapped", [43]], [[64298, 64298], "mapped", [1513, 1473]], [[64299, 64299], "mapped", [1513, 1474]], [[64300, 64300], "mapped", [1513, 1468, 1473]], [[64301, 64301], "mapped", [1513, 1468, 1474]], [[64302, 64302], "mapped", [1488, 1463]], [[64303, 64303], "mapped", [1488, 1464]], [[64304, 64304], "mapped", [1488, 1468]], [[64305, 64305], "mapped", [1489, 1468]], [[64306, 64306], "mapped", [1490, 1468]], [[64307, 64307], "mapped", [1491, 1468]], [[64308, 64308], "mapped", [1492, 1468]], [[64309, 64309], "mapped", [1493, 1468]], [[64310, 64310], "mapped", [1494, 1468]], [[64311, 64311], "disallowed"], [[64312, 64312], "mapped", [1496, 1468]], [[64313, 64313], "mapped", [1497, 1468]], [[64314, 64314], "mapped", [1498, 1468]], [[64315, 64315], "mapped", [1499, 1468]], [[64316, 64316], "mapped", [1500, 1468]], [[64317, 64317], "disallowed"], [[64318, 64318], "mapped", [1502, 1468]], [[64319, 64319], "disallowed"], [[64320, 64320], "mapped", [1504, 1468]], [[64321, 64321], "mapped", [1505, 1468]], [[64322, 64322], "disallowed"], [[64323, 64323], "mapped", [1507, 1468]], [[64324, 64324], "mapped", [1508, 1468]], [[64325, 64325], "disallowed"], [[64326, 64326], "mapped", [1510, 1468]], [[64327, 64327], "mapped", [1511, 1468]], [[64328, 64328], "mapped", [1512, 1468]], [[64329, 64329], "mapped", [1513, 1468]], [[64330, 64330], "mapped", [1514, 1468]], [[64331, 64331], "mapped", [1493, 1465]], [[64332, 64332], "mapped", [1489, 1471]], [[64333, 64333], "mapped", [1499, 1471]], [[64334, 64334], "mapped", [1508, 1471]], [[64335, 64335], "mapped", [1488, 1500]], [[64336, 64337], "mapped", [1649]], [[64338, 64341], "mapped", [1659]], [[64342, 64345], "mapped", [1662]], [[64346, 64349], "mapped", [1664]], [[64350, 64353], "mapped", [1658]], [[64354, 64357], "mapped", [1663]], [[64358, 64361], "mapped", [1657]], [[64362, 64365], "mapped", [1700]], [[64366, 64369], "mapped", [1702]], [[64370, 64373], "mapped", [1668]], [[64374, 64377], "mapped", [1667]], [[64378, 64381], "mapped", [1670]], [[64382, 64385], "mapped", [1671]], [[64386, 64387], "mapped", [1677]], [[64388, 64389], "mapped", [1676]], [[64390, 64391], "mapped", [1678]], [[64392, 64393], "mapped", [1672]], [[64394, 64395], "mapped", [1688]], [[64396, 64397], "mapped", [1681]], [[64398, 64401], "mapped", [1705]], [[64402, 64405], "mapped", [1711]], [[64406, 64409], "mapped", [1715]], [[64410, 64413], "mapped", [1713]], [[64414, 64415], "mapped", [1722]], [[64416, 64419], "mapped", [1723]], [[64420, 64421], "mapped", [1728]], [[64422, 64425], "mapped", [1729]], [[64426, 64429], "mapped", [1726]], [[64430, 64431], "mapped", [1746]], [[64432, 64433], "mapped", [1747]], [[64434, 64449], "valid", [], "NV8"], [[64450, 64466], "disallowed"], [[64467, 64470], "mapped", [1709]], [[64471, 64472], "mapped", [1735]], [[64473, 64474], "mapped", [1734]], [[64475, 64476], "mapped", [1736]], [[64477, 64477], "mapped", [1735, 1652]], [[64478, 64479], "mapped", [1739]], [[64480, 64481], "mapped", [1733]], [[64482, 64483], "mapped", [1737]], [[64484, 64487], "mapped", [1744]], [[64488, 64489], "mapped", [1609]], [[64490, 64491], "mapped", [1574, 1575]], [[64492, 64493], "mapped", [1574, 1749]], [[64494, 64495], "mapped", [1574, 1608]], [[64496, 64497], "mapped", [1574, 1735]], [[64498, 64499], "mapped", [1574, 1734]], [[64500, 64501], "mapped", [1574, 1736]], [[64502, 64504], "mapped", [1574, 1744]], [[64505, 64507], "mapped", [1574, 1609]], [[64508, 64511], "mapped", [1740]], [[64512, 64512], "mapped", [1574, 1580]], [[64513, 64513], "mapped", [1574, 1581]], [[64514, 64514], "mapped", [1574, 1605]], [[64515, 64515], "mapped", [1574, 1609]], [[64516, 64516], "mapped", [1574, 1610]], [[64517, 64517], "mapped", [1576, 1580]], [[64518, 64518], "mapped", [1576, 1581]], [[64519, 64519], "mapped", [1576, 1582]], [[64520, 64520], "mapped", [1576, 1605]], [[64521, 64521], "mapped", [1576, 1609]], [[64522, 64522], "mapped", [1576, 1610]], [[64523, 64523], "mapped", [1578, 1580]], [[64524, 64524], "mapped", [1578, 1581]], [[64525, 64525], "mapped", [1578, 1582]], [[64526, 64526], "mapped", [1578, 1605]], [[64527, 64527], "mapped", [1578, 1609]], [[64528, 64528], "mapped", [1578, 1610]], [[64529, 64529], "mapped", [1579, 1580]], [[64530, 64530], "mapped", [1579, 1605]], [[64531, 64531], "mapped", [1579, 1609]], [[64532, 64532], "mapped", [1579, 1610]], [[64533, 64533], "mapped", [1580, 1581]], [[64534, 64534], "mapped", [1580, 1605]], [[64535, 64535], "mapped", [1581, 1580]], [[64536, 64536], "mapped", [1581, 1605]], [[64537, 64537], "mapped", [1582, 1580]], [[64538, 64538], "mapped", [1582, 1581]], [[64539, 64539], "mapped", [1582, 1605]], [[64540, 64540], "mapped", [1587, 1580]], [[64541, 64541], "mapped", [1587, 1581]], [[64542, 64542], "mapped", [1587, 1582]], [[64543, 64543], "mapped", [1587, 1605]], [[64544, 64544], "mapped", [1589, 1581]], [[64545, 64545], "mapped", [1589, 1605]], [[64546, 64546], "mapped", [1590, 1580]], [[64547, 64547], "mapped", [1590, 1581]], [[64548, 64548], "mapped", [1590, 1582]], [[64549, 64549], "mapped", [1590, 1605]], [[64550, 64550], "mapped", [1591, 1581]], [[64551, 64551], "mapped", [1591, 1605]], [[64552, 64552], "mapped", [1592, 1605]], [[64553, 64553], "mapped", [1593, 1580]], [[64554, 64554], "mapped", [1593, 1605]], [[64555, 64555], "mapped", [1594, 1580]], [[64556, 64556], "mapped", [1594, 1605]], [[64557, 64557], "mapped", [1601, 1580]], [[64558, 64558], "mapped", [1601, 1581]], [[64559, 64559], "mapped", [1601, 1582]], [[64560, 64560], "mapped", [1601, 1605]], [[64561, 64561], "mapped", [1601, 1609]], [[64562, 64562], "mapped", [1601, 1610]], [[64563, 64563], "mapped", [1602, 1581]], [[64564, 64564], "mapped", [1602, 1605]], [[64565, 64565], "mapped", [1602, 1609]], [[64566, 64566], "mapped", [1602, 1610]], [[64567, 64567], "mapped", [1603, 1575]], [[64568, 64568], "mapped", [1603, 1580]], [[64569, 64569], "mapped", [1603, 1581]], [[64570, 64570], "mapped", [1603, 1582]], [[64571, 64571], "mapped", [1603, 1604]], [[64572, 64572], "mapped", [1603, 1605]], [[64573, 64573], "mapped", [1603, 1609]], [[64574, 64574], "mapped", [1603, 1610]], [[64575, 64575], "mapped", [1604, 1580]], [[64576, 64576], "mapped", [1604, 1581]], [[64577, 64577], "mapped", [1604, 1582]], [[64578, 64578], "mapped", [1604, 1605]], [[64579, 64579], "mapped", [1604, 1609]], [[64580, 64580], "mapped", [1604, 1610]], [[64581, 64581], "mapped", [1605, 1580]], [[64582, 64582], "mapped", [1605, 1581]], [[64583, 64583], "mapped", [1605, 1582]], [[64584, 64584], "mapped", [1605, 1605]], [[64585, 64585], "mapped", [1605, 1609]], [[64586, 64586], "mapped", [1605, 1610]], [[64587, 64587], "mapped", [1606, 1580]], [[64588, 64588], "mapped", [1606, 1581]], [[64589, 64589], "mapped", [1606, 1582]], [[64590, 64590], "mapped", [1606, 1605]], [[64591, 64591], "mapped", [1606, 1609]], [[64592, 64592], "mapped", [1606, 1610]], [[64593, 64593], "mapped", [1607, 1580]], [[64594, 64594], "mapped", [1607, 1605]], [[64595, 64595], "mapped", [1607, 1609]], [[64596, 64596], "mapped", [1607, 1610]], [[64597, 64597], "mapped", [1610, 1580]], [[64598, 64598], "mapped", [1610, 1581]], [[64599, 64599], "mapped", [1610, 1582]], [[64600, 64600], "mapped", [1610, 1605]], [[64601, 64601], "mapped", [1610, 1609]], [[64602, 64602], "mapped", [1610, 1610]], [[64603, 64603], "mapped", [1584, 1648]], [[64604, 64604], "mapped", [1585, 1648]], [[64605, 64605], "mapped", [1609, 1648]], [[64606, 64606], "disallowed_STD3_mapped", [32, 1612, 1617]], [[64607, 64607], "disallowed_STD3_mapped", [32, 1613, 1617]], [[64608, 64608], "disallowed_STD3_mapped", [32, 1614, 1617]], [[64609, 64609], "disallowed_STD3_mapped", [32, 1615, 1617]], [[64610, 64610], "disallowed_STD3_mapped", [32, 1616, 1617]], [[64611, 64611], "disallowed_STD3_mapped", [32, 1617, 1648]], [[64612, 64612], "mapped", [1574, 1585]], [[64613, 64613], "mapped", [1574, 1586]], [[64614, 64614], "mapped", [1574, 1605]], [[64615, 64615], "mapped", [1574, 1606]], [[64616, 64616], "mapped", [1574, 1609]], [[64617, 64617], "mapped", [1574, 1610]], [[64618, 64618], "mapped", [1576, 1585]], [[64619, 64619], "mapped", [1576, 1586]], [[64620, 64620], "mapped", [1576, 1605]], [[64621, 64621], "mapped", [1576, 1606]], [[64622, 64622], "mapped", [1576, 1609]], [[64623, 64623], "mapped", [1576, 1610]], [[64624, 64624], "mapped", [1578, 1585]], [[64625, 64625], "mapped", [1578, 1586]], [[64626, 64626], "mapped", [1578, 1605]], [[64627, 64627], "mapped", [1578, 1606]], [[64628, 64628], "mapped", [1578, 1609]], [[64629, 64629], "mapped", [1578, 1610]], [[64630, 64630], "mapped", [1579, 1585]], [[64631, 64631], "mapped", [1579, 1586]], [[64632, 64632], "mapped", [1579, 1605]], [[64633, 64633], "mapped", [1579, 1606]], [[64634, 64634], "mapped", [1579, 1609]], [[64635, 64635], "mapped", [1579, 1610]], [[64636, 64636], "mapped", [1601, 1609]], [[64637, 64637], "mapped", [1601, 1610]], [[64638, 64638], "mapped", [1602, 1609]], [[64639, 64639], "mapped", [1602, 1610]], [[64640, 64640], "mapped", [1603, 1575]], [[64641, 64641], "mapped", [1603, 1604]], [[64642, 64642], "mapped", [1603, 1605]], [[64643, 64643], "mapped", [1603, 1609]], [[64644, 64644], "mapped", [1603, 1610]], [[64645, 64645], "mapped", [1604, 1605]], [[64646, 64646], "mapped", [1604, 1609]], [[64647, 64647], "mapped", [1604, 1610]], [[64648, 64648], "mapped", [1605, 1575]], [[64649, 64649], "mapped", [1605, 1605]], [[64650, 64650], "mapped", [1606, 1585]], [[64651, 64651], "mapped", [1606, 1586]], [[64652, 64652], "mapped", [1606, 1605]], [[64653, 64653], "mapped", [1606, 1606]], [[64654, 64654], "mapped", [1606, 1609]], [[64655, 64655], "mapped", [1606, 1610]], [[64656, 64656], "mapped", [1609, 1648]], [[64657, 64657], "mapped", [1610, 1585]], [[64658, 64658], "mapped", [1610, 1586]], [[64659, 64659], "mapped", [1610, 1605]], [[64660, 64660], "mapped", [1610, 1606]], [[64661, 64661], "mapped", [1610, 1609]], [[64662, 64662], "mapped", [1610, 1610]], [[64663, 64663], "mapped", [1574, 1580]], [[64664, 64664], "mapped", [1574, 1581]], [[64665, 64665], "mapped", [1574, 1582]], [[64666, 64666], "mapped", [1574, 1605]], [[64667, 64667], "mapped", [1574, 1607]], [[64668, 64668], "mapped", [1576, 1580]], [[64669, 64669], "mapped", [1576, 1581]], [[64670, 64670], "mapped", [1576, 1582]], [[64671, 64671], "mapped", [1576, 1605]], [[64672, 64672], "mapped", [1576, 1607]], [[64673, 64673], "mapped", [1578, 1580]], [[64674, 64674], "mapped", [1578, 1581]], [[64675, 64675], "mapped", [1578, 1582]], [[64676, 64676], "mapped", [1578, 1605]], [[64677, 64677], "mapped", [1578, 1607]], [[64678, 64678], "mapped", [1579, 1605]], [[64679, 64679], "mapped", [1580, 1581]], [[64680, 64680], "mapped", [1580, 1605]], [[64681, 64681], "mapped", [1581, 1580]], [[64682, 64682], "mapped", [1581, 1605]], [[64683, 64683], "mapped", [1582, 1580]], [[64684, 64684], "mapped", [1582, 1605]], [[64685, 64685], "mapped", [1587, 1580]], [[64686, 64686], "mapped", [1587, 1581]], [[64687, 64687], "mapped", [1587, 1582]], [[64688, 64688], "mapped", [1587, 1605]], [[64689, 64689], "mapped", [1589, 1581]], [[64690, 64690], "mapped", [1589, 1582]], [[64691, 64691], "mapped", [1589, 1605]], [[64692, 64692], "mapped", [1590, 1580]], [[64693, 64693], "mapped", [1590, 1581]], [[64694, 64694], "mapped", [1590, 1582]], [[64695, 64695], "mapped", [1590, 1605]], [[64696, 64696], "mapped", [1591, 1581]], [[64697, 64697], "mapped", [1592, 1605]], [[64698, 64698], "mapped", [1593, 1580]], [[64699, 64699], "mapped", [1593, 1605]], [[64700, 64700], "mapped", [1594, 1580]], [[64701, 64701], "mapped", [1594, 1605]], [[64702, 64702], "mapped", [1601, 1580]], [[64703, 64703], "mapped", [1601, 1581]], [[64704, 64704], "mapped", [1601, 1582]], [[64705, 64705], "mapped", [1601, 1605]], [[64706, 64706], "mapped", [1602, 1581]], [[64707, 64707], "mapped", [1602, 1605]], [[64708, 64708], "mapped", [1603, 1580]], [[64709, 64709], "mapped", [1603, 1581]], [[64710, 64710], "mapped", [1603, 1582]], [[64711, 64711], "mapped", [1603, 1604]], [[64712, 64712], "mapped", [1603, 1605]], [[64713, 64713], "mapped", [1604, 1580]], [[64714, 64714], "mapped", [1604, 1581]], [[64715, 64715], "mapped", [1604, 1582]], [[64716, 64716], "mapped", [1604, 1605]], [[64717, 64717], "mapped", [1604, 1607]], [[64718, 64718], "mapped", [1605, 1580]], [[64719, 64719], "mapped", [1605, 1581]], [[64720, 64720], "mapped", [1605, 1582]], [[64721, 64721], "mapped", [1605, 1605]], [[64722, 64722], "mapped", [1606, 1580]], [[64723, 64723], "mapped", [1606, 1581]], [[64724, 64724], "mapped", [1606, 1582]], [[64725, 64725], "mapped", [1606, 1605]], [[64726, 64726], "mapped", [1606, 1607]], [[64727, 64727], "mapped", [1607, 1580]], [[64728, 64728], "mapped", [1607, 1605]], [[64729, 64729], "mapped", [1607, 1648]], [[64730, 64730], "mapped", [1610, 1580]], [[64731, 64731], "mapped", [1610, 1581]], [[64732, 64732], "mapped", [1610, 1582]], [[64733, 64733], "mapped", [1610, 1605]], [[64734, 64734], "mapped", [1610, 1607]], [[64735, 64735], "mapped", [1574, 1605]], [[64736, 64736], "mapped", [1574, 1607]], [[64737, 64737], "mapped", [1576, 1605]], [[64738, 64738], "mapped", [1576, 1607]], [[64739, 64739], "mapped", [1578, 1605]], [[64740, 64740], "mapped", [1578, 1607]], [[64741, 64741], "mapped", [1579, 1605]], [[64742, 64742], "mapped", [1579, 1607]], [[64743, 64743], "mapped", [1587, 1605]], [[64744, 64744], "mapped", [1587, 1607]], [[64745, 64745], "mapped", [1588, 1605]], [[64746, 64746], "mapped", [1588, 1607]], [[64747, 64747], "mapped", [1603, 1604]], [[64748, 64748], "mapped", [1603, 1605]], [[64749, 64749], "mapped", [1604, 1605]], [[64750, 64750], "mapped", [1606, 1605]], [[64751, 64751], "mapped", [1606, 1607]], [[64752, 64752], "mapped", [1610, 1605]], [[64753, 64753], "mapped", [1610, 1607]], [[64754, 64754], "mapped", [1600, 1614, 1617]], [[64755, 64755], "mapped", [1600, 1615, 1617]], [[64756, 64756], "mapped", [1600, 1616, 1617]], [[64757, 64757], "mapped", [1591, 1609]], [[64758, 64758], "mapped", [1591, 1610]], [[64759, 64759], "mapped", [1593, 1609]], [[64760, 64760], "mapped", [1593, 1610]], [[64761, 64761], "mapped", [1594, 1609]], [[64762, 64762], "mapped", [1594, 1610]], [[64763, 64763], "mapped", [1587, 1609]], [[64764, 64764], "mapped", [1587, 1610]], [[64765, 64765], "mapped", [1588, 1609]], [[64766, 64766], "mapped", [1588, 1610]], [[64767, 64767], "mapped", [1581, 1609]], [[64768, 64768], "mapped", [1581, 1610]], [[64769, 64769], "mapped", [1580, 1609]], [[64770, 64770], "mapped", [1580, 1610]], [[64771, 64771], "mapped", [1582, 1609]], [[64772, 64772], "mapped", [1582, 1610]], [[64773, 64773], "mapped", [1589, 1609]], [[64774, 64774], "mapped", [1589, 1610]], [[64775, 64775], "mapped", [1590, 1609]], [[64776, 64776], "mapped", [1590, 1610]], [[64777, 64777], "mapped", [1588, 1580]], [[64778, 64778], "mapped", [1588, 1581]], [[64779, 64779], "mapped", [1588, 1582]], [[64780, 64780], "mapped", [1588, 1605]], [[64781, 64781], "mapped", [1588, 1585]], [[64782, 64782], "mapped", [1587, 1585]], [[64783, 64783], "mapped", [1589, 1585]], [[64784, 64784], "mapped", [1590, 1585]], [[64785, 64785], "mapped", [1591, 1609]], [[64786, 64786], "mapped", [1591, 1610]], [[64787, 64787], "mapped", [1593, 1609]], [[64788, 64788], "mapped", [1593, 1610]], [[64789, 64789], "mapped", [1594, 1609]], [[64790, 64790], "mapped", [1594, 1610]], [[64791, 64791], "mapped", [1587, 1609]], [[64792, 64792], "mapped", [1587, 1610]], [[64793, 64793], "mapped", [1588, 1609]], [[64794, 64794], "mapped", [1588, 1610]], [[64795, 64795], "mapped", [1581, 1609]], [[64796, 64796], "mapped", [1581, 1610]], [[64797, 64797], "mapped", [1580, 1609]], [[64798, 64798], "mapped", [1580, 1610]], [[64799, 64799], "mapped", [1582, 1609]], [[64800, 64800], "mapped", [1582, 1610]], [[64801, 64801], "mapped", [1589, 1609]], [[64802, 64802], "mapped", [1589, 1610]], [[64803, 64803], "mapped", [1590, 1609]], [[64804, 64804], "mapped", [1590, 1610]], [[64805, 64805], "mapped", [1588, 1580]], [[64806, 64806], "mapped", [1588, 1581]], [[64807, 64807], "mapped", [1588, 1582]], [[64808, 64808], "mapped", [1588, 1605]], [[64809, 64809], "mapped", [1588, 1585]], [[64810, 64810], "mapped", [1587, 1585]], [[64811, 64811], "mapped", [1589, 1585]], [[64812, 64812], "mapped", [1590, 1585]], [[64813, 64813], "mapped", [1588, 1580]], [[64814, 64814], "mapped", [1588, 1581]], [[64815, 64815], "mapped", [1588, 1582]], [[64816, 64816], "mapped", [1588, 1605]], [[64817, 64817], "mapped", [1587, 1607]], [[64818, 64818], "mapped", [1588, 1607]], [[64819, 64819], "mapped", [1591, 1605]], [[64820, 64820], "mapped", [1587, 1580]], [[64821, 64821], "mapped", [1587, 1581]], [[64822, 64822], "mapped", [1587, 1582]], [[64823, 64823], "mapped", [1588, 1580]], [[64824, 64824], "mapped", [1588, 1581]], [[64825, 64825], "mapped", [1588, 1582]], [[64826, 64826], "mapped", [1591, 1605]], [[64827, 64827], "mapped", [1592, 1605]], [[64828, 64829], "mapped", [1575, 1611]], [[64830, 64831], "valid", [], "NV8"], [[64832, 64847], "disallowed"], [[64848, 64848], "mapped", [1578, 1580, 1605]], [[64849, 64850], "mapped", [1578, 1581, 1580]], [[64851, 64851], "mapped", [1578, 1581, 1605]], [[64852, 64852], "mapped", [1578, 1582, 1605]], [[64853, 64853], "mapped", [1578, 1605, 1580]], [[64854, 64854], "mapped", [1578, 1605, 1581]], [[64855, 64855], "mapped", [1578, 1605, 1582]], [[64856, 64857], "mapped", [1580, 1605, 1581]], [[64858, 64858], "mapped", [1581, 1605, 1610]], [[64859, 64859], "mapped", [1581, 1605, 1609]], [[64860, 64860], "mapped", [1587, 1581, 1580]], [[64861, 64861], "mapped", [1587, 1580, 1581]], [[64862, 64862], "mapped", [1587, 1580, 1609]], [[64863, 64864], "mapped", [1587, 1605, 1581]], [[64865, 64865], "mapped", [1587, 1605, 1580]], [[64866, 64867], "mapped", [1587, 1605, 1605]], [[64868, 64869], "mapped", [1589, 1581, 1581]], [[64870, 64870], "mapped", [1589, 1605, 1605]], [[64871, 64872], "mapped", [1588, 1581, 1605]], [[64873, 64873], "mapped", [1588, 1580, 1610]], [[64874, 64875], "mapped", [1588, 1605, 1582]], [[64876, 64877], "mapped", [1588, 1605, 1605]], [[64878, 64878], "mapped", [1590, 1581, 1609]], [[64879, 64880], "mapped", [1590, 1582, 1605]], [[64881, 64882], "mapped", [1591, 1605, 1581]], [[64883, 64883], "mapped", [1591, 1605, 1605]], [[64884, 64884], "mapped", [1591, 1605, 1610]], [[64885, 64885], "mapped", [1593, 1580, 1605]], [[64886, 64887], "mapped", [1593, 1605, 1605]], [[64888, 64888], "mapped", [1593, 1605, 1609]], [[64889, 64889], "mapped", [1594, 1605, 1605]], [[64890, 64890], "mapped", [1594, 1605, 1610]], [[64891, 64891], "mapped", [1594, 1605, 1609]], [[64892, 64893], "mapped", [1601, 1582, 1605]], [[64894, 64894], "mapped", [1602, 1605, 1581]], [[64895, 64895], "mapped", [1602, 1605, 1605]], [[64896, 64896], "mapped", [1604, 1581, 1605]], [[64897, 64897], "mapped", [1604, 1581, 1610]], [[64898, 64898], "mapped", [1604, 1581, 1609]], [[64899, 64900], "mapped", [1604, 1580, 1580]], [[64901, 64902], "mapped", [1604, 1582, 1605]], [[64903, 64904], "mapped", [1604, 1605, 1581]], [[64905, 64905], "mapped", [1605, 1581, 1580]], [[64906, 64906], "mapped", [1605, 1581, 1605]], [[64907, 64907], "mapped", [1605, 1581, 1610]], [[64908, 64908], "mapped", [1605, 1580, 1581]], [[64909, 64909], "mapped", [1605, 1580, 1605]], [[64910, 64910], "mapped", [1605, 1582, 1580]], [[64911, 64911], "mapped", [1605, 1582, 1605]], [[64912, 64913], "disallowed"], [[64914, 64914], "mapped", [1605, 1580, 1582]], [[64915, 64915], "mapped", [1607, 1605, 1580]], [[64916, 64916], "mapped", [1607, 1605, 1605]], [[64917, 64917], "mapped", [1606, 1581, 1605]], [[64918, 64918], "mapped", [1606, 1581, 1609]], [[64919, 64920], "mapped", [1606, 1580, 1605]], [[64921, 64921], "mapped", [1606, 1580, 1609]], [[64922, 64922], "mapped", [1606, 1605, 1610]], [[64923, 64923], "mapped", [1606, 1605, 1609]], [[64924, 64925], "mapped", [1610, 1605, 1605]], [[64926, 64926], "mapped", [1576, 1582, 1610]], [[64927, 64927], "mapped", [1578, 1580, 1610]], [[64928, 64928], "mapped", [1578, 1580, 1609]], [[64929, 64929], "mapped", [1578, 1582, 1610]], [[64930, 64930], "mapped", [1578, 1582, 1609]], [[64931, 64931], "mapped", [1578, 1605, 1610]], [[64932, 64932], "mapped", [1578, 1605, 1609]], [[64933, 64933], "mapped", [1580, 1605, 1610]], [[64934, 64934], "mapped", [1580, 1581, 1609]], [[64935, 64935], "mapped", [1580, 1605, 1609]], [[64936, 64936], "mapped", [1587, 1582, 1609]], [[64937, 64937], "mapped", [1589, 1581, 1610]], [[64938, 64938], "mapped", [1588, 1581, 1610]], [[64939, 64939], "mapped", [1590, 1581, 1610]], [[64940, 64940], "mapped", [1604, 1580, 1610]], [[64941, 64941], "mapped", [1604, 1605, 1610]], [[64942, 64942], "mapped", [1610, 1581, 1610]], [[64943, 64943], "mapped", [1610, 1580, 1610]], [[64944, 64944], "mapped", [1610, 1605, 1610]], [[64945, 64945], "mapped", [1605, 1605, 1610]], [[64946, 64946], "mapped", [1602, 1605, 1610]], [[64947, 64947], "mapped", [1606, 1581, 1610]], [[64948, 64948], "mapped", [1602, 1605, 1581]], [[64949, 64949], "mapped", [1604, 1581, 1605]], [[64950, 64950], "mapped", [1593, 1605, 1610]], [[64951, 64951], "mapped", [1603, 1605, 1610]], [[64952, 64952], "mapped", [1606, 1580, 1581]], [[64953, 64953], "mapped", [1605, 1582, 1610]], [[64954, 64954], "mapped", [1604, 1580, 1605]], [[64955, 64955], "mapped", [1603, 1605, 1605]], [[64956, 64956], "mapped", [1604, 1580, 1605]], [[64957, 64957], "mapped", [1606, 1580, 1581]], [[64958, 64958], "mapped", [1580, 1581, 1610]], [[64959, 64959], "mapped", [1581, 1580, 1610]], [[64960, 64960], "mapped", [1605, 1580, 1610]], [[64961, 64961], "mapped", [1601, 1605, 1610]], [[64962, 64962], "mapped", [1576, 1581, 1610]], [[64963, 64963], "mapped", [1603, 1605, 1605]], [[64964, 64964], "mapped", [1593, 1580, 1605]], [[64965, 64965], "mapped", [1589, 1605, 1605]], [[64966, 64966], "mapped", [1587, 1582, 1610]], [[64967, 64967], "mapped", [1606, 1580, 1610]], [[64968, 64975], "disallowed"], [[64976, 65007], "disallowed"], [[65008, 65008], "mapped", [1589, 1604, 1746]], [[65009, 65009], "mapped", [1602, 1604, 1746]], [[65010, 65010], "mapped", [1575, 1604, 1604, 1607]], [[65011, 65011], "mapped", [1575, 1603, 1576, 1585]], [[65012, 65012], "mapped", [1605, 1581, 1605, 1583]], [[65013, 65013], "mapped", [1589, 1604, 1593, 1605]], [[65014, 65014], "mapped", [1585, 1587, 1608, 1604]], [[65015, 65015], "mapped", [1593, 1604, 1610, 1607]], [[65016, 65016], "mapped", [1608, 1587, 1604, 1605]], [[65017, 65017], "mapped", [1589, 1604, 1609]], [[65018, 65018], "disallowed_STD3_mapped", [1589, 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605]], [[65019, 65019], "disallowed_STD3_mapped", [1580, 1604, 32, 1580, 1604, 1575, 1604, 1607]], [[65020, 65020], "mapped", [1585, 1740, 1575, 1604]], [[65021, 65021], "valid", [], "NV8"], [[65022, 65023], "disallowed"], [[65024, 65039], "ignored"], [[65040, 65040], "disallowed_STD3_mapped", [44]], [[65041, 65041], "mapped", [12289]], [[65042, 65042], "disallowed"], [[65043, 65043], "disallowed_STD3_mapped", [58]], [[65044, 65044], "disallowed_STD3_mapped", [59]], [[65045, 65045], "disallowed_STD3_mapped", [33]], [[65046, 65046], "disallowed_STD3_mapped", [63]], [[65047, 65047], "mapped", [12310]], [[65048, 65048], "mapped", [12311]], [[65049, 65049], "disallowed"], [[65050, 65055], "disallowed"], [[65056, 65059], "valid"], [[65060, 65062], "valid"], [[65063, 65069], "valid"], [[65070, 65071], "valid"], [[65072, 65072], "disallowed"], [[65073, 65073], "mapped", [8212]], [[65074, 65074], "mapped", [8211]], [[65075, 65076], "disallowed_STD3_mapped", [95]], [[65077, 65077], "disallowed_STD3_mapped", [40]], [[65078, 65078], "disallowed_STD3_mapped", [41]], [[65079, 65079], "disallowed_STD3_mapped", [123]], [[65080, 65080], "disallowed_STD3_mapped", [125]], [[65081, 65081], "mapped", [12308]], [[65082, 65082], "mapped", [12309]], [[65083, 65083], "mapped", [12304]], [[65084, 65084], "mapped", [12305]], [[65085, 65085], "mapped", [12298]], [[65086, 65086], "mapped", [12299]], [[65087, 65087], "mapped", [12296]], [[65088, 65088], "mapped", [12297]], [[65089, 65089], "mapped", [12300]], [[65090, 65090], "mapped", [12301]], [[65091, 65091], "mapped", [12302]], [[65092, 65092], "mapped", [12303]], [[65093, 65094], "valid", [], "NV8"], [[65095, 65095], "disallowed_STD3_mapped", [91]], [[65096, 65096], "disallowed_STD3_mapped", [93]], [[65097, 65100], "disallowed_STD3_mapped", [32, 773]], [[65101, 65103], "disallowed_STD3_mapped", [95]], [[65104, 65104], "disallowed_STD3_mapped", [44]], [[65105, 65105], "mapped", [12289]], [[65106, 65106], "disallowed"], [[65107, 65107], "disallowed"], [[65108, 65108], "disallowed_STD3_mapped", [59]], [[65109, 65109], "disallowed_STD3_mapped", [58]], [[65110, 65110], "disallowed_STD3_mapped", [63]], [[65111, 65111], "disallowed_STD3_mapped", [33]], [[65112, 65112], "mapped", [8212]], [[65113, 65113], "disallowed_STD3_mapped", [40]], [[65114, 65114], "disallowed_STD3_mapped", [41]], [[65115, 65115], "disallowed_STD3_mapped", [123]], [[65116, 65116], "disallowed_STD3_mapped", [125]], [[65117, 65117], "mapped", [12308]], [[65118, 65118], "mapped", [12309]], [[65119, 65119], "disallowed_STD3_mapped", [35]], [[65120, 65120], "disallowed_STD3_mapped", [38]], [[65121, 65121], "disallowed_STD3_mapped", [42]], [[65122, 65122], "disallowed_STD3_mapped", [43]], [[65123, 65123], "mapped", [45]], [[65124, 65124], "disallowed_STD3_mapped", [60]], [[65125, 65125], "disallowed_STD3_mapped", [62]], [[65126, 65126], "disallowed_STD3_mapped", [61]], [[65127, 65127], "disallowed"], [[65128, 65128], "disallowed_STD3_mapped", [92]], [[65129, 65129], "disallowed_STD3_mapped", [36]], [[65130, 65130], "disallowed_STD3_mapped", [37]], [[65131, 65131], "disallowed_STD3_mapped", [64]], [[65132, 65135], "disallowed"], [[65136, 65136], "disallowed_STD3_mapped", [32, 1611]], [[65137, 65137], "mapped", [1600, 1611]], [[65138, 65138], "disallowed_STD3_mapped", [32, 1612]], [[65139, 65139], "valid"], [[65140, 65140], "disallowed_STD3_mapped", [32, 1613]], [[65141, 65141], "disallowed"], [[65142, 65142], "disallowed_STD3_mapped", [32, 1614]], [[65143, 65143], "mapped", [1600, 1614]], [[65144, 65144], "disallowed_STD3_mapped", [32, 1615]], [[65145, 65145], "mapped", [1600, 1615]], [[65146, 65146], "disallowed_STD3_mapped", [32, 1616]], [[65147, 65147], "mapped", [1600, 1616]], [[65148, 65148], "disallowed_STD3_mapped", [32, 1617]], [[65149, 65149], "mapped", [1600, 1617]], [[65150, 65150], "disallowed_STD3_mapped", [32, 1618]], [[65151, 65151], "mapped", [1600, 1618]], [[65152, 65152], "mapped", [1569]], [[65153, 65154], "mapped", [1570]], [[65155, 65156], "mapped", [1571]], [[65157, 65158], "mapped", [1572]], [[65159, 65160], "mapped", [1573]], [[65161, 65164], "mapped", [1574]], [[65165, 65166], "mapped", [1575]], [[65167, 65170], "mapped", [1576]], [[65171, 65172], "mapped", [1577]], [[65173, 65176], "mapped", [1578]], [[65177, 65180], "mapped", [1579]], [[65181, 65184], "mapped", [1580]], [[65185, 65188], "mapped", [1581]], [[65189, 65192], "mapped", [1582]], [[65193, 65194], "mapped", [1583]], [[65195, 65196], "mapped", [1584]], [[65197, 65198], "mapped", [1585]], [[65199, 65200], "mapped", [1586]], [[65201, 65204], "mapped", [1587]], [[65205, 65208], "mapped", [1588]], [[65209, 65212], "mapped", [1589]], [[65213, 65216], "mapped", [1590]], [[65217, 65220], "mapped", [1591]], [[65221, 65224], "mapped", [1592]], [[65225, 65228], "mapped", [1593]], [[65229, 65232], "mapped", [1594]], [[65233, 65236], "mapped", [1601]], [[65237, 65240], "mapped", [1602]], [[65241, 65244], "mapped", [1603]], [[65245, 65248], "mapped", [1604]], [[65249, 65252], "mapped", [1605]], [[65253, 65256], "mapped", [1606]], [[65257, 65260], "mapped", [1607]], [[65261, 65262], "mapped", [1608]], [[65263, 65264], "mapped", [1609]], [[65265, 65268], "mapped", [1610]], [[65269, 65270], "mapped", [1604, 1570]], [[65271, 65272], "mapped", [1604, 1571]], [[65273, 65274], "mapped", [1604, 1573]], [[65275, 65276], "mapped", [1604, 1575]], [[65277, 65278], "disallowed"], [[65279, 65279], "ignored"], [[65280, 65280], "disallowed"], [[65281, 65281], "disallowed_STD3_mapped", [33]], [[65282, 65282], "disallowed_STD3_mapped", [34]], [[65283, 65283], "disallowed_STD3_mapped", [35]], [[65284, 65284], "disallowed_STD3_mapped", [36]], [[65285, 65285], "disallowed_STD3_mapped", [37]], [[65286, 65286], "disallowed_STD3_mapped", [38]], [[65287, 65287], "disallowed_STD3_mapped", [39]], [[65288, 65288], "disallowed_STD3_mapped", [40]], [[65289, 65289], "disallowed_STD3_mapped", [41]], [[65290, 65290], "disallowed_STD3_mapped", [42]], [[65291, 65291], "disallowed_STD3_mapped", [43]], [[65292, 65292], "disallowed_STD3_mapped", [44]], [[65293, 65293], "mapped", [45]], [[65294, 65294], "mapped", [46]], [[65295, 65295], "disallowed_STD3_mapped", [47]], [[65296, 65296], "mapped", [48]], [[65297, 65297], "mapped", [49]], [[65298, 65298], "mapped", [50]], [[65299, 65299], "mapped", [51]], [[65300, 65300], "mapped", [52]], [[65301, 65301], "mapped", [53]], [[65302, 65302], "mapped", [54]], [[65303, 65303], "mapped", [55]], [[65304, 65304], "mapped", [56]], [[65305, 65305], "mapped", [57]], [[65306, 65306], "disallowed_STD3_mapped", [58]], [[65307, 65307], "disallowed_STD3_mapped", [59]], [[65308, 65308], "disallowed_STD3_mapped", [60]], [[65309, 65309], "disallowed_STD3_mapped", [61]], [[65310, 65310], "disallowed_STD3_mapped", [62]], [[65311, 65311], "disallowed_STD3_mapped", [63]], [[65312, 65312], "disallowed_STD3_mapped", [64]], [[65313, 65313], "mapped", [97]], [[65314, 65314], "mapped", [98]], [[65315, 65315], "mapped", [99]], [[65316, 65316], "mapped", [100]], [[65317, 65317], "mapped", [101]], [[65318, 65318], "mapped", [102]], [[65319, 65319], "mapped", [103]], [[65320, 65320], "mapped", [104]], [[65321, 65321], "mapped", [105]], [[65322, 65322], "mapped", [106]], [[65323, 65323], "mapped", [107]], [[65324, 65324], "mapped", [108]], [[65325, 65325], "mapped", [109]], [[65326, 65326], "mapped", [110]], [[65327, 65327], "mapped", [111]], [[65328, 65328], "mapped", [112]], [[65329, 65329], "mapped", [113]], [[65330, 65330], "mapped", [114]], [[65331, 65331], "mapped", [115]], [[65332, 65332], "mapped", [116]], [[65333, 65333], "mapped", [117]], [[65334, 65334], "mapped", [118]], [[65335, 65335], "mapped", [119]], [[65336, 65336], "mapped", [120]], [[65337, 65337], "mapped", [121]], [[65338, 65338], "mapped", [122]], [[65339, 65339], "disallowed_STD3_mapped", [91]], [[65340, 65340], "disallowed_STD3_mapped", [92]], [[65341, 65341], "disallowed_STD3_mapped", [93]], [[65342, 65342], "disallowed_STD3_mapped", [94]], [[65343, 65343], "disallowed_STD3_mapped", [95]], [[65344, 65344], "disallowed_STD3_mapped", [96]], [[65345, 65345], "mapped", [97]], [[65346, 65346], "mapped", [98]], [[65347, 65347], "mapped", [99]], [[65348, 65348], "mapped", [100]], [[65349, 65349], "mapped", [101]], [[65350, 65350], "mapped", [102]], [[65351, 65351], "mapped", [103]], [[65352, 65352], "mapped", [104]], [[65353, 65353], "mapped", [105]], [[65354, 65354], "mapped", [106]], [[65355, 65355], "mapped", [107]], [[65356, 65356], "mapped", [108]], [[65357, 65357], "mapped", [109]], [[65358, 65358], "mapped", [110]], [[65359, 65359], "mapped", [111]], [[65360, 65360], "mapped", [112]], [[65361, 65361], "mapped", [113]], [[65362, 65362], "mapped", [114]], [[65363, 65363], "mapped", [115]], [[65364, 65364], "mapped", [116]], [[65365, 65365], "mapped", [117]], [[65366, 65366], "mapped", [118]], [[65367, 65367], "mapped", [119]], [[65368, 65368], "mapped", [120]], [[65369, 65369], "mapped", [121]], [[65370, 65370], "mapped", [122]], [[65371, 65371], "disallowed_STD3_mapped", [123]], [[65372, 65372], "disallowed_STD3_mapped", [124]], [[65373, 65373], "disallowed_STD3_mapped", [125]], [[65374, 65374], "disallowed_STD3_mapped", [126]], [[65375, 65375], "mapped", [10629]], [[65376, 65376], "mapped", [10630]], [[65377, 65377], "mapped", [46]], [[65378, 65378], "mapped", [12300]], [[65379, 65379], "mapped", [12301]], [[65380, 65380], "mapped", [12289]], [[65381, 65381], "mapped", [12539]], [[65382, 65382], "mapped", [12530]], [[65383, 65383], "mapped", [12449]], [[65384, 65384], "mapped", [12451]], [[65385, 65385], "mapped", [12453]], [[65386, 65386], "mapped", [12455]], [[65387, 65387], "mapped", [12457]], [[65388, 65388], "mapped", [12515]], [[65389, 65389], "mapped", [12517]], [[65390, 65390], "mapped", [12519]], [[65391, 65391], "mapped", [12483]], [[65392, 65392], "mapped", [12540]], [[65393, 65393], "mapped", [12450]], [[65394, 65394], "mapped", [12452]], [[65395, 65395], "mapped", [12454]], [[65396, 65396], "mapped", [12456]], [[65397, 65397], "mapped", [12458]], [[65398, 65398], "mapped", [12459]], [[65399, 65399], "mapped", [12461]], [[65400, 65400], "mapped", [12463]], [[65401, 65401], "mapped", [12465]], [[65402, 65402], "mapped", [12467]], [[65403, 65403], "mapped", [12469]], [[65404, 65404], "mapped", [12471]], [[65405, 65405], "mapped", [12473]], [[65406, 65406], "mapped", [12475]], [[65407, 65407], "mapped", [12477]], [[65408, 65408], "mapped", [12479]], [[65409, 65409], "mapped", [12481]], [[65410, 65410], "mapped", [12484]], [[65411, 65411], "mapped", [12486]], [[65412, 65412], "mapped", [12488]], [[65413, 65413], "mapped", [12490]], [[65414, 65414], "mapped", [12491]], [[65415, 65415], "mapped", [12492]], [[65416, 65416], "mapped", [12493]], [[65417, 65417], "mapped", [12494]], [[65418, 65418], "mapped", [12495]], [[65419, 65419], "mapped", [12498]], [[65420, 65420], "mapped", [12501]], [[65421, 65421], "mapped", [12504]], [[65422, 65422], "mapped", [12507]], [[65423, 65423], "mapped", [12510]], [[65424, 65424], "mapped", [12511]], [[65425, 65425], "mapped", [12512]], [[65426, 65426], "mapped", [12513]], [[65427, 65427], "mapped", [12514]], [[65428, 65428], "mapped", [12516]], [[65429, 65429], "mapped", [12518]], [[65430, 65430], "mapped", [12520]], [[65431, 65431], "mapped", [12521]], [[65432, 65432], "mapped", [12522]], [[65433, 65433], "mapped", [12523]], [[65434, 65434], "mapped", [12524]], [[65435, 65435], "mapped", [12525]], [[65436, 65436], "mapped", [12527]], [[65437, 65437], "mapped", [12531]], [[65438, 65438], "mapped", [12441]], [[65439, 65439], "mapped", [12442]], [[65440, 65440], "disallowed"], [[65441, 65441], "mapped", [4352]], [[65442, 65442], "mapped", [4353]], [[65443, 65443], "mapped", [4522]], [[65444, 65444], "mapped", [4354]], [[65445, 65445], "mapped", [4524]], [[65446, 65446], "mapped", [4525]], [[65447, 65447], "mapped", [4355]], [[65448, 65448], "mapped", [4356]], [[65449, 65449], "mapped", [4357]], [[65450, 65450], "mapped", [4528]], [[65451, 65451], "mapped", [4529]], [[65452, 65452], "mapped", [4530]], [[65453, 65453], "mapped", [4531]], [[65454, 65454], "mapped", [4532]], [[65455, 65455], "mapped", [4533]], [[65456, 65456], "mapped", [4378]], [[65457, 65457], "mapped", [4358]], [[65458, 65458], "mapped", [4359]], [[65459, 65459], "mapped", [4360]], [[65460, 65460], "mapped", [4385]], [[65461, 65461], "mapped", [4361]], [[65462, 65462], "mapped", [4362]], [[65463, 65463], "mapped", [4363]], [[65464, 65464], "mapped", [4364]], [[65465, 65465], "mapped", [4365]], [[65466, 65466], "mapped", [4366]], [[65467, 65467], "mapped", [4367]], [[65468, 65468], "mapped", [4368]], [[65469, 65469], "mapped", [4369]], [[65470, 65470], "mapped", [4370]], [[65471, 65473], "disallowed"], [[65474, 65474], "mapped", [4449]], [[65475, 65475], "mapped", [4450]], [[65476, 65476], "mapped", [4451]], [[65477, 65477], "mapped", [4452]], [[65478, 65478], "mapped", [4453]], [[65479, 65479], "mapped", [4454]], [[65480, 65481], "disallowed"], [[65482, 65482], "mapped", [4455]], [[65483, 65483], "mapped", [4456]], [[65484, 65484], "mapped", [4457]], [[65485, 65485], "mapped", [4458]], [[65486, 65486], "mapped", [4459]], [[65487, 65487], "mapped", [4460]], [[65488, 65489], "disallowed"], [[65490, 65490], "mapped", [4461]], [[65491, 65491], "mapped", [4462]], [[65492, 65492], "mapped", [4463]], [[65493, 65493], "mapped", [4464]], [[65494, 65494], "mapped", [4465]], [[65495, 65495], "mapped", [4466]], [[65496, 65497], "disallowed"], [[65498, 65498], "mapped", [4467]], [[65499, 65499], "mapped", [4468]], [[65500, 65500], "mapped", [4469]], [[65501, 65503], "disallowed"], [[65504, 65504], "mapped", [162]], [[65505, 65505], "mapped", [163]], [[65506, 65506], "mapped", [172]], [[65507, 65507], "disallowed_STD3_mapped", [32, 772]], [[65508, 65508], "mapped", [166]], [[65509, 65509], "mapped", [165]], [[65510, 65510], "mapped", [8361]], [[65511, 65511], "disallowed"], [[65512, 65512], "mapped", [9474]], [[65513, 65513], "mapped", [8592]], [[65514, 65514], "mapped", [8593]], [[65515, 65515], "mapped", [8594]], [[65516, 65516], "mapped", [8595]], [[65517, 65517], "mapped", [9632]], [[65518, 65518], "mapped", [9675]], [[65519, 65528], "disallowed"], [[65529, 65531], "disallowed"], [[65532, 65532], "disallowed"], [[65533, 65533], "disallowed"], [[65534, 65535], "disallowed"], [[65536, 65547], "valid"], [[65548, 65548], "disallowed"], [[65549, 65574], "valid"], [[65575, 65575], "disallowed"], [[65576, 65594], "valid"], [[65595, 65595], "disallowed"], [[65596, 65597], "valid"], [[65598, 65598], "disallowed"], [[65599, 65613], "valid"], [[65614, 65615], "disallowed"], [[65616, 65629], "valid"], [[65630, 65663], "disallowed"], [[65664, 65786], "valid"], [[65787, 65791], "disallowed"], [[65792, 65794], "valid", [], "NV8"], [[65795, 65798], "disallowed"], [[65799, 65843], "valid", [], "NV8"], [[65844, 65846], "disallowed"], [[65847, 65855], "valid", [], "NV8"], [[65856, 65930], "valid", [], "NV8"], [[65931, 65932], "valid", [], "NV8"], [[65933, 65935], "disallowed"], [[65936, 65947], "valid", [], "NV8"], [[65948, 65951], "disallowed"], [[65952, 65952], "valid", [], "NV8"], [[65953, 65999], "disallowed"], [[66e3, 66044], "valid", [], "NV8"], [[66045, 66045], "valid"], [[66046, 66175], "disallowed"], [[66176, 66204], "valid"], [[66205, 66207], "disallowed"], [[66208, 66256], "valid"], [[66257, 66271], "disallowed"], [[66272, 66272], "valid"], [[66273, 66299], "valid", [], "NV8"], [[66300, 66303], "disallowed"], [[66304, 66334], "valid"], [[66335, 66335], "valid"], [[66336, 66339], "valid", [], "NV8"], [[66340, 66351], "disallowed"], [[66352, 66368], "valid"], [[66369, 66369], "valid", [], "NV8"], [[66370, 66377], "valid"], [[66378, 66378], "valid", [], "NV8"], [[66379, 66383], "disallowed"], [[66384, 66426], "valid"], [[66427, 66431], "disallowed"], [[66432, 66461], "valid"], [[66462, 66462], "disallowed"], [[66463, 66463], "valid", [], "NV8"], [[66464, 66499], "valid"], [[66500, 66503], "disallowed"], [[66504, 66511], "valid"], [[66512, 66517], "valid", [], "NV8"], [[66518, 66559], "disallowed"], [[66560, 66560], "mapped", [66600]], [[66561, 66561], "mapped", [66601]], [[66562, 66562], "mapped", [66602]], [[66563, 66563], "mapped", [66603]], [[66564, 66564], "mapped", [66604]], [[66565, 66565], "mapped", [66605]], [[66566, 66566], "mapped", [66606]], [[66567, 66567], "mapped", [66607]], [[66568, 66568], "mapped", [66608]], [[66569, 66569], "mapped", [66609]], [[66570, 66570], "mapped", [66610]], [[66571, 66571], "mapped", [66611]], [[66572, 66572], "mapped", [66612]], [[66573, 66573], "mapped", [66613]], [[66574, 66574], "mapped", [66614]], [[66575, 66575], "mapped", [66615]], [[66576, 66576], "mapped", [66616]], [[66577, 66577], "mapped", [66617]], [[66578, 66578], "mapped", [66618]], [[66579, 66579], "mapped", [66619]], [[66580, 66580], "mapped", [66620]], [[66581, 66581], "mapped", [66621]], [[66582, 66582], "mapped", [66622]], [[66583, 66583], "mapped", [66623]], [[66584, 66584], "mapped", [66624]], [[66585, 66585], "mapped", [66625]], [[66586, 66586], "mapped", [66626]], [[66587, 66587], "mapped", [66627]], [[66588, 66588], "mapped", [66628]], [[66589, 66589], "mapped", [66629]], [[66590, 66590], "mapped", [66630]], [[66591, 66591], "mapped", [66631]], [[66592, 66592], "mapped", [66632]], [[66593, 66593], "mapped", [66633]], [[66594, 66594], "mapped", [66634]], [[66595, 66595], "mapped", [66635]], [[66596, 66596], "mapped", [66636]], [[66597, 66597], "mapped", [66637]], [[66598, 66598], "mapped", [66638]], [[66599, 66599], "mapped", [66639]], [[66600, 66637], "valid"], [[66638, 66717], "valid"], [[66718, 66719], "disallowed"], [[66720, 66729], "valid"], [[66730, 66815], "disallowed"], [[66816, 66855], "valid"], [[66856, 66863], "disallowed"], [[66864, 66915], "valid"], [[66916, 66926], "disallowed"], [[66927, 66927], "valid", [], "NV8"], [[66928, 67071], "disallowed"], [[67072, 67382], "valid"], [[67383, 67391], "disallowed"], [[67392, 67413], "valid"], [[67414, 67423], "disallowed"], [[67424, 67431], "valid"], [[67432, 67583], "disallowed"], [[67584, 67589], "valid"], [[67590, 67591], "disallowed"], [[67592, 67592], "valid"], [[67593, 67593], "disallowed"], [[67594, 67637], "valid"], [[67638, 67638], "disallowed"], [[67639, 67640], "valid"], [[67641, 67643], "disallowed"], [[67644, 67644], "valid"], [[67645, 67646], "disallowed"], [[67647, 67647], "valid"], [[67648, 67669], "valid"], [[67670, 67670], "disallowed"], [[67671, 67679], "valid", [], "NV8"], [[67680, 67702], "valid"], [[67703, 67711], "valid", [], "NV8"], [[67712, 67742], "valid"], [[67743, 67750], "disallowed"], [[67751, 67759], "valid", [], "NV8"], [[67760, 67807], "disallowed"], [[67808, 67826], "valid"], [[67827, 67827], "disallowed"], [[67828, 67829], "valid"], [[67830, 67834], "disallowed"], [[67835, 67839], "valid", [], "NV8"], [[67840, 67861], "valid"], [[67862, 67865], "valid", [], "NV8"], [[67866, 67867], "valid", [], "NV8"], [[67868, 67870], "disallowed"], [[67871, 67871], "valid", [], "NV8"], [[67872, 67897], "valid"], [[67898, 67902], "disallowed"], [[67903, 67903], "valid", [], "NV8"], [[67904, 67967], "disallowed"], [[67968, 68023], "valid"], [[68024, 68027], "disallowed"], [[68028, 68029], "valid", [], "NV8"], [[68030, 68031], "valid"], [[68032, 68047], "valid", [], "NV8"], [[68048, 68049], "disallowed"], [[68050, 68095], "valid", [], "NV8"], [[68096, 68099], "valid"], [[68100, 68100], "disallowed"], [[68101, 68102], "valid"], [[68103, 68107], "disallowed"], [[68108, 68115], "valid"], [[68116, 68116], "disallowed"], [[68117, 68119], "valid"], [[68120, 68120], "disallowed"], [[68121, 68147], "valid"], [[68148, 68151], "disallowed"], [[68152, 68154], "valid"], [[68155, 68158], "disallowed"], [[68159, 68159], "valid"], [[68160, 68167], "valid", [], "NV8"], [[68168, 68175], "disallowed"], [[68176, 68184], "valid", [], "NV8"], [[68185, 68191], "disallowed"], [[68192, 68220], "valid"], [[68221, 68223], "valid", [], "NV8"], [[68224, 68252], "valid"], [[68253, 68255], "valid", [], "NV8"], [[68256, 68287], "disallowed"], [[68288, 68295], "valid"], [[68296, 68296], "valid", [], "NV8"], [[68297, 68326], "valid"], [[68327, 68330], "disallowed"], [[68331, 68342], "valid", [], "NV8"], [[68343, 68351], "disallowed"], [[68352, 68405], "valid"], [[68406, 68408], "disallowed"], [[68409, 68415], "valid", [], "NV8"], [[68416, 68437], "valid"], [[68438, 68439], "disallowed"], [[68440, 68447], "valid", [], "NV8"], [[68448, 68466], "valid"], [[68467, 68471], "disallowed"], [[68472, 68479], "valid", [], "NV8"], [[68480, 68497], "valid"], [[68498, 68504], "disallowed"], [[68505, 68508], "valid", [], "NV8"], [[68509, 68520], "disallowed"], [[68521, 68527], "valid", [], "NV8"], [[68528, 68607], "disallowed"], [[68608, 68680], "valid"], [[68681, 68735], "disallowed"], [[68736, 68736], "mapped", [68800]], [[68737, 68737], "mapped", [68801]], [[68738, 68738], "mapped", [68802]], [[68739, 68739], "mapped", [68803]], [[68740, 68740], "mapped", [68804]], [[68741, 68741], "mapped", [68805]], [[68742, 68742], "mapped", [68806]], [[68743, 68743], "mapped", [68807]], [[68744, 68744], "mapped", [68808]], [[68745, 68745], "mapped", [68809]], [[68746, 68746], "mapped", [68810]], [[68747, 68747], "mapped", [68811]], [[68748, 68748], "mapped", [68812]], [[68749, 68749], "mapped", [68813]], [[68750, 68750], "mapped", [68814]], [[68751, 68751], "mapped", [68815]], [[68752, 68752], "mapped", [68816]], [[68753, 68753], "mapped", [68817]], [[68754, 68754], "mapped", [68818]], [[68755, 68755], "mapped", [68819]], [[68756, 68756], "mapped", [68820]], [[68757, 68757], "mapped", [68821]], [[68758, 68758], "mapped", [68822]], [[68759, 68759], "mapped", [68823]], [[68760, 68760], "mapped", [68824]], [[68761, 68761], "mapped", [68825]], [[68762, 68762], "mapped", [68826]], [[68763, 68763], "mapped", [68827]], [[68764, 68764], "mapped", [68828]], [[68765, 68765], "mapped", [68829]], [[68766, 68766], "mapped", [68830]], [[68767, 68767], "mapped", [68831]], [[68768, 68768], "mapped", [68832]], [[68769, 68769], "mapped", [68833]], [[68770, 68770], "mapped", [68834]], [[68771, 68771], "mapped", [68835]], [[68772, 68772], "mapped", [68836]], [[68773, 68773], "mapped", [68837]], [[68774, 68774], "mapped", [68838]], [[68775, 68775], "mapped", [68839]], [[68776, 68776], "mapped", [68840]], [[68777, 68777], "mapped", [68841]], [[68778, 68778], "mapped", [68842]], [[68779, 68779], "mapped", [68843]], [[68780, 68780], "mapped", [68844]], [[68781, 68781], "mapped", [68845]], [[68782, 68782], "mapped", [68846]], [[68783, 68783], "mapped", [68847]], [[68784, 68784], "mapped", [68848]], [[68785, 68785], "mapped", [68849]], [[68786, 68786], "mapped", [68850]], [[68787, 68799], "disallowed"], [[68800, 68850], "valid"], [[68851, 68857], "disallowed"], [[68858, 68863], "valid", [], "NV8"], [[68864, 69215], "disallowed"], [[69216, 69246], "valid", [], "NV8"], [[69247, 69631], "disallowed"], [[69632, 69702], "valid"], [[69703, 69709], "valid", [], "NV8"], [[69710, 69713], "disallowed"], [[69714, 69733], "valid", [], "NV8"], [[69734, 69743], "valid"], [[69744, 69758], "disallowed"], [[69759, 69759], "valid"], [[69760, 69818], "valid"], [[69819, 69820], "valid", [], "NV8"], [[69821, 69821], "disallowed"], [[69822, 69825], "valid", [], "NV8"], [[69826, 69839], "disallowed"], [[69840, 69864], "valid"], [[69865, 69871], "disallowed"], [[69872, 69881], "valid"], [[69882, 69887], "disallowed"], [[69888, 69940], "valid"], [[69941, 69941], "disallowed"], [[69942, 69951], "valid"], [[69952, 69955], "valid", [], "NV8"], [[69956, 69967], "disallowed"], [[69968, 70003], "valid"], [[70004, 70005], "valid", [], "NV8"], [[70006, 70006], "valid"], [[70007, 70015], "disallowed"], [[70016, 70084], "valid"], [[70085, 70088], "valid", [], "NV8"], [[70089, 70089], "valid", [], "NV8"], [[70090, 70092], "valid"], [[70093, 70093], "valid", [], "NV8"], [[70094, 70095], "disallowed"], [[70096, 70105], "valid"], [[70106, 70106], "valid"], [[70107, 70107], "valid", [], "NV8"], [[70108, 70108], "valid"], [[70109, 70111], "valid", [], "NV8"], [[70112, 70112], "disallowed"], [[70113, 70132], "valid", [], "NV8"], [[70133, 70143], "disallowed"], [[70144, 70161], "valid"], [[70162, 70162], "disallowed"], [[70163, 70199], "valid"], [[70200, 70205], "valid", [], "NV8"], [[70206, 70271], "disallowed"], [[70272, 70278], "valid"], [[70279, 70279], "disallowed"], [[70280, 70280], "valid"], [[70281, 70281], "disallowed"], [[70282, 70285], "valid"], [[70286, 70286], "disallowed"], [[70287, 70301], "valid"], [[70302, 70302], "disallowed"], [[70303, 70312], "valid"], [[70313, 70313], "valid", [], "NV8"], [[70314, 70319], "disallowed"], [[70320, 70378], "valid"], [[70379, 70383], "disallowed"], [[70384, 70393], "valid"], [[70394, 70399], "disallowed"], [[70400, 70400], "valid"], [[70401, 70403], "valid"], [[70404, 70404], "disallowed"], [[70405, 70412], "valid"], [[70413, 70414], "disallowed"], [[70415, 70416], "valid"], [[70417, 70418], "disallowed"], [[70419, 70440], "valid"], [[70441, 70441], "disallowed"], [[70442, 70448], "valid"], [[70449, 70449], "disallowed"], [[70450, 70451], "valid"], [[70452, 70452], "disallowed"], [[70453, 70457], "valid"], [[70458, 70459], "disallowed"], [[70460, 70468], "valid"], [[70469, 70470], "disallowed"], [[70471, 70472], "valid"], [[70473, 70474], "disallowed"], [[70475, 70477], "valid"], [[70478, 70479], "disallowed"], [[70480, 70480], "valid"], [[70481, 70486], "disallowed"], [[70487, 70487], "valid"], [[70488, 70492], "disallowed"], [[70493, 70499], "valid"], [[70500, 70501], "disallowed"], [[70502, 70508], "valid"], [[70509, 70511], "disallowed"], [[70512, 70516], "valid"], [[70517, 70783], "disallowed"], [[70784, 70853], "valid"], [[70854, 70854], "valid", [], "NV8"], [[70855, 70855], "valid"], [[70856, 70863], "disallowed"], [[70864, 70873], "valid"], [[70874, 71039], "disallowed"], [[71040, 71093], "valid"], [[71094, 71095], "disallowed"], [[71096, 71104], "valid"], [[71105, 71113], "valid", [], "NV8"], [[71114, 71127], "valid", [], "NV8"], [[71128, 71133], "valid"], [[71134, 71167], "disallowed"], [[71168, 71232], "valid"], [[71233, 71235], "valid", [], "NV8"], [[71236, 71236], "valid"], [[71237, 71247], "disallowed"], [[71248, 71257], "valid"], [[71258, 71295], "disallowed"], [[71296, 71351], "valid"], [[71352, 71359], "disallowed"], [[71360, 71369], "valid"], [[71370, 71423], "disallowed"], [[71424, 71449], "valid"], [[71450, 71452], "disallowed"], [[71453, 71467], "valid"], [[71468, 71471], "disallowed"], [[71472, 71481], "valid"], [[71482, 71487], "valid", [], "NV8"], [[71488, 71839], "disallowed"], [[71840, 71840], "mapped", [71872]], [[71841, 71841], "mapped", [71873]], [[71842, 71842], "mapped", [71874]], [[71843, 71843], "mapped", [71875]], [[71844, 71844], "mapped", [71876]], [[71845, 71845], "mapped", [71877]], [[71846, 71846], "mapped", [71878]], [[71847, 71847], "mapped", [71879]], [[71848, 71848], "mapped", [71880]], [[71849, 71849], "mapped", [71881]], [[71850, 71850], "mapped", [71882]], [[71851, 71851], "mapped", [71883]], [[71852, 71852], "mapped", [71884]], [[71853, 71853], "mapped", [71885]], [[71854, 71854], "mapped", [71886]], [[71855, 71855], "mapped", [71887]], [[71856, 71856], "mapped", [71888]], [[71857, 71857], "mapped", [71889]], [[71858, 71858], "mapped", [71890]], [[71859, 71859], "mapped", [71891]], [[71860, 71860], "mapped", [71892]], [[71861, 71861], "mapped", [71893]], [[71862, 71862], "mapped", [71894]], [[71863, 71863], "mapped", [71895]], [[71864, 71864], "mapped", [71896]], [[71865, 71865], "mapped", [71897]], [[71866, 71866], "mapped", [71898]], [[71867, 71867], "mapped", [71899]], [[71868, 71868], "mapped", [71900]], [[71869, 71869], "mapped", [71901]], [[71870, 71870], "mapped", [71902]], [[71871, 71871], "mapped", [71903]], [[71872, 71913], "valid"], [[71914, 71922], "valid", [], "NV8"], [[71923, 71934], "disallowed"], [[71935, 71935], "valid"], [[71936, 72383], "disallowed"], [[72384, 72440], "valid"], [[72441, 73727], "disallowed"], [[73728, 74606], "valid"], [[74607, 74648], "valid"], [[74649, 74649], "valid"], [[74650, 74751], "disallowed"], [[74752, 74850], "valid", [], "NV8"], [[74851, 74862], "valid", [], "NV8"], [[74863, 74863], "disallowed"], [[74864, 74867], "valid", [], "NV8"], [[74868, 74868], "valid", [], "NV8"], [[74869, 74879], "disallowed"], [[74880, 75075], "valid"], [[75076, 77823], "disallowed"], [[77824, 78894], "valid"], [[78895, 82943], "disallowed"], [[82944, 83526], "valid"], [[83527, 92159], "disallowed"], [[92160, 92728], "valid"], [[92729, 92735], "disallowed"], [[92736, 92766], "valid"], [[92767, 92767], "disallowed"], [[92768, 92777], "valid"], [[92778, 92781], "disallowed"], [[92782, 92783], "valid", [], "NV8"], [[92784, 92879], "disallowed"], [[92880, 92909], "valid"], [[92910, 92911], "disallowed"], [[92912, 92916], "valid"], [[92917, 92917], "valid", [], "NV8"], [[92918, 92927], "disallowed"], [[92928, 92982], "valid"], [[92983, 92991], "valid", [], "NV8"], [[92992, 92995], "valid"], [[92996, 92997], "valid", [], "NV8"], [[92998, 93007], "disallowed"], [[93008, 93017], "valid"], [[93018, 93018], "disallowed"], [[93019, 93025], "valid", [], "NV8"], [[93026, 93026], "disallowed"], [[93027, 93047], "valid"], [[93048, 93052], "disallowed"], [[93053, 93071], "valid"], [[93072, 93951], "disallowed"], [[93952, 94020], "valid"], [[94021, 94031], "disallowed"], [[94032, 94078], "valid"], [[94079, 94094], "disallowed"], [[94095, 94111], "valid"], [[94112, 110591], "disallowed"], [[110592, 110593], "valid"], [[110594, 113663], "disallowed"], [[113664, 113770], "valid"], [[113771, 113775], "disallowed"], [[113776, 113788], "valid"], [[113789, 113791], "disallowed"], [[113792, 113800], "valid"], [[113801, 113807], "disallowed"], [[113808, 113817], "valid"], [[113818, 113819], "disallowed"], [[113820, 113820], "valid", [], "NV8"], [[113821, 113822], "valid"], [[113823, 113823], "valid", [], "NV8"], [[113824, 113827], "ignored"], [[113828, 118783], "disallowed"], [[118784, 119029], "valid", [], "NV8"], [[119030, 119039], "disallowed"], [[119040, 119078], "valid", [], "NV8"], [[119079, 119080], "disallowed"], [[119081, 119081], "valid", [], "NV8"], [[119082, 119133], "valid", [], "NV8"], [[119134, 119134], "mapped", [119127, 119141]], [[119135, 119135], "mapped", [119128, 119141]], [[119136, 119136], "mapped", [119128, 119141, 119150]], [[119137, 119137], "mapped", [119128, 119141, 119151]], [[119138, 119138], "mapped", [119128, 119141, 119152]], [[119139, 119139], "mapped", [119128, 119141, 119153]], [[119140, 119140], "mapped", [119128, 119141, 119154]], [[119141, 119154], "valid", [], "NV8"], [[119155, 119162], "disallowed"], [[119163, 119226], "valid", [], "NV8"], [[119227, 119227], "mapped", [119225, 119141]], [[119228, 119228], "mapped", [119226, 119141]], [[119229, 119229], "mapped", [119225, 119141, 119150]], [[119230, 119230], "mapped", [119226, 119141, 119150]], [[119231, 119231], "mapped", [119225, 119141, 119151]], [[119232, 119232], "mapped", [119226, 119141, 119151]], [[119233, 119261], "valid", [], "NV8"], [[119262, 119272], "valid", [], "NV8"], [[119273, 119295], "disallowed"], [[119296, 119365], "valid", [], "NV8"], [[119366, 119551], "disallowed"], [[119552, 119638], "valid", [], "NV8"], [[119639, 119647], "disallowed"], [[119648, 119665], "valid", [], "NV8"], [[119666, 119807], "disallowed"], [[119808, 119808], "mapped", [97]], [[119809, 119809], "mapped", [98]], [[119810, 119810], "mapped", [99]], [[119811, 119811], "mapped", [100]], [[119812, 119812], "mapped", [101]], [[119813, 119813], "mapped", [102]], [[119814, 119814], "mapped", [103]], [[119815, 119815], "mapped", [104]], [[119816, 119816], "mapped", [105]], [[119817, 119817], "mapped", [106]], [[119818, 119818], "mapped", [107]], [[119819, 119819], "mapped", [108]], [[119820, 119820], "mapped", [109]], [[119821, 119821], "mapped", [110]], [[119822, 119822], "mapped", [111]], [[119823, 119823], "mapped", [112]], [[119824, 119824], "mapped", [113]], [[119825, 119825], "mapped", [114]], [[119826, 119826], "mapped", [115]], [[119827, 119827], "mapped", [116]], [[119828, 119828], "mapped", [117]], [[119829, 119829], "mapped", [118]], [[119830, 119830], "mapped", [119]], [[119831, 119831], "mapped", [120]], [[119832, 119832], "mapped", [121]], [[119833, 119833], "mapped", [122]], [[119834, 119834], "mapped", [97]], [[119835, 119835], "mapped", [98]], [[119836, 119836], "mapped", [99]], [[119837, 119837], "mapped", [100]], [[119838, 119838], "mapped", [101]], [[119839, 119839], "mapped", [102]], [[119840, 119840], "mapped", [103]], [[119841, 119841], "mapped", [104]], [[119842, 119842], "mapped", [105]], [[119843, 119843], "mapped", [106]], [[119844, 119844], "mapped", [107]], [[119845, 119845], "mapped", [108]], [[119846, 119846], "mapped", [109]], [[119847, 119847], "mapped", [110]], [[119848, 119848], "mapped", [111]], [[119849, 119849], "mapped", [112]], [[119850, 119850], "mapped", [113]], [[119851, 119851], "mapped", [114]], [[119852, 119852], "mapped", [115]], [[119853, 119853], "mapped", [116]], [[119854, 119854], "mapped", [117]], [[119855, 119855], "mapped", [118]], [[119856, 119856], "mapped", [119]], [[119857, 119857], "mapped", [120]], [[119858, 119858], "mapped", [121]], [[119859, 119859], "mapped", [122]], [[119860, 119860], "mapped", [97]], [[119861, 119861], "mapped", [98]], [[119862, 119862], "mapped", [99]], [[119863, 119863], "mapped", [100]], [[119864, 119864], "mapped", [101]], [[119865, 119865], "mapped", [102]], [[119866, 119866], "mapped", [103]], [[119867, 119867], "mapped", [104]], [[119868, 119868], "mapped", [105]], [[119869, 119869], "mapped", [106]], [[119870, 119870], "mapped", [107]], [[119871, 119871], "mapped", [108]], [[119872, 119872], "mapped", [109]], [[119873, 119873], "mapped", [110]], [[119874, 119874], "mapped", [111]], [[119875, 119875], "mapped", [112]], [[119876, 119876], "mapped", [113]], [[119877, 119877], "mapped", [114]], [[119878, 119878], "mapped", [115]], [[119879, 119879], "mapped", [116]], [[119880, 119880], "mapped", [117]], [[119881, 119881], "mapped", [118]], [[119882, 119882], "mapped", [119]], [[119883, 119883], "mapped", [120]], [[119884, 119884], "mapped", [121]], [[119885, 119885], "mapped", [122]], [[119886, 119886], "mapped", [97]], [[119887, 119887], "mapped", [98]], [[119888, 119888], "mapped", [99]], [[119889, 119889], "mapped", [100]], [[119890, 119890], "mapped", [101]], [[119891, 119891], "mapped", [102]], [[119892, 119892], "mapped", [103]], [[119893, 119893], "disallowed"], [[119894, 119894], "mapped", [105]], [[119895, 119895], "mapped", [106]], [[119896, 119896], "mapped", [107]], [[119897, 119897], "mapped", [108]], [[119898, 119898], "mapped", [109]], [[119899, 119899], "mapped", [110]], [[119900, 119900], "mapped", [111]], [[119901, 119901], "mapped", [112]], [[119902, 119902], "mapped", [113]], [[119903, 119903], "mapped", [114]], [[119904, 119904], "mapped", [115]], [[119905, 119905], "mapped", [116]], [[119906, 119906], "mapped", [117]], [[119907, 119907], "mapped", [118]], [[119908, 119908], "mapped", [119]], [[119909, 119909], "mapped", [120]], [[119910, 119910], "mapped", [121]], [[119911, 119911], "mapped", [122]], [[119912, 119912], "mapped", [97]], [[119913, 119913], "mapped", [98]], [[119914, 119914], "mapped", [99]], [[119915, 119915], "mapped", [100]], [[119916, 119916], "mapped", [101]], [[119917, 119917], "mapped", [102]], [[119918, 119918], "mapped", [103]], [[119919, 119919], "mapped", [104]], [[119920, 119920], "mapped", [105]], [[119921, 119921], "mapped", [106]], [[119922, 119922], "mapped", [107]], [[119923, 119923], "mapped", [108]], [[119924, 119924], "mapped", [109]], [[119925, 119925], "mapped", [110]], [[119926, 119926], "mapped", [111]], [[119927, 119927], "mapped", [112]], [[119928, 119928], "mapped", [113]], [[119929, 119929], "mapped", [114]], [[119930, 119930], "mapped", [115]], [[119931, 119931], "mapped", [116]], [[119932, 119932], "mapped", [117]], [[119933, 119933], "mapped", [118]], [[119934, 119934], "mapped", [119]], [[119935, 119935], "mapped", [120]], [[119936, 119936], "mapped", [121]], [[119937, 119937], "mapped", [122]], [[119938, 119938], "mapped", [97]], [[119939, 119939], "mapped", [98]], [[119940, 119940], "mapped", [99]], [[119941, 119941], "mapped", [100]], [[119942, 119942], "mapped", [101]], [[119943, 119943], "mapped", [102]], [[119944, 119944], "mapped", [103]], [[119945, 119945], "mapped", [104]], [[119946, 119946], "mapped", [105]], [[119947, 119947], "mapped", [106]], [[119948, 119948], "mapped", [107]], [[119949, 119949], "mapped", [108]], [[119950, 119950], "mapped", [109]], [[119951, 119951], "mapped", [110]], [[119952, 119952], "mapped", [111]], [[119953, 119953], "mapped", [112]], [[119954, 119954], "mapped", [113]], [[119955, 119955], "mapped", [114]], [[119956, 119956], "mapped", [115]], [[119957, 119957], "mapped", [116]], [[119958, 119958], "mapped", [117]], [[119959, 119959], "mapped", [118]], [[119960, 119960], "mapped", [119]], [[119961, 119961], "mapped", [120]], [[119962, 119962], "mapped", [121]], [[119963, 119963], "mapped", [122]], [[119964, 119964], "mapped", [97]], [[119965, 119965], "disallowed"], [[119966, 119966], "mapped", [99]], [[119967, 119967], "mapped", [100]], [[119968, 119969], "disallowed"], [[119970, 119970], "mapped", [103]], [[119971, 119972], "disallowed"], [[119973, 119973], "mapped", [106]], [[119974, 119974], "mapped", [107]], [[119975, 119976], "disallowed"], [[119977, 119977], "mapped", [110]], [[119978, 119978], "mapped", [111]], [[119979, 119979], "mapped", [112]], [[119980, 119980], "mapped", [113]], [[119981, 119981], "disallowed"], [[119982, 119982], "mapped", [115]], [[119983, 119983], "mapped", [116]], [[119984, 119984], "mapped", [117]], [[119985, 119985], "mapped", [118]], [[119986, 119986], "mapped", [119]], [[119987, 119987], "mapped", [120]], [[119988, 119988], "mapped", [121]], [[119989, 119989], "mapped", [122]], [[119990, 119990], "mapped", [97]], [[119991, 119991], "mapped", [98]], [[119992, 119992], "mapped", [99]], [[119993, 119993], "mapped", [100]], [[119994, 119994], "disallowed"], [[119995, 119995], "mapped", [102]], [[119996, 119996], "disallowed"], [[119997, 119997], "mapped", [104]], [[119998, 119998], "mapped", [105]], [[119999, 119999], "mapped", [106]], [[12e4, 12e4], "mapped", [107]], [[120001, 120001], "mapped", [108]], [[120002, 120002], "mapped", [109]], [[120003, 120003], "mapped", [110]], [[120004, 120004], "disallowed"], [[120005, 120005], "mapped", [112]], [[120006, 120006], "mapped", [113]], [[120007, 120007], "mapped", [114]], [[120008, 120008], "mapped", [115]], [[120009, 120009], "mapped", [116]], [[120010, 120010], "mapped", [117]], [[120011, 120011], "mapped", [118]], [[120012, 120012], "mapped", [119]], [[120013, 120013], "mapped", [120]], [[120014, 120014], "mapped", [121]], [[120015, 120015], "mapped", [122]], [[120016, 120016], "mapped", [97]], [[120017, 120017], "mapped", [98]], [[120018, 120018], "mapped", [99]], [[120019, 120019], "mapped", [100]], [[120020, 120020], "mapped", [101]], [[120021, 120021], "mapped", [102]], [[120022, 120022], "mapped", [103]], [[120023, 120023], "mapped", [104]], [[120024, 120024], "mapped", [105]], [[120025, 120025], "mapped", [106]], [[120026, 120026], "mapped", [107]], [[120027, 120027], "mapped", [108]], [[120028, 120028], "mapped", [109]], [[120029, 120029], "mapped", [110]], [[120030, 120030], "mapped", [111]], [[120031, 120031], "mapped", [112]], [[120032, 120032], "mapped", [113]], [[120033, 120033], "mapped", [114]], [[120034, 120034], "mapped", [115]], [[120035, 120035], "mapped", [116]], [[120036, 120036], "mapped", [117]], [[120037, 120037], "mapped", [118]], [[120038, 120038], "mapped", [119]], [[120039, 120039], "mapped", [120]], [[120040, 120040], "mapped", [121]], [[120041, 120041], "mapped", [122]], [[120042, 120042], "mapped", [97]], [[120043, 120043], "mapped", [98]], [[120044, 120044], "mapped", [99]], [[120045, 120045], "mapped", [100]], [[120046, 120046], "mapped", [101]], [[120047, 120047], "mapped", [102]], [[120048, 120048], "mapped", [103]], [[120049, 120049], "mapped", [104]], [[120050, 120050], "mapped", [105]], [[120051, 120051], "mapped", [106]], [[120052, 120052], "mapped", [107]], [[120053, 120053], "mapped", [108]], [[120054, 120054], "mapped", [109]], [[120055, 120055], "mapped", [110]], [[120056, 120056], "mapped", [111]], [[120057, 120057], "mapped", [112]], [[120058, 120058], "mapped", [113]], [[120059, 120059], "mapped", [114]], [[120060, 120060], "mapped", [115]], [[120061, 120061], "mapped", [116]], [[120062, 120062], "mapped", [117]], [[120063, 120063], "mapped", [118]], [[120064, 120064], "mapped", [119]], [[120065, 120065], "mapped", [120]], [[120066, 120066], "mapped", [121]], [[120067, 120067], "mapped", [122]], [[120068, 120068], "mapped", [97]], [[120069, 120069], "mapped", [98]], [[120070, 120070], "disallowed"], [[120071, 120071], "mapped", [100]], [[120072, 120072], "mapped", [101]], [[120073, 120073], "mapped", [102]], [[120074, 120074], "mapped", [103]], [[120075, 120076], "disallowed"], [[120077, 120077], "mapped", [106]], [[120078, 120078], "mapped", [107]], [[120079, 120079], "mapped", [108]], [[120080, 120080], "mapped", [109]], [[120081, 120081], "mapped", [110]], [[120082, 120082], "mapped", [111]], [[120083, 120083], "mapped", [112]], [[120084, 120084], "mapped", [113]], [[120085, 120085], "disallowed"], [[120086, 120086], "mapped", [115]], [[120087, 120087], "mapped", [116]], [[120088, 120088], "mapped", [117]], [[120089, 120089], "mapped", [118]], [[120090, 120090], "mapped", [119]], [[120091, 120091], "mapped", [120]], [[120092, 120092], "mapped", [121]], [[120093, 120093], "disallowed"], [[120094, 120094], "mapped", [97]], [[120095, 120095], "mapped", [98]], [[120096, 120096], "mapped", [99]], [[120097, 120097], "mapped", [100]], [[120098, 120098], "mapped", [101]], [[120099, 120099], "mapped", [102]], [[120100, 120100], "mapped", [103]], [[120101, 120101], "mapped", [104]], [[120102, 120102], "mapped", [105]], [[120103, 120103], "mapped", [106]], [[120104, 120104], "mapped", [107]], [[120105, 120105], "mapped", [108]], [[120106, 120106], "mapped", [109]], [[120107, 120107], "mapped", [110]], [[120108, 120108], "mapped", [111]], [[120109, 120109], "mapped", [112]], [[120110, 120110], "mapped", [113]], [[120111, 120111], "mapped", [114]], [[120112, 120112], "mapped", [115]], [[120113, 120113], "mapped", [116]], [[120114, 120114], "mapped", [117]], [[120115, 120115], "mapped", [118]], [[120116, 120116], "mapped", [119]], [[120117, 120117], "mapped", [120]], [[120118, 120118], "mapped", [121]], [[120119, 120119], "mapped", [122]], [[120120, 120120], "mapped", [97]], [[120121, 120121], "mapped", [98]], [[120122, 120122], "disallowed"], [[120123, 120123], "mapped", [100]], [[120124, 120124], "mapped", [101]], [[120125, 120125], "mapped", [102]], [[120126, 120126], "mapped", [103]], [[120127, 120127], "disallowed"], [[120128, 120128], "mapped", [105]], [[120129, 120129], "mapped", [106]], [[120130, 120130], "mapped", [107]], [[120131, 120131], "mapped", [108]], [[120132, 120132], "mapped", [109]], [[120133, 120133], "disallowed"], [[120134, 120134], "mapped", [111]], [[120135, 120137], "disallowed"], [[120138, 120138], "mapped", [115]], [[120139, 120139], "mapped", [116]], [[120140, 120140], "mapped", [117]], [[120141, 120141], "mapped", [118]], [[120142, 120142], "mapped", [119]], [[120143, 120143], "mapped", [120]], [[120144, 120144], "mapped", [121]], [[120145, 120145], "disallowed"], [[120146, 120146], "mapped", [97]], [[120147, 120147], "mapped", [98]], [[120148, 120148], "mapped", [99]], [[120149, 120149], "mapped", [100]], [[120150, 120150], "mapped", [101]], [[120151, 120151], "mapped", [102]], [[120152, 120152], "mapped", [103]], [[120153, 120153], "mapped", [104]], [[120154, 120154], "mapped", [105]], [[120155, 120155], "mapped", [106]], [[120156, 120156], "mapped", [107]], [[120157, 120157], "mapped", [108]], [[120158, 120158], "mapped", [109]], [[120159, 120159], "mapped", [110]], [[120160, 120160], "mapped", [111]], [[120161, 120161], "mapped", [112]], [[120162, 120162], "mapped", [113]], [[120163, 120163], "mapped", [114]], [[120164, 120164], "mapped", [115]], [[120165, 120165], "mapped", [116]], [[120166, 120166], "mapped", [117]], [[120167, 120167], "mapped", [118]], [[120168, 120168], "mapped", [119]], [[120169, 120169], "mapped", [120]], [[120170, 120170], "mapped", [121]], [[120171, 120171], "mapped", [122]], [[120172, 120172], "mapped", [97]], [[120173, 120173], "mapped", [98]], [[120174, 120174], "mapped", [99]], [[120175, 120175], "mapped", [100]], [[120176, 120176], "mapped", [101]], [[120177, 120177], "mapped", [102]], [[120178, 120178], "mapped", [103]], [[120179, 120179], "mapped", [104]], [[120180, 120180], "mapped", [105]], [[120181, 120181], "mapped", [106]], [[120182, 120182], "mapped", [107]], [[120183, 120183], "mapped", [108]], [[120184, 120184], "mapped", [109]], [[120185, 120185], "mapped", [110]], [[120186, 120186], "mapped", [111]], [[120187, 120187], "mapped", [112]], [[120188, 120188], "mapped", [113]], [[120189, 120189], "mapped", [114]], [[120190, 120190], "mapped", [115]], [[120191, 120191], "mapped", [116]], [[120192, 120192], "mapped", [117]], [[120193, 120193], "mapped", [118]], [[120194, 120194], "mapped", [119]], [[120195, 120195], "mapped", [120]], [[120196, 120196], "mapped", [121]], [[120197, 120197], "mapped", [122]], [[120198, 120198], "mapped", [97]], [[120199, 120199], "mapped", [98]], [[120200, 120200], "mapped", [99]], [[120201, 120201], "mapped", [100]], [[120202, 120202], "mapped", [101]], [[120203, 120203], "mapped", [102]], [[120204, 120204], "mapped", [103]], [[120205, 120205], "mapped", [104]], [[120206, 120206], "mapped", [105]], [[120207, 120207], "mapped", [106]], [[120208, 120208], "mapped", [107]], [[120209, 120209], "mapped", [108]], [[120210, 120210], "mapped", [109]], [[120211, 120211], "mapped", [110]], [[120212, 120212], "mapped", [111]], [[120213, 120213], "mapped", [112]], [[120214, 120214], "mapped", [113]], [[120215, 120215], "mapped", [114]], [[120216, 120216], "mapped", [115]], [[120217, 120217], "mapped", [116]], [[120218, 120218], "mapped", [117]], [[120219, 120219], "mapped", [118]], [[120220, 120220], "mapped", [119]], [[120221, 120221], "mapped", [120]], [[120222, 120222], "mapped", [121]], [[120223, 120223], "mapped", [122]], [[120224, 120224], "mapped", [97]], [[120225, 120225], "mapped", [98]], [[120226, 120226], "mapped", [99]], [[120227, 120227], "mapped", [100]], [[120228, 120228], "mapped", [101]], [[120229, 120229], "mapped", [102]], [[120230, 120230], "mapped", [103]], [[120231, 120231], "mapped", [104]], [[120232, 120232], "mapped", [105]], [[120233, 120233], "mapped", [106]], [[120234, 120234], "mapped", [107]], [[120235, 120235], "mapped", [108]], [[120236, 120236], "mapped", [109]], [[120237, 120237], "mapped", [110]], [[120238, 120238], "mapped", [111]], [[120239, 120239], "mapped", [112]], [[120240, 120240], "mapped", [113]], [[120241, 120241], "mapped", [114]], [[120242, 120242], "mapped", [115]], [[120243, 120243], "mapped", [116]], [[120244, 120244], "mapped", [117]], [[120245, 120245], "mapped", [118]], [[120246, 120246], "mapped", [119]], [[120247, 120247], "mapped", [120]], [[120248, 120248], "mapped", [121]], [[120249, 120249], "mapped", [122]], [[120250, 120250], "mapped", [97]], [[120251, 120251], "mapped", [98]], [[120252, 120252], "mapped", [99]], [[120253, 120253], "mapped", [100]], [[120254, 120254], "mapped", [101]], [[120255, 120255], "mapped", [102]], [[120256, 120256], "mapped", [103]], [[120257, 120257], "mapped", [104]], [[120258, 120258], "mapped", [105]], [[120259, 120259], "mapped", [106]], [[120260, 120260], "mapped", [107]], [[120261, 120261], "mapped", [108]], [[120262, 120262], "mapped", [109]], [[120263, 120263], "mapped", [110]], [[120264, 120264], "mapped", [111]], [[120265, 120265], "mapped", [112]], [[120266, 120266], "mapped", [113]], [[120267, 120267], "mapped", [114]], [[120268, 120268], "mapped", [115]], [[120269, 120269], "mapped", [116]], [[120270, 120270], "mapped", [117]], [[120271, 120271], "mapped", [118]], [[120272, 120272], "mapped", [119]], [[120273, 120273], "mapped", [120]], [[120274, 120274], "mapped", [121]], [[120275, 120275], "mapped", [122]], [[120276, 120276], "mapped", [97]], [[120277, 120277], "mapped", [98]], [[120278, 120278], "mapped", [99]], [[120279, 120279], "mapped", [100]], [[120280, 120280], "mapped", [101]], [[120281, 120281], "mapped", [102]], [[120282, 120282], "mapped", [103]], [[120283, 120283], "mapped", [104]], [[120284, 120284], "mapped", [105]], [[120285, 120285], "mapped", [106]], [[120286, 120286], "mapped", [107]], [[120287, 120287], "mapped", [108]], [[120288, 120288], "mapped", [109]], [[120289, 120289], "mapped", [110]], [[120290, 120290], "mapped", [111]], [[120291, 120291], "mapped", [112]], [[120292, 120292], "mapped", [113]], [[120293, 120293], "mapped", [114]], [[120294, 120294], "mapped", [115]], [[120295, 120295], "mapped", [116]], [[120296, 120296], "mapped", [117]], [[120297, 120297], "mapped", [118]], [[120298, 120298], "mapped", [119]], [[120299, 120299], "mapped", [120]], [[120300, 120300], "mapped", [121]], [[120301, 120301], "mapped", [122]], [[120302, 120302], "mapped", [97]], [[120303, 120303], "mapped", [98]], [[120304, 120304], "mapped", [99]], [[120305, 120305], "mapped", [100]], [[120306, 120306], "mapped", [101]], [[120307, 120307], "mapped", [102]], [[120308, 120308], "mapped", [103]], [[120309, 120309], "mapped", [104]], [[120310, 120310], "mapped", [105]], [[120311, 120311], "mapped", [106]], [[120312, 120312], "mapped", [107]], [[120313, 120313], "mapped", [108]], [[120314, 120314], "mapped", [109]], [[120315, 120315], "mapped", [110]], [[120316, 120316], "mapped", [111]], [[120317, 120317], "mapped", [112]], [[120318, 120318], "mapped", [113]], [[120319, 120319], "mapped", [114]], [[120320, 120320], "mapped", [115]], [[120321, 120321], "mapped", [116]], [[120322, 120322], "mapped", [117]], [[120323, 120323], "mapped", [118]], [[120324, 120324], "mapped", [119]], [[120325, 120325], "mapped", [120]], [[120326, 120326], "mapped", [121]], [[120327, 120327], "mapped", [122]], [[120328, 120328], "mapped", [97]], [[120329, 120329], "mapped", [98]], [[120330, 120330], "mapped", [99]], [[120331, 120331], "mapped", [100]], [[120332, 120332], "mapped", [101]], [[120333, 120333], "mapped", [102]], [[120334, 120334], "mapped", [103]], [[120335, 120335], "mapped", [104]], [[120336, 120336], "mapped", [105]], [[120337, 120337], "mapped", [106]], [[120338, 120338], "mapped", [107]], [[120339, 120339], "mapped", [108]], [[120340, 120340], "mapped", [109]], [[120341, 120341], "mapped", [110]], [[120342, 120342], "mapped", [111]], [[120343, 120343], "mapped", [112]], [[120344, 120344], "mapped", [113]], [[120345, 120345], "mapped", [114]], [[120346, 120346], "mapped", [115]], [[120347, 120347], "mapped", [116]], [[120348, 120348], "mapped", [117]], [[120349, 120349], "mapped", [118]], [[120350, 120350], "mapped", [119]], [[120351, 120351], "mapped", [120]], [[120352, 120352], "mapped", [121]], [[120353, 120353], "mapped", [122]], [[120354, 120354], "mapped", [97]], [[120355, 120355], "mapped", [98]], [[120356, 120356], "mapped", [99]], [[120357, 120357], "mapped", [100]], [[120358, 120358], "mapped", [101]], [[120359, 120359], "mapped", [102]], [[120360, 120360], "mapped", [103]], [[120361, 120361], "mapped", [104]], [[120362, 120362], "mapped", [105]], [[120363, 120363], "mapped", [106]], [[120364, 120364], "mapped", [107]], [[120365, 120365], "mapped", [108]], [[120366, 120366], "mapped", [109]], [[120367, 120367], "mapped", [110]], [[120368, 120368], "mapped", [111]], [[120369, 120369], "mapped", [112]], [[120370, 120370], "mapped", [113]], [[120371, 120371], "mapped", [114]], [[120372, 120372], "mapped", [115]], [[120373, 120373], "mapped", [116]], [[120374, 120374], "mapped", [117]], [[120375, 120375], "mapped", [118]], [[120376, 120376], "mapped", [119]], [[120377, 120377], "mapped", [120]], [[120378, 120378], "mapped", [121]], [[120379, 120379], "mapped", [122]], [[120380, 120380], "mapped", [97]], [[120381, 120381], "mapped", [98]], [[120382, 120382], "mapped", [99]], [[120383, 120383], "mapped", [100]], [[120384, 120384], "mapped", [101]], [[120385, 120385], "mapped", [102]], [[120386, 120386], "mapped", [103]], [[120387, 120387], "mapped", [104]], [[120388, 120388], "mapped", [105]], [[120389, 120389], "mapped", [106]], [[120390, 120390], "mapped", [107]], [[120391, 120391], "mapped", [108]], [[120392, 120392], "mapped", [109]], [[120393, 120393], "mapped", [110]], [[120394, 120394], "mapped", [111]], [[120395, 120395], "mapped", [112]], [[120396, 120396], "mapped", [113]], [[120397, 120397], "mapped", [114]], [[120398, 120398], "mapped", [115]], [[120399, 120399], "mapped", [116]], [[120400, 120400], "mapped", [117]], [[120401, 120401], "mapped", [118]], [[120402, 120402], "mapped", [119]], [[120403, 120403], "mapped", [120]], [[120404, 120404], "mapped", [121]], [[120405, 120405], "mapped", [122]], [[120406, 120406], "mapped", [97]], [[120407, 120407], "mapped", [98]], [[120408, 120408], "mapped", [99]], [[120409, 120409], "mapped", [100]], [[120410, 120410], "mapped", [101]], [[120411, 120411], "mapped", [102]], [[120412, 120412], "mapped", [103]], [[120413, 120413], "mapped", [104]], [[120414, 120414], "mapped", [105]], [[120415, 120415], "mapped", [106]], [[120416, 120416], "mapped", [107]], [[120417, 120417], "mapped", [108]], [[120418, 120418], "mapped", [109]], [[120419, 120419], "mapped", [110]], [[120420, 120420], "mapped", [111]], [[120421, 120421], "mapped", [112]], [[120422, 120422], "mapped", [113]], [[120423, 120423], "mapped", [114]], [[120424, 120424], "mapped", [115]], [[120425, 120425], "mapped", [116]], [[120426, 120426], "mapped", [117]], [[120427, 120427], "mapped", [118]], [[120428, 120428], "mapped", [119]], [[120429, 120429], "mapped", [120]], [[120430, 120430], "mapped", [121]], [[120431, 120431], "mapped", [122]], [[120432, 120432], "mapped", [97]], [[120433, 120433], "mapped", [98]], [[120434, 120434], "mapped", [99]], [[120435, 120435], "mapped", [100]], [[120436, 120436], "mapped", [101]], [[120437, 120437], "mapped", [102]], [[120438, 120438], "mapped", [103]], [[120439, 120439], "mapped", [104]], [[120440, 120440], "mapped", [105]], [[120441, 120441], "mapped", [106]], [[120442, 120442], "mapped", [107]], [[120443, 120443], "mapped", [108]], [[120444, 120444], "mapped", [109]], [[120445, 120445], "mapped", [110]], [[120446, 120446], "mapped", [111]], [[120447, 120447], "mapped", [112]], [[120448, 120448], "mapped", [113]], [[120449, 120449], "mapped", [114]], [[120450, 120450], "mapped", [115]], [[120451, 120451], "mapped", [116]], [[120452, 120452], "mapped", [117]], [[120453, 120453], "mapped", [118]], [[120454, 120454], "mapped", [119]], [[120455, 120455], "mapped", [120]], [[120456, 120456], "mapped", [121]], [[120457, 120457], "mapped", [122]], [[120458, 120458], "mapped", [97]], [[120459, 120459], "mapped", [98]], [[120460, 120460], "mapped", [99]], [[120461, 120461], "mapped", [100]], [[120462, 120462], "mapped", [101]], [[120463, 120463], "mapped", [102]], [[120464, 120464], "mapped", [103]], [[120465, 120465], "mapped", [104]], [[120466, 120466], "mapped", [105]], [[120467, 120467], "mapped", [106]], [[120468, 120468], "mapped", [107]], [[120469, 120469], "mapped", [108]], [[120470, 120470], "mapped", [109]], [[120471, 120471], "mapped", [110]], [[120472, 120472], "mapped", [111]], [[120473, 120473], "mapped", [112]], [[120474, 120474], "mapped", [113]], [[120475, 120475], "mapped", [114]], [[120476, 120476], "mapped", [115]], [[120477, 120477], "mapped", [116]], [[120478, 120478], "mapped", [117]], [[120479, 120479], "mapped", [118]], [[120480, 120480], "mapped", [119]], [[120481, 120481], "mapped", [120]], [[120482, 120482], "mapped", [121]], [[120483, 120483], "mapped", [122]], [[120484, 120484], "mapped", [305]], [[120485, 120485], "mapped", [567]], [[120486, 120487], "disallowed"], [[120488, 120488], "mapped", [945]], [[120489, 120489], "mapped", [946]], [[120490, 120490], "mapped", [947]], [[120491, 120491], "mapped", [948]], [[120492, 120492], "mapped", [949]], [[120493, 120493], "mapped", [950]], [[120494, 120494], "mapped", [951]], [[120495, 120495], "mapped", [952]], [[120496, 120496], "mapped", [953]], [[120497, 120497], "mapped", [954]], [[120498, 120498], "mapped", [955]], [[120499, 120499], "mapped", [956]], [[120500, 120500], "mapped", [957]], [[120501, 120501], "mapped", [958]], [[120502, 120502], "mapped", [959]], [[120503, 120503], "mapped", [960]], [[120504, 120504], "mapped", [961]], [[120505, 120505], "mapped", [952]], [[120506, 120506], "mapped", [963]], [[120507, 120507], "mapped", [964]], [[120508, 120508], "mapped", [965]], [[120509, 120509], "mapped", [966]], [[120510, 120510], "mapped", [967]], [[120511, 120511], "mapped", [968]], [[120512, 120512], "mapped", [969]], [[120513, 120513], "mapped", [8711]], [[120514, 120514], "mapped", [945]], [[120515, 120515], "mapped", [946]], [[120516, 120516], "mapped", [947]], [[120517, 120517], "mapped", [948]], [[120518, 120518], "mapped", [949]], [[120519, 120519], "mapped", [950]], [[120520, 120520], "mapped", [951]], [[120521, 120521], "mapped", [952]], [[120522, 120522], "mapped", [953]], [[120523, 120523], "mapped", [954]], [[120524, 120524], "mapped", [955]], [[120525, 120525], "mapped", [956]], [[120526, 120526], "mapped", [957]], [[120527, 120527], "mapped", [958]], [[120528, 120528], "mapped", [959]], [[120529, 120529], "mapped", [960]], [[120530, 120530], "mapped", [961]], [[120531, 120532], "mapped", [963]], [[120533, 120533], "mapped", [964]], [[120534, 120534], "mapped", [965]], [[120535, 120535], "mapped", [966]], [[120536, 120536], "mapped", [967]], [[120537, 120537], "mapped", [968]], [[120538, 120538], "mapped", [969]], [[120539, 120539], "mapped", [8706]], [[120540, 120540], "mapped", [949]], [[120541, 120541], "mapped", [952]], [[120542, 120542], "mapped", [954]], [[120543, 120543], "mapped", [966]], [[120544, 120544], "mapped", [961]], [[120545, 120545], "mapped", [960]], [[120546, 120546], "mapped", [945]], [[120547, 120547], "mapped", [946]], [[120548, 120548], "mapped", [947]], [[120549, 120549], "mapped", [948]], [[120550, 120550], "mapped", [949]], [[120551, 120551], "mapped", [950]], [[120552, 120552], "mapped", [951]], [[120553, 120553], "mapped", [952]], [[120554, 120554], "mapped", [953]], [[120555, 120555], "mapped", [954]], [[120556, 120556], "mapped", [955]], [[120557, 120557], "mapped", [956]], [[120558, 120558], "mapped", [957]], [[120559, 120559], "mapped", [958]], [[120560, 120560], "mapped", [959]], [[120561, 120561], "mapped", [960]], [[120562, 120562], "mapped", [961]], [[120563, 120563], "mapped", [952]], [[120564, 120564], "mapped", [963]], [[120565, 120565], "mapped", [964]], [[120566, 120566], "mapped", [965]], [[120567, 120567], "mapped", [966]], [[120568, 120568], "mapped", [967]], [[120569, 120569], "mapped", [968]], [[120570, 120570], "mapped", [969]], [[120571, 120571], "mapped", [8711]], [[120572, 120572], "mapped", [945]], [[120573, 120573], "mapped", [946]], [[120574, 120574], "mapped", [947]], [[120575, 120575], "mapped", [948]], [[120576, 120576], "mapped", [949]], [[120577, 120577], "mapped", [950]], [[120578, 120578], "mapped", [951]], [[120579, 120579], "mapped", [952]], [[120580, 120580], "mapped", [953]], [[120581, 120581], "mapped", [954]], [[120582, 120582], "mapped", [955]], [[120583, 120583], "mapped", [956]], [[120584, 120584], "mapped", [957]], [[120585, 120585], "mapped", [958]], [[120586, 120586], "mapped", [959]], [[120587, 120587], "mapped", [960]], [[120588, 120588], "mapped", [961]], [[120589, 120590], "mapped", [963]], [[120591, 120591], "mapped", [964]], [[120592, 120592], "mapped", [965]], [[120593, 120593], "mapped", [966]], [[120594, 120594], "mapped", [967]], [[120595, 120595], "mapped", [968]], [[120596, 120596], "mapped", [969]], [[120597, 120597], "mapped", [8706]], [[120598, 120598], "mapped", [949]], [[120599, 120599], "mapped", [952]], [[120600, 120600], "mapped", [954]], [[120601, 120601], "mapped", [966]], [[120602, 120602], "mapped", [961]], [[120603, 120603], "mapped", [960]], [[120604, 120604], "mapped", [945]], [[120605, 120605], "mapped", [946]], [[120606, 120606], "mapped", [947]], [[120607, 120607], "mapped", [948]], [[120608, 120608], "mapped", [949]], [[120609, 120609], "mapped", [950]], [[120610, 120610], "mapped", [951]], [[120611, 120611], "mapped", [952]], [[120612, 120612], "mapped", [953]], [[120613, 120613], "mapped", [954]], [[120614, 120614], "mapped", [955]], [[120615, 120615], "mapped", [956]], [[120616, 120616], "mapped", [957]], [[120617, 120617], "mapped", [958]], [[120618, 120618], "mapped", [959]], [[120619, 120619], "mapped", [960]], [[120620, 120620], "mapped", [961]], [[120621, 120621], "mapped", [952]], [[120622, 120622], "mapped", [963]], [[120623, 120623], "mapped", [964]], [[120624, 120624], "mapped", [965]], [[120625, 120625], "mapped", [966]], [[120626, 120626], "mapped", [967]], [[120627, 120627], "mapped", [968]], [[120628, 120628], "mapped", [969]], [[120629, 120629], "mapped", [8711]], [[120630, 120630], "mapped", [945]], [[120631, 120631], "mapped", [946]], [[120632, 120632], "mapped", [947]], [[120633, 120633], "mapped", [948]], [[120634, 120634], "mapped", [949]], [[120635, 120635], "mapped", [950]], [[120636, 120636], "mapped", [951]], [[120637, 120637], "mapped", [952]], [[120638, 120638], "mapped", [953]], [[120639, 120639], "mapped", [954]], [[120640, 120640], "mapped", [955]], [[120641, 120641], "mapped", [956]], [[120642, 120642], "mapped", [957]], [[120643, 120643], "mapped", [958]], [[120644, 120644], "mapped", [959]], [[120645, 120645], "mapped", [960]], [[120646, 120646], "mapped", [961]], [[120647, 120648], "mapped", [963]], [[120649, 120649], "mapped", [964]], [[120650, 120650], "mapped", [965]], [[120651, 120651], "mapped", [966]], [[120652, 120652], "mapped", [967]], [[120653, 120653], "mapped", [968]], [[120654, 120654], "mapped", [969]], [[120655, 120655], "mapped", [8706]], [[120656, 120656], "mapped", [949]], [[120657, 120657], "mapped", [952]], [[120658, 120658], "mapped", [954]], [[120659, 120659], "mapped", [966]], [[120660, 120660], "mapped", [961]], [[120661, 120661], "mapped", [960]], [[120662, 120662], "mapped", [945]], [[120663, 120663], "mapped", [946]], [[120664, 120664], "mapped", [947]], [[120665, 120665], "mapped", [948]], [[120666, 120666], "mapped", [949]], [[120667, 120667], "mapped", [950]], [[120668, 120668], "mapped", [951]], [[120669, 120669], "mapped", [952]], [[120670, 120670], "mapped", [953]], [[120671, 120671], "mapped", [954]], [[120672, 120672], "mapped", [955]], [[120673, 120673], "mapped", [956]], [[120674, 120674], "mapped", [957]], [[120675, 120675], "mapped", [958]], [[120676, 120676], "mapped", [959]], [[120677, 120677], "mapped", [960]], [[120678, 120678], "mapped", [961]], [[120679, 120679], "mapped", [952]], [[120680, 120680], "mapped", [963]], [[120681, 120681], "mapped", [964]], [[120682, 120682], "mapped", [965]], [[120683, 120683], "mapped", [966]], [[120684, 120684], "mapped", [967]], [[120685, 120685], "mapped", [968]], [[120686, 120686], "mapped", [969]], [[120687, 120687], "mapped", [8711]], [[120688, 120688], "mapped", [945]], [[120689, 120689], "mapped", [946]], [[120690, 120690], "mapped", [947]], [[120691, 120691], "mapped", [948]], [[120692, 120692], "mapped", [949]], [[120693, 120693], "mapped", [950]], [[120694, 120694], "mapped", [951]], [[120695, 120695], "mapped", [952]], [[120696, 120696], "mapped", [953]], [[120697, 120697], "mapped", [954]], [[120698, 120698], "mapped", [955]], [[120699, 120699], "mapped", [956]], [[120700, 120700], "mapped", [957]], [[120701, 120701], "mapped", [958]], [[120702, 120702], "mapped", [959]], [[120703, 120703], "mapped", [960]], [[120704, 120704], "mapped", [961]], [[120705, 120706], "mapped", [963]], [[120707, 120707], "mapped", [964]], [[120708, 120708], "mapped", [965]], [[120709, 120709], "mapped", [966]], [[120710, 120710], "mapped", [967]], [[120711, 120711], "mapped", [968]], [[120712, 120712], "mapped", [969]], [[120713, 120713], "mapped", [8706]], [[120714, 120714], "mapped", [949]], [[120715, 120715], "mapped", [952]], [[120716, 120716], "mapped", [954]], [[120717, 120717], "mapped", [966]], [[120718, 120718], "mapped", [961]], [[120719, 120719], "mapped", [960]], [[120720, 120720], "mapped", [945]], [[120721, 120721], "mapped", [946]], [[120722, 120722], "mapped", [947]], [[120723, 120723], "mapped", [948]], [[120724, 120724], "mapped", [949]], [[120725, 120725], "mapped", [950]], [[120726, 120726], "mapped", [951]], [[120727, 120727], "mapped", [952]], [[120728, 120728], "mapped", [953]], [[120729, 120729], "mapped", [954]], [[120730, 120730], "mapped", [955]], [[120731, 120731], "mapped", [956]], [[120732, 120732], "mapped", [957]], [[120733, 120733], "mapped", [958]], [[120734, 120734], "mapped", [959]], [[120735, 120735], "mapped", [960]], [[120736, 120736], "mapped", [961]], [[120737, 120737], "mapped", [952]], [[120738, 120738], "mapped", [963]], [[120739, 120739], "mapped", [964]], [[120740, 120740], "mapped", [965]], [[120741, 120741], "mapped", [966]], [[120742, 120742], "mapped", [967]], [[120743, 120743], "mapped", [968]], [[120744, 120744], "mapped", [969]], [[120745, 120745], "mapped", [8711]], [[120746, 120746], "mapped", [945]], [[120747, 120747], "mapped", [946]], [[120748, 120748], "mapped", [947]], [[120749, 120749], "mapped", [948]], [[120750, 120750], "mapped", [949]], [[120751, 120751], "mapped", [950]], [[120752, 120752], "mapped", [951]], [[120753, 120753], "mapped", [952]], [[120754, 120754], "mapped", [953]], [[120755, 120755], "mapped", [954]], [[120756, 120756], "mapped", [955]], [[120757, 120757], "mapped", [956]], [[120758, 120758], "mapped", [957]], [[120759, 120759], "mapped", [958]], [[120760, 120760], "mapped", [959]], [[120761, 120761], "mapped", [960]], [[120762, 120762], "mapped", [961]], [[120763, 120764], "mapped", [963]], [[120765, 120765], "mapped", [964]], [[120766, 120766], "mapped", [965]], [[120767, 120767], "mapped", [966]], [[120768, 120768], "mapped", [967]], [[120769, 120769], "mapped", [968]], [[120770, 120770], "mapped", [969]], [[120771, 120771], "mapped", [8706]], [[120772, 120772], "mapped", [949]], [[120773, 120773], "mapped", [952]], [[120774, 120774], "mapped", [954]], [[120775, 120775], "mapped", [966]], [[120776, 120776], "mapped", [961]], [[120777, 120777], "mapped", [960]], [[120778, 120779], "mapped", [989]], [[120780, 120781], "disallowed"], [[120782, 120782], "mapped", [48]], [[120783, 120783], "mapped", [49]], [[120784, 120784], "mapped", [50]], [[120785, 120785], "mapped", [51]], [[120786, 120786], "mapped", [52]], [[120787, 120787], "mapped", [53]], [[120788, 120788], "mapped", [54]], [[120789, 120789], "mapped", [55]], [[120790, 120790], "mapped", [56]], [[120791, 120791], "mapped", [57]], [[120792, 120792], "mapped", [48]], [[120793, 120793], "mapped", [49]], [[120794, 120794], "mapped", [50]], [[120795, 120795], "mapped", [51]], [[120796, 120796], "mapped", [52]], [[120797, 120797], "mapped", [53]], [[120798, 120798], "mapped", [54]], [[120799, 120799], "mapped", [55]], [[120800, 120800], "mapped", [56]], [[120801, 120801], "mapped", [57]], [[120802, 120802], "mapped", [48]], [[120803, 120803], "mapped", [49]], [[120804, 120804], "mapped", [50]], [[120805, 120805], "mapped", [51]], [[120806, 120806], "mapped", [52]], [[120807, 120807], "mapped", [53]], [[120808, 120808], "mapped", [54]], [[120809, 120809], "mapped", [55]], [[120810, 120810], "mapped", [56]], [[120811, 120811], "mapped", [57]], [[120812, 120812], "mapped", [48]], [[120813, 120813], "mapped", [49]], [[120814, 120814], "mapped", [50]], [[120815, 120815], "mapped", [51]], [[120816, 120816], "mapped", [52]], [[120817, 120817], "mapped", [53]], [[120818, 120818], "mapped", [54]], [[120819, 120819], "mapped", [55]], [[120820, 120820], "mapped", [56]], [[120821, 120821], "mapped", [57]], [[120822, 120822], "mapped", [48]], [[120823, 120823], "mapped", [49]], [[120824, 120824], "mapped", [50]], [[120825, 120825], "mapped", [51]], [[120826, 120826], "mapped", [52]], [[120827, 120827], "mapped", [53]], [[120828, 120828], "mapped", [54]], [[120829, 120829], "mapped", [55]], [[120830, 120830], "mapped", [56]], [[120831, 120831], "mapped", [57]], [[120832, 121343], "valid", [], "NV8"], [[121344, 121398], "valid"], [[121399, 121402], "valid", [], "NV8"], [[121403, 121452], "valid"], [[121453, 121460], "valid", [], "NV8"], [[121461, 121461], "valid"], [[121462, 121475], "valid", [], "NV8"], [[121476, 121476], "valid"], [[121477, 121483], "valid", [], "NV8"], [[121484, 121498], "disallowed"], [[121499, 121503], "valid"], [[121504, 121504], "disallowed"], [[121505, 121519], "valid"], [[121520, 124927], "disallowed"], [[124928, 125124], "valid"], [[125125, 125126], "disallowed"], [[125127, 125135], "valid", [], "NV8"], [[125136, 125142], "valid"], [[125143, 126463], "disallowed"], [[126464, 126464], "mapped", [1575]], [[126465, 126465], "mapped", [1576]], [[126466, 126466], "mapped", [1580]], [[126467, 126467], "mapped", [1583]], [[126468, 126468], "disallowed"], [[126469, 126469], "mapped", [1608]], [[126470, 126470], "mapped", [1586]], [[126471, 126471], "mapped", [1581]], [[126472, 126472], "mapped", [1591]], [[126473, 126473], "mapped", [1610]], [[126474, 126474], "mapped", [1603]], [[126475, 126475], "mapped", [1604]], [[126476, 126476], "mapped", [1605]], [[126477, 126477], "mapped", [1606]], [[126478, 126478], "mapped", [1587]], [[126479, 126479], "mapped", [1593]], [[126480, 126480], "mapped", [1601]], [[126481, 126481], "mapped", [1589]], [[126482, 126482], "mapped", [1602]], [[126483, 126483], "mapped", [1585]], [[126484, 126484], "mapped", [1588]], [[126485, 126485], "mapped", [1578]], [[126486, 126486], "mapped", [1579]], [[126487, 126487], "mapped", [1582]], [[126488, 126488], "mapped", [1584]], [[126489, 126489], "mapped", [1590]], [[126490, 126490], "mapped", [1592]], [[126491, 126491], "mapped", [1594]], [[126492, 126492], "mapped", [1646]], [[126493, 126493], "mapped", [1722]], [[126494, 126494], "mapped", [1697]], [[126495, 126495], "mapped", [1647]], [[126496, 126496], "disallowed"], [[126497, 126497], "mapped", [1576]], [[126498, 126498], "mapped", [1580]], [[126499, 126499], "disallowed"], [[126500, 126500], "mapped", [1607]], [[126501, 126502], "disallowed"], [[126503, 126503], "mapped", [1581]], [[126504, 126504], "disallowed"], [[126505, 126505], "mapped", [1610]], [[126506, 126506], "mapped", [1603]], [[126507, 126507], "mapped", [1604]], [[126508, 126508], "mapped", [1605]], [[126509, 126509], "mapped", [1606]], [[126510, 126510], "mapped", [1587]], [[126511, 126511], "mapped", [1593]], [[126512, 126512], "mapped", [1601]], [[126513, 126513], "mapped", [1589]], [[126514, 126514], "mapped", [1602]], [[126515, 126515], "disallowed"], [[126516, 126516], "mapped", [1588]], [[126517, 126517], "mapped", [1578]], [[126518, 126518], "mapped", [1579]], [[126519, 126519], "mapped", [1582]], [[126520, 126520], "disallowed"], [[126521, 126521], "mapped", [1590]], [[126522, 126522], "disallowed"], [[126523, 126523], "mapped", [1594]], [[126524, 126529], "disallowed"], [[126530, 126530], "mapped", [1580]], [[126531, 126534], "disallowed"], [[126535, 126535], "mapped", [1581]], [[126536, 126536], "disallowed"], [[126537, 126537], "mapped", [1610]], [[126538, 126538], "disallowed"], [[126539, 126539], "mapped", [1604]], [[126540, 126540], "disallowed"], [[126541, 126541], "mapped", [1606]], [[126542, 126542], "mapped", [1587]], [[126543, 126543], "mapped", [1593]], [[126544, 126544], "disallowed"], [[126545, 126545], "mapped", [1589]], [[126546, 126546], "mapped", [1602]], [[126547, 126547], "disallowed"], [[126548, 126548], "mapped", [1588]], [[126549, 126550], "disallowed"], [[126551, 126551], "mapped", [1582]], [[126552, 126552], "disallowed"], [[126553, 126553], "mapped", [1590]], [[126554, 126554], "disallowed"], [[126555, 126555], "mapped", [1594]], [[126556, 126556], "disallowed"], [[126557, 126557], "mapped", [1722]], [[126558, 126558], "disallowed"], [[126559, 126559], "mapped", [1647]], [[126560, 126560], "disallowed"], [[126561, 126561], "mapped", [1576]], [[126562, 126562], "mapped", [1580]], [[126563, 126563], "disallowed"], [[126564, 126564], "mapped", [1607]], [[126565, 126566], "disallowed"], [[126567, 126567], "mapped", [1581]], [[126568, 126568], "mapped", [1591]], [[126569, 126569], "mapped", [1610]], [[126570, 126570], "mapped", [1603]], [[126571, 126571], "disallowed"], [[126572, 126572], "mapped", [1605]], [[126573, 126573], "mapped", [1606]], [[126574, 126574], "mapped", [1587]], [[126575, 126575], "mapped", [1593]], [[126576, 126576], "mapped", [1601]], [[126577, 126577], "mapped", [1589]], [[126578, 126578], "mapped", [1602]], [[126579, 126579], "disallowed"], [[126580, 126580], "mapped", [1588]], [[126581, 126581], "mapped", [1578]], [[126582, 126582], "mapped", [1579]], [[126583, 126583], "mapped", [1582]], [[126584, 126584], "disallowed"], [[126585, 126585], "mapped", [1590]], [[126586, 126586], "mapped", [1592]], [[126587, 126587], "mapped", [1594]], [[126588, 126588], "mapped", [1646]], [[126589, 126589], "disallowed"], [[126590, 126590], "mapped", [1697]], [[126591, 126591], "disallowed"], [[126592, 126592], "mapped", [1575]], [[126593, 126593], "mapped", [1576]], [[126594, 126594], "mapped", [1580]], [[126595, 126595], "mapped", [1583]], [[126596, 126596], "mapped", [1607]], [[126597, 126597], "mapped", [1608]], [[126598, 126598], "mapped", [1586]], [[126599, 126599], "mapped", [1581]], [[126600, 126600], "mapped", [1591]], [[126601, 126601], "mapped", [1610]], [[126602, 126602], "disallowed"], [[126603, 126603], "mapped", [1604]], [[126604, 126604], "mapped", [1605]], [[126605, 126605], "mapped", [1606]], [[126606, 126606], "mapped", [1587]], [[126607, 126607], "mapped", [1593]], [[126608, 126608], "mapped", [1601]], [[126609, 126609], "mapped", [1589]], [[126610, 126610], "mapped", [1602]], [[126611, 126611], "mapped", [1585]], [[126612, 126612], "mapped", [1588]], [[126613, 126613], "mapped", [1578]], [[126614, 126614], "mapped", [1579]], [[126615, 126615], "mapped", [1582]], [[126616, 126616], "mapped", [1584]], [[126617, 126617], "mapped", [1590]], [[126618, 126618], "mapped", [1592]], [[126619, 126619], "mapped", [1594]], [[126620, 126624], "disallowed"], [[126625, 126625], "mapped", [1576]], [[126626, 126626], "mapped", [1580]], [[126627, 126627], "mapped", [1583]], [[126628, 126628], "disallowed"], [[126629, 126629], "mapped", [1608]], [[126630, 126630], "mapped", [1586]], [[126631, 126631], "mapped", [1581]], [[126632, 126632], "mapped", [1591]], [[126633, 126633], "mapped", [1610]], [[126634, 126634], "disallowed"], [[126635, 126635], "mapped", [1604]], [[126636, 126636], "mapped", [1605]], [[126637, 126637], "mapped", [1606]], [[126638, 126638], "mapped", [1587]], [[126639, 126639], "mapped", [1593]], [[126640, 126640], "mapped", [1601]], [[126641, 126641], "mapped", [1589]], [[126642, 126642], "mapped", [1602]], [[126643, 126643], "mapped", [1585]], [[126644, 126644], "mapped", [1588]], [[126645, 126645], "mapped", [1578]], [[126646, 126646], "mapped", [1579]], [[126647, 126647], "mapped", [1582]], [[126648, 126648], "mapped", [1584]], [[126649, 126649], "mapped", [1590]], [[126650, 126650], "mapped", [1592]], [[126651, 126651], "mapped", [1594]], [[126652, 126703], "disallowed"], [[126704, 126705], "valid", [], "NV8"], [[126706, 126975], "disallowed"], [[126976, 127019], "valid", [], "NV8"], [[127020, 127023], "disallowed"], [[127024, 127123], "valid", [], "NV8"], [[127124, 127135], "disallowed"], [[127136, 127150], "valid", [], "NV8"], [[127151, 127152], "disallowed"], [[127153, 127166], "valid", [], "NV8"], [[127167, 127167], "valid", [], "NV8"], [[127168, 127168], "disallowed"], [[127169, 127183], "valid", [], "NV8"], [[127184, 127184], "disallowed"], [[127185, 127199], "valid", [], "NV8"], [[127200, 127221], "valid", [], "NV8"], [[127222, 127231], "disallowed"], [[127232, 127232], "disallowed"], [[127233, 127233], "disallowed_STD3_mapped", [48, 44]], [[127234, 127234], "disallowed_STD3_mapped", [49, 44]], [[127235, 127235], "disallowed_STD3_mapped", [50, 44]], [[127236, 127236], "disallowed_STD3_mapped", [51, 44]], [[127237, 127237], "disallowed_STD3_mapped", [52, 44]], [[127238, 127238], "disallowed_STD3_mapped", [53, 44]], [[127239, 127239], "disallowed_STD3_mapped", [54, 44]], [[127240, 127240], "disallowed_STD3_mapped", [55, 44]], [[127241, 127241], "disallowed_STD3_mapped", [56, 44]], [[127242, 127242], "disallowed_STD3_mapped", [57, 44]], [[127243, 127244], "valid", [], "NV8"], [[127245, 127247], "disallowed"], [[127248, 127248], "disallowed_STD3_mapped", [40, 97, 41]], [[127249, 127249], "disallowed_STD3_mapped", [40, 98, 41]], [[127250, 127250], "disallowed_STD3_mapped", [40, 99, 41]], [[127251, 127251], "disallowed_STD3_mapped", [40, 100, 41]], [[127252, 127252], "disallowed_STD3_mapped", [40, 101, 41]], [[127253, 127253], "disallowed_STD3_mapped", [40, 102, 41]], [[127254, 127254], "disallowed_STD3_mapped", [40, 103, 41]], [[127255, 127255], "disallowed_STD3_mapped", [40, 104, 41]], [[127256, 127256], "disallowed_STD3_mapped", [40, 105, 41]], [[127257, 127257], "disallowed_STD3_mapped", [40, 106, 41]], [[127258, 127258], "disallowed_STD3_mapped", [40, 107, 41]], [[127259, 127259], "disallowed_STD3_mapped", [40, 108, 41]], [[127260, 127260], "disallowed_STD3_mapped", [40, 109, 41]], [[127261, 127261], "disallowed_STD3_mapped", [40, 110, 41]], [[127262, 127262], "disallowed_STD3_mapped", [40, 111, 41]], [[127263, 127263], "disallowed_STD3_mapped", [40, 112, 41]], [[127264, 127264], "disallowed_STD3_mapped", [40, 113, 41]], [[127265, 127265], "disallowed_STD3_mapped", [40, 114, 41]], [[127266, 127266], "disallowed_STD3_mapped", [40, 115, 41]], [[127267, 127267], "disallowed_STD3_mapped", [40, 116, 41]], [[127268, 127268], "disallowed_STD3_mapped", [40, 117, 41]], [[127269, 127269], "disallowed_STD3_mapped", [40, 118, 41]], [[127270, 127270], "disallowed_STD3_mapped", [40, 119, 41]], [[127271, 127271], "disallowed_STD3_mapped", [40, 120, 41]], [[127272, 127272], "disallowed_STD3_mapped", [40, 121, 41]], [[127273, 127273], "disallowed_STD3_mapped", [40, 122, 41]], [[127274, 127274], "mapped", [12308, 115, 12309]], [[127275, 127275], "mapped", [99]], [[127276, 127276], "mapped", [114]], [[127277, 127277], "mapped", [99, 100]], [[127278, 127278], "mapped", [119, 122]], [[127279, 127279], "disallowed"], [[127280, 127280], "mapped", [97]], [[127281, 127281], "mapped", [98]], [[127282, 127282], "mapped", [99]], [[127283, 127283], "mapped", [100]], [[127284, 127284], "mapped", [101]], [[127285, 127285], "mapped", [102]], [[127286, 127286], "mapped", [103]], [[127287, 127287], "mapped", [104]], [[127288, 127288], "mapped", [105]], [[127289, 127289], "mapped", [106]], [[127290, 127290], "mapped", [107]], [[127291, 127291], "mapped", [108]], [[127292, 127292], "mapped", [109]], [[127293, 127293], "mapped", [110]], [[127294, 127294], "mapped", [111]], [[127295, 127295], "mapped", [112]], [[127296, 127296], "mapped", [113]], [[127297, 127297], "mapped", [114]], [[127298, 127298], "mapped", [115]], [[127299, 127299], "mapped", [116]], [[127300, 127300], "mapped", [117]], [[127301, 127301], "mapped", [118]], [[127302, 127302], "mapped", [119]], [[127303, 127303], "mapped", [120]], [[127304, 127304], "mapped", [121]], [[127305, 127305], "mapped", [122]], [[127306, 127306], "mapped", [104, 118]], [[127307, 127307], "mapped", [109, 118]], [[127308, 127308], "mapped", [115, 100]], [[127309, 127309], "mapped", [115, 115]], [[127310, 127310], "mapped", [112, 112, 118]], [[127311, 127311], "mapped", [119, 99]], [[127312, 127318], "valid", [], "NV8"], [[127319, 127319], "valid", [], "NV8"], [[127320, 127326], "valid", [], "NV8"], [[127327, 127327], "valid", [], "NV8"], [[127328, 127337], "valid", [], "NV8"], [[127338, 127338], "mapped", [109, 99]], [[127339, 127339], "mapped", [109, 100]], [[127340, 127343], "disallowed"], [[127344, 127352], "valid", [], "NV8"], [[127353, 127353], "valid", [], "NV8"], [[127354, 127354], "valid", [], "NV8"], [[127355, 127356], "valid", [], "NV8"], [[127357, 127358], "valid", [], "NV8"], [[127359, 127359], "valid", [], "NV8"], [[127360, 127369], "valid", [], "NV8"], [[127370, 127373], "valid", [], "NV8"], [[127374, 127375], "valid", [], "NV8"], [[127376, 127376], "mapped", [100, 106]], [[127377, 127386], "valid", [], "NV8"], [[127387, 127461], "disallowed"], [[127462, 127487], "valid", [], "NV8"], [[127488, 127488], "mapped", [12411, 12363]], [[127489, 127489], "mapped", [12467, 12467]], [[127490, 127490], "mapped", [12469]], [[127491, 127503], "disallowed"], [[127504, 127504], "mapped", [25163]], [[127505, 127505], "mapped", [23383]], [[127506, 127506], "mapped", [21452]], [[127507, 127507], "mapped", [12487]], [[127508, 127508], "mapped", [20108]], [[127509, 127509], "mapped", [22810]], [[127510, 127510], "mapped", [35299]], [[127511, 127511], "mapped", [22825]], [[127512, 127512], "mapped", [20132]], [[127513, 127513], "mapped", [26144]], [[127514, 127514], "mapped", [28961]], [[127515, 127515], "mapped", [26009]], [[127516, 127516], "mapped", [21069]], [[127517, 127517], "mapped", [24460]], [[127518, 127518], "mapped", [20877]], [[127519, 127519], "mapped", [26032]], [[127520, 127520], "mapped", [21021]], [[127521, 127521], "mapped", [32066]], [[127522, 127522], "mapped", [29983]], [[127523, 127523], "mapped", [36009]], [[127524, 127524], "mapped", [22768]], [[127525, 127525], "mapped", [21561]], [[127526, 127526], "mapped", [28436]], [[127527, 127527], "mapped", [25237]], [[127528, 127528], "mapped", [25429]], [[127529, 127529], "mapped", [19968]], [[127530, 127530], "mapped", [19977]], [[127531, 127531], "mapped", [36938]], [[127532, 127532], "mapped", [24038]], [[127533, 127533], "mapped", [20013]], [[127534, 127534], "mapped", [21491]], [[127535, 127535], "mapped", [25351]], [[127536, 127536], "mapped", [36208]], [[127537, 127537], "mapped", [25171]], [[127538, 127538], "mapped", [31105]], [[127539, 127539], "mapped", [31354]], [[127540, 127540], "mapped", [21512]], [[127541, 127541], "mapped", [28288]], [[127542, 127542], "mapped", [26377]], [[127543, 127543], "mapped", [26376]], [[127544, 127544], "mapped", [30003]], [[127545, 127545], "mapped", [21106]], [[127546, 127546], "mapped", [21942]], [[127547, 127551], "disallowed"], [[127552, 127552], "mapped", [12308, 26412, 12309]], [[127553, 127553], "mapped", [12308, 19977, 12309]], [[127554, 127554], "mapped", [12308, 20108, 12309]], [[127555, 127555], "mapped", [12308, 23433, 12309]], [[127556, 127556], "mapped", [12308, 28857, 12309]], [[127557, 127557], "mapped", [12308, 25171, 12309]], [[127558, 127558], "mapped", [12308, 30423, 12309]], [[127559, 127559], "mapped", [12308, 21213, 12309]], [[127560, 127560], "mapped", [12308, 25943, 12309]], [[127561, 127567], "disallowed"], [[127568, 127568], "mapped", [24471]], [[127569, 127569], "mapped", [21487]], [[127570, 127743], "disallowed"], [[127744, 127776], "valid", [], "NV8"], [[127777, 127788], "valid", [], "NV8"], [[127789, 127791], "valid", [], "NV8"], [[127792, 127797], "valid", [], "NV8"], [[127798, 127798], "valid", [], "NV8"], [[127799, 127868], "valid", [], "NV8"], [[127869, 127869], "valid", [], "NV8"], [[127870, 127871], "valid", [], "NV8"], [[127872, 127891], "valid", [], "NV8"], [[127892, 127903], "valid", [], "NV8"], [[127904, 127940], "valid", [], "NV8"], [[127941, 127941], "valid", [], "NV8"], [[127942, 127946], "valid", [], "NV8"], [[127947, 127950], "valid", [], "NV8"], [[127951, 127955], "valid", [], "NV8"], [[127956, 127967], "valid", [], "NV8"], [[127968, 127984], "valid", [], "NV8"], [[127985, 127991], "valid", [], "NV8"], [[127992, 127999], "valid", [], "NV8"], [[128e3, 128062], "valid", [], "NV8"], [[128063, 128063], "valid", [], "NV8"], [[128064, 128064], "valid", [], "NV8"], [[128065, 128065], "valid", [], "NV8"], [[128066, 128247], "valid", [], "NV8"], [[128248, 128248], "valid", [], "NV8"], [[128249, 128252], "valid", [], "NV8"], [[128253, 128254], "valid", [], "NV8"], [[128255, 128255], "valid", [], "NV8"], [[128256, 128317], "valid", [], "NV8"], [[128318, 128319], "valid", [], "NV8"], [[128320, 128323], "valid", [], "NV8"], [[128324, 128330], "valid", [], "NV8"], [[128331, 128335], "valid", [], "NV8"], [[128336, 128359], "valid", [], "NV8"], [[128360, 128377], "valid", [], "NV8"], [[128378, 128378], "disallowed"], [[128379, 128419], "valid", [], "NV8"], [[128420, 128420], "disallowed"], [[128421, 128506], "valid", [], "NV8"], [[128507, 128511], "valid", [], "NV8"], [[128512, 128512], "valid", [], "NV8"], [[128513, 128528], "valid", [], "NV8"], [[128529, 128529], "valid", [], "NV8"], [[128530, 128532], "valid", [], "NV8"], [[128533, 128533], "valid", [], "NV8"], [[128534, 128534], "valid", [], "NV8"], [[128535, 128535], "valid", [], "NV8"], [[128536, 128536], "valid", [], "NV8"], [[128537, 128537], "valid", [], "NV8"], [[128538, 128538], "valid", [], "NV8"], [[128539, 128539], "valid", [], "NV8"], [[128540, 128542], "valid", [], "NV8"], [[128543, 128543], "valid", [], "NV8"], [[128544, 128549], "valid", [], "NV8"], [[128550, 128551], "valid", [], "NV8"], [[128552, 128555], "valid", [], "NV8"], [[128556, 128556], "valid", [], "NV8"], [[128557, 128557], "valid", [], "NV8"], [[128558, 128559], "valid", [], "NV8"], [[128560, 128563], "valid", [], "NV8"], [[128564, 128564], "valid", [], "NV8"], [[128565, 128576], "valid", [], "NV8"], [[128577, 128578], "valid", [], "NV8"], [[128579, 128580], "valid", [], "NV8"], [[128581, 128591], "valid", [], "NV8"], [[128592, 128639], "valid", [], "NV8"], [[128640, 128709], "valid", [], "NV8"], [[128710, 128719], "valid", [], "NV8"], [[128720, 128720], "valid", [], "NV8"], [[128721, 128735], "disallowed"], [[128736, 128748], "valid", [], "NV8"], [[128749, 128751], "disallowed"], [[128752, 128755], "valid", [], "NV8"], [[128756, 128767], "disallowed"], [[128768, 128883], "valid", [], "NV8"], [[128884, 128895], "disallowed"], [[128896, 128980], "valid", [], "NV8"], [[128981, 129023], "disallowed"], [[129024, 129035], "valid", [], "NV8"], [[129036, 129039], "disallowed"], [[129040, 129095], "valid", [], "NV8"], [[129096, 129103], "disallowed"], [[129104, 129113], "valid", [], "NV8"], [[129114, 129119], "disallowed"], [[129120, 129159], "valid", [], "NV8"], [[129160, 129167], "disallowed"], [[129168, 129197], "valid", [], "NV8"], [[129198, 129295], "disallowed"], [[129296, 129304], "valid", [], "NV8"], [[129305, 129407], "disallowed"], [[129408, 129412], "valid", [], "NV8"], [[129413, 129471], "disallowed"], [[129472, 129472], "valid", [], "NV8"], [[129473, 131069], "disallowed"], [[131070, 131071], "disallowed"], [[131072, 173782], "valid"], [[173783, 173823], "disallowed"], [[173824, 177972], "valid"], [[177973, 177983], "disallowed"], [[177984, 178205], "valid"], [[178206, 178207], "disallowed"], [[178208, 183969], "valid"], [[183970, 194559], "disallowed"], [[194560, 194560], "mapped", [20029]], [[194561, 194561], "mapped", [20024]], [[194562, 194562], "mapped", [20033]], [[194563, 194563], "mapped", [131362]], [[194564, 194564], "mapped", [20320]], [[194565, 194565], "mapped", [20398]], [[194566, 194566], "mapped", [20411]], [[194567, 194567], "mapped", [20482]], [[194568, 194568], "mapped", [20602]], [[194569, 194569], "mapped", [20633]], [[194570, 194570], "mapped", [20711]], [[194571, 194571], "mapped", [20687]], [[194572, 194572], "mapped", [13470]], [[194573, 194573], "mapped", [132666]], [[194574, 194574], "mapped", [20813]], [[194575, 194575], "mapped", [20820]], [[194576, 194576], "mapped", [20836]], [[194577, 194577], "mapped", [20855]], [[194578, 194578], "mapped", [132380]], [[194579, 194579], "mapped", [13497]], [[194580, 194580], "mapped", [20839]], [[194581, 194581], "mapped", [20877]], [[194582, 194582], "mapped", [132427]], [[194583, 194583], "mapped", [20887]], [[194584, 194584], "mapped", [20900]], [[194585, 194585], "mapped", [20172]], [[194586, 194586], "mapped", [20908]], [[194587, 194587], "mapped", [20917]], [[194588, 194588], "mapped", [168415]], [[194589, 194589], "mapped", [20981]], [[194590, 194590], "mapped", [20995]], [[194591, 194591], "mapped", [13535]], [[194592, 194592], "mapped", [21051]], [[194593, 194593], "mapped", [21062]], [[194594, 194594], "mapped", [21106]], [[194595, 194595], "mapped", [21111]], [[194596, 194596], "mapped", [13589]], [[194597, 194597], "mapped", [21191]], [[194598, 194598], "mapped", [21193]], [[194599, 194599], "mapped", [21220]], [[194600, 194600], "mapped", [21242]], [[194601, 194601], "mapped", [21253]], [[194602, 194602], "mapped", [21254]], [[194603, 194603], "mapped", [21271]], [[194604, 194604], "mapped", [21321]], [[194605, 194605], "mapped", [21329]], [[194606, 194606], "mapped", [21338]], [[194607, 194607], "mapped", [21363]], [[194608, 194608], "mapped", [21373]], [[194609, 194611], "mapped", [21375]], [[194612, 194612], "mapped", [133676]], [[194613, 194613], "mapped", [28784]], [[194614, 194614], "mapped", [21450]], [[194615, 194615], "mapped", [21471]], [[194616, 194616], "mapped", [133987]], [[194617, 194617], "mapped", [21483]], [[194618, 194618], "mapped", [21489]], [[194619, 194619], "mapped", [21510]], [[194620, 194620], "mapped", [21662]], [[194621, 194621], "mapped", [21560]], [[194622, 194622], "mapped", [21576]], [[194623, 194623], "mapped", [21608]], [[194624, 194624], "mapped", [21666]], [[194625, 194625], "mapped", [21750]], [[194626, 194626], "mapped", [21776]], [[194627, 194627], "mapped", [21843]], [[194628, 194628], "mapped", [21859]], [[194629, 194630], "mapped", [21892]], [[194631, 194631], "mapped", [21913]], [[194632, 194632], "mapped", [21931]], [[194633, 194633], "mapped", [21939]], [[194634, 194634], "mapped", [21954]], [[194635, 194635], "mapped", [22294]], [[194636, 194636], "mapped", [22022]], [[194637, 194637], "mapped", [22295]], [[194638, 194638], "mapped", [22097]], [[194639, 194639], "mapped", [22132]], [[194640, 194640], "mapped", [20999]], [[194641, 194641], "mapped", [22766]], [[194642, 194642], "mapped", [22478]], [[194643, 194643], "mapped", [22516]], [[194644, 194644], "mapped", [22541]], [[194645, 194645], "mapped", [22411]], [[194646, 194646], "mapped", [22578]], [[194647, 194647], "mapped", [22577]], [[194648, 194648], "mapped", [22700]], [[194649, 194649], "mapped", [136420]], [[194650, 194650], "mapped", [22770]], [[194651, 194651], "mapped", [22775]], [[194652, 194652], "mapped", [22790]], [[194653, 194653], "mapped", [22810]], [[194654, 194654], "mapped", [22818]], [[194655, 194655], "mapped", [22882]], [[194656, 194656], "mapped", [136872]], [[194657, 194657], "mapped", [136938]], [[194658, 194658], "mapped", [23020]], [[194659, 194659], "mapped", [23067]], [[194660, 194660], "mapped", [23079]], [[194661, 194661], "mapped", [23e3]], [[194662, 194662], "mapped", [23142]], [[194663, 194663], "mapped", [14062]], [[194664, 194664], "disallowed"], [[194665, 194665], "mapped", [23304]], [[194666, 194667], "mapped", [23358]], [[194668, 194668], "mapped", [137672]], [[194669, 194669], "mapped", [23491]], [[194670, 194670], "mapped", [23512]], [[194671, 194671], "mapped", [23527]], [[194672, 194672], "mapped", [23539]], [[194673, 194673], "mapped", [138008]], [[194674, 194674], "mapped", [23551]], [[194675, 194675], "mapped", [23558]], [[194676, 194676], "disallowed"], [[194677, 194677], "mapped", [23586]], [[194678, 194678], "mapped", [14209]], [[194679, 194679], "mapped", [23648]], [[194680, 194680], "mapped", [23662]], [[194681, 194681], "mapped", [23744]], [[194682, 194682], "mapped", [23693]], [[194683, 194683], "mapped", [138724]], [[194684, 194684], "mapped", [23875]], [[194685, 194685], "mapped", [138726]], [[194686, 194686], "mapped", [23918]], [[194687, 194687], "mapped", [23915]], [[194688, 194688], "mapped", [23932]], [[194689, 194689], "mapped", [24033]], [[194690, 194690], "mapped", [24034]], [[194691, 194691], "mapped", [14383]], [[194692, 194692], "mapped", [24061]], [[194693, 194693], "mapped", [24104]], [[194694, 194694], "mapped", [24125]], [[194695, 194695], "mapped", [24169]], [[194696, 194696], "mapped", [14434]], [[194697, 194697], "mapped", [139651]], [[194698, 194698], "mapped", [14460]], [[194699, 194699], "mapped", [24240]], [[194700, 194700], "mapped", [24243]], [[194701, 194701], "mapped", [24246]], [[194702, 194702], "mapped", [24266]], [[194703, 194703], "mapped", [172946]], [[194704, 194704], "mapped", [24318]], [[194705, 194706], "mapped", [140081]], [[194707, 194707], "mapped", [33281]], [[194708, 194709], "mapped", [24354]], [[194710, 194710], "mapped", [14535]], [[194711, 194711], "mapped", [144056]], [[194712, 194712], "mapped", [156122]], [[194713, 194713], "mapped", [24418]], [[194714, 194714], "mapped", [24427]], [[194715, 194715], "mapped", [14563]], [[194716, 194716], "mapped", [24474]], [[194717, 194717], "mapped", [24525]], [[194718, 194718], "mapped", [24535]], [[194719, 194719], "mapped", [24569]], [[194720, 194720], "mapped", [24705]], [[194721, 194721], "mapped", [14650]], [[194722, 194722], "mapped", [14620]], [[194723, 194723], "mapped", [24724]], [[194724, 194724], "mapped", [141012]], [[194725, 194725], "mapped", [24775]], [[194726, 194726], "mapped", [24904]], [[194727, 194727], "mapped", [24908]], [[194728, 194728], "mapped", [24910]], [[194729, 194729], "mapped", [24908]], [[194730, 194730], "mapped", [24954]], [[194731, 194731], "mapped", [24974]], [[194732, 194732], "mapped", [25010]], [[194733, 194733], "mapped", [24996]], [[194734, 194734], "mapped", [25007]], [[194735, 194735], "mapped", [25054]], [[194736, 194736], "mapped", [25074]], [[194737, 194737], "mapped", [25078]], [[194738, 194738], "mapped", [25104]], [[194739, 194739], "mapped", [25115]], [[194740, 194740], "mapped", [25181]], [[194741, 194741], "mapped", [25265]], [[194742, 194742], "mapped", [25300]], [[194743, 194743], "mapped", [25424]], [[194744, 194744], "mapped", [142092]], [[194745, 194745], "mapped", [25405]], [[194746, 194746], "mapped", [25340]], [[194747, 194747], "mapped", [25448]], [[194748, 194748], "mapped", [25475]], [[194749, 194749], "mapped", [25572]], [[194750, 194750], "mapped", [142321]], [[194751, 194751], "mapped", [25634]], [[194752, 194752], "mapped", [25541]], [[194753, 194753], "mapped", [25513]], [[194754, 194754], "mapped", [14894]], [[194755, 194755], "mapped", [25705]], [[194756, 194756], "mapped", [25726]], [[194757, 194757], "mapped", [25757]], [[194758, 194758], "mapped", [25719]], [[194759, 194759], "mapped", [14956]], [[194760, 194760], "mapped", [25935]], [[194761, 194761], "mapped", [25964]], [[194762, 194762], "mapped", [143370]], [[194763, 194763], "mapped", [26083]], [[194764, 194764], "mapped", [26360]], [[194765, 194765], "mapped", [26185]], [[194766, 194766], "mapped", [15129]], [[194767, 194767], "mapped", [26257]], [[194768, 194768], "mapped", [15112]], [[194769, 194769], "mapped", [15076]], [[194770, 194770], "mapped", [20882]], [[194771, 194771], "mapped", [20885]], [[194772, 194772], "mapped", [26368]], [[194773, 194773], "mapped", [26268]], [[194774, 194774], "mapped", [32941]], [[194775, 194775], "mapped", [17369]], [[194776, 194776], "mapped", [26391]], [[194777, 194777], "mapped", [26395]], [[194778, 194778], "mapped", [26401]], [[194779, 194779], "mapped", [26462]], [[194780, 194780], "mapped", [26451]], [[194781, 194781], "mapped", [144323]], [[194782, 194782], "mapped", [15177]], [[194783, 194783], "mapped", [26618]], [[194784, 194784], "mapped", [26501]], [[194785, 194785], "mapped", [26706]], [[194786, 194786], "mapped", [26757]], [[194787, 194787], "mapped", [144493]], [[194788, 194788], "mapped", [26766]], [[194789, 194789], "mapped", [26655]], [[194790, 194790], "mapped", [26900]], [[194791, 194791], "mapped", [15261]], [[194792, 194792], "mapped", [26946]], [[194793, 194793], "mapped", [27043]], [[194794, 194794], "mapped", [27114]], [[194795, 194795], "mapped", [27304]], [[194796, 194796], "mapped", [145059]], [[194797, 194797], "mapped", [27355]], [[194798, 194798], "mapped", [15384]], [[194799, 194799], "mapped", [27425]], [[194800, 194800], "mapped", [145575]], [[194801, 194801], "mapped", [27476]], [[194802, 194802], "mapped", [15438]], [[194803, 194803], "mapped", [27506]], [[194804, 194804], "mapped", [27551]], [[194805, 194805], "mapped", [27578]], [[194806, 194806], "mapped", [27579]], [[194807, 194807], "mapped", [146061]], [[194808, 194808], "mapped", [138507]], [[194809, 194809], "mapped", [146170]], [[194810, 194810], "mapped", [27726]], [[194811, 194811], "mapped", [146620]], [[194812, 194812], "mapped", [27839]], [[194813, 194813], "mapped", [27853]], [[194814, 194814], "mapped", [27751]], [[194815, 194815], "mapped", [27926]], [[194816, 194816], "mapped", [27966]], [[194817, 194817], "mapped", [28023]], [[194818, 194818], "mapped", [27969]], [[194819, 194819], "mapped", [28009]], [[194820, 194820], "mapped", [28024]], [[194821, 194821], "mapped", [28037]], [[194822, 194822], "mapped", [146718]], [[194823, 194823], "mapped", [27956]], [[194824, 194824], "mapped", [28207]], [[194825, 194825], "mapped", [28270]], [[194826, 194826], "mapped", [15667]], [[194827, 194827], "mapped", [28363]], [[194828, 194828], "mapped", [28359]], [[194829, 194829], "mapped", [147153]], [[194830, 194830], "mapped", [28153]], [[194831, 194831], "mapped", [28526]], [[194832, 194832], "mapped", [147294]], [[194833, 194833], "mapped", [147342]], [[194834, 194834], "mapped", [28614]], [[194835, 194835], "mapped", [28729]], [[194836, 194836], "mapped", [28702]], [[194837, 194837], "mapped", [28699]], [[194838, 194838], "mapped", [15766]], [[194839, 194839], "mapped", [28746]], [[194840, 194840], "mapped", [28797]], [[194841, 194841], "mapped", [28791]], [[194842, 194842], "mapped", [28845]], [[194843, 194843], "mapped", [132389]], [[194844, 194844], "mapped", [28997]], [[194845, 194845], "mapped", [148067]], [[194846, 194846], "mapped", [29084]], [[194847, 194847], "disallowed"], [[194848, 194848], "mapped", [29224]], [[194849, 194849], "mapped", [29237]], [[194850, 194850], "mapped", [29264]], [[194851, 194851], "mapped", [149e3]], [[194852, 194852], "mapped", [29312]], [[194853, 194853], "mapped", [29333]], [[194854, 194854], "mapped", [149301]], [[194855, 194855], "mapped", [149524]], [[194856, 194856], "mapped", [29562]], [[194857, 194857], "mapped", [29579]], [[194858, 194858], "mapped", [16044]], [[194859, 194859], "mapped", [29605]], [[194860, 194861], "mapped", [16056]], [[194862, 194862], "mapped", [29767]], [[194863, 194863], "mapped", [29788]], [[194864, 194864], "mapped", [29809]], [[194865, 194865], "mapped", [29829]], [[194866, 194866], "mapped", [29898]], [[194867, 194867], "mapped", [16155]], [[194868, 194868], "mapped", [29988]], [[194869, 194869], "mapped", [150582]], [[194870, 194870], "mapped", [30014]], [[194871, 194871], "mapped", [150674]], [[194872, 194872], "mapped", [30064]], [[194873, 194873], "mapped", [139679]], [[194874, 194874], "mapped", [30224]], [[194875, 194875], "mapped", [151457]], [[194876, 194876], "mapped", [151480]], [[194877, 194877], "mapped", [151620]], [[194878, 194878], "mapped", [16380]], [[194879, 194879], "mapped", [16392]], [[194880, 194880], "mapped", [30452]], [[194881, 194881], "mapped", [151795]], [[194882, 194882], "mapped", [151794]], [[194883, 194883], "mapped", [151833]], [[194884, 194884], "mapped", [151859]], [[194885, 194885], "mapped", [30494]], [[194886, 194887], "mapped", [30495]], [[194888, 194888], "mapped", [30538]], [[194889, 194889], "mapped", [16441]], [[194890, 194890], "mapped", [30603]], [[194891, 194891], "mapped", [16454]], [[194892, 194892], "mapped", [16534]], [[194893, 194893], "mapped", [152605]], [[194894, 194894], "mapped", [30798]], [[194895, 194895], "mapped", [30860]], [[194896, 194896], "mapped", [30924]], [[194897, 194897], "mapped", [16611]], [[194898, 194898], "mapped", [153126]], [[194899, 194899], "mapped", [31062]], [[194900, 194900], "mapped", [153242]], [[194901, 194901], "mapped", [153285]], [[194902, 194902], "mapped", [31119]], [[194903, 194903], "mapped", [31211]], [[194904, 194904], "mapped", [16687]], [[194905, 194905], "mapped", [31296]], [[194906, 194906], "mapped", [31306]], [[194907, 194907], "mapped", [31311]], [[194908, 194908], "mapped", [153980]], [[194909, 194910], "mapped", [154279]], [[194911, 194911], "disallowed"], [[194912, 194912], "mapped", [16898]], [[194913, 194913], "mapped", [154539]], [[194914, 194914], "mapped", [31686]], [[194915, 194915], "mapped", [31689]], [[194916, 194916], "mapped", [16935]], [[194917, 194917], "mapped", [154752]], [[194918, 194918], "mapped", [31954]], [[194919, 194919], "mapped", [17056]], [[194920, 194920], "mapped", [31976]], [[194921, 194921], "mapped", [31971]], [[194922, 194922], "mapped", [32e3]], [[194923, 194923], "mapped", [155526]], [[194924, 194924], "mapped", [32099]], [[194925, 194925], "mapped", [17153]], [[194926, 194926], "mapped", [32199]], [[194927, 194927], "mapped", [32258]], [[194928, 194928], "mapped", [32325]], [[194929, 194929], "mapped", [17204]], [[194930, 194930], "mapped", [156200]], [[194931, 194931], "mapped", [156231]], [[194932, 194932], "mapped", [17241]], [[194933, 194933], "mapped", [156377]], [[194934, 194934], "mapped", [32634]], [[194935, 194935], "mapped", [156478]], [[194936, 194936], "mapped", [32661]], [[194937, 194937], "mapped", [32762]], [[194938, 194938], "mapped", [32773]], [[194939, 194939], "mapped", [156890]], [[194940, 194940], "mapped", [156963]], [[194941, 194941], "mapped", [32864]], [[194942, 194942], "mapped", [157096]], [[194943, 194943], "mapped", [32880]], [[194944, 194944], "mapped", [144223]], [[194945, 194945], "mapped", [17365]], [[194946, 194946], "mapped", [32946]], [[194947, 194947], "mapped", [33027]], [[194948, 194948], "mapped", [17419]], [[194949, 194949], "mapped", [33086]], [[194950, 194950], "mapped", [23221]], [[194951, 194951], "mapped", [157607]], [[194952, 194952], "mapped", [157621]], [[194953, 194953], "mapped", [144275]], [[194954, 194954], "mapped", [144284]], [[194955, 194955], "mapped", [33281]], [[194956, 194956], "mapped", [33284]], [[194957, 194957], "mapped", [36766]], [[194958, 194958], "mapped", [17515]], [[194959, 194959], "mapped", [33425]], [[194960, 194960], "mapped", [33419]], [[194961, 194961], "mapped", [33437]], [[194962, 194962], "mapped", [21171]], [[194963, 194963], "mapped", [33457]], [[194964, 194964], "mapped", [33459]], [[194965, 194965], "mapped", [33469]], [[194966, 194966], "mapped", [33510]], [[194967, 194967], "mapped", [158524]], [[194968, 194968], "mapped", [33509]], [[194969, 194969], "mapped", [33565]], [[194970, 194970], "mapped", [33635]], [[194971, 194971], "mapped", [33709]], [[194972, 194972], "mapped", [33571]], [[194973, 194973], "mapped", [33725]], [[194974, 194974], "mapped", [33767]], [[194975, 194975], "mapped", [33879]], [[194976, 194976], "mapped", [33619]], [[194977, 194977], "mapped", [33738]], [[194978, 194978], "mapped", [33740]], [[194979, 194979], "mapped", [33756]], [[194980, 194980], "mapped", [158774]], [[194981, 194981], "mapped", [159083]], [[194982, 194982], "mapped", [158933]], [[194983, 194983], "mapped", [17707]], [[194984, 194984], "mapped", [34033]], [[194985, 194985], "mapped", [34035]], [[194986, 194986], "mapped", [34070]], [[194987, 194987], "mapped", [160714]], [[194988, 194988], "mapped", [34148]], [[194989, 194989], "mapped", [159532]], [[194990, 194990], "mapped", [17757]], [[194991, 194991], "mapped", [17761]], [[194992, 194992], "mapped", [159665]], [[194993, 194993], "mapped", [159954]], [[194994, 194994], "mapped", [17771]], [[194995, 194995], "mapped", [34384]], [[194996, 194996], "mapped", [34396]], [[194997, 194997], "mapped", [34407]], [[194998, 194998], "mapped", [34409]], [[194999, 194999], "mapped", [34473]], [[195e3, 195e3], "mapped", [34440]], [[195001, 195001], "mapped", [34574]], [[195002, 195002], "mapped", [34530]], [[195003, 195003], "mapped", [34681]], [[195004, 195004], "mapped", [34600]], [[195005, 195005], "mapped", [34667]], [[195006, 195006], "mapped", [34694]], [[195007, 195007], "disallowed"], [[195008, 195008], "mapped", [34785]], [[195009, 195009], "mapped", [34817]], [[195010, 195010], "mapped", [17913]], [[195011, 195011], "mapped", [34912]], [[195012, 195012], "mapped", [34915]], [[195013, 195013], "mapped", [161383]], [[195014, 195014], "mapped", [35031]], [[195015, 195015], "mapped", [35038]], [[195016, 195016], "mapped", [17973]], [[195017, 195017], "mapped", [35066]], [[195018, 195018], "mapped", [13499]], [[195019, 195019], "mapped", [161966]], [[195020, 195020], "mapped", [162150]], [[195021, 195021], "mapped", [18110]], [[195022, 195022], "mapped", [18119]], [[195023, 195023], "mapped", [35488]], [[195024, 195024], "mapped", [35565]], [[195025, 195025], "mapped", [35722]], [[195026, 195026], "mapped", [35925]], [[195027, 195027], "mapped", [162984]], [[195028, 195028], "mapped", [36011]], [[195029, 195029], "mapped", [36033]], [[195030, 195030], "mapped", [36123]], [[195031, 195031], "mapped", [36215]], [[195032, 195032], "mapped", [163631]], [[195033, 195033], "mapped", [133124]], [[195034, 195034], "mapped", [36299]], [[195035, 195035], "mapped", [36284]], [[195036, 195036], "mapped", [36336]], [[195037, 195037], "mapped", [133342]], [[195038, 195038], "mapped", [36564]], [[195039, 195039], "mapped", [36664]], [[195040, 195040], "mapped", [165330]], [[195041, 195041], "mapped", [165357]], [[195042, 195042], "mapped", [37012]], [[195043, 195043], "mapped", [37105]], [[195044, 195044], "mapped", [37137]], [[195045, 195045], "mapped", [165678]], [[195046, 195046], "mapped", [37147]], [[195047, 195047], "mapped", [37432]], [[195048, 195048], "mapped", [37591]], [[195049, 195049], "mapped", [37592]], [[195050, 195050], "mapped", [37500]], [[195051, 195051], "mapped", [37881]], [[195052, 195052], "mapped", [37909]], [[195053, 195053], "mapped", [166906]], [[195054, 195054], "mapped", [38283]], [[195055, 195055], "mapped", [18837]], [[195056, 195056], "mapped", [38327]], [[195057, 195057], "mapped", [167287]], [[195058, 195058], "mapped", [18918]], [[195059, 195059], "mapped", [38595]], [[195060, 195060], "mapped", [23986]], [[195061, 195061], "mapped", [38691]], [[195062, 195062], "mapped", [168261]], [[195063, 195063], "mapped", [168474]], [[195064, 195064], "mapped", [19054]], [[195065, 195065], "mapped", [19062]], [[195066, 195066], "mapped", [38880]], [[195067, 195067], "mapped", [168970]], [[195068, 195068], "mapped", [19122]], [[195069, 195069], "mapped", [169110]], [[195070, 195071], "mapped", [38923]], [[195072, 195072], "mapped", [38953]], [[195073, 195073], "mapped", [169398]], [[195074, 195074], "mapped", [39138]], [[195075, 195075], "mapped", [19251]], [[195076, 195076], "mapped", [39209]], [[195077, 195077], "mapped", [39335]], [[195078, 195078], "mapped", [39362]], [[195079, 195079], "mapped", [39422]], [[195080, 195080], "mapped", [19406]], [[195081, 195081], "mapped", [170800]], [[195082, 195082], "mapped", [39698]], [[195083, 195083], "mapped", [4e4]], [[195084, 195084], "mapped", [40189]], [[195085, 195085], "mapped", [19662]], [[195086, 195086], "mapped", [19693]], [[195087, 195087], "mapped", [40295]], [[195088, 195088], "mapped", [172238]], [[195089, 195089], "mapped", [19704]], [[195090, 195090], "mapped", [172293]], [[195091, 195091], "mapped", [172558]], [[195092, 195092], "mapped", [172689]], [[195093, 195093], "mapped", [40635]], [[195094, 195094], "mapped", [19798]], [[195095, 195095], "mapped", [40697]], [[195096, 195096], "mapped", [40702]], [[195097, 195097], "mapped", [40709]], [[195098, 195098], "mapped", [40719]], [[195099, 195099], "mapped", [40726]], [[195100, 195100], "mapped", [40763]], [[195101, 195101], "mapped", [173568]], [[195102, 196605], "disallowed"], [[196606, 196607], "disallowed"], [[196608, 262141], "disallowed"], [[262142, 262143], "disallowed"], [[262144, 327677], "disallowed"], [[327678, 327679], "disallowed"], [[327680, 393213], "disallowed"], [[393214, 393215], "disallowed"], [[393216, 458749], "disallowed"], [[458750, 458751], "disallowed"], [[458752, 524285], "disallowed"], [[524286, 524287], "disallowed"], [[524288, 589821], "disallowed"], [[589822, 589823], "disallowed"], [[589824, 655357], "disallowed"], [[655358, 655359], "disallowed"], [[655360, 720893], "disallowed"], [[720894, 720895], "disallowed"], [[720896, 786429], "disallowed"], [[786430, 786431], "disallowed"], [[786432, 851965], "disallowed"], [[851966, 851967], "disallowed"], [[851968, 917501], "disallowed"], [[917502, 917503], "disallowed"], [[917504, 917504], "disallowed"], [[917505, 917505], "disallowed"], [[917506, 917535], "disallowed"], [[917536, 917631], "disallowed"], [[917632, 917759], "disallowed"], [[917760, 917999], "ignored"], [[918e3, 983037], "disallowed"], [[983038, 983039], "disallowed"], [[983040, 1048573], "disallowed"], [[1048574, 1048575], "disallowed"], [[1048576, 1114109], "disallowed"], [[1114110, 1114111], "disallowed"]]; + } +}); + +// node_modules/tr46/index.js +var require_tr46 = __commonJS({ + "node_modules/tr46/index.js"(exports2, module2) { + "use strict"; + var punycode = require("punycode"); + var mappingTable = require_mappingTable(); + var PROCESSING_OPTIONS = { + TRANSITIONAL: 0, + NONTRANSITIONAL: 1 + }; + function normalize(str) { + return str.split("\0").map(function(s) { + return s.normalize("NFC"); + }).join("\0"); + } + function findStatus(val) { + var start = 0; + var end = mappingTable.length - 1; + while (start <= end) { + var mid = Math.floor((start + end) / 2); + var target = mappingTable[mid]; + if (target[0][0] <= val && target[0][1] >= val) { + return target; + } else if (target[0][0] > val) { + end = mid - 1; + } else { + start = mid + 1; + } + } + return null; + } + var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + function countSymbols(string) { + return string.replace(regexAstralSymbols, "_").length; + } + function mapChars(domain_name, useSTD3, processing_option) { + var hasError = false; + var processed = ""; + var len = countSymbols(domain_name); + for (var i = 0; i < len; ++i) { + var codePoint = domain_name.codePointAt(i); + var status = findStatus(codePoint); + switch (status[1]) { + case "disallowed": + hasError = true; + processed += String.fromCodePoint(codePoint); + break; + case "ignored": + break; + case "mapped": + processed += String.fromCodePoint.apply(String, status[2]); + break; + case "deviation": + if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { + processed += String.fromCodePoint.apply(String, status[2]); + } else { + processed += String.fromCodePoint(codePoint); + } + break; + case "valid": + processed += String.fromCodePoint(codePoint); + break; + case "disallowed_STD3_mapped": + if (useSTD3) { + hasError = true; + processed += String.fromCodePoint(codePoint); + } else { + processed += String.fromCodePoint.apply(String, status[2]); + } + break; + case "disallowed_STD3_valid": + if (useSTD3) { + hasError = true; + } + processed += String.fromCodePoint(codePoint); + break; + } + } + return { + string: processed, + error: hasError + }; + } + var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; + function validateLabel(label, processing_option) { + if (label.substr(0, 4) === "xn--") { + label = punycode.toUnicode(label); + processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; + } + var error = false; + if (normalize(label) !== label || label[3] === "-" && label[4] === "-" || label[0] === "-" || label[label.length - 1] === "-" || label.indexOf(".") !== -1 || label.search(combiningMarksRegex) === 0) { + error = true; + } + var len = countSymbols(label); + for (var i = 0; i < len; ++i) { + var status = findStatus(label.codePointAt(i)); + if (processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid" || processing === PROCESSING_OPTIONS.NONTRANSITIONAL && status[1] !== "valid" && status[1] !== "deviation") { + error = true; + break; + } + } + return { + label, + error + }; + } + function processing(domain_name, useSTD3, processing_option) { + var result = mapChars(domain_name, useSTD3, processing_option); + result.string = normalize(result.string); + var labels = result.string.split("."); + for (var i = 0; i < labels.length; ++i) { + try { + var validation = validateLabel(labels[i]); + labels[i] = validation.label; + result.error = result.error || validation.error; + } catch (e) { + result.error = true; + } + } + return { + string: labels.join("."), + error: result.error + }; + } + module2.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { + var result = processing(domain_name, useSTD3, processing_option); + var labels = result.string.split("."); + labels = labels.map(function(l) { + try { + return punycode.toASCII(l); + } catch (e) { + result.error = true; + return l; + } + }); + if (verifyDnsLength) { + var total = labels.slice(0, labels.length - 1).join(".").length; + if (total.length > 253 || total.length === 0) { + result.error = true; + } + for (var i = 0; i < labels.length; ++i) { + if (labels.length > 63 || labels.length === 0) { + result.error = true; + break; + } + } + } + if (result.error) return null; + return labels.join("."); + }; + module2.exports.toUnicode = function(domain_name, useSTD3) { + var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); + return { + domain: result.string, + error: result.error + }; + }; + module2.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; + } +}); + +// node_modules/whatwg-url/lib/url-state-machine.js +var require_url_state_machine = __commonJS({ + "node_modules/whatwg-url/lib/url-state-machine.js"(exports2, module2) { + "use strict"; + var punycode = require("punycode"); + var tr46 = require_tr46(); + var specialSchemes = { + ftp: 21, + file: null, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443 + }; + var failure = Symbol("failure"); + function countSymbols(str) { + return punycode.ucs2.decode(str).length; + } + function at(input, idx) { + const c = input[idx]; + return isNaN(c) ? void 0 : String.fromCodePoint(c); + } + function isASCIIDigit(c) { + return c >= 48 && c <= 57; + } + function isASCIIAlpha(c) { + return c >= 65 && c <= 90 || c >= 97 && c <= 122; + } + function isASCIIAlphanumeric(c) { + return isASCIIAlpha(c) || isASCIIDigit(c); + } + function isASCIIHex(c) { + return isASCIIDigit(c) || c >= 65 && c <= 70 || c >= 97 && c <= 102; + } + function isSingleDot(buffer) { + return buffer === "." || buffer.toLowerCase() === "%2e"; + } + function isDoubleDot(buffer) { + buffer = buffer.toLowerCase(); + return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e"; + } + function isWindowsDriveLetterCodePoints(cp1, cp2) { + return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124); + } + function isWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|"); + } + function isNormalizedWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":"; + } + function containsForbiddenHostCodePoint(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1; + } + function containsForbiddenHostCodePointExcludingPercent(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1; + } + function isSpecialScheme(scheme) { + return specialSchemes[scheme] !== void 0; + } + function isSpecial(url) { + return isSpecialScheme(url.scheme); + } + function defaultPort(scheme) { + return specialSchemes[scheme]; + } + function percentEncode(c) { + let hex = c.toString(16).toUpperCase(); + if (hex.length === 1) { + hex = "0" + hex; + } + return "%" + hex; + } + function utf8PercentEncode(c) { + const buf = new Buffer(c); + let str = ""; + for (let i = 0; i < buf.length; ++i) { + str += percentEncode(buf[i]); + } + return str; + } + function utf8PercentDecode(str) { + const input = new Buffer(str); + const output = []; + for (let i = 0; i < input.length; ++i) { + if (input[i] !== 37) { + output.push(input[i]); + } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) { + output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)); + i += 2; + } else { + output.push(input[i]); + } + } + return new Buffer(output).toString(); + } + function isC0ControlPercentEncode(c) { + return c <= 31 || c > 126; + } + var extraPathPercentEncodeSet = /* @__PURE__ */ new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]); + function isPathPercentEncode(c) { + return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c); + } + var extraUserinfoPercentEncodeSet = /* @__PURE__ */ new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]); + function isUserinfoPercentEncode(c) { + return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c); + } + function percentEncodeChar(c, encodeSetPredicate) { + const cStr = String.fromCodePoint(c); + if (encodeSetPredicate(c)) { + return utf8PercentEncode(cStr); + } + return cStr; + } + function parseIPv4Number(input) { + let R = 10; + if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") { + input = input.substring(2); + R = 16; + } else if (input.length >= 2 && input.charAt(0) === "0") { + input = input.substring(1); + R = 8; + } + if (input === "") { + return 0; + } + const regex = R === 10 ? /[^0-9]/ : R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/; + if (regex.test(input)) { + return failure; + } + return parseInt(input, R); + } + function parseIPv4(input) { + const parts = input.split("."); + if (parts[parts.length - 1] === "") { + if (parts.length > 1) { + parts.pop(); + } + } + if (parts.length > 4) { + return input; + } + const numbers = []; + for (const part of parts) { + if (part === "") { + return input; + } + const n = parseIPv4Number(part); + if (n === failure) { + return input; + } + numbers.push(n); + } + for (let i = 0; i < numbers.length - 1; ++i) { + if (numbers[i] > 255) { + return failure; + } + } + if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { + return failure; + } + let ipv4 = numbers.pop(); + let counter = 0; + for (const n of numbers) { + ipv4 += n * Math.pow(256, 3 - counter); + ++counter; + } + return ipv4; + } + function serializeIPv4(address) { + let output = ""; + let n = address; + for (let i = 1; i <= 4; ++i) { + output = String(n % 256) + output; + if (i !== 4) { + output = "." + output; + } + n = Math.floor(n / 256); + } + return output; + } + function parseIPv6(input) { + const address = [0, 0, 0, 0, 0, 0, 0, 0]; + let pieceIndex = 0; + let compress = null; + let pointer = 0; + input = punycode.ucs2.decode(input); + if (input[pointer] === 58) { + if (input[pointer + 1] !== 58) { + return failure; + } + pointer += 2; + ++pieceIndex; + compress = pieceIndex; + } + while (pointer < input.length) { + if (pieceIndex === 8) { + return failure; + } + if (input[pointer] === 58) { + if (compress !== null) { + return failure; + } + ++pointer; + ++pieceIndex; + compress = pieceIndex; + continue; + } + let value = 0; + let length = 0; + while (length < 4 && isASCIIHex(input[pointer])) { + value = value * 16 + parseInt(at(input, pointer), 16); + ++pointer; + ++length; + } + if (input[pointer] === 46) { + if (length === 0) { + return failure; + } + pointer -= length; + if (pieceIndex > 6) { + return failure; + } + let numbersSeen = 0; + while (input[pointer] !== void 0) { + let ipv4Piece = null; + if (numbersSeen > 0) { + if (input[pointer] === 46 && numbersSeen < 4) { + ++pointer; + } else { + return failure; + } + } + if (!isASCIIDigit(input[pointer])) { + return failure; + } + while (isASCIIDigit(input[pointer])) { + const number = parseInt(at(input, pointer)); + if (ipv4Piece === null) { + ipv4Piece = number; + } else if (ipv4Piece === 0) { + return failure; + } else { + ipv4Piece = ipv4Piece * 10 + number; + } + if (ipv4Piece > 255) { + return failure; + } + ++pointer; + } + address[pieceIndex] = address[pieceIndex] * 256 + ipv4Piece; + ++numbersSeen; + if (numbersSeen === 2 || numbersSeen === 4) { + ++pieceIndex; + } + } + if (numbersSeen !== 4) { + return failure; + } + break; + } else if (input[pointer] === 58) { + ++pointer; + if (input[pointer] === void 0) { + return failure; + } + } else if (input[pointer] !== void 0) { + return failure; + } + address[pieceIndex] = value; + ++pieceIndex; + } + if (compress !== null) { + let swaps = pieceIndex - compress; + pieceIndex = 7; + while (pieceIndex !== 0 && swaps > 0) { + const temp = address[compress + swaps - 1]; + address[compress + swaps - 1] = address[pieceIndex]; + address[pieceIndex] = temp; + --pieceIndex; + --swaps; + } + } else if (compress === null && pieceIndex !== 8) { + return failure; + } + return address; + } + function serializeIPv6(address) { + let output = ""; + const seqResult = findLongestZeroSequence(address); + const compress = seqResult.idx; + let ignore0 = false; + for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { + if (ignore0 && address[pieceIndex] === 0) { + continue; + } else if (ignore0) { + ignore0 = false; + } + if (compress === pieceIndex) { + const separator = pieceIndex === 0 ? "::" : ":"; + output += separator; + ignore0 = true; + continue; + } + output += address[pieceIndex].toString(16); + if (pieceIndex !== 7) { + output += ":"; + } + } + return output; + } + function parseHost(input, isSpecialArg) { + if (input[0] === "[") { + if (input[input.length - 1] !== "]") { + return failure; + } + return parseIPv6(input.substring(1, input.length - 1)); + } + if (!isSpecialArg) { + return parseOpaqueHost(input); + } + const domain = utf8PercentDecode(input); + const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false); + if (asciiDomain === null) { + return failure; + } + if (containsForbiddenHostCodePoint(asciiDomain)) { + return failure; + } + const ipv4Host = parseIPv4(asciiDomain); + if (typeof ipv4Host === "number" || ipv4Host === failure) { + return ipv4Host; + } + return asciiDomain; + } + function parseOpaqueHost(input) { + if (containsForbiddenHostCodePointExcludingPercent(input)) { + return failure; + } + let output = ""; + const decoded = punycode.ucs2.decode(input); + for (let i = 0; i < decoded.length; ++i) { + output += percentEncodeChar(decoded[i], isC0ControlPercentEncode); + } + return output; + } + function findLongestZeroSequence(arr) { + let maxIdx = null; + let maxLen = 1; + let currStart = null; + let currLen = 0; + for (let i = 0; i < arr.length; ++i) { + if (arr[i] !== 0) { + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + currStart = null; + currLen = 0; + } else { + if (currStart === null) { + currStart = i; + } + ++currLen; + } + } + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + return { + idx: maxIdx, + len: maxLen + }; + } + function serializeHost(host) { + if (typeof host === "number") { + return serializeIPv4(host); + } + if (host instanceof Array) { + return "[" + serializeIPv6(host) + "]"; + } + return host; + } + function trimControlChars(url) { + return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, ""); + } + function trimTabAndNewline(url) { + return url.replace(/\u0009|\u000A|\u000D/g, ""); + } + function shortenPath(url) { + const path3 = url.path; + if (path3.length === 0) { + return; + } + if (url.scheme === "file" && path3.length === 1 && isNormalizedWindowsDriveLetter(path3[0])) { + return; + } + path3.pop(); + } + function includesCredentials(url) { + return url.username !== "" || url.password !== ""; + } + function cannotHaveAUsernamePasswordPort(url) { + return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file"; + } + function isNormalizedWindowsDriveLetter(string) { + return /^[A-Za-z]:$/.test(string); + } + function URLStateMachine(input, base, encodingOverride, url, stateOverride) { + this.pointer = 0; + this.input = input; + this.base = base || null; + this.encodingOverride = encodingOverride || "utf-8"; + this.stateOverride = stateOverride; + this.url = url; + this.failure = false; + this.parseError = false; + if (!this.url) { + this.url = { + scheme: "", + username: "", + password: "", + host: null, + port: null, + path: [], + query: null, + fragment: null, + cannotBeABaseURL: false + }; + const res2 = trimControlChars(this.input); + if (res2 !== this.input) { + this.parseError = true; + } + this.input = res2; + } + const res = trimTabAndNewline(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + this.state = stateOverride || "scheme start"; + this.buffer = ""; + this.atFlag = false; + this.arrFlag = false; + this.passwordTokenSeenFlag = false; + this.input = punycode.ucs2.decode(this.input); + for (; this.pointer <= this.input.length; ++this.pointer) { + const c = this.input[this.pointer]; + const cStr = isNaN(c) ? void 0 : String.fromCodePoint(c); + const ret = this["parse " + this.state](c, cStr); + if (!ret) { + break; + } else if (ret === failure) { + this.failure = true; + break; + } + } + } + URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) { + if (isASCIIAlpha(c)) { + this.buffer += cStr.toLowerCase(); + this.state = "scheme"; + } else if (!this.stateOverride) { + this.state = "no scheme"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + return true; + }; + URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) { + if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { + this.buffer += cStr.toLowerCase(); + } else if (c === 58) { + if (this.stateOverride) { + if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { + return false; + } + if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { + return false; + } + if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") { + return false; + } + if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) { + return false; + } + } + this.url.scheme = this.buffer; + this.buffer = ""; + if (this.stateOverride) { + return false; + } + if (this.url.scheme === "file") { + if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) { + this.parseError = true; + } + this.state = "file"; + } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) { + this.state = "special relative or authority"; + } else if (isSpecial(this.url)) { + this.state = "special authority slashes"; + } else if (this.input[this.pointer + 1] === 47) { + this.state = "path or authority"; + ++this.pointer; + } else { + this.url.cannotBeABaseURL = true; + this.url.path.push(""); + this.state = "cannot-be-a-base-URL path"; + } + } else if (!this.stateOverride) { + this.buffer = ""; + this.state = "no scheme"; + this.pointer = -1; + } else { + this.parseError = true; + return failure; + } + return true; + }; + URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) { + if (this.base === null || this.base.cannotBeABaseURL && c !== 35) { + return failure; + } else if (this.base.cannotBeABaseURL && c === 35) { + this.url.scheme = this.base.scheme; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.url.cannotBeABaseURL = true; + this.state = "fragment"; + } else if (this.base.scheme === "file") { + this.state = "file"; + --this.pointer; + } else { + this.state = "relative"; + --this.pointer; + } + return true; + }; + URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "relative"; + --this.pointer; + } + return true; + }; + URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) { + if (c === 47) { + this.state = "authority"; + } else { + this.state = "path"; + --this.pointer; + } + return true; + }; + URLStateMachine.prototype["parse relative"] = function parseRelative(c) { + this.url.scheme = this.base.scheme; + if (isNaN(c)) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 47) { + this.state = "relative slash"; + } else if (c === 63) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else if (isSpecial(this.url) && c === 92) { + this.parseError = true; + this.state = "relative slash"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(0, this.base.path.length - 1); + this.state = "path"; + --this.pointer; + } + return true; + }; + URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) { + if (isSpecial(this.url) && (c === 47 || c === 92)) { + if (c === 92) { + this.parseError = true; + } + this.state = "special authority ignore slashes"; + } else if (c === 47) { + this.state = "authority"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.state = "path"; + --this.pointer; + } + return true; + }; + URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "special authority ignore slashes"; + --this.pointer; + } + return true; + }; + URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) { + if (c !== 47 && c !== 92) { + this.state = "authority"; + --this.pointer; + } else { + this.parseError = true; + } + return true; + }; + URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) { + if (c === 64) { + this.parseError = true; + if (this.atFlag) { + this.buffer = "%40" + this.buffer; + } + this.atFlag = true; + const len = countSymbols(this.buffer); + for (let pointer = 0; pointer < len; ++pointer) { + const codePoint = this.buffer.codePointAt(pointer); + if (codePoint === 58 && !this.passwordTokenSeenFlag) { + this.passwordTokenSeenFlag = true; + continue; + } + const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode); + if (this.passwordTokenSeenFlag) { + this.url.password += encodedCodePoints; + } else { + this.url.username += encodedCodePoints; + } + } + this.buffer = ""; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || isSpecial(this.url) && c === 92) { + if (this.atFlag && this.buffer === "") { + this.parseError = true; + return failure; + } + this.pointer -= countSymbols(this.buffer) + 1; + this.buffer = ""; + this.state = "host"; + } else { + this.buffer += cStr; + } + return true; + }; + URLStateMachine.prototype["parse hostname"] = URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) { + if (this.stateOverride && this.url.scheme === "file") { + --this.pointer; + this.state = "file host"; + } else if (c === 58 && !this.arrFlag) { + if (this.buffer === "") { + this.parseError = true; + return failure; + } + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + this.url.host = host; + this.buffer = ""; + this.state = "port"; + if (this.stateOverride === "hostname") { + return false; + } + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || isSpecial(this.url) && c === 92) { + --this.pointer; + if (isSpecial(this.url) && this.buffer === "") { + this.parseError = true; + return failure; + } else if (this.stateOverride && this.buffer === "" && (includesCredentials(this.url) || this.url.port !== null)) { + this.parseError = true; + return false; + } + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + this.url.host = host; + this.buffer = ""; + this.state = "path start"; + if (this.stateOverride) { + return false; + } + } else { + if (c === 91) { + this.arrFlag = true; + } else if (c === 93) { + this.arrFlag = false; + } + this.buffer += cStr; + } + return true; + }; + URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) { + if (isASCIIDigit(c)) { + this.buffer += cStr; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || isSpecial(this.url) && c === 92 || this.stateOverride) { + if (this.buffer !== "") { + const port = parseInt(this.buffer); + if (port > Math.pow(2, 16) - 1) { + this.parseError = true; + return failure; + } + this.url.port = port === defaultPort(this.url.scheme) ? null : port; + this.buffer = ""; + } + if (this.stateOverride) { + return false; + } + this.state = "path start"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + return true; + }; + var fileOtherwiseCodePoints = /* @__PURE__ */ new Set([47, 92, 63, 35]); + URLStateMachine.prototype["parse file"] = function parseFile(c) { + this.url.scheme = "file"; + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file slash"; + } else if (this.base !== null && this.base.scheme === "file") { + if (isNaN(c)) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 63) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else { + if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points + !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) || this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points + !fileOtherwiseCodePoints.has(this.input[this.pointer + 2])) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + shortenPath(this.url); + } else { + this.parseError = true; + } + this.state = "path"; + --this.pointer; + } + } else { + this.state = "path"; + --this.pointer; + } + return true; + }; + URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) { + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file host"; + } else { + if (this.base !== null && this.base.scheme === "file") { + if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { + this.url.path.push(this.base.path[0]); + } else { + this.url.host = this.base.host; + } + } + this.state = "path"; + --this.pointer; + } + return true; + }; + URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) { + if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { + --this.pointer; + if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { + this.parseError = true; + this.state = "path"; + } else if (this.buffer === "") { + this.url.host = ""; + if (this.stateOverride) { + return false; + } + this.state = "path start"; + } else { + let host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + if (host === "localhost") { + host = ""; + } + this.url.host = host; + if (this.stateOverride) { + return false; + } + this.buffer = ""; + this.state = "path start"; + } + } else { + this.buffer += cStr; + } + return true; + }; + URLStateMachine.prototype["parse path start"] = function parsePathStart(c) { + if (isSpecial(this.url)) { + if (c === 92) { + this.parseError = true; + } + this.state = "path"; + if (c !== 47 && c !== 92) { + --this.pointer; + } + } else if (!this.stateOverride && c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (!this.stateOverride && c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else if (c !== void 0) { + this.state = "path"; + if (c !== 47) { + --this.pointer; + } + } + return true; + }; + URLStateMachine.prototype["parse path"] = function parsePath(c) { + if (isNaN(c) || c === 47 || isSpecial(this.url) && c === 92 || !this.stateOverride && (c === 63 || c === 35)) { + if (isSpecial(this.url) && c === 92) { + this.parseError = true; + } + if (isDoubleDot(this.buffer)) { + shortenPath(this.url); + if (c !== 47 && !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } + } else if (isSingleDot(this.buffer) && c !== 47 && !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } else if (!isSingleDot(this.buffer)) { + if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) { + if (this.url.host !== "" && this.url.host !== null) { + this.parseError = true; + this.url.host = ""; + } + this.buffer = this.buffer[0] + ":"; + } + this.url.path.push(this.buffer); + } + this.buffer = ""; + if (this.url.scheme === "file" && (c === void 0 || c === 63 || c === 35)) { + while (this.url.path.length > 1 && this.url.path[0] === "") { + this.parseError = true; + this.url.path.shift(); + } + } + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + if (c === 37 && (!isASCIIHex(this.input[this.pointer + 1]) || !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + this.buffer += percentEncodeChar(c, isPathPercentEncode); + } + return true; + }; + URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) { + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else { + if (!isNaN(c) && c !== 37) { + this.parseError = true; + } + if (c === 37 && (!isASCIIHex(this.input[this.pointer + 1]) || !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + if (!isNaN(c)) { + this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode); + } + } + return true; + }; + URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) { + if (isNaN(c) || !this.stateOverride && c === 35) { + if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") { + this.encodingOverride = "utf-8"; + } + const buffer = new Buffer(this.buffer); + for (let i = 0; i < buffer.length; ++i) { + if (buffer[i] < 33 || buffer[i] > 126 || buffer[i] === 34 || buffer[i] === 35 || buffer[i] === 60 || buffer[i] === 62) { + this.url.query += percentEncode(buffer[i]); + } else { + this.url.query += String.fromCodePoint(buffer[i]); + } + } + this.buffer = ""; + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + if (c === 37 && (!isASCIIHex(this.input[this.pointer + 1]) || !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + this.buffer += cStr; + } + return true; + }; + URLStateMachine.prototype["parse fragment"] = function parseFragment(c) { + if (isNaN(c)) { + } else if (c === 0) { + this.parseError = true; + } else { + if (c === 37 && (!isASCIIHex(this.input[this.pointer + 1]) || !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode); + } + return true; + }; + function serializeURL(url, excludeFragment) { + let output = url.scheme + ":"; + if (url.host !== null) { + output += "//"; + if (url.username !== "" || url.password !== "") { + output += url.username; + if (url.password !== "") { + output += ":" + url.password; + } + output += "@"; + } + output += serializeHost(url.host); + if (url.port !== null) { + output += ":" + url.port; + } + } else if (url.host === null && url.scheme === "file") { + output += "//"; + } + if (url.cannotBeABaseURL) { + output += url.path[0]; + } else { + for (const string of url.path) { + output += "/" + string; + } + } + if (url.query !== null) { + output += "?" + url.query; + } + if (!excludeFragment && url.fragment !== null) { + output += "#" + url.fragment; + } + return output; + } + function serializeOrigin(tuple) { + let result = tuple.scheme + "://"; + result += serializeHost(tuple.host); + if (tuple.port !== null) { + result += ":" + tuple.port; + } + return result; + } + module2.exports.serializeURL = serializeURL; + module2.exports.serializeURLOrigin = function(url) { + switch (url.scheme) { + case "blob": + try { + return module2.exports.serializeURLOrigin(module2.exports.parseURL(url.path[0])); + } catch (e) { + return "null"; + } + case "ftp": + case "gopher": + case "http": + case "https": + case "ws": + case "wss": + return serializeOrigin({ + scheme: url.scheme, + host: url.host, + port: url.port + }); + case "file": + return "file://"; + default: + return "null"; + } + }; + module2.exports.basicURLParse = function(input, options) { + if (options === void 0) { + options = {}; + } + const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride); + if (usm.failure) { + return "failure"; + } + return usm.url; + }; + module2.exports.setTheUsername = function(url, username) { + url.username = ""; + const decoded = punycode.ucs2.decode(username); + for (let i = 0; i < decoded.length; ++i) { + url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } + }; + module2.exports.setThePassword = function(url, password) { + url.password = ""; + const decoded = punycode.ucs2.decode(password); + for (let i = 0; i < decoded.length; ++i) { + url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } + }; + module2.exports.serializeHost = serializeHost; + module2.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; + module2.exports.serializeInteger = function(integer) { + return String(integer); + }; + module2.exports.parseURL = function(input, options) { + if (options === void 0) { + options = {}; + } + return module2.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride }); + }; + } +}); + +// node_modules/whatwg-url/lib/URL-impl.js +var require_URL_impl = __commonJS({ + "node_modules/whatwg-url/lib/URL-impl.js"(exports2) { + "use strict"; + var usm = require_url_state_machine(); + exports2.implementation = class URLImpl { + constructor(constructorArgs) { + const url = constructorArgs[0]; + const base = constructorArgs[1]; + let parsedBase = null; + if (base !== void 0) { + parsedBase = usm.basicURLParse(base); + if (parsedBase === "failure") { + throw new TypeError("Invalid base URL"); + } + } + const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } + this._url = parsedURL; + } + get href() { + return usm.serializeURL(this._url); + } + set href(v) { + const parsedURL = usm.basicURLParse(v); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } + this._url = parsedURL; + } + get origin() { + return usm.serializeURLOrigin(this._url); + } + get protocol() { + return this._url.scheme + ":"; + } + set protocol(v) { + usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); + } + get username() { + return this._url.username; + } + set username(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } + usm.setTheUsername(this._url, v); + } + get password() { + return this._url.password; + } + set password(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } + usm.setThePassword(this._url, v); + } + get host() { + const url = this._url; + if (url.host === null) { + return ""; + } + if (url.port === null) { + return usm.serializeHost(url.host); + } + return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); + } + set host(v) { + if (this._url.cannotBeABaseURL) { + return; + } + usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); + } + get hostname() { + if (this._url.host === null) { + return ""; + } + return usm.serializeHost(this._url.host); + } + set hostname(v) { + if (this._url.cannotBeABaseURL) { + return; + } + usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); + } + get port() { + if (this._url.port === null) { + return ""; + } + return usm.serializeInteger(this._url.port); + } + set port(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } + if (v === "") { + this._url.port = null; + } else { + usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); + } + } + get pathname() { + if (this._url.cannotBeABaseURL) { + return this._url.path[0]; + } + if (this._url.path.length === 0) { + return ""; + } + return "/" + this._url.path.join("/"); + } + set pathname(v) { + if (this._url.cannotBeABaseURL) { + return; + } + this._url.path = []; + usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); + } + get search() { + if (this._url.query === null || this._url.query === "") { + return ""; + } + return "?" + this._url.query; + } + set search(v) { + const url = this._url; + if (v === "") { + url.query = null; + return; + } + const input = v[0] === "?" ? v.substring(1) : v; + url.query = ""; + usm.basicURLParse(input, { url, stateOverride: "query" }); + } + get hash() { + if (this._url.fragment === null || this._url.fragment === "") { + return ""; + } + return "#" + this._url.fragment; + } + set hash(v) { + if (v === "") { + this._url.fragment = null; + return; + } + const input = v[0] === "#" ? v.substring(1) : v; + this._url.fragment = ""; + usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); + } + toJSON() { + return this.href; + } + }; + } +}); + +// node_modules/whatwg-url/lib/URL.js +var require_URL = __commonJS({ + "node_modules/whatwg-url/lib/URL.js"(exports2, module2) { + "use strict"; + var conversions = require_lib6(); + var utils = require_utils5(); + var Impl = require_URL_impl(); + var impl = utils.implSymbol; + function URL5(url) { + if (!this || this[impl] || !(this instanceof URL5)) { + throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); + } + if (arguments.length < 1) { + throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); + } + const args = []; + for (let i = 0; i < arguments.length && i < 2; ++i) { + args[i] = arguments[i]; + } + args[0] = conversions["USVString"](args[0]); + if (args[1] !== void 0) { + args[1] = conversions["USVString"](args[1]); + } + module2.exports.setup(this, args); + } + URL5.prototype.toJSON = function toJSON() { + if (!this || !module2.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + const args = []; + for (let i = 0; i < arguments.length && i < 0; ++i) { + args[i] = arguments[i]; + } + return this[impl].toJSON.apply(this[impl], args); + }; + Object.defineProperty(URL5.prototype, "href", { + get() { + return this[impl].href; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].href = V; + }, + enumerable: true, + configurable: true + }); + URL5.prototype.toString = function() { + if (!this || !module2.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + return this.href; + }; + Object.defineProperty(URL5.prototype, "origin", { + get() { + return this[impl].origin; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "protocol", { + get() { + return this[impl].protocol; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].protocol = V; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "username", { + get() { + return this[impl].username; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].username = V; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "password", { + get() { + return this[impl].password; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].password = V; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "host", { + get() { + return this[impl].host; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].host = V; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "hostname", { + get() { + return this[impl].hostname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hostname = V; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "port", { + get() { + return this[impl].port; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].port = V; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "pathname", { + get() { + return this[impl].pathname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].pathname = V; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "search", { + get() { + return this[impl].search; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].search = V; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(URL5.prototype, "hash", { + get() { + return this[impl].hash; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hash = V; + }, + enumerable: true, + configurable: true + }); + module2.exports = { + is(obj) { + return !!obj && obj[impl] instanceof Impl.implementation; + }, + create(constructorArgs, privateData) { + let obj = Object.create(URL5.prototype); + this.setup(obj, constructorArgs, privateData); + return obj; + }, + setup(obj, constructorArgs, privateData) { + if (!privateData) privateData = {}; + privateData.wrapper = obj; + obj[impl] = new Impl.implementation(constructorArgs, privateData); + obj[impl][utils.wrapperSymbol] = obj; + }, + interface: URL5, + expose: { + Window: { URL: URL5 }, + Worker: { URL: URL5 } + } + }; + } +}); + +// node_modules/whatwg-url/lib/public-api.js +var require_public_api = __commonJS({ + "node_modules/whatwg-url/lib/public-api.js"(exports2) { + "use strict"; + exports2.URL = require_URL().interface; + exports2.serializeURL = require_url_state_machine().serializeURL; + exports2.serializeURLOrigin = require_url_state_machine().serializeURLOrigin; + exports2.basicURLParse = require_url_state_machine().basicURLParse; + exports2.setTheUsername = require_url_state_machine().setTheUsername; + exports2.setThePassword = require_url_state_machine().setThePassword; + exports2.serializeHost = require_url_state_machine().serializeHost; + exports2.serializeInteger = require_url_state_machine().serializeInteger; + exports2.parseURL = require_url_state_machine().parseURL; + } +}); + +// node_modules/node-fetch/lib/index.js +var require_lib7 = __commonJS({ + "node_modules/node-fetch/lib/index.js"(exports2, module2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + function _interopDefault(ex) { + return ex && typeof ex === "object" && "default" in ex ? ex["default"] : ex; + } + var Stream = _interopDefault(require("stream")); + var http = _interopDefault(require("http")); + var Url = _interopDefault(require("url")); + var whatwgUrl = _interopDefault(require_public_api()); + var https = _interopDefault(require("https")); + var zlib = _interopDefault(require("zlib")); + var Readable = Stream.Readable; + var BUFFER = Symbol("buffer"); + var TYPE = Symbol("type"); + var Blob2 = class _Blob { + constructor() { + this[TYPE] = ""; + const blobParts = arguments[0]; + const options = arguments[1]; + const buffers = []; + let size = 0; + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof _Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === "string" ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } + this[BUFFER] = Buffer.concat(buffers); + let type = options && options.type !== void 0 && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function() { + }; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return "[object Blob]"; + } + slice() { + const size = this.size; + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === void 0) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === void 0) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new _Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } + }; + Object.defineProperties(Blob2.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } + }); + Object.defineProperty(Blob2.prototype, Symbol.toStringTag, { + value: "Blob", + writable: false, + enumerable: false, + configurable: true + }); + function FetchError(message, type, systemError) { + Error.call(this, message); + this.message = message; + this.type = type; + if (systemError) { + this.code = this.errno = systemError.code; + } + Error.captureStackTrace(this, this.constructor); + } + FetchError.prototype = Object.create(Error.prototype); + FetchError.prototype.constructor = FetchError; + FetchError.prototype.name = "FetchError"; + var convert; + try { + convert = require("encoding").convert; + } catch (e) { + } + var INTERNALS = Symbol("Body internals"); + var PassThrough = Stream.PassThrough; + function Body(body) { + var _this = this; + var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, _ref$size = _ref.size; + let size = _ref$size === void 0 ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === void 0 ? 0 : _ref$timeout; + if (body == null) { + body = null; + } else if (isURLSearchParams(body)) { + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; + else if (Buffer.isBuffer(body)) ; + else if (Object.prototype.toString.call(body) === "[object ArrayBuffer]") { + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; + else { + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + if (body instanceof Stream) { + body.on("error", function(err) { + const error = err.name === "AbortError" ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, "system", err); + _this[INTERNALS].error = error; + }); + } + } + Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function(buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get("content-type") || ""; + return consumeBody.call(this).then(function(buf) { + return Object.assign( + // Prevent copying + new Blob2([], { + type: ct.toLowerCase() + }), + { + [BUFFER]: buf + } + ); + }); + }, + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + return consumeBody.call(this).then(function(buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, "invalid-json")); + } + }); + }, + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function(buffer) { + return buffer.toString(); + }); + }, + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + return consumeBody.call(this).then(function(buffer) { + return convertBody(buffer, _this3.headers); + }); + } + }; + Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } + }); + Body.mixIn = function(proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } + }; + function consumeBody() { + var _this4 = this; + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } + this[INTERNALS].disturbed = true; + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + let body = this.body; + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + if (isBlob(body)) { + body = body.stream(); + } + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + let accum = []; + let accumBytes = 0; + let abort = false; + return new Body.Promise(function(resolve, reject) { + let resTimeout; + if (_this4.timeout) { + resTimeout = setTimeout(function() { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, "body-timeout")); + }, _this4.timeout); + } + body.on("error", function(err) { + if (err.name === "AbortError") { + abort = true; + reject(err); + } else { + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, "system", err)); + } + }); + body.on("data", function(chunk) { + if (abort || chunk === null) { + return; + } + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, "max-size")); + return; + } + accumBytes += chunk.length; + accum.push(chunk); + }); + body.on("end", function() { + if (abort) { + return; + } + clearTimeout(resTimeout); + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err)); + } + }); + }); + } + function convertBody(buffer, headers) { + if (typeof convert !== "function") { + throw new Error("The package `encoding` must be installed to use the textConverted() function"); + } + const ct = headers.get("content-type"); + let charset = "utf-8"; + let res, str; + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + str = buffer.slice(0, 1024).toString(); + if (!res && str) { + res = / 0 && arguments[0] !== void 0 ? arguments[0] : void 0; + this[MAP] = /* @__PURE__ */ Object.create(null); + if (init instanceof _Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + return; + } + if (init == null) ; + else if (typeof init === "object") { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== "function") { + throw new TypeError("Header pairs must be iterable"); + } + const pairs = []; + for (const pair of init) { + if (typeof pair !== "object" || typeof pair[Symbol.iterator] !== "function") { + throw new TypeError("Each header pair must be iterable"); + } + pairs.push(Array.from(pair)); + } + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError("Each header pair must be a name/value tuple"); + } + this.append(pair[0], pair[1]); + } + } else { + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError("Provided initializer must be an object"); + } + } + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === void 0) { + return null; + } + return this[MAP][key].join(", "); + } + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : void 0; + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], value = _pairs$i[1]; + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== void 0 ? key : name] = [value]; + } + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== void 0) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== void 0; + } + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== void 0) { + delete this[MAP][key]; + } + } + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, "key"); + } + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, "value"); + } + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, "key+value"); + } + }; + Headers2.prototype.entries = Headers2.prototype[Symbol.iterator]; + Object.defineProperty(Headers2.prototype, Symbol.toStringTag, { + value: "Headers", + writable: false, + enumerable: false, + configurable: true + }); + Object.defineProperties(Headers2.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } + }); + function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "key+value"; + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === "key" ? function(k) { + return k.toLowerCase(); + } : kind === "value" ? function(k) { + return headers[MAP][k].join(", "); + } : function(k) { + return [k.toLowerCase(), headers[MAP][k].join(", ")]; + }); + } + var INTERNAL = Symbol("internal"); + function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; + } + var HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError("Value of `this` is not a HeadersIterator"); + } + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, kind = _INTERNAL.kind, index = _INTERNAL.index; + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: void 0, + done: true + }; + } + this[INTERNAL].index = index + 1; + return { + value: values[index], + done: false + }; + } + }, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: "HeadersIterator", + writable: false, + enumerable: false, + configurable: true + }); + function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); + const hostHeaderKey = find(headers[MAP], "Host"); + if (hostHeaderKey !== void 0) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + return obj; + } + function createHeadersLenient(obj) { + const headers = new Headers2(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === void 0) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; + } + var INTERNALS$1 = Symbol("Response internals"); + var STATUS_CODES = http.STATUS_CODES; + var Response = class _Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; + Body.call(this, body, opts); + const status = opts.status || 200; + const headers = new Headers2(opts.headers); + if (body != null && !headers.has("Content-Type")) { + const contentType = extractContentType(body); + if (contentType) { + headers.append("Content-Type", contentType); + } + } + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } + get url() { + return this[INTERNALS$1].url || ""; + } + get status() { + return this[INTERNALS$1].status; + } + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } + get redirected() { + return this[INTERNALS$1].counter > 0; + } + get statusText() { + return this[INTERNALS$1].statusText; + } + get headers() { + return this[INTERNALS$1].headers; + } + /** + * Clone this response + * + * @return Response + */ + clone() { + return new _Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } + }; + Body.mixIn(Response.prototype); + Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } + }); + Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: "Response", + writable: false, + enumerable: false, + configurable: true + }); + var INTERNALS$2 = Symbol("Request internals"); + var URL5 = Url.URL || whatwgUrl.URL; + var parse_url = Url.parse; + var format_url = Url.format; + function parseURL(urlStr) { + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL5(urlStr).toString(); + } + return parse_url(urlStr); + } + var streamDestructionSupported = "destroy" in Stream.Readable.prototype; + function isRequest(input) { + return typeof input === "object" && typeof input[INTERNALS$2] === "object"; + } + function isAbortSignal(signal) { + const proto = signal && typeof signal === "object" && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === "AbortSignal"); + } + var Request = class _Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; + let parsedURL; + if (!isRequest(input)) { + if (input && input.href) { + parsedURL = parseURL(input.href); + } else { + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + let method = init.method || input.method || "GET"; + method = method.toUpperCase(); + if ((init.body != null || isRequest(input) && input.body !== null) && (method === "GET" || method === "HEAD")) { + throw new TypeError("Request with GET/HEAD method cannot have body"); + } + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + const headers = new Headers2(init.headers || input.headers || {}); + if (inputBody != null && !headers.has("Content-Type")) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append("Content-Type", contentType); + } + } + let signal = isRequest(input) ? input.signal : null; + if ("signal" in init) signal = init.signal; + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError("Expected signal to be an instanceof AbortSignal"); + } + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || "follow", + headers, + parsedURL, + signal + }; + this.follow = init.follow !== void 0 ? init.follow : input.follow !== void 0 ? input.follow : 20; + this.compress = init.compress !== void 0 ? init.compress : input.compress !== void 0 ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } + get method() { + return this[INTERNALS$2].method; + } + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } + get headers() { + return this[INTERNALS$2].headers; + } + get redirect() { + return this[INTERNALS$2].redirect; + } + get signal() { + return this[INTERNALS$2].signal; + } + /** + * Clone this request + * + * @return Request + */ + clone() { + return new _Request(this); + } + }; + Body.mixIn(Request.prototype); + Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: "Request", + writable: false, + enumerable: false, + configurable: true + }); + Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } + }); + function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers2(request[INTERNALS$2].headers); + if (!headers.has("Accept")) { + headers.set("Accept", "*/*"); + } + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError("Only absolute URLs are supported"); + } + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError("Only HTTP(S) protocols are supported"); + } + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error("Cancellation of streamed requests with AbortSignal is not supported in node < 8"); + } + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = "0"; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === "number") { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set("Content-Length", contentLengthValue); + } + if (!headers.has("User-Agent")) { + headers.set("User-Agent", "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)"); + } + if (request.compress && !headers.has("Accept-Encoding")) { + headers.set("Accept-Encoding", "gzip,deflate"); + } + let agent = request.agent; + if (typeof agent === "function") { + agent = agent(parsedURL); + } + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); + } + function AbortError2(message) { + Error.call(this, message); + this.type = "aborted"; + this.message = message; + Error.captureStackTrace(this, this.constructor); + } + AbortError2.prototype = Object.create(Error.prototype); + AbortError2.prototype.constructor = AbortError2; + AbortError2.prototype.name = "AbortError"; + var URL$1 = Url.URL || whatwgUrl.URL; + var PassThrough$1 = Stream.PassThrough; + var isDomainOrSubdomain = function isDomainOrSubdomain2(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; + return orig === dest || orig[orig.length - dest.length - 1] === "." && orig.endsWith(dest); + }; + var isSameProtocol = function isSameProtocol2(destination, original) { + const orig = new URL$1(original).protocol; + const dest = new URL$1(destination).protocol; + return orig === dest; + }; + function fetch2(url, opts) { + if (!fetch2.Promise) { + throw new Error("native promise missing, set fetch.Promise to your favorite alternative"); + } + Body.Promise = fetch2.Promise; + return new fetch2.Promise(function(resolve, reject) { + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); + const send = (options.protocol === "https:" ? https : http).request; + const signal = request.signal; + let response = null; + const abort = function abort2() { + let error = new AbortError2("The user aborted a request."); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + destroyStream(request.body, error); + } + if (!response || !response.body) return; + response.body.emit("error", error); + }; + if (signal && signal.aborted) { + abort(); + return; + } + const abortAndFinalize = function abortAndFinalize2() { + abort(); + finalize(); + }; + const req = send(options); + let reqTimeout; + if (signal) { + signal.addEventListener("abort", abortAndFinalize); + } + function finalize() { + req.abort(); + if (signal) signal.removeEventListener("abort", abortAndFinalize); + clearTimeout(reqTimeout); + } + if (request.timeout) { + req.once("socket", function(socket) { + reqTimeout = setTimeout(function() { + reject(new FetchError(`network timeout at: ${request.url}`, "request-timeout")); + finalize(); + }, request.timeout); + }); + } + req.on("error", function(err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, "system", err)); + if (response && response.body) { + destroyStream(response.body, err); + } + finalize(); + }); + fixResponseChunkedTransferBadEnding(req, function(err) { + if (signal && signal.aborted) { + return; + } + if (response && response.body) { + destroyStream(response.body, err); + } + }); + if (parseInt(process.version.substring(1)) < 14) { + req.on("socket", function(s) { + s.addListener("close", function(hadError) { + const hasDataListener = s.listenerCount("data") > 0; + if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { + const err = new Error("Premature close"); + err.code = "ERR_STREAM_PREMATURE_CLOSE"; + response.body.emit("error", err); + } + }); + }); + } + req.on("response", function(res) { + clearTimeout(reqTimeout); + const headers = createHeadersLenient(res.headers); + if (fetch2.isRedirect(res.statusCode)) { + const location = headers.get("Location"); + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + if (request.redirect !== "manual") { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, "invalid-redirect")); + finalize(); + return; + } + } + switch (request.redirect) { + case "error": + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, "no-redirect")); + finalize(); + return; + case "manual": + if (locationURL !== null) { + try { + headers.set("Location", locationURL); + } catch (err) { + reject(err); + } + } + break; + case "follow": + if (locationURL === null) { + break; + } + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, "max-redirect")); + finalize(); + return; + } + const requestOpts = { + headers: new Headers2(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ["authorization", "www-authenticate", "cookie", "cookie2"]) { + requestOpts.headers.delete(name); + } + } + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError("Cannot follow redirect with body being a readable stream", "unsupported-redirect")); + finalize(); + return; + } + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === "POST") { + requestOpts.method = "GET"; + requestOpts.body = void 0; + requestOpts.headers.delete("content-length"); + } + resolve(fetch2(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + res.once("end", function() { + if (signal) signal.removeEventListener("abort", abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + const codings = headers.get("Content-Encoding"); + if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; + if (codings == "gzip" || codings == "x-gzip") { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + if (codings == "deflate" || codings == "x-deflate") { + const raw = res.pipe(new PassThrough$1()); + raw.once("data", function(chunk) { + if ((chunk[0] & 15) === 8) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + raw.on("end", function() { + if (!response) { + response = new Response(body, response_options); + resolve(response); + } + }); + return; + } + if (codings == "br" && typeof zlib.createBrotliDecompress === "function") { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + response = new Response(body, response_options); + resolve(response); + }); + writeToStream(req, request); + }); + } + function fixResponseChunkedTransferBadEnding(request, errorCallback) { + let socket; + request.on("socket", function(s) { + socket = s; + }); + request.on("response", function(response) { + const headers = response.headers; + if (headers["transfer-encoding"] === "chunked" && !headers["content-length"]) { + response.once("close", function(hadError) { + const hasDataListener = socket && socket.listenerCount("data") > 0; + if (hasDataListener && !hadError) { + const err = new Error("Premature close"); + err.code = "ERR_STREAM_PREMATURE_CLOSE"; + errorCallback(err); + } + }); + } + }); + } + function destroyStream(stream, err) { + if (stream.destroy) { + stream.destroy(err); + } else { + stream.emit("error", err); + stream.end(); + } + } + fetch2.isRedirect = function(code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; + }; + fetch2.Promise = global.Promise; + module2.exports = exports2 = fetch2; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.default = exports2; + exports2.Headers = Headers2; + exports2.Request = Request; + exports2.Response = Response; + exports2.FetchError = FetchError; + exports2.AbortError = AbortError2; + } +}); + +// node_modules/botframework-connector/lib/auth/openIdMetadata.js +var require_openIdMetadata = __commonJS({ + "node_modules/botframework-connector/lib/auth/openIdMetadata.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.OpenIdMetadata = void 0; + var rsa_pem_from_mod_exp_1 = __importDefault2(require_rsa_pem_from_mod_exp()); + var base64url_1 = __importDefault2(require_base64url2()); + var node_fetch_1 = __importDefault2(require_lib7()); + var https_proxy_agent_1 = require_dist2(); + var authenticationError_1 = require_authenticationError(); + var botframework_schema_1 = require_lib4(); + var OpenIdMetadata = class { + /** + * Initializes a new instance of the [OpenIdMetadata](xref:botframework-connector.OpenIdMetadata) class. + * + * @param url Metadata Url. + * @param proxySettings The proxy settings for the request. + * @param tokenRefreshInterval The token refresh interval in hours. The default value is 24 hours. + */ + constructor(url, proxySettings, tokenRefreshInterval = 24) { + this.url = url; + this.proxySettings = proxySettings; + this.tokenRefreshInterval = tokenRefreshInterval; + this.lastUpdated = 0; + } + /** + * Gets the Signing key. + * + * @param keyId The key ID to search for. + * @returns A `Promise` representation for either a [IOpenIdMetadataKey](botframework-connector:module.IOpenIdMetadataKey) or `null`. + */ + getKey(keyId) { + return __awaiter2(this, void 0, void 0, function* () { + if (this.lastUpdated < Date.now() - this.tokenRefreshInterval * 1e3 * 60 * 60) { + yield this.refreshCache(); + const key = this.findKey(keyId); + return key; + } else { + const key = this.findKey(keyId); + if (!key && this.lastUpdated < Date.now() - 1e3 * 60 * 60) { + yield this.refreshCache(); + return this.findKey(keyId); + } + return key; + } + }); + } + /** + * @private + */ + refreshCache() { + return __awaiter2(this, void 0, void 0, function* () { + let agent = null; + if (this.proxySettings) { + const proxyUrl = `http://${this.proxySettings.host}:${this.proxySettings.port}`; + agent = new https_proxy_agent_1.HttpsProxyAgent(proxyUrl); + } + const res = yield (0, node_fetch_1.default)(this.url, { agent }); + if (res.ok) { + const openIdConfig = yield res.json(); + const getKeyResponse = yield (0, node_fetch_1.default)(openIdConfig.jwks_uri, { agent }); + if (getKeyResponse.ok) { + this.lastUpdated = (/* @__PURE__ */ new Date()).getTime(); + this.keys = (yield getKeyResponse.json()).keys; + } else { + throw new authenticationError_1.AuthenticationError(`Failed to load Keys: ${getKeyResponse.status}`, botframework_schema_1.StatusCodes.INTERNAL_SERVER_ERROR); + } + } else { + throw new authenticationError_1.AuthenticationError(`Failed to load openID config: ${res.status}`, botframework_schema_1.StatusCodes.INTERNAL_SERVER_ERROR); + } + }); + } + /** + * @private + */ + findKey(keyId) { + if (!this.keys) { + return null; + } + for (const key of this.keys) { + if (key.kid === keyId) { + if (!key.n || !key.e) { + return null; + } + const modulus = base64url_1.default.toBase64(key.n); + const exponent = key.e; + return { + key: (0, rsa_pem_from_mod_exp_1.default)(modulus, exponent), + endorsements: key.endorsements + }; + } + } + return null; + } + }; + exports2.OpenIdMetadata = OpenIdMetadata; + } +}); + +// node_modules/botframework-connector/lib/auth/jwtTokenExtractor.js +var require_jwtTokenExtractor = __commonJS({ + "node_modules/botframework-connector/lib/auth/jwtTokenExtractor.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.JwtTokenExtractor = void 0; + var jsonwebtoken_1 = require_jsonwebtoken(); + var claimsIdentity_1 = require_claimsIdentity(); + var endorsementsValidator_1 = require_endorsementsValidator(); + var openIdMetadata_1 = require_openIdMetadata(); + var authenticationError_1 = require_authenticationError(); + var botframework_schema_1 = require_lib4(); + var JwtTokenExtractor = class _JwtTokenExtractor { + /** + * Initializes a new instance of the [JwtTokenExtractor](xref:botframework-connector.JwtTokenExtractor) class. Extracts relevant data from JWT Tokens. + * + * @param tokenValidationParameters Token validation parameters. + * @param metadataUrl Metadata Url. + * @param allowedSigningAlgorithms Allowed signing algorithms. + * @param proxySettings The proxy settings for the request. + * @param tokenRefreshInterval The token refresh interval in hours. The default value is 24 hours. + */ + constructor(tokenValidationParameters, metadataUrl, allowedSigningAlgorithms, proxySettings, tokenRefreshInterval) { + this.tokenValidationParameters = Object.assign({}, tokenValidationParameters); + this.tokenValidationParameters.algorithms = allowedSigningAlgorithms; + this.openIdMetadata = _JwtTokenExtractor.getOrAddOpenIdMetadata(metadataUrl, proxySettings, tokenRefreshInterval); + } + static getOrAddOpenIdMetadata(metadataUrl, proxySettings, tokenRefreshInterval) { + let metadata = this.openIdMetadataCache.get(metadataUrl); + if (!metadata) { + metadata = new openIdMetadata_1.OpenIdMetadata(metadataUrl, proxySettings, tokenRefreshInterval); + this.openIdMetadataCache.set(metadataUrl, metadata); + } + return metadata; + } + /** + * Gets the claims identity associated with a request. + * + * @param authorizationHeader The raw HTTP header in the format: "Bearer [longString]". + * @param channelId The Id of the channel being validated in the original request. + * @param requiredEndorsements The required JWT endorsements. + * @returns A `Promise` representation for either a [ClaimsIdentity](botframework-connector:module.ClaimsIdentity) or `null`. + */ + getIdentityFromAuthHeader(authorizationHeader, channelId, requiredEndorsements) { + return __awaiter2(this, void 0, void 0, function* () { + if (!authorizationHeader) { + return null; + } + const parts = authorizationHeader.split(" "); + if (parts.length === 2) { + return yield this.getIdentity(parts[0], parts[1], channelId, requiredEndorsements || []); + } + return null; + }); + } + /** + * Gets the claims identity associated with a request. + * + * @param scheme The associated scheme. + * @param parameter The token. + * @param channelId The Id of the channel being validated in the original request. + * @param requiredEndorsements The required JWT endorsements. + * @returns A `Promise` representation for either a [ClaimsIdentity](botframework-connector:module.ClaimsIdentity) or `null`. + */ + getIdentity(scheme, parameter, channelId, requiredEndorsements = []) { + return __awaiter2(this, void 0, void 0, function* () { + if (scheme !== "Bearer" || !parameter) { + return null; + } + if (!this.hasAllowedIssuer(parameter)) { + return null; + } + return yield this.validateToken(parameter, channelId, requiredEndorsements); + }); + } + /** + * @private + */ + hasAllowedIssuer(jwtToken) { + const payload = (0, jsonwebtoken_1.decode)(jwtToken); + let issuer; + if (payload && typeof payload === "object") { + issuer = payload.iss; + } else { + return false; + } + if (Array.isArray(this.tokenValidationParameters.issuer)) { + return this.tokenValidationParameters.issuer.indexOf(issuer) !== -1; + } + if (typeof this.tokenValidationParameters.issuer === "string") { + return this.tokenValidationParameters.issuer === issuer; + } + return false; + } + /** + * @private + */ + validateToken(jwtToken, channelId, requiredEndorsements) { + return __awaiter2(this, void 0, void 0, function* () { + let header = {}; + const decodedToken = (0, jsonwebtoken_1.decode)(jwtToken, { complete: true }); + if (decodedToken && typeof decodedToken === "object") { + header = decodedToken.header; + } + const keyId = header.kid; + const metadata = yield this.openIdMetadata.getKey(keyId); + if (!metadata) { + throw new authenticationError_1.AuthenticationError("Signing Key could not be retrieved.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + try { + let decodedPayload = {}; + const verifyResults = (0, jsonwebtoken_1.verify)(jwtToken, metadata.key, this.tokenValidationParameters); + if (verifyResults && typeof verifyResults === "object") { + decodedPayload = verifyResults; + } + const endorsements = metadata.endorsements; + if (Array.isArray(endorsements) && endorsements.length !== 0) { + const isEndorsed = endorsementsValidator_1.EndorsementsValidator.validate(channelId, endorsements); + if (!isEndorsed) { + throw new authenticationError_1.AuthenticationError(`Could not validate endorsement for key: ${keyId} with endorsements: ${endorsements.join(",")}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const additionalEndorsementsSatisfied = requiredEndorsements.every((endorsement) => endorsementsValidator_1.EndorsementsValidator.validate(endorsement, endorsements)); + if (!additionalEndorsementsSatisfied) { + throw new authenticationError_1.AuthenticationError(`Could not validate additional endorsement for key: ${keyId} with endorsements: ${requiredEndorsements.join(",")}. Expected endorsements: ${requiredEndorsements.join(",")}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + } + if (this.tokenValidationParameters.algorithms) { + if (this.tokenValidationParameters.algorithms.indexOf(header.alg) === -1) { + throw new authenticationError_1.AuthenticationError(`"Token signing algorithm '${header.alg}' not in allowed list`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + } + const claims = Object.entries(decodedPayload).map(([type, value]) => ({ type, value })); + return new claimsIdentity_1.ClaimsIdentity(claims, true); + } catch (err) { + if (err.name === "TokenExpiredError") { + console.error(err); + throw new authenticationError_1.AuthenticationError("The token has expired", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + console.error(`Error finding key for token. Available keys: ${metadata.key}`); + throw err; + } + }); + } + }; + exports2.JwtTokenExtractor = JwtTokenExtractor; + JwtTokenExtractor.openIdMetadataCache = /* @__PURE__ */ new Map(); + } +}); + +// node_modules/botframework-connector/lib/auth/channelValidation.js +var require_channelValidation = __commonJS({ + "node_modules/botframework-connector/lib/auth/channelValidation.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ChannelValidation = void 0; + var authenticationConstants_1 = require_authenticationConstants(); + var authenticationConfiguration_1 = require_authenticationConfiguration(); + var jwtTokenExtractor_1 = require_jwtTokenExtractor(); + var authenticationError_1 = require_authenticationError(); + var botframework_schema_1 = require_lib4(); + var ChannelValidation; + (function(ChannelValidation2) { + ChannelValidation2.ToBotFromChannelTokenValidationParameters = { + issuer: [authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer], + audience: void 0, + clockTolerance: 5 * 60, + ignoreExpiration: false + }; + function authenticateChannelTokenWithServiceUrl(authHeader, credentials, serviceUrl, channelId, authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { + return __awaiter2(this, void 0, void 0, function* () { + const identity = yield authenticateChannelToken(authHeader, credentials, channelId, authConfig); + const serviceUrlClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.ServiceUrlClaim); + if (serviceUrlClaim !== serviceUrl) { + throw new authenticationError_1.AuthenticationError("Unauthorized. ServiceUrl claim do not match.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + ChannelValidation2.authenticateChannelTokenWithServiceUrl = authenticateChannelTokenWithServiceUrl; + function authenticateChannelToken(authHeader, credentials, channelId, authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { + return __awaiter2(this, void 0, void 0, function* () { + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(ChannelValidation2.ToBotFromChannelTokenValidationParameters, ChannelValidation2.OpenIdMetadataEndpoint ? ChannelValidation2.OpenIdMetadataEndpoint : authenticationConstants_1.AuthenticationConstants.ToBotFromChannelOpenIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms); + const identity = yield tokenExtractor.getIdentityFromAuthHeader(authHeader, channelId, authConfig.requiredEndorsements); + return yield validateIdentity(identity, credentials); + }); + } + ChannelValidation2.authenticateChannelToken = authenticateChannelToken; + function validateIdentity(identity, credentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!identity || !identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Is not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.IssuerClaim) !== authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Issuer Claim MUST be present.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const audClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim); + if (!(yield credentials.isValidAppId(audClaim || ""))) { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Invalid AppId passed on token: ${audClaim}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + ChannelValidation2.validateIdentity = validateIdentity; + })(ChannelValidation = exports2.ChannelValidation || (exports2.ChannelValidation = {})); + } +}); + +// node_modules/botframework-connector/lib/auth/governmentConstants.js +var require_governmentConstants = __commonJS({ + "node_modules/botframework-connector/lib/auth/governmentConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.GovernmentConstants = void 0; + var GovernmentConstants; + (function(GovernmentConstants2) { + GovernmentConstants2.ChannelService = "https://botframework.azure.us"; + GovernmentConstants2.ToChannelFromBotLoginUrl = "https://login.microsoftonline.us/MicrosoftServices.onmicrosoft.us"; + GovernmentConstants2.ToChannelFromBotLoginUrlPrefix = "https://login.microsoftonline.us/"; + GovernmentConstants2.DefaultChannelAuthTenant = "MicrosoftServices.onmicrosoft.us"; + GovernmentConstants2.ToChannelFromBotOAuthScope = "https://api.botframework.us"; + GovernmentConstants2.ToBotFromChannelTokenIssuer = "https://api.botframework.us"; + GovernmentConstants2.OAuthUrl = "https://api.botframework.azure.us"; + GovernmentConstants2.ToBotFromChannelOpenIdMetadataUrl = "https://login.botframework.azure.us/v1/.well-known/openidconfiguration"; + GovernmentConstants2.ToBotFromEmulatorOpenIdMetadataUrl = "https://login.microsoftonline.us/cab8a31a-1906-4287-a0d8-4eef66b95f6e/v2.0/.well-known/openid-configuration"; + })(GovernmentConstants = exports2.GovernmentConstants || (exports2.GovernmentConstants = {})); + } +}); + +// node_modules/botframework-connector/lib/auth/tokenValidationParameters.js +var require_tokenValidationParameters = __commonJS({ + "node_modules/botframework-connector/lib/auth/tokenValidationParameters.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BetweenBotAndAseChannelTokenValidationParameters = exports2.ToBotFromBotOrEmulatorTokenValidationParameters = void 0; + exports2.ToBotFromBotOrEmulatorTokenValidationParameters = { + issuer: [ + "https://sts.windows.net/d6d49420-f39b-4df7-a1dc-d59a935871db/", + "https://login.microsoftonline.com/d6d49420-f39b-4df7-a1dc-d59a935871db/v2.0", + "https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/", + "https://login.microsoftonline.com/f8cdef31-a31e-4b4a-93e4-5f571e91255a/v2.0", + "https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/", + "https://sts.windows.net/cab8a31a-1906-4287-a0d8-4eef66b95f6e/", + "https://login.microsoftonline.us/cab8a31a-1906-4287-a0d8-4eef66b95f6e/v2.0", + "https://login.microsoftonline.us/f8cdef31-a31e-4b4a-93e4-5f571e91255a/", + "https://login.microsoftonline.us/f8cdef31-a31e-4b4a-93e4-5f571e91255a/v2.0" + // Auth for US Gov, 2.0 token + ], + audience: void 0, + clockTolerance: 5 * 60, + ignoreExpiration: false + }; + exports2.BetweenBotAndAseChannelTokenValidationParameters = { + issuer: [], + audience: void 0, + clockTolerance: 5 * 60, + ignoreExpiration: false + }; + } +}); + +// node_modules/botframework-connector/lib/auth/emulatorValidation.js +var require_emulatorValidation = __commonJS({ + "node_modules/botframework-connector/lib/auth/emulatorValidation.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.EmulatorValidation = void 0; + var jsonwebtoken_1 = require_jsonwebtoken(); + var authenticationConstants_1 = require_authenticationConstants(); + var authenticationConfiguration_1 = require_authenticationConfiguration(); + var governmentConstants_1 = require_governmentConstants(); + var jwtTokenExtractor_1 = require_jwtTokenExtractor(); + var jwtTokenValidation_1 = require_jwtTokenValidation(); + var authenticationError_1 = require_authenticationError(); + var botframework_schema_1 = require_lib4(); + var tokenValidationParameters_1 = require_tokenValidationParameters(); + var EmulatorValidation; + (function(EmulatorValidation2) { + EmulatorValidation2.ToBotFromEmulatorTokenValidationParameters = tokenValidationParameters_1.ToBotFromBotOrEmulatorTokenValidationParameters; + function isTokenFromEmulator(authHeader) { + var _a; + if (!authHeader) { + return false; + } + const parts = authHeader.split(" "); + if (parts.length !== 2) { + return false; + } + const authScheme = parts[0]; + const bearerToken = parts[1]; + if (authScheme !== "Bearer") { + return false; + } + const token = (0, jsonwebtoken_1.decode)(bearerToken, { complete: true }); + if (!token) { + return false; + } + const issuer = token.payload[authenticationConstants_1.AuthenticationConstants.IssuerClaim]; + if (!issuer) { + return false; + } + const validTokenIssuers = tokenValidationParameters_1.ToBotFromBotOrEmulatorTokenValidationParameters.issuer; + if (Array.isArray(validTokenIssuers)) { + const tenantId = (_a = token === null || token === void 0 ? void 0 : token.payload[authenticationConstants_1.AuthenticationConstants.TenantIdClaim]) !== null && _a !== void 0 ? _a : ""; + if (tenantId != "" && validTokenIssuers.find((issuer2) => issuer2.includes(tenantId)) == null) { + validTokenIssuers.push(`${authenticationConstants_1.AuthenticationConstants.ValidTokenIssuerUrlTemplateV1}${tenantId}/`); + validTokenIssuers.push(`${authenticationConstants_1.AuthenticationConstants.ValidTokenIssuerUrlTemplateV2}${tenantId}/v2.0`); + validTokenIssuers.push(`${authenticationConstants_1.AuthenticationConstants.ValidGovernmentTokenIssuerUrlTemplateV1}${tenantId}/`); + validTokenIssuers.push(`${authenticationConstants_1.AuthenticationConstants.ValidGovernmentTokenIssuerUrlTemplateV2}${tenantId}/v2.0`); + } + } + if (validTokenIssuers && validTokenIssuers.indexOf(issuer) === -1) { + return false; + } + return true; + } + EmulatorValidation2.isTokenFromEmulator = isTokenFromEmulator; + function authenticateEmulatorToken(authHeader, credentials, channelService, channelId, authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { + return __awaiter2(this, void 0, void 0, function* () { + const openIdMetadataUrl = channelService !== void 0 && jwtTokenValidation_1.JwtTokenValidation.isGovernment(channelService) ? governmentConstants_1.GovernmentConstants.ToBotFromEmulatorOpenIdMetadataUrl : authenticationConstants_1.AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl; + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(EmulatorValidation2.ToBotFromEmulatorTokenValidationParameters, openIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms); + const identity = yield tokenExtractor.getIdentityFromAuthHeader(authHeader, channelId, authConfig.requiredEndorsements); + if (!identity) { + throw new authenticationError_1.AuthenticationError("Unauthorized. No valid identity.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Is not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const versionClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.VersionClaim); + if (versionClaim === null) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "ver" claim is required on Emulator Tokens.', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + let appId = ""; + if (!versionClaim || versionClaim === "1.0") { + const appIdClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AppIdClaim); + if (!appIdClaim) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "appid" claim is required on Emulator Token version "1.0".', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + appId = appIdClaim; + } else if (versionClaim === "2.0") { + const appZClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AuthorizedParty); + if (!appZClaim) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "azp" claim is required on Emulator Token version "2.0".', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + appId = appZClaim; + } else { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Unknown Emulator Token version "${versionClaim}".`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!(yield credentials.isValidAppId(appId))) { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Invalid AppId passed on token: ${appId}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + EmulatorValidation2.authenticateEmulatorToken = authenticateEmulatorToken; + })(EmulatorValidation = exports2.EmulatorValidation || (exports2.EmulatorValidation = {})); + } +}); + +// node_modules/botframework-connector/lib/auth/enterpriseChannelValidation.js +var require_enterpriseChannelValidation = __commonJS({ + "node_modules/botframework-connector/lib/auth/enterpriseChannelValidation.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.EnterpriseChannelValidation = void 0; + var authenticationConfiguration_1 = require_authenticationConfiguration(); + var authenticationConstants_1 = require_authenticationConstants(); + var channelValidation_1 = require_channelValidation(); + var jwtTokenExtractor_1 = require_jwtTokenExtractor(); + var authenticationError_1 = require_authenticationError(); + var botframework_schema_1 = require_lib4(); + var EnterpriseChannelValidation; + (function(EnterpriseChannelValidation2) { + EnterpriseChannelValidation2.ToBotFromEnterpriseChannelTokenValidationParameters = { + issuer: [authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer], + audience: void 0, + clockTolerance: 5 * 60, + ignoreExpiration: false + }; + function authenticateChannelTokenWithServiceUrl(authHeader, credentials, serviceUrl, channelId, channelService) { + return __awaiter2(this, void 0, void 0, function* () { + const identity = yield authenticateChannelToken(authHeader, credentials, channelId, channelService); + const serviceUrlClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.ServiceUrlClaim); + if (serviceUrlClaim !== serviceUrl) { + throw new authenticationError_1.AuthenticationError("Unauthorized. ServiceUrl claim do not match.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + EnterpriseChannelValidation2.authenticateChannelTokenWithServiceUrl = authenticateChannelTokenWithServiceUrl; + function authenticateChannelToken(authHeader, credentials, channelId, channelService, authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { + return __awaiter2(this, void 0, void 0, function* () { + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(EnterpriseChannelValidation2.ToBotFromEnterpriseChannelTokenValidationParameters, channelValidation_1.ChannelValidation.OpenIdMetadataEndpoint ? channelValidation_1.ChannelValidation.OpenIdMetadataEndpoint : authenticationConstants_1.AuthenticationConstants.ToBotFromEnterpriseChannelOpenIdMetadataUrlFormat.replace("{channelService}", channelService), authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms); + const identity = yield tokenExtractor.getIdentityFromAuthHeader(authHeader, channelId, authConfig.requiredEndorsements); + return yield validateIdentity(identity, credentials); + }); + } + EnterpriseChannelValidation2.authenticateChannelToken = authenticateChannelToken; + function validateIdentity(identity, credentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!identity) { + throw new authenticationError_1.AuthenticationError("Unauthorized. No valid identity.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Is not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.IssuerClaim) !== authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Issuer Claim MUST be present.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const audClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim); + if (!(yield credentials.isValidAppId(audClaim || ""))) { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Invalid AppId passed on token: ${audClaim}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + EnterpriseChannelValidation2.validateIdentity = validateIdentity; + })(EnterpriseChannelValidation = exports2.EnterpriseChannelValidation || (exports2.EnterpriseChannelValidation = {})); + } +}); + +// node_modules/botframework-connector/lib/auth/governmentChannelValidation.js +var require_governmentChannelValidation = __commonJS({ + "node_modules/botframework-connector/lib/auth/governmentChannelValidation.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.GovernmentChannelValidation = void 0; + var authenticationConfiguration_1 = require_authenticationConfiguration(); + var authenticationConstants_1 = require_authenticationConstants(); + var governmentConstants_1 = require_governmentConstants(); + var jwtTokenExtractor_1 = require_jwtTokenExtractor(); + var authenticationError_1 = require_authenticationError(); + var botframework_schema_1 = require_lib4(); + var GovernmentChannelValidation; + (function(GovernmentChannelValidation2) { + GovernmentChannelValidation2.ToBotFromGovernmentChannelTokenValidationParameters = { + issuer: [governmentConstants_1.GovernmentConstants.ToBotFromChannelTokenIssuer], + audience: void 0, + clockTolerance: 5 * 60, + ignoreExpiration: false + }; + function authenticateChannelTokenWithServiceUrl(authHeader, credentials, serviceUrl, channelId) { + return __awaiter2(this, void 0, void 0, function* () { + const identity = yield authenticateChannelToken(authHeader, credentials, channelId); + const serviceUrlClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.ServiceUrlClaim); + if (serviceUrlClaim !== serviceUrl) { + throw new authenticationError_1.AuthenticationError("Unauthorized. ServiceUrl claim do not match.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + GovernmentChannelValidation2.authenticateChannelTokenWithServiceUrl = authenticateChannelTokenWithServiceUrl; + function authenticateChannelToken(authHeader, credentials, channelId, authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { + return __awaiter2(this, void 0, void 0, function* () { + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(GovernmentChannelValidation2.ToBotFromGovernmentChannelTokenValidationParameters, GovernmentChannelValidation2.OpenIdMetadataEndpoint ? GovernmentChannelValidation2.OpenIdMetadataEndpoint : governmentConstants_1.GovernmentConstants.ToBotFromChannelOpenIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms); + const identity = yield tokenExtractor.getIdentityFromAuthHeader(authHeader, channelId, authConfig.requiredEndorsements); + return yield validateIdentity(identity, credentials); + }); + } + GovernmentChannelValidation2.authenticateChannelToken = authenticateChannelToken; + function validateIdentity(identity, credentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!identity) { + throw new authenticationError_1.AuthenticationError("Unauthorized. No valid identity.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Is not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.IssuerClaim) !== governmentConstants_1.GovernmentConstants.ToBotFromChannelTokenIssuer) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Issuer Claim MUST be present.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const audClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim); + if (!(yield credentials.isValidAppId(audClaim || ""))) { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Invalid AppId passed on token: ${audClaim}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + GovernmentChannelValidation2.validateIdentity = validateIdentity; + })(GovernmentChannelValidation = exports2.GovernmentChannelValidation || (exports2.GovernmentChannelValidation = {})); + } +}); + +// node_modules/botframework-connector/lib/auth/skillValidation.js +var require_skillValidation = __commonJS({ + "node_modules/botframework-connector/lib/auth/skillValidation.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkillValidation = void 0; + var authenticationConstants_1 = require_authenticationConstants(); + var authenticationError_1 = require_authenticationError(); + var claimsIdentity_1 = require_claimsIdentity(); + var governmentConstants_1 = require_governmentConstants(); + var jwtTokenExtractor_1 = require_jwtTokenExtractor(); + var jwtTokenValidation_1 = require_jwtTokenValidation(); + var botframework_schema_1 = require_lib4(); + var tokenValidationParameters_1 = require_tokenValidationParameters(); + var jsonwebtoken_1 = require_jsonwebtoken(); + var SkillValidation; + (function(SkillValidation2) { + function isSkillToken(authHeader) { + if (!jwtTokenValidation_1.JwtTokenValidation.isValidTokenFormat(authHeader)) { + return false; + } + const [, ...bearerTokens] = authHeader.trim().split(" "); + const payload = (0, jsonwebtoken_1.decode)(bearerTokens.join(" ")); + let claims = []; + if (payload && typeof payload === "object") { + claims = Object.entries(payload).map(([type, value]) => ({ + type, + value + })); + } + return isSkillClaim(claims); + } + SkillValidation2.isSkillToken = isSkillToken; + function isSkillClaim(claims) { + if (!claims) { + throw new TypeError("SkillValidation.isSkillClaim(): missing claims."); + } + const claimsByType = claims.reduce((acc, claim) => Object.assign(Object.assign({}, acc), { [claim.type]: claim }), {}); + const appIdClaim = claimsByType[authenticationConstants_1.AuthenticationConstants.AppIdClaim]; + if (appIdClaim && appIdClaim.value === authenticationConstants_1.AuthenticationConstants.AnonymousSkillAppId) { + return true; + } + const versionClaim = claimsByType[authenticationConstants_1.AuthenticationConstants.VersionClaim]; + const versionValue = versionClaim && versionClaim.value; + if (!versionValue) { + return false; + } + const audClaim = claimsByType[authenticationConstants_1.AuthenticationConstants.AudienceClaim]; + const audienceValue = audClaim && audClaim.value; + if (!audClaim || authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer === audienceValue || governmentConstants_1.GovernmentConstants.ToBotFromChannelTokenIssuer === audienceValue) { + return false; + } + const appId = jwtTokenValidation_1.JwtTokenValidation.getAppIdFromClaims(claims); + if (!appId) { + return false; + } + return appId !== audienceValue; + } + SkillValidation2.isSkillClaim = isSkillClaim; + function authenticateChannelToken(authHeader, credentials, channelService, channelId, authConfig) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + if (!authConfig) { + throw new authenticationError_1.AuthenticationError("SkillValidation.authenticateChannelToken(): invalid authConfig parameter", botframework_schema_1.StatusCodes.INTERNAL_SERVER_ERROR); + } + const openIdMetadataUrl = jwtTokenValidation_1.JwtTokenValidation.isGovernment(channelService) ? governmentConstants_1.GovernmentConstants.ToBotFromEmulatorOpenIdMetadataUrl : authenticationConstants_1.AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl; + const verifyOptions = Object.assign(Object.assign({}, tokenValidationParameters_1.ToBotFromBotOrEmulatorTokenValidationParameters), { issuer: [ + ...tokenValidationParameters_1.ToBotFromBotOrEmulatorTokenValidationParameters.issuer, + ...(_a = authConfig.validTokenIssuers) !== null && _a !== void 0 ? _a : [] + ] }); + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(verifyOptions, openIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms); + const parts = authHeader.split(" "); + const identity = yield tokenExtractor.getIdentity(parts[0], parts[1], channelId, authConfig.requiredEndorsements); + yield validateIdentity(identity, credentials); + return identity; + }); + } + SkillValidation2.authenticateChannelToken = authenticateChannelToken; + function validateIdentity(identity, credentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!identity) { + throw new authenticationError_1.AuthenticationError("SkillValidation.validateIdentity(): Invalid identity", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("SkillValidation.validateIdentity(): Token not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const versionClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.VersionClaim); + if (!versionClaim) { + throw new authenticationError_1.AuthenticationError(`SkillValidation.validateIdentity(): '${authenticationConstants_1.AuthenticationConstants.VersionClaim}' claim is required on skill Tokens.`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const audienceClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim); + if (!audienceClaim) { + throw new authenticationError_1.AuthenticationError(`SkillValidation.validateIdentity(): '${authenticationConstants_1.AuthenticationConstants.AudienceClaim}' claim is required on skill Tokens.`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!(yield credentials.isValidAppId(audienceClaim))) { + throw new authenticationError_1.AuthenticationError("SkillValidation.validateIdentity(): Invalid audience.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const appId = jwtTokenValidation_1.JwtTokenValidation.getAppIdFromClaims(identity.claims); + if (!appId) { + throw new authenticationError_1.AuthenticationError("SkillValidation.validateIdentity(): Invalid appId.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + }); + } + SkillValidation2.validateIdentity = validateIdentity; + function createAnonymousSkillClaim() { + return new claimsIdentity_1.ClaimsIdentity([ + { + type: authenticationConstants_1.AuthenticationConstants.AppIdClaim, + value: authenticationConstants_1.AuthenticationConstants.AnonymousSkillAppId + } + ], authenticationConstants_1.AuthenticationConstants.AnonymousAuthType); + } + SkillValidation2.createAnonymousSkillClaim = createAnonymousSkillClaim; + })(SkillValidation = exports2.SkillValidation || (exports2.SkillValidation = {})); + } +}); + +// node_modules/botframework-connector/lib/auth/credentialProvider.js +var require_credentialProvider = __commonJS({ + "node_modules/botframework-connector/lib/auth/credentialProvider.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SimpleCredentialProvider = void 0; + var SimpleCredentialProvider = class { + /** + * Initializes a new instance of the [SimpleCredentialProvider](xref:botframework-connector.SimpleCredentialProvider) class with the provided credentials. + * + * @param {string} appId The app ID. + * @param {string} appPassword The app password. + */ + constructor(appId, appPassword) { + this.appId = appId; + this.appPassword = appPassword; + } + // Protects against JSON.stringify leaking secrets + toJSON() { + return { name: this.constructor.name, appId: this.appId }; + } + /** + * Validate AppId. + * + * This method is async to enable custom implementations + * that may need to call out to service to validate the appId / password pair. + * + * @param {string} appId bot appid + * @returns {Promise} true if it is a valid AppId + */ + isValidAppId(appId) { + return Promise.resolve(this.appId === appId); + } + /** + * Get the app password for a given bot appId, if it is not a valid appId, return Null + * + * This method is async to enable custom implementations + * that may need to call out to serviced to validate the appId / password pair. + * + * @param {string} appId bot appid + * @returns {Promise} password or null for invalid appid + */ + getAppPassword(appId) { + return Promise.resolve(this.appId === appId ? this.appPassword : null); + } + /** + * Checks if bot authentication is disabled. + * Return true if bot authentication is disabled. + * + * This method is async to enable custom implementations + * that may need to call out to serviced to validate the appId / password pair. + * + * @returns {Promise} true if bot authentication is disabled. + */ + isAuthenticationDisabled() { + return Promise.resolve(!this.appId); + } + }; + exports2.SimpleCredentialProvider = SimpleCredentialProvider; + } +}); + +// node_modules/botframework-connector/lib/auth/aseChannelValidation.js +var require_aseChannelValidation = __commonJS({ + "node_modules/botframework-connector/lib/auth/aseChannelValidation.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AseChannelValidation = void 0; + var authenticationConstants_1 = require_authenticationConstants(); + var authenticationConfiguration_1 = require_authenticationConfiguration(); + var governmentConstants_1 = require_governmentConstants(); + var credentialProvider_1 = require_credentialProvider(); + var jwtTokenExtractor_1 = require_jwtTokenExtractor(); + var jwtTokenValidation_1 = require_jwtTokenValidation(); + var authenticationError_1 = require_authenticationError(); + var botframework_schema_1 = require_lib4(); + var tokenValidationParameters_1 = require_tokenValidationParameters(); + var AseChannelValidation; + (function(AseChannelValidation2) { + const ChannelId = "AseChannel"; + let _creadentialProvider; + let _channelService; + function init(configuration) { + const appId = configuration.MicrosoftAppId; + const tenantId = configuration.MicrosoftAppTenantId; + _channelService = configuration.ChannelService; + AseChannelValidation2.MetadataUrl = _channelService !== void 0 && jwtTokenValidation_1.JwtTokenValidation.isGovernment(_channelService) ? governmentConstants_1.GovernmentConstants.ToBotFromEmulatorOpenIdMetadataUrl : authenticationConstants_1.AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl; + _creadentialProvider = new credentialProvider_1.SimpleCredentialProvider(appId, ""); + const tenantIds = [ + tenantId, + "f8cdef31-a31e-4b4a-93e4-5f571e91255a", + "d6d49420-f39b-4df7-a1dc-d59a935871db" + // Public botframework.com + ]; + const validIssuers = []; + tenantIds.forEach((tmpId) => { + validIssuers.push(`https://sts.windows.net/${tmpId}/`); + validIssuers.push(`https://login.microsoftonline.com/${tmpId}/v2.0`); + validIssuers.push(`https://login.microsoftonline.us/${tmpId}/v2.0`); + }); + tokenValidationParameters_1.BetweenBotAndAseChannelTokenValidationParameters.issuer = validIssuers; + } + AseChannelValidation2.init = init; + function isTokenFromAseChannel(channelId) { + return channelId === ChannelId; + } + AseChannelValidation2.isTokenFromAseChannel = isTokenFromAseChannel; + function authenticateAseChannelToken(authHeader, authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { + return __awaiter2(this, void 0, void 0, function* () { + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(tokenValidationParameters_1.BetweenBotAndAseChannelTokenValidationParameters, AseChannelValidation2.MetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms); + const identity = yield tokenExtractor.getIdentityFromAuthHeader(authHeader, ChannelId, authConfig.requiredEndorsements); + if (!identity) { + throw new authenticationError_1.AuthenticationError("Unauthorized. No valid identity.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Is not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const versionClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.VersionClaim); + if (versionClaim === null) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "ver" claim is required on Emulator Tokens.', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + let appId = ""; + if (!versionClaim || versionClaim === "1.0") { + const appIdClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AppIdClaim); + if (!appIdClaim) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "appid" claim is required on Emulator Token version "1.0".', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + appId = appIdClaim; + } else if (versionClaim === "2.0") { + const appZClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AuthorizedParty); + if (!appZClaim) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "azp" claim is required on Emulator Token version "2.0".', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + appId = appZClaim; + } else { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Unknown Emulator Token version "${versionClaim}".`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!(yield _creadentialProvider.isValidAppId(appId))) { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Invalid AppId passed on token: ${appId}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + AseChannelValidation2.authenticateAseChannelToken = authenticateAseChannelToken; + })(AseChannelValidation = exports2.AseChannelValidation || (exports2.AseChannelValidation = {})); + } +}); + +// node_modules/botframework-connector/lib/auth/jwtTokenValidation.js +var require_jwtTokenValidation = __commonJS({ + "node_modules/botframework-connector/lib/auth/jwtTokenValidation.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.JwtTokenValidation = void 0; + var botframework_schema_1 = require_lib4(); + var authenticationError_1 = require_authenticationError(); + var authenticationConfiguration_1 = require_authenticationConfiguration(); + var authenticationConstants_1 = require_authenticationConstants(); + var channelValidation_1 = require_channelValidation(); + var claimsIdentity_1 = require_claimsIdentity(); + var emulatorValidation_1 = require_emulatorValidation(); + var enterpriseChannelValidation_1 = require_enterpriseChannelValidation(); + var governmentChannelValidation_1 = require_governmentChannelValidation(); + var governmentConstants_1 = require_governmentConstants(); + var skillValidation_1 = require_skillValidation(); + var aseChannelValidation_1 = require_aseChannelValidation(); + var JwtTokenValidation; + (function(JwtTokenValidation2) { + function authenticateRequest(activity, authHeader, credentials, channelService, authConfig) { + return __awaiter2(this, void 0, void 0, function* () { + if (!authConfig) { + authConfig = new authenticationConfiguration_1.AuthenticationConfiguration(); + } + const isAuthDisabled = yield credentials.isAuthenticationDisabled(); + if (isAuthDisabled) { + if (activity.channelId === botframework_schema_1.Channels.Emulator && activity.recipient && activity.recipient.role === botframework_schema_1.RoleTypes.Skill) { + return skillValidation_1.SkillValidation.createAnonymousSkillClaim(); + } + return new claimsIdentity_1.ClaimsIdentity([], authenticationConstants_1.AuthenticationConstants.AnonymousAuthType); + } else { + if (!authHeader.trim()) { + throw new authenticationError_1.AuthenticationError("Unauthorized Access. Request is not authorized", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const claimsIdentity = yield validateAuthHeader(authHeader, credentials, channelService, activity.channelId, activity.serviceUrl, authConfig); + return claimsIdentity; + } + }); + } + JwtTokenValidation2.authenticateRequest = authenticateRequest; + function validateAuthHeader(authHeader, credentials, channelService, channelId, serviceUrl = "", authConfig = new authenticationConfiguration_1.AuthenticationConfiguration()) { + return __awaiter2(this, void 0, void 0, function* () { + if (!authHeader.trim()) { + throw new authenticationError_1.AuthenticationError("'authHeader' required.", botframework_schema_1.StatusCodes.BAD_REQUEST); + } + const identity = yield authenticateToken(authHeader, credentials, channelService, channelId, authConfig, serviceUrl); + yield validateClaims(authConfig, identity.claims); + return identity; + }); + } + JwtTokenValidation2.validateAuthHeader = validateAuthHeader; + function authenticateToken(authHeader, credentials, channelService, channelId, authConfig, serviceUrl) { + return __awaiter2(this, void 0, void 0, function* () { + if (aseChannelValidation_1.AseChannelValidation.isTokenFromAseChannel(channelId)) { + return aseChannelValidation_1.AseChannelValidation.authenticateAseChannelToken(authHeader); + } + if (skillValidation_1.SkillValidation.isSkillToken(authHeader)) { + return yield skillValidation_1.SkillValidation.authenticateChannelToken(authHeader, credentials, channelService, channelId, authConfig); + } + if (emulatorValidation_1.EmulatorValidation.isTokenFromEmulator(authHeader)) { + return yield emulatorValidation_1.EmulatorValidation.authenticateEmulatorToken(authHeader, credentials, channelService, channelId); + } + if (isPublicAzure(channelService)) { + if (isValidServiceURL(serviceUrl)) { + return yield channelValidation_1.ChannelValidation.authenticateChannelTokenWithServiceUrl(authHeader, credentials, serviceUrl, channelId); + } + return yield channelValidation_1.ChannelValidation.authenticateChannelToken(authHeader, credentials, channelId); + } + if (isGovernment(channelService)) { + if (isValidServiceURL(serviceUrl)) { + return yield governmentChannelValidation_1.GovernmentChannelValidation.authenticateChannelTokenWithServiceUrl(authHeader, credentials, serviceUrl, channelId); + } + return yield governmentChannelValidation_1.GovernmentChannelValidation.authenticateChannelToken(authHeader, credentials, channelId); + } + if (isValidServiceURL(serviceUrl)) { + return yield enterpriseChannelValidation_1.EnterpriseChannelValidation.authenticateChannelTokenWithServiceUrl(authHeader, credentials, serviceUrl, channelId, channelService); + } + return yield enterpriseChannelValidation_1.EnterpriseChannelValidation.authenticateChannelToken(authHeader, credentials, channelId, channelService); + }); + } + function validateClaims(authConfig, claims = []) { + return __awaiter2(this, void 0, void 0, function* () { + if (authConfig.validateClaims) { + yield authConfig.validateClaims(claims); + } else if (skillValidation_1.SkillValidation.isSkillClaim(claims)) { + throw new authenticationError_1.AuthenticationError("Unauthorized Access. Request is not authorized. Skill Claims require validation.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + }); + } + function getAppIdFromClaims(claims) { + if (!claims) { + throw new TypeError("JwtTokenValidation.getAppIdFromClaims(): missing claims."); + } + let appId; + const claimsByType = claims.reduce((acc, claim) => Object.assign(Object.assign({}, acc), { [claim.type]: claim }), {}); + const versionClaim = claimsByType[authenticationConstants_1.AuthenticationConstants.VersionClaim]; + const versionValue = versionClaim && versionClaim.value; + if (!versionValue || versionValue === "1.0") { + const appIdClaim = claimsByType[authenticationConstants_1.AuthenticationConstants.AppIdClaim]; + if (appIdClaim && appIdClaim.value) { + appId = appIdClaim.value; + } + } else if (versionValue === "2.0") { + const azpClaim = claimsByType[authenticationConstants_1.AuthenticationConstants.AuthorizedParty]; + if (azpClaim && azpClaim.value) { + appId = azpClaim.value; + } + } + return appId; + } + JwtTokenValidation2.getAppIdFromClaims = getAppIdFromClaims; + function isPublicAzure(channelService) { + return !channelService || channelService.length === 0; + } + function isValidServiceURL(serviceUrl) { + const trimmedUrl = serviceUrl.trim(); + const absoluteUrl = trimmedUrl.startsWith("http") || trimmedUrl.startsWith("wss") ? trimmedUrl : `https://${trimmedUrl}`; + try { + const newUri = new URL(absoluteUrl); + return !!newUri; + } catch (_a) { + return false; + } + } + function isGovernment(channelService) { + return channelService && channelService.toLowerCase() === governmentConstants_1.GovernmentConstants.ChannelService; + } + JwtTokenValidation2.isGovernment = isGovernment; + function isValidTokenFormat(authHeader) { + if (!authHeader) { + return false; + } + const parts = authHeader.trim().split(" "); + if (parts.length !== 2) { + return false; + } + const authScheme = parts[0]; + if (authScheme !== "Bearer") { + return false; + } + return true; + } + JwtTokenValidation2.isValidTokenFormat = isValidTokenFormat; + })(JwtTokenValidation = exports2.JwtTokenValidation || (exports2.JwtTokenValidation = {})); + } +}); + +// node_modules/botframework-connector/lib/auth/allowedCallersClaimsValidator.js +var require_allowedCallersClaimsValidator = __commonJS({ + "node_modules/botframework-connector/lib/auth/allowedCallersClaimsValidator.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.allowedCallersClaimsValidator = void 0; + var jwtTokenValidation_1 = require_jwtTokenValidation(); + var skillValidation_1 = require_skillValidation(); + var assert_1 = require("assert"); + function allowedCallersClaimsValidator(allowedCallers) { + (0, assert_1.ok)(allowedCallers); + (0, assert_1.ok)(allowedCallers.length); + const allowed = new Set(allowedCallers); + return (claims) => __awaiter2(this, void 0, void 0, function* () { + if (!allowed.has("*") && skillValidation_1.SkillValidation.isSkillClaim(claims)) { + const appId = jwtTokenValidation_1.JwtTokenValidation.getAppIdFromClaims(claims); + if (!allowed.has(appId)) { + throw new Error(`Received a request from an application with an appID of "${appId}". To enable requests from this skill, add the skill to your configuration file.`); + } + } + }); + } + exports2.allowedCallersClaimsValidator = allowedCallersClaimsValidator; + } +}); + +// node_modules/botframework-connector/lib/auth/tokenCredentials.js +var require_tokenCredentials = __commonJS({ + "node_modules/botframework-connector/lib/auth/tokenCredentials.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TokenCredentials = void 0; + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var TokenCredentials = class { + /** + * Creates a new TokenCredentials object. + * + * @class + * @param {string} token The token. + * @param {string} [authorizationScheme] The authorization scheme. + */ + constructor(token, authorizationScheme = azureCoreHttpCompat_1.Constants.HeaderConstants.AUTHORIZATION_SCHEME) { + this.authorizationScheme = azureCoreHttpCompat_1.Constants.HeaderConstants.AUTHORIZATION_SCHEME; + if (!token) { + throw new Error("token cannot be null or undefined."); + } + this.token = token; + this.authorizationScheme = authorizationScheme; + } + /** + * Signs a request with the Authentication header. + * + * @param {WebResourceLike} webResource The WebResourceLike to be signed. + * @returns {Promise} The signed request object. + */ + signRequest(webResource) { + if (!webResource.headers) + webResource.headers = new azureCoreHttpCompat_1.HttpHeaders(); + webResource.headers.set(azureCoreHttpCompat_1.Constants.HeaderConstants.AUTHORIZATION, `${this.authorizationScheme} ${this.token}`); + return Promise.resolve(webResource); + } + }; + exports2.TokenCredentials = TokenCredentials; + } +}); + +// node_modules/botframework-connector/lib/auth/appCredentials.js +var require_appCredentials = __commonJS({ + "node_modules/botframework-connector/lib/auth/appCredentials.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AppCredentials = void 0; + var tokenCredentials_1 = require_tokenCredentials(); + var authenticationConstants_1 = require_authenticationConstants(); + var AppCredentials = class _AppCredentials { + /** + * Initializes a new instance of the [AppCredentials](xref:botframework-connector.AppCredentials) class. + * + * @param appId The App ID. + * @param channelAuthTenant Tenant ID of the Azure AD tenant where the bot is created. + * - Required for SingleTenant app types. + * - Optional for MultiTenant app types. **Note**: '_botframework.com_' is the default tenant when no value is provided. + * + * More information: https://learn.microsoft.com/en-us/security/zero-trust/develop/identity-supported-account-types. + * @param oAuthScope The scope for the token. + */ + constructor(appId, channelAuthTenant, oAuthScope = null) { + this.appId = appId; + this.tenant = channelAuthTenant; + this.oAuthEndpoint = this.GetToChannelFromBotLoginUrlPrefix() + this.tenant; + this.oAuthScope = oAuthScope && oAuthScope.length > 0 ? oAuthScope : this.GetToChannelFromBotOAuthScope(); + } + // Protects against JSON.stringify leaking secrets + toJSON() { + return { + name: this.constructor.name, + appId: this.appId, + tenant: this.tenant, + oAuthEndpoint: this.oAuthEndpoint, + oAuthScope: this.oAuthScope + }; + } + /** + * Gets tenant to be used for channel authentication. + * + * @returns The channel auth token tenant for this credential. + */ + get tenant() { + return this._tenant; + } + /** + * Sets tenant to be used for channel authentication. + */ + set tenant(value) { + this._tenant = value && value.length > 0 ? value : this.GetDefaultChannelAuthTenant(); + } + /** + * Gets the OAuth scope to use. + * + * @returns The OAuth scope to use. + */ + get oAuthScope() { + return this._oAuthScope; + } + /** + * Sets the OAuth scope to use. + */ + set oAuthScope(value) { + this._oAuthScope = value; + this.tokenCacheKey = `${this.appId}${this.oAuthScope}-cache`; + } + /** + * Gets the OAuth endpoint to use. + * + * @returns The OAuthEndpoint to use. + */ + get oAuthEndpoint() { + return this._oAuthEndpoint; + } + /** + * Sets the OAuth endpoint to use. + */ + set oAuthEndpoint(value) { + this._oAuthEndpoint = value; + } + /** + * Adds the host of service url to trusted hosts. + * If expiration time is not provided, the expiration date will be current (utc) date + 1 day. + */ + static trustServiceUrl() { + } + /** + * Checks if the service url is for a trusted host or not. + * + * @returns {boolean} True if the host of the service url is trusted; False otherwise. + */ + static isTrustedServiceUrl() { + return true; + } + /** + * Apply the credentials to the HTTP request. + * + * @param webResource The WebResource HTTP request. + * @returns A Promise representing the asynchronous operation. + */ + signRequest(webResource) { + return __awaiter2(this, void 0, void 0, function* () { + if (this.shouldSetToken()) { + return new tokenCredentials_1.TokenCredentials(yield this.getToken()).signRequest(webResource); + } + return webResource; + }); + } + /** + * Gets an OAuth access token. + * + * @param forceRefresh True to force a refresh of the token; or false to get + * a cached token if it exists. + * @returns A Promise that represents the work queued to execute. + * @remarks If the promise is successful, the result contains the access token string. + */ + getToken(forceRefresh = false) { + return __awaiter2(this, void 0, void 0, function* () { + if (!forceRefresh) { + const oAuthToken = _AppCredentials.cache.get(this.tokenCacheKey); + if (oAuthToken && oAuthToken.expiresOn > /* @__PURE__ */ new Date()) { + return oAuthToken.accessToken; + } + } + const res = yield this.refreshToken(); + if (res && res.accessToken) { + res.expiresOn.setMinutes(res.expiresOn.getMinutes() - 5); + _AppCredentials.cache.set(this.tokenCacheKey, res); + return res.accessToken; + } else { + throw new Error("Authentication: No response or error received from MSAL."); + } + }); + } + GetToChannelFromBotOAuthScope() { + return authenticationConstants_1.AuthenticationConstants.ToChannelFromBotOAuthScope; + } + GetToChannelFromBotLoginUrlPrefix() { + return authenticationConstants_1.AuthenticationConstants.ToChannelFromBotLoginUrlPrefix; + } + GetDefaultChannelAuthTenant() { + return authenticationConstants_1.AuthenticationConstants.DefaultChannelAuthTenant; + } + /** + * @private + */ + shouldSetToken() { + return this.appId && this.appId !== authenticationConstants_1.AuthenticationConstants.AnonymousSkillAppId; + } + }; + exports2.AppCredentials = AppCredentials; + AppCredentials.cache = /* @__PURE__ */ new Map(); + } +}); + +// node_modules/botframework-connector/lib/auth/authenticateRequestResult.js +var require_authenticateRequestResult = __commonJS({ + "node_modules/botframework-connector/lib/auth/authenticateRequestResult.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-connector/lib/auth/authenticatorResult.js +var require_authenticatorResult = __commonJS({ + "node_modules/botframework-connector/lib/auth/authenticatorResult.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-connector/lib/auth/botFrameworkAuthentication.js +var require_botFrameworkAuthentication = __commonJS({ + "node_modules/botframework-connector/lib/auth/botFrameworkAuthentication.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotFrameworkAuthentication = void 0; + var botframework_schema_1 = require_lib4(); + var jwtTokenValidation_1 = require_jwtTokenValidation(); + var skillValidation_1 = require_skillValidation(); + var BotFrameworkAuthentication = class { + // eslint-disable-next-line jsdoc/require-returns-check + /** + * Creates a BotFrameworkClient for calling Skills. + * + * @returns A [BotFrameworkClient](xref:botframework-connector.BotFrameworkClient). + */ + createBotFrameworkClient() { + throw new Error("NotImplemented"); + } + // eslint-disable-next-line jsdoc/require-returns-check + /** + * Gets the originating audience from Bot OAuth scope. + * + * @returns The originating audience. + */ + getOriginatingAudience() { + throw new Error("NotImplemented"); + } + // TODO: Update docstring - this is a direct port from .NET + // eslint-disable-next-line jsdoc/require-returns-check + /** + * Authenticate Bot Framework Protocol request to Skills. + * + * @param authHeader The HTTP auth header in the skill request. + * @returns {Promise} A [ClaimsIdentity](xref:botframework-connector.ClaimsIdentity). + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + authenticateChannelRequest(authHeader) { + throw new Error("NotImplemented"); + } + /** + * Generates the appropriate callerId to write onto the Activity, this might be null. + * + * @param credentialFactory A ServiceClientCredentialsFactory to use. + * @param claimsIdentity The inbound claims. + * @param callerId The default callerId to use if this is not a skill. + * @returns The callerId, this might be null. + */ + generateCallerId(credentialFactory, claimsIdentity, callerId) { + return __awaiter2(this, void 0, void 0, function* () { + if (yield credentialFactory.isAuthenticationDisabled()) { + return null; + } + return skillValidation_1.SkillValidation.isSkillClaim(claimsIdentity.claims) ? `${botframework_schema_1.CallerIdConstants.BotToBotPrefix}${jwtTokenValidation_1.JwtTokenValidation.getAppIdFromClaims(claimsIdentity.claims)}` : callerId; + }); + } + }; + exports2.BotFrameworkAuthentication = BotFrameworkAuthentication; + } +}); + +// node_modules/botframework-connector/lib/connectorApi/models/mappers.js +var require_mappers = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/models/mappers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PaymentCurrencyAmount = exports2.PaymentAddress = exports2.MicrosoftPayMethodData = exports2.TokenResponse = exports2.TokenRequest = exports2.MediaEventValue = exports2.Thing = exports2.Place = exports2.Mention = exports2.GeoCoordinates = exports2.VideoCard = exports2.ThumbnailCard = exports2.OAuthCard = exports2.SigninCard = exports2.ReceiptCard = exports2.ReceiptItem = exports2.Fact = exports2.MediaCard = exports2.BasicCard = exports2.AudioCard = exports2.AnimationCard = exports2.MediaUrl = exports2.ThumbnailUrl = exports2.HeroCard = exports2.CardImage = exports2.AttachmentData = exports2.PagedMembersResult = exports2.Transcript = exports2.ResourceResponse = exports2.ExpectedReplies = exports2.ConversationsResult = exports2.ConversationMembers = exports2.ConversationResourceResponse = exports2.ConversationParameters = exports2.Activity = exports2.SemanticAction = exports2.TextHighlight = exports2.ConversationReference = exports2.Entity = exports2.Attachment = exports2.SuggestedActions = exports2.CardAction = exports2.MessageReaction = exports2.ConversationAccount = exports2.ChannelAccount = exports2.ErrorResponse = exports2.ErrorModel = exports2.InnerHttpError = exports2.AttachmentInfo = exports2.AttachmentView = void 0; + exports2.PaymentRequestUpdateResult = exports2.PaymentRequestUpdate = exports2.PaymentRequestCompleteResult = exports2.PaymentRequestComplete = exports2.PaymentResponse = exports2.PaymentRequest = exports2.PaymentOptions = exports2.PaymentMethodData = exports2.PaymentDetails = exports2.PaymentDetailsModifier = exports2.PaymentShippingOption = exports2.PaymentItem = void 0; + exports2.AttachmentView = { + serializedName: "AttachmentView", + type: { + name: "Composite", + className: "AttachmentView", + modelProperties: { + viewId: { + serializedName: "viewId", + type: { + name: "String" + } + }, + size: { + serializedName: "size", + type: { + name: "Number" + } + } + } + } + }; + exports2.AttachmentInfo = { + serializedName: "AttachmentInfo", + type: { + name: "Composite", + className: "AttachmentInfo", + modelProperties: { + name: { + serializedName: "name", + type: { + name: "String" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + }, + views: { + serializedName: "views", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "AttachmentView" + } + } + } + } + } + } + }; + exports2.InnerHttpError = { + serializedName: "InnerHttpError", + type: { + name: "Composite", + className: "InnerHttpError", + modelProperties: { + statusCode: { + serializedName: "statusCode", + type: { + name: "Number" + } + }, + body: { + serializedName: "body", + type: { + name: "Object" + } + } + } + } + }; + exports2.ErrorModel = { + serializedName: "Error", + type: { + name: "Composite", + className: "ErrorModel", + modelProperties: { + code: { + serializedName: "code", + type: { + name: "String" + } + }, + message: { + serializedName: "message", + type: { + name: "String" + } + }, + innerHttpError: { + serializedName: "innerHttpError", + type: { + name: "Composite", + className: "InnerHttpError" + } + } + } + } + }; + exports2.ErrorResponse = { + serializedName: "ErrorResponse", + type: { + name: "Composite", + className: "ErrorResponse", + modelProperties: { + error: { + serializedName: "error", + type: { + name: "Composite", + className: "ErrorModel" + } + } + } + } + }; + exports2.ChannelAccount = { + serializedName: "ChannelAccount", + type: { + name: "Composite", + className: "ChannelAccount", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + aadObjectId: { + serializedName: "aadObjectId", + type: { + name: "String" + } + }, + role: { + serializedName: "role", + type: { + name: "String" + } + }, + properties: { + serializedName: "properties", + type: { + name: "Object" + } + } + } + } + }; + exports2.ConversationAccount = { + serializedName: "ConversationAccount", + type: { + name: "Composite", + className: "ConversationAccount", + modelProperties: { + isGroup: { + serializedName: "isGroup", + type: { + name: "Boolean" + } + }, + conversationType: { + serializedName: "conversationType", + type: { + name: "String" + } + }, + id: { + serializedName: "id", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + aadObjectId: { + serializedName: "aadObjectId", + type: { + name: "String" + } + }, + role: { + serializedName: "role", + type: { + name: "String" + } + }, + tenantId: { + serializedName: "tenantId", + type: { + name: "String" + } + }, + properties: { + serializedName: "properties", + type: { + name: "Object" + } + } + } + } + }; + exports2.MessageReaction = { + serializedName: "MessageReaction", + type: { + name: "Composite", + className: "MessageReaction", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + } + } + } + }; + exports2.CardAction = { + serializedName: "CardAction", + type: { + name: "Composite", + className: "CardAction", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + }, + title: { + serializedName: "title", + type: { + name: "String" + } + }, + image: { + serializedName: "image", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + displayText: { + serializedName: "displayText", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "Object" + } + }, + channelData: { + serializedName: "channelData", + type: { + name: "Object" + } + }, + imageAltText: { + serializedName: "imageAltText", + type: { + name: "String" + } + } + } + } + }; + exports2.SuggestedActions = { + serializedName: "SuggestedActions", + type: { + name: "Composite", + className: "SuggestedActions", + modelProperties: { + to: { + serializedName: "to", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + actions: { + serializedName: "actions", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + } + } + }; + exports2.Attachment = { + serializedName: "Attachment", + type: { + name: "Composite", + className: "Attachment", + modelProperties: { + contentType: { + serializedName: "contentType", + type: { + name: "String" + } + }, + contentUrl: { + serializedName: "contentUrl", + type: { + name: "String" + } + }, + content: { + serializedName: "content", + type: { + name: "Object" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + thumbnailUrl: { + serializedName: "thumbnailUrl", + type: { + name: "String" + } + } + } + } + }; + exports2.Entity = { + serializedName: "Entity", + type: { + name: "Composite", + className: "Entity", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + mentioned: { + serializedName: "mentioned", + type: { + name: "Composite", + className: "ChannelAccount" + } + } + } + } + }; + exports2.ConversationReference = { + serializedName: "ConversationReference", + type: { + name: "Composite", + className: "ConversationReference", + modelProperties: { + activityId: { + serializedName: "activityId", + type: { + name: "String" + } + }, + user: { + serializedName: "user", + type: { + name: "Composite", + className: "ChannelAccount" + } + }, + bot: { + serializedName: "bot", + type: { + name: "Composite", + className: "ChannelAccount" + } + }, + conversation: { + serializedName: "conversation", + type: { + name: "Composite", + className: "ConversationAccount" + } + }, + channelId: { + serializedName: "channelId", + type: { + name: "String" + } + }, + serviceUrl: { + serializedName: "serviceUrl", + type: { + name: "String" + } + } + } + } + }; + exports2.TextHighlight = { + serializedName: "TextHighlight", + type: { + name: "Composite", + className: "TextHighlight", + modelProperties: { + text: { + serializedName: "text", + type: { + name: "String" + } + }, + occurrence: { + serializedName: "occurrence", + type: { + name: "Number" + } + } + } + } + }; + exports2.SemanticAction = { + serializedName: "SemanticAction", + type: { + name: "Composite", + className: "SemanticAction", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + state: { + serializedName: "state", + type: { + name: "String" + } + }, + entities: { + serializedName: "entities", + type: { + name: "Dictionary", + value: { + type: { + name: "Composite", + className: "Entity" + } + } + } + } + } + } + }; + exports2.Activity = { + serializedName: "Activity", + type: { + name: "Composite", + className: "Activity", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + }, + id: { + serializedName: "id", + type: { + name: "String" + } + }, + timestamp: { + serializedName: "timestamp", + type: { + name: "DateTime" + } + }, + localTimestamp: { + serializedName: "localTimestamp", + type: { + name: "DateTime" + } + }, + localTimezone: { + serializedName: "localTimezone", + type: { + name: "String" + } + }, + callerId: { + serializedName: "callerId", + type: { + name: "String" + } + }, + serviceUrl: { + serializedName: "serviceUrl", + type: { + name: "String" + } + }, + channelId: { + serializedName: "channelId", + type: { + name: "String" + } + }, + from: { + serializedName: "from", + type: { + name: "Composite", + className: "ChannelAccount" + } + }, + conversation: { + serializedName: "conversation", + type: { + name: "Composite", + className: "ConversationAccount" + } + }, + recipient: { + serializedName: "recipient", + type: { + name: "Composite", + className: "ChannelAccount" + } + }, + textFormat: { + serializedName: "textFormat", + type: { + name: "String" + } + }, + attachmentLayout: { + serializedName: "attachmentLayout", + type: { + name: "String" + } + }, + membersAdded: { + serializedName: "membersAdded", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ChannelAccount" + } + } + } + }, + membersRemoved: { + serializedName: "membersRemoved", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ChannelAccount" + } + } + } + }, + reactionsAdded: { + serializedName: "reactionsAdded", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MessageReaction" + } + } + } + }, + reactionsRemoved: { + serializedName: "reactionsRemoved", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MessageReaction" + } + } + } + }, + topicName: { + serializedName: "topicName", + type: { + name: "String" + } + }, + historyDisclosed: { + serializedName: "historyDisclosed", + type: { + name: "Boolean" + } + }, + locale: { + serializedName: "locale", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + speak: { + serializedName: "speak", + type: { + name: "String" + } + }, + inputHint: { + serializedName: "inputHint", + type: { + name: "String" + } + }, + summary: { + serializedName: "summary", + type: { + name: "String" + } + }, + suggestedActions: { + serializedName: "suggestedActions", + type: { + name: "Composite", + className: "SuggestedActions" + } + }, + attachments: { + serializedName: "attachments", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Attachment" + } + } + } + }, + entities: { + serializedName: "entities", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Entity", + additionalProperties: { + type: { + name: "Object" + } + } + } + } + } + }, + channelData: { + serializedName: "channelData", + type: { + name: "Object" + } + }, + action: { + serializedName: "action", + type: { + name: "String" + } + }, + replyToId: { + serializedName: "replyToId", + type: { + name: "String" + } + }, + label: { + serializedName: "label", + type: { + name: "String" + } + }, + valueType: { + serializedName: "valueType", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "Object" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + relatesTo: { + serializedName: "relatesTo", + type: { + name: "Composite", + className: "ConversationReference" + } + }, + code: { + serializedName: "code", + type: { + name: "String" + } + }, + expiration: { + serializedName: "expiration", + type: { + name: "DateTime" + } + }, + importance: { + serializedName: "importance", + type: { + name: "String" + } + }, + deliveryMode: { + serializedName: "deliveryMode", + type: { + name: "String" + } + }, + listenFor: { + serializedName: "listenFor", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + textHighlights: { + serializedName: "textHighlights", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "TextHighlight" + } + } + } + }, + semanticAction: { + serializedName: "semanticAction", + type: { + name: "Composite", + className: "SemanticAction" + } + } + } + } + }; + exports2.ConversationParameters = { + serializedName: "ConversationParameters", + type: { + name: "Composite", + className: "ConversationParameters", + modelProperties: { + isGroup: { + serializedName: "isGroup", + type: { + name: "Boolean" + } + }, + bot: { + serializedName: "bot", + type: { + name: "Composite", + className: "ChannelAccount" + } + }, + members: { + serializedName: "members", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ChannelAccount" + } + } + } + }, + topicName: { + serializedName: "topicName", + type: { + name: "String" + } + }, + tenantId: { + serializedName: "tenantId", + type: { + name: "String" + } + }, + activity: { + serializedName: "activity", + type: { + name: "Composite", + className: "Activity" + } + }, + channelData: { + serializedName: "channelData", + type: { + name: "Object" + } + } + } + } + }; + exports2.ConversationResourceResponse = { + serializedName: "ConversationResourceResponse", + type: { + name: "Composite", + className: "ConversationResourceResponse", + modelProperties: { + activityId: { + serializedName: "activityId", + type: { + name: "String" + } + }, + serviceUrl: { + serializedName: "serviceUrl", + type: { + name: "String" + } + }, + id: { + serializedName: "id", + type: { + name: "String" + } + } + } + } + }; + exports2.ConversationMembers = { + serializedName: "ConversationMembers", + type: { + name: "Composite", + className: "ConversationMembers", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + members: { + serializedName: "members", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ChannelAccount" + } + } + } + } + } + } + }; + exports2.ConversationsResult = { + serializedName: "ConversationsResult", + type: { + name: "Composite", + className: "ConversationsResult", + modelProperties: { + continuationToken: { + serializedName: "continuationToken", + type: { + name: "String" + } + }, + conversations: { + serializedName: "conversations", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ConversationMembers" + } + } + } + } + } + } + }; + exports2.ExpectedReplies = { + serializedName: "ExpectedReplies", + type: { + name: "Composite", + className: "ExpectedReplies", + modelProperties: { + activities: { + serializedName: "activities", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Activity" + } + } + } + } + } + } + }; + exports2.ResourceResponse = { + serializedName: "ResourceResponse", + type: { + name: "Composite", + className: "ResourceResponse", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + } + } + } + }; + exports2.Transcript = { + serializedName: "Transcript", + type: { + name: "Composite", + className: "Transcript", + modelProperties: { + activities: { + serializedName: "activities", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Activity" + } + } + } + } + } + } + }; + exports2.PagedMembersResult = { + serializedName: "PagedMembersResult", + type: { + name: "Composite", + className: "PagedMembersResult", + modelProperties: { + continuationToken: { + serializedName: "continuationToken", + type: { + name: "String" + } + }, + members: { + serializedName: "members", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ChannelAccount" + } + } + } + } + } + } + }; + exports2.AttachmentData = { + serializedName: "AttachmentData", + type: { + name: "Composite", + className: "AttachmentData", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + originalBase64: { + serializedName: "originalBase64", + type: { + name: "ByteArray" + } + }, + thumbnailBase64: { + serializedName: "thumbnailBase64", + type: { + name: "ByteArray" + } + } + } + } + }; + exports2.CardImage = { + serializedName: "CardImage", + type: { + name: "Composite", + className: "CardImage", + modelProperties: { + url: { + serializedName: "url", + type: { + name: "String" + } + }, + alt: { + serializedName: "alt", + type: { + name: "String" + } + }, + tap: { + serializedName: "tap", + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + }; + exports2.HeroCard = { + serializedName: "HeroCard", + type: { + name: "Composite", + className: "HeroCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + subtitle: { + serializedName: "subtitle", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + images: { + serializedName: "images", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardImage" + } + } + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + }, + tap: { + serializedName: "tap", + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + }; + exports2.ThumbnailUrl = { + serializedName: "ThumbnailUrl", + type: { + name: "Composite", + className: "ThumbnailUrl", + modelProperties: { + url: { + serializedName: "url", + type: { + name: "String" + } + }, + alt: { + serializedName: "alt", + type: { + name: "String" + } + } + } + } + }; + exports2.MediaUrl = { + serializedName: "MediaUrl", + type: { + name: "Composite", + className: "MediaUrl", + modelProperties: { + url: { + serializedName: "url", + type: { + name: "String" + } + }, + profile: { + serializedName: "profile", + type: { + name: "String" + } + } + } + } + }; + exports2.AnimationCard = { + serializedName: "AnimationCard", + type: { + name: "Composite", + className: "AnimationCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + subtitle: { + serializedName: "subtitle", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + image: { + serializedName: "image", + type: { + name: "Composite", + className: "ThumbnailUrl" + } + }, + media: { + serializedName: "media", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MediaUrl" + } + } + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + }, + shareable: { + serializedName: "shareable", + type: { + name: "Boolean" + } + }, + autoloop: { + serializedName: "autoloop", + type: { + name: "Boolean" + } + }, + autostart: { + serializedName: "autostart", + type: { + name: "Boolean" + } + }, + aspect: { + serializedName: "aspect", + type: { + name: "String" + } + }, + duration: { + serializedName: "duration", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "Object" + } + } + } + } + }; + exports2.AudioCard = { + serializedName: "AudioCard", + type: { + name: "Composite", + className: "AudioCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + subtitle: { + serializedName: "subtitle", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + image: { + serializedName: "image", + type: { + name: "Composite", + className: "ThumbnailUrl" + } + }, + media: { + serializedName: "media", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MediaUrl" + } + } + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + }, + shareable: { + serializedName: "shareable", + type: { + name: "Boolean" + } + }, + autoloop: { + serializedName: "autoloop", + type: { + name: "Boolean" + } + }, + autostart: { + serializedName: "autostart", + type: { + name: "Boolean" + } + }, + aspect: { + serializedName: "aspect", + type: { + name: "String" + } + }, + duration: { + serializedName: "duration", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "Object" + } + } + } + } + }; + exports2.BasicCard = { + serializedName: "BasicCard", + type: { + name: "Composite", + className: "BasicCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + subtitle: { + serializedName: "subtitle", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + images: { + serializedName: "images", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardImage" + } + } + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + }, + tap: { + serializedName: "tap", + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + }; + exports2.MediaCard = { + serializedName: "MediaCard", + type: { + name: "Composite", + className: "MediaCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + subtitle: { + serializedName: "subtitle", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + image: { + serializedName: "image", + type: { + name: "Composite", + className: "ThumbnailUrl" + } + }, + media: { + serializedName: "media", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MediaUrl" + } + } + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + }, + shareable: { + serializedName: "shareable", + type: { + name: "Boolean" + } + }, + autoloop: { + serializedName: "autoloop", + type: { + name: "Boolean" + } + }, + autostart: { + serializedName: "autostart", + type: { + name: "Boolean" + } + }, + aspect: { + serializedName: "aspect", + type: { + name: "String" + } + }, + duration: { + serializedName: "duration", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "Object" + } + } + } + } + }; + exports2.Fact = { + serializedName: "Fact", + type: { + name: "Composite", + className: "Fact", + modelProperties: { + key: { + serializedName: "key", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "String" + } + } + } + } + }; + exports2.ReceiptItem = { + serializedName: "ReceiptItem", + type: { + name: "Composite", + className: "ReceiptItem", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + subtitle: { + serializedName: "subtitle", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + image: { + serializedName: "image", + type: { + name: "Composite", + className: "CardImage" + } + }, + price: { + serializedName: "price", + type: { + name: "String" + } + }, + quantity: { + serializedName: "quantity", + type: { + name: "String" + } + }, + tap: { + serializedName: "tap", + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + }; + exports2.ReceiptCard = { + serializedName: "ReceiptCard", + type: { + name: "Composite", + className: "ReceiptCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + facts: { + serializedName: "facts", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Fact" + } + } + } + }, + items: { + serializedName: "items", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ReceiptItem" + } + } + } + }, + tap: { + serializedName: "tap", + type: { + name: "Composite", + className: "CardAction" + } + }, + total: { + serializedName: "total", + type: { + name: "String" + } + }, + tax: { + serializedName: "tax", + type: { + name: "String" + } + }, + vat: { + serializedName: "vat", + type: { + name: "String" + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + } + } + }; + exports2.SigninCard = { + serializedName: "SigninCard", + type: { + name: "Composite", + className: "SigninCard", + modelProperties: { + text: { + serializedName: "text", + type: { + name: "String" + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + } + } + }; + exports2.OAuthCard = { + serializedName: "OAuthCard", + type: { + name: "Composite", + className: "OAuthCard", + modelProperties: { + text: { + serializedName: "text", + type: { + name: "String" + } + }, + connectionName: { + serializedName: "connectionName", + type: { + name: "String" + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + } + } + }; + exports2.ThumbnailCard = { + serializedName: "ThumbnailCard", + type: { + name: "Composite", + className: "ThumbnailCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + subtitle: { + serializedName: "subtitle", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + images: { + serializedName: "images", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardImage" + } + } + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + }, + tap: { + serializedName: "tap", + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + }; + exports2.VideoCard = { + serializedName: "VideoCard", + type: { + name: "Composite", + className: "VideoCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + subtitle: { + serializedName: "subtitle", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + image: { + serializedName: "image", + type: { + name: "Composite", + className: "ThumbnailUrl" + } + }, + media: { + serializedName: "media", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MediaUrl" + } + } + } + }, + buttons: { + serializedName: "buttons", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + }, + shareable: { + serializedName: "shareable", + type: { + name: "Boolean" + } + }, + autoloop: { + serializedName: "autoloop", + type: { + name: "Boolean" + } + }, + autostart: { + serializedName: "autostart", + type: { + name: "Boolean" + } + }, + aspect: { + serializedName: "aspect", + type: { + name: "String" + } + }, + duration: { + serializedName: "duration", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "Object" + } + } + } + } + }; + exports2.GeoCoordinates = { + serializedName: "GeoCoordinates", + type: { + name: "Composite", + className: "GeoCoordinates", + modelProperties: { + elevation: { + serializedName: "elevation", + type: { + name: "Number" + } + }, + latitude: { + serializedName: "latitude", + type: { + name: "Number" + } + }, + longitude: { + serializedName: "longitude", + type: { + name: "Number" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + } + } + } + }; + exports2.Mention = { + serializedName: "Mention", + type: { + name: "Composite", + className: "Mention", + modelProperties: { + mentioned: { + serializedName: "mentioned", + type: { + name: "Composite", + className: "ChannelAccount" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + } + } + } + }; + exports2.Place = { + serializedName: "Place", + type: { + name: "Composite", + className: "Place", + modelProperties: { + address: { + serializedName: "address", + type: { + name: "Object" + } + }, + geo: { + serializedName: "geo", + type: { + name: "Object" + } + }, + hasMap: { + serializedName: "hasMap", + type: { + name: "Object" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + } + } + } + }; + exports2.Thing = { + serializedName: "Thing", + type: { + name: "Composite", + className: "Thing", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + } + } + } + }; + exports2.MediaEventValue = { + serializedName: "MediaEventValue", + type: { + name: "Composite", + className: "MediaEventValue", + modelProperties: { + cardValue: { + serializedName: "cardValue", + type: { + name: "Object" + } + } + } + } + }; + exports2.TokenRequest = { + serializedName: "TokenRequest", + type: { + name: "Composite", + className: "TokenRequest", + modelProperties: { + provider: { + serializedName: "provider", + type: { + name: "String" + } + }, + settings: { + serializedName: "settings", + type: { + name: "Dictionary", + value: { + type: { + name: "Object" + } + } + } + } + } + } + }; + exports2.TokenResponse = { + serializedName: "TokenResponse", + type: { + name: "Composite", + className: "TokenResponse", + modelProperties: { + channelId: { + serializedName: "channelId", + type: { + name: "String" + } + }, + connectionName: { + serializedName: "connectionName", + type: { + name: "String" + } + }, + token: { + serializedName: "token", + type: { + name: "String" + } + }, + expiration: { + serializedName: "expiration", + type: { + name: "String" + } + } + } + } + }; + exports2.MicrosoftPayMethodData = { + serializedName: "MicrosoftPayMethodData", + type: { + name: "Composite", + className: "MicrosoftPayMethodData", + modelProperties: { + merchantId: { + serializedName: "merchantId", + type: { + name: "String" + } + }, + supportedNetworks: { + serializedName: "supportedNetworks", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + supportedTypes: { + serializedName: "supportedTypes", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + } + } + } + }; + exports2.PaymentAddress = { + serializedName: "PaymentAddress", + type: { + name: "Composite", + className: "PaymentAddress", + modelProperties: { + country: { + serializedName: "country", + type: { + name: "String" + } + }, + addressLine: { + serializedName: "addressLine", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + region: { + serializedName: "region", + type: { + name: "String" + } + }, + city: { + serializedName: "city", + type: { + name: "String" + } + }, + dependentLocality: { + serializedName: "dependentLocality", + type: { + name: "String" + } + }, + postalCode: { + serializedName: "postalCode", + type: { + name: "String" + } + }, + sortingCode: { + serializedName: "sortingCode", + type: { + name: "String" + } + }, + languageCode: { + serializedName: "languageCode", + type: { + name: "String" + } + }, + organization: { + serializedName: "organization", + type: { + name: "String" + } + }, + recipient: { + serializedName: "recipient", + type: { + name: "String" + } + }, + phone: { + serializedName: "phone", + type: { + name: "String" + } + } + } + } + }; + exports2.PaymentCurrencyAmount = { + serializedName: "PaymentCurrencyAmount", + type: { + name: "Composite", + className: "PaymentCurrencyAmount", + modelProperties: { + currency: { + serializedName: "currency", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "String" + } + }, + currencySystem: { + serializedName: "currencySystem", + type: { + name: "String" + } + } + } + } + }; + exports2.PaymentItem = { + serializedName: "PaymentItem", + type: { + name: "Composite", + className: "PaymentItem", + modelProperties: { + label: { + serializedName: "label", + type: { + name: "String" + } + }, + amount: { + serializedName: "amount", + type: { + name: "Composite", + className: "PaymentCurrencyAmount" + } + }, + pending: { + serializedName: "pending", + type: { + name: "Boolean" + } + } + } + } + }; + exports2.PaymentShippingOption = { + serializedName: "PaymentShippingOption", + type: { + name: "Composite", + className: "PaymentShippingOption", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + label: { + serializedName: "label", + type: { + name: "String" + } + }, + amount: { + serializedName: "amount", + type: { + name: "Composite", + className: "PaymentCurrencyAmount" + } + }, + selected: { + serializedName: "selected", + type: { + name: "Boolean" + } + } + } + } + }; + exports2.PaymentDetailsModifier = { + serializedName: "PaymentDetailsModifier", + type: { + name: "Composite", + className: "PaymentDetailsModifier", + modelProperties: { + supportedMethods: { + serializedName: "supportedMethods", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + total: { + serializedName: "total", + type: { + name: "Composite", + className: "PaymentItem" + } + }, + additionalDisplayItems: { + serializedName: "additionalDisplayItems", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "PaymentItem" + } + } + } + }, + data: { + serializedName: "data", + type: { + name: "Object" + } + } + } + } + }; + exports2.PaymentDetails = { + serializedName: "PaymentDetails", + type: { + name: "Composite", + className: "PaymentDetails", + modelProperties: { + total: { + serializedName: "total", + type: { + name: "Composite", + className: "PaymentItem" + } + }, + displayItems: { + serializedName: "displayItems", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "PaymentItem" + } + } + } + }, + shippingOptions: { + serializedName: "shippingOptions", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "PaymentShippingOption" + } + } + } + }, + modifiers: { + serializedName: "modifiers", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "PaymentDetailsModifier" + } + } + } + }, + error: { + serializedName: "error", + type: { + name: "String" + } + } + } + } + }; + exports2.PaymentMethodData = { + serializedName: "PaymentMethodData", + type: { + name: "Composite", + className: "PaymentMethodData", + modelProperties: { + supportedMethods: { + serializedName: "supportedMethods", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + }, + data: { + serializedName: "data", + type: { + name: "Object" + } + } + } + } + }; + exports2.PaymentOptions = { + serializedName: "PaymentOptions", + type: { + name: "Composite", + className: "PaymentOptions", + modelProperties: { + requestPayerName: { + serializedName: "requestPayerName", + type: { + name: "Boolean" + } + }, + requestPayerEmail: { + serializedName: "requestPayerEmail", + type: { + name: "Boolean" + } + }, + requestPayerPhone: { + serializedName: "requestPayerPhone", + type: { + name: "Boolean" + } + }, + requestShipping: { + serializedName: "requestShipping", + type: { + name: "Boolean" + } + }, + shippingType: { + serializedName: "shippingType", + type: { + name: "String" + } + } + } + } + }; + exports2.PaymentRequest = { + serializedName: "PaymentRequest", + type: { + name: "Composite", + className: "PaymentRequest", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + methodData: { + serializedName: "methodData", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "PaymentMethodData" + } + } + } + }, + details: { + serializedName: "details", + type: { + name: "Composite", + className: "PaymentDetails" + } + }, + options: { + serializedName: "options", + type: { + name: "Composite", + className: "PaymentOptions" + } + }, + expires: { + serializedName: "expires", + type: { + name: "String" + } + } + } + } + }; + exports2.PaymentResponse = { + serializedName: "PaymentResponse", + type: { + name: "Composite", + className: "PaymentResponse", + modelProperties: { + methodName: { + serializedName: "methodName", + type: { + name: "String" + } + }, + details: { + serializedName: "details", + type: { + name: "Object" + } + }, + shippingAddress: { + serializedName: "shippingAddress", + type: { + name: "Composite", + className: "PaymentAddress" + } + }, + shippingOption: { + serializedName: "shippingOption", + type: { + name: "String" + } + }, + payerEmail: { + serializedName: "payerEmail", + type: { + name: "String" + } + }, + payerPhone: { + serializedName: "payerPhone", + type: { + name: "String" + } + } + } + } + }; + exports2.PaymentRequestComplete = { + serializedName: "PaymentRequestComplete", + type: { + name: "Composite", + className: "PaymentRequestComplete", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + paymentRequest: { + serializedName: "paymentRequest", + type: { + name: "Composite", + className: "PaymentRequest" + } + }, + paymentResponse: { + serializedName: "paymentResponse", + type: { + name: "Composite", + className: "PaymentResponse" + } + } + } + } + }; + exports2.PaymentRequestCompleteResult = { + serializedName: "PaymentRequestCompleteResult", + type: { + name: "Composite", + className: "PaymentRequestCompleteResult", + modelProperties: { + result: { + serializedName: "result", + type: { + name: "String" + } + } + } + } + }; + exports2.PaymentRequestUpdate = { + serializedName: "PaymentRequestUpdate", + type: { + name: "Composite", + className: "PaymentRequestUpdate", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + details: { + serializedName: "details", + type: { + name: "Composite", + className: "PaymentDetails" + } + }, + shippingAddress: { + serializedName: "shippingAddress", + type: { + name: "Composite", + className: "PaymentAddress" + } + }, + shippingOption: { + serializedName: "shippingOption", + type: { + name: "String" + } + } + } + } + }; + exports2.PaymentRequestUpdateResult = { + serializedName: "PaymentRequestUpdateResult", + type: { + name: "Composite", + className: "PaymentRequestUpdateResult", + modelProperties: { + details: { + serializedName: "details", + type: { + name: "Composite", + className: "PaymentDetails" + } + } + } + } + }; + } +}); + +// node_modules/botframework-connector/lib/connectorApi/models/index.js +var require_models = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/models/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_lib4(), exports2); + } +}); + +// node_modules/botframework-connector/lib/connectorApi/models/attachmentsMappers.js +var require_attachmentsMappers = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/models/attachmentsMappers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.InnerHttpError = exports2.ErrorResponse = exports2.ErrorModel = exports2.AttachmentView = exports2.AttachmentInfo = void 0; + var mappers_1 = require_mappers(); + Object.defineProperty(exports2, "AttachmentInfo", { enumerable: true, get: function() { + return mappers_1.AttachmentInfo; + } }); + Object.defineProperty(exports2, "AttachmentView", { enumerable: true, get: function() { + return mappers_1.AttachmentView; + } }); + Object.defineProperty(exports2, "ErrorModel", { enumerable: true, get: function() { + return mappers_1.ErrorModel; + } }); + Object.defineProperty(exports2, "ErrorResponse", { enumerable: true, get: function() { + return mappers_1.ErrorResponse; + } }); + Object.defineProperty(exports2, "InnerHttpError", { enumerable: true, get: function() { + return mappers_1.InnerHttpError; + } }); + } +}); + +// node_modules/botframework-connector/lib/connectorApi/models/parameters.js +var require_parameters = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/models/parameters.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.viewId = exports2.pageSize = exports2.memberId = exports2.conversationId = exports2.continuationToken = exports2.attachmentId = exports2.activityId = void 0; + exports2.activityId = { + parameterPath: "activityId", + mapper: { + required: true, + serializedName: "activityId", + type: { + name: "String" + } + } + }; + exports2.attachmentId = { + parameterPath: "attachmentId", + mapper: { + required: true, + serializedName: "attachmentId", + type: { + name: "String" + } + } + }; + exports2.continuationToken = { + parameterPath: [ + "options", + "continuationToken" + ], + mapper: { + serializedName: "continuationToken", + type: { + name: "String" + } + } + }; + exports2.conversationId = { + parameterPath: "conversationId", + mapper: { + required: true, + serializedName: "conversationId", + type: { + name: "String" + } + } + }; + exports2.memberId = { + parameterPath: "memberId", + mapper: { + required: true, + serializedName: "memberId", + type: { + name: "String" + } + } + }; + exports2.pageSize = { + parameterPath: [ + "options", + "pageSize" + ], + mapper: { + serializedName: "pageSize", + type: { + name: "Number" + } + } + }; + exports2.viewId = { + parameterPath: "viewId", + mapper: { + required: true, + serializedName: "viewId", + type: { + name: "String" + } + } + }; + } +}); + +// node_modules/botframework-connector/lib/connectorApi/operations/attachments.js +var require_attachments = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/operations/attachments.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Attachments = void 0; + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var Mappers = __importStar2(require_attachmentsMappers()); + var Parameters = __importStar2(require_parameters()); + var Attachments = class { + /** + * Create a Attachments. + * @param {ConnectorClientContext} client Reference to the service client. + */ + constructor(client) { + this.client = client; + } + getAttachmentInfo(attachmentId, options, callback) { + return this.client.sendOperationRequest({ + attachmentId, + options + }, getAttachmentInfoOperationSpec, callback); + } + getAttachment(attachmentId, viewId, options, callback) { + return this.client.sendOperationRequest({ + attachmentId, + viewId, + options + }, getAttachmentOperationSpec, callback); + } + }; + exports2.Attachments = Attachments; + var serializer = (0, azureCoreHttpCompat_1.createSerializer)(Mappers); + var getAttachmentInfoOperationSpec = { + httpMethod: "GET", + path: "v3/attachments/{attachmentId}", + urlParameters: [ + Parameters.attachmentId + ], + responses: { + 200: { + bodyMapper: Mappers.AttachmentInfo + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getAttachmentOperationSpec = { + httpMethod: "GET", + path: "v3/attachments/{attachmentId}/views/{viewId}", + urlParameters: [ + Parameters.attachmentId, + Parameters.viewId + ], + responses: { + 200: { + bodyMapper: { + serializedName: "parsedResponse", + type: { + name: "Stream" + } + } + }, + 301: {}, + 302: {}, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + } +}); + +// node_modules/botframework-connector/lib/connectorApi/models/conversationsMappers.js +var require_conversationsMappers = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/models/conversationsMappers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Transcript = exports2.TextHighlight = exports2.SuggestedActions = exports2.SemanticAction = exports2.ResourceResponse = exports2.PagedMembersResult = exports2.MessageReaction = exports2.InnerHttpError = exports2.ErrorResponse = exports2.ErrorModel = exports2.Entity = exports2.ConversationsResult = exports2.ConversationResourceResponse = exports2.ConversationReference = exports2.ConversationParameters = exports2.ConversationMembers = exports2.ConversationAccount = exports2.ChannelAccount = exports2.CardAction = exports2.AttachmentData = exports2.Attachment = exports2.Activity = void 0; + var mappers_1 = require_mappers(); + Object.defineProperty(exports2, "Activity", { enumerable: true, get: function() { + return mappers_1.Activity; + } }); + Object.defineProperty(exports2, "Attachment", { enumerable: true, get: function() { + return mappers_1.Attachment; + } }); + Object.defineProperty(exports2, "AttachmentData", { enumerable: true, get: function() { + return mappers_1.AttachmentData; + } }); + Object.defineProperty(exports2, "CardAction", { enumerable: true, get: function() { + return mappers_1.CardAction; + } }); + Object.defineProperty(exports2, "ChannelAccount", { enumerable: true, get: function() { + return mappers_1.ChannelAccount; + } }); + Object.defineProperty(exports2, "ConversationAccount", { enumerable: true, get: function() { + return mappers_1.ConversationAccount; + } }); + Object.defineProperty(exports2, "ConversationMembers", { enumerable: true, get: function() { + return mappers_1.ConversationMembers; + } }); + Object.defineProperty(exports2, "ConversationParameters", { enumerable: true, get: function() { + return mappers_1.ConversationParameters; + } }); + Object.defineProperty(exports2, "ConversationReference", { enumerable: true, get: function() { + return mappers_1.ConversationReference; + } }); + Object.defineProperty(exports2, "ConversationResourceResponse", { enumerable: true, get: function() { + return mappers_1.ConversationResourceResponse; + } }); + Object.defineProperty(exports2, "ConversationsResult", { enumerable: true, get: function() { + return mappers_1.ConversationsResult; + } }); + Object.defineProperty(exports2, "Entity", { enumerable: true, get: function() { + return mappers_1.Entity; + } }); + Object.defineProperty(exports2, "ErrorModel", { enumerable: true, get: function() { + return mappers_1.ErrorModel; + } }); + Object.defineProperty(exports2, "ErrorResponse", { enumerable: true, get: function() { + return mappers_1.ErrorResponse; + } }); + Object.defineProperty(exports2, "InnerHttpError", { enumerable: true, get: function() { + return mappers_1.InnerHttpError; + } }); + Object.defineProperty(exports2, "MessageReaction", { enumerable: true, get: function() { + return mappers_1.MessageReaction; + } }); + Object.defineProperty(exports2, "PagedMembersResult", { enumerable: true, get: function() { + return mappers_1.PagedMembersResult; + } }); + Object.defineProperty(exports2, "ResourceResponse", { enumerable: true, get: function() { + return mappers_1.ResourceResponse; + } }); + Object.defineProperty(exports2, "SemanticAction", { enumerable: true, get: function() { + return mappers_1.SemanticAction; + } }); + Object.defineProperty(exports2, "SuggestedActions", { enumerable: true, get: function() { + return mappers_1.SuggestedActions; + } }); + Object.defineProperty(exports2, "TextHighlight", { enumerable: true, get: function() { + return mappers_1.TextHighlight; + } }); + Object.defineProperty(exports2, "Transcript", { enumerable: true, get: function() { + return mappers_1.Transcript; + } }); + } +}); + +// node_modules/botframework-connector/lib/conversationConstants.js +var require_conversationConstants = __commonJS({ + "node_modules/botframework-connector/lib/conversationConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ConversationIdHttpHeaderName = void 0; + exports2.ConversationIdHttpHeaderName = "x-ms-conversation-id"; + } +}); + +// node_modules/botframework-connector/lib/connectorApi/operations/conversations.js +var require_conversations = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/operations/conversations.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Conversations = void 0; + var Mappers = __importStar2(require_conversationsMappers()); + var Parameters = __importStar2(require_parameters()); + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var conversationConstants_1 = require_conversationConstants(); + var Conversations = class { + /** + * Create a Conversations. + * @param {ConnectorClientContext} client Reference to the service client. + */ + constructor(client) { + this.client = client; + } + getConversations(options, callback) { + return this.client.sendOperationRequest({ + options + }, getConversationsOperationSpec, callback); + } + createConversation(parameters, options, callback) { + return this.client.sendOperationRequest({ + parameters, + options + }, createConversationOperationSpec, callback); + } + sendToConversation(conversationId, activity, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + activity, + options + }, sendToConversationOperationSpec, callback); + } + sendConversationHistory(conversationId, history, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + history, + options + }, sendConversationHistoryOperationSpec, callback); + } + updateActivity(conversationId, activityId, activity, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + activityId, + activity, + options + }, updateActivityOperationSpec, callback); + } + replyToActivity(conversationId, activityId, activity, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + activityId, + activity, + options + }, replyToActivityOperationSpec, callback); + } + deleteActivity(conversationId, activityId, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + activityId, + options + }, deleteActivityOperationSpec, callback); + } + getConversationMembers(conversationId, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + options + }, getConversationMembersOperationSpec, callback); + } + /** + * @param conversationId Conversation ID + * @param memberId MemberId for the user + * @param options The optional parameters + * @param callback The callback + */ + getConversationMember(conversationId, memberId, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + memberId, + options + }, getConversationMemberOperationSpec, callback); + } + getConversationPagedMembers(conversationId, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + options + }, getConversationPagedMembersOperationSpec, callback); + } + deleteConversationMember(conversationId, memberId, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + memberId, + options + }, deleteConversationMemberOperationSpec, callback); + } + getActivityMembers(conversationId, activityId, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + activityId, + options + }, getActivityMembersOperationSpec, callback); + } + uploadAttachment(conversationId, attachmentUpload, options, callback) { + return this.client.sendOperationRequest({ + conversationId, + attachmentUpload, + options + }, uploadAttachmentOperationSpec, callback); + } + }; + exports2.Conversations = Conversations; + var serializer = (0, azureCoreHttpCompat_1.createSerializer)(Mappers); + var getConversationsOperationSpec = { + httpMethod: "GET", + path: "v3/conversations", + queryParameters: [ + Parameters.continuationToken + ], + responses: { + 200: { + bodyMapper: Mappers.ConversationsResult + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var createConversationOperationSpec = { + httpMethod: "POST", + path: "v3/conversations", + requestBody: { + parameterPath: "parameters", + mapper: Object.assign(Object.assign({}, Mappers.ConversationParameters), { required: true }) + }, + responses: { + 200: { + bodyMapper: Mappers.ConversationResourceResponse + }, + 201: { + bodyMapper: Mappers.ConversationResourceResponse + }, + 202: { + bodyMapper: Mappers.ConversationResourceResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var sendToConversationOperationSpec = { + httpMethod: "POST", + path: "v3/conversations/{conversationId}/activities", + urlParameters: [ + Parameters.conversationId + ], + requestBody: { + parameterPath: "activity", + mapper: Object.assign(Object.assign({}, Mappers.Activity), { required: true }) + }, + responses: { + 200: { + bodyMapper: Mappers.ResourceResponse + }, + 201: { + bodyMapper: Mappers.ResourceResponse + }, + 202: { + bodyMapper: Mappers.ResourceResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var sendConversationHistoryOperationSpec = { + httpMethod: "POST", + path: "v3/conversations/{conversationId}/activities/history", + urlParameters: [ + Parameters.conversationId + ], + requestBody: { + parameterPath: "history", + mapper: Object.assign(Object.assign({}, Mappers.Transcript), { required: true }) + }, + responses: { + 200: { + bodyMapper: Mappers.ResourceResponse + }, + 201: { + bodyMapper: Mappers.ResourceResponse + }, + 202: { + bodyMapper: Mappers.ResourceResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var updateActivityOperationSpec = { + httpMethod: "PUT", + path: "v3/conversations/{conversationId}/activities/{activityId}", + urlParameters: [ + Parameters.conversationId, + Parameters.activityId + ], + requestBody: { + parameterPath: "activity", + mapper: Object.assign(Object.assign({}, Mappers.Activity), { required: true }) + }, + responses: { + 200: { + bodyMapper: Mappers.ResourceResponse + }, + 201: { + bodyMapper: Mappers.ResourceResponse + }, + 202: { + bodyMapper: Mappers.ResourceResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var replyToActivityOperationSpec = { + httpMethod: "POST", + path: "v3/conversations/{conversationId}/activities/{activityId}", + urlParameters: [ + Parameters.conversationId, + Parameters.activityId + ], + headerParameters: [{ + parameterPath: "conversationId", + mapper: { + serializedName: conversationConstants_1.ConversationIdHttpHeaderName, + type: { + name: "String" + } + } + }], + requestBody: { + parameterPath: "activity", + mapper: Object.assign(Object.assign({}, Mappers.Activity), { required: true }) + }, + responses: { + 200: { + bodyMapper: Mappers.ResourceResponse + }, + 201: { + bodyMapper: Mappers.ResourceResponse + }, + 202: { + bodyMapper: Mappers.ResourceResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var deleteActivityOperationSpec = { + httpMethod: "DELETE", + path: "v3/conversations/{conversationId}/activities/{activityId}", + urlParameters: [ + Parameters.conversationId, + Parameters.activityId + ], + responses: { + 200: {}, + 202: {}, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getConversationMembersOperationSpec = { + httpMethod: "GET", + path: "v3/conversations/{conversationId}/members", + urlParameters: [ + Parameters.conversationId + ], + responses: { + 200: { + bodyMapper: { + serializedName: "parsedResponse", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ChannelAccount" + } + } + } + } + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getConversationMemberOperationSpec = { + httpMethod: "GET", + path: "v3/conversations/{conversationId}/members/{memberId}", + urlParameters: [ + Parameters.conversationId, + Parameters.memberId + ], + responses: { + 200: { + bodyMapper: Mappers.ChannelAccount + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getConversationPagedMembersOperationSpec = { + httpMethod: "GET", + path: "v3/conversations/{conversationId}/pagedmembers", + urlParameters: [ + Parameters.conversationId + ], + queryParameters: [ + Parameters.pageSize, + Parameters.continuationToken + ], + responses: { + 200: { + bodyMapper: Mappers.PagedMembersResult + }, + default: {} + }, + serializer + }; + var deleteConversationMemberOperationSpec = { + httpMethod: "DELETE", + path: "v3/conversations/{conversationId}/members/{memberId}", + urlParameters: [ + Parameters.conversationId, + Parameters.memberId + ], + responses: { + 200: {}, + 204: {}, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getActivityMembersOperationSpec = { + httpMethod: "GET", + path: "v3/conversations/{conversationId}/activities/{activityId}/members", + urlParameters: [ + Parameters.conversationId, + Parameters.activityId + ], + responses: { + 200: { + bodyMapper: { + serializedName: "parsedResponse", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ChannelAccount" + } + } + } + } + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var uploadAttachmentOperationSpec = { + httpMethod: "POST", + path: "v3/conversations/{conversationId}/attachments", + urlParameters: [ + Parameters.conversationId + ], + requestBody: { + parameterPath: "attachmentUpload", + mapper: Object.assign(Object.assign({}, Mappers.AttachmentData), { required: true }) + }, + responses: { + 200: { + bodyMapper: Mappers.ResourceResponse + }, + 201: { + bodyMapper: Mappers.ResourceResponse + }, + 202: { + bodyMapper: Mappers.ResourceResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + } +}); + +// node_modules/botframework-connector/lib/connectorApi/operations/index.js +var require_operations = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/operations/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_attachments(), exports2); + __exportStar2(require_conversations(), exports2); + } +}); + +// node_modules/botframework-connector/lib/connectorApi/connectorClientContext.js +var require_connectorClientContext = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/connectorClientContext.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ConnectorClientContext = void 0; + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var packageName = "botframework-connector"; + var packageVersion = "4.0.0"; + var ConnectorClientContext = class extends azureCoreHttpCompat_1.ServiceClientContext { + /** + * Initializes a new instance of the ConnectorClientContext class. + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials, options) { + super(credentials, Object.assign(Object.assign({}, options), { baseUri: (options === null || options === void 0 ? void 0 : options.baseUri) || "https://api.botframework.com", userAgent: `${packageName}/${packageVersion} ${(options === null || options === void 0 ? void 0 : options.userAgent) || ""}` })); + } + }; + exports2.ConnectorClientContext = ConnectorClientContext; + } +}); + +// node_modules/botframework-connector/lib/connectorApi/connectorClient.js +var require_connectorClient = __commonJS({ + "node_modules/botframework-connector/lib/connectorApi/connectorClient.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ConnectorMappers = exports2.ConnectorModels = exports2.ConnectorClientContext = exports2.ConnectorClient = void 0; + var Mappers = __importStar2(require_mappers()); + exports2.ConnectorMappers = Mappers; + var Models = __importStar2(require_models()); + exports2.ConnectorModels = Models; + var operations = __importStar2(require_operations()); + var connectorClientContext_1 = require_connectorClientContext(); + Object.defineProperty(exports2, "ConnectorClientContext", { enumerable: true, get: function() { + return connectorClientContext_1.ConnectorClientContext; + } }); + var ConnectorClient = class extends connectorClientContext_1.ConnectorClientContext { + /** + * Initializes a new instance of the ConnectorClient class. + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials, options) { + super(credentials, options); + this.attachments = new operations.Attachments(this); + this.conversations = new operations.Conversations(this); + } + }; + exports2.ConnectorClient = ConnectorClient; + __exportStar2(require_operations(), exports2); + } +}); + +// node_modules/botframework-connector/lib/auth/connectorFactory.js +var require_connectorFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/connectorFactory.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ConnectorFactory = void 0; + var ConnectorFactory = class { + }; + exports2.ConnectorFactory = ConnectorFactory; + } +}); + +// node_modules/botframework-connector/package.json +var require_package3 = __commonJS({ + "node_modules/botframework-connector/package.json"(exports2, module2) { + module2.exports = { + name: "botframework-connector", + author: "Microsoft Corp.", + description: "Bot Connector is autorest generated connector client.", + version: "4.23.3", + license: "MIT", + keywords: [ + "botconnector", + "bots", + "chatbots" + ], + bugs: { + url: "https://github.com/Microsoft/botbuilder-js/issues" + }, + repository: { + type: "git", + url: "https://github.com/Microsoft/botbuilder-js.git" + }, + main: "lib/index.js", + browser: "lib/browser.js", + types: "lib/index.d.ts", + typesVersions: { + "<3.9": { + "*": [ + "_ts3.4/*" + ] + } + }, + dependencies: { + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/identity": "^4.4.1", + "@azure/msal-node": "^2.13.1", + "@types/jsonwebtoken": "9.0.6", + axios: "^1.8.2", + base64url: "^3.0.0", + "botbuilder-stdlib": "4.23.3-internal", + "botframework-schema": "4.23.3", + buffer: "^6.0.3", + "cross-fetch": "^4.0.0", + "https-proxy-agent": "^7.0.5", + jsonwebtoken: "^9.0.2", + "node-fetch": "^2.7.0", + "openssl-wrapper": "^0.3.4", + "rsa-pem-from-mod-exp": "^0.8.6", + zod: "^3.23.8" + }, + devDependencies: { + "@types/node": "^18.19.123", + "botbuilder-test-utils": "0.0.0", + dotenv: "^16.4.5", + nock: "^13.5.5", + should: "^13.2.3", + uuid: "^11.0.5" + }, + scripts: { + build: "tsc -b", + "build:browser": "npm-run-all build:browser:clean build:browser:run", + "build:browser:clean": "rimraf --glob lib/browser.*", + "build:browser:run": "tsup --config ../../tsup/browser.config.ts", + "build:downlevel-dts": "downlevel-dts lib _ts3.4/lib --checksum", + clean: "rimraf _ts3.4 lib tsconfig.tsbuildinfo", + depcheck: "depcheck --config ../../.depcheckrc --ignores azure,sinon,browserify-fs,buffer,https-browserify,stream-browserify,stream-http", + lint: "eslint .", + postbuild: "npm-run-all -p build:browser build:downlevel-dts", + test: "yarn build && yarn test:mocha", + "test:mocha": "nyc mocha tests --recursive" + }, + files: [ + "_ts3.4", + "lib", + "src" + ] + }; + } +}); + +// node_modules/botframework-connector/lib/auth/connectorFactoryImpl.js +var require_connectorFactoryImpl = __commonJS({ + "node_modules/botframework-connector/lib/auth/connectorFactoryImpl.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ConnectorFactoryImpl = exports2.USER_AGENT = void 0; + var connectorClient_1 = require_connectorClient(); + var connectorFactory_1 = require_connectorFactory(); + var packageInfo = require_package3(); + exports2.USER_AGENT = `Microsoft-BotFramework/3.1 ${packageInfo.name}/${packageInfo.version} `; + var ConnectorFactoryImpl = class extends connectorFactory_1.ConnectorFactory { + /** + * @param appId The AppID. + * @param toChannelFromBotOAuthScope The to Channel from bot oauth scope. + * @param loginEndpoint The login url. + * @param validateAuthority The validate authority value to use. + * @param credentialFactory A ServiceClientCredentialsFactory to use. + * @param connectorClientOptions The [ConnectorClientOptions](xref:botframework-connector.ConnectorClientOptions) to use when creating ConnectorClients. + */ + constructor(appId, toChannelFromBotOAuthScope, loginEndpoint, validateAuthority, credentialFactory, connectorClientOptions = {}) { + super(); + this.appId = appId; + this.toChannelFromBotOAuthScope = toChannelFromBotOAuthScope; + this.loginEndpoint = loginEndpoint; + this.validateAuthority = validateAuthority; + this.credentialFactory = credentialFactory; + this.connectorClientOptions = connectorClientOptions; + } + /** + * @param serviceUrl The client's service URL. + * @param audience The audience to use for outbound communication. It will vary by cloud environment. + * @returns The new instance of the ConnectorClient class. + */ + create(serviceUrl, audience) { + var _a, _b, _c; + return __awaiter2(this, void 0, void 0, function* () { + const credentials = yield this.credentialFactory.createCredentials(this.appId, audience !== null && audience !== void 0 ? audience : this.toChannelFromBotOAuthScope, this.loginEndpoint, this.validateAuthority); + const userAgent = typeof ((_a = this.connectorClientOptions) === null || _a === void 0 ? void 0 : _a.userAgent) === "function" ? (_b = this.connectorClientOptions) === null || _b === void 0 ? void 0 : _b.userAgent(exports2.USER_AGENT) : (_c = this.connectorClientOptions) === null || _c === void 0 ? void 0 : _c.userAgent; + const options = Object.assign(Object.assign({}, this.connectorClientOptions), { baseUri: serviceUrl, userAgent: `${exports2.USER_AGENT} ${userAgent !== null && userAgent !== void 0 ? userAgent : ""}` }); + options.requestPolicyFactories = [ + { + create: (nextPolicy) => ({ + sendRequest: (httpRequest) => { + if (!httpRequest.headers.contains("accept")) { + httpRequest.headers.set("accept", "*/*"); + } + return nextPolicy.sendRequest(httpRequest); + } + }) + } + ]; + return new connectorClient_1.ConnectorClient(credentials, options); + }); + } + }; + exports2.ConnectorFactoryImpl = ConnectorFactoryImpl; + } +}); + +// node_modules/delayed-stream/lib/delayed_stream.js +var require_delayed_stream = __commonJS({ + "node_modules/delayed-stream/lib/delayed_stream.js"(exports2, module2) { + var Stream = require("stream").Stream; + var util = require("util"); + module2.exports = DelayedStream; + function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; + } + util.inherits(DelayedStream, Stream); + DelayedStream.create = function(source, options) { + var delayedStream = new this(); + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; + } + delayedStream.source = source; + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; + source.on("error", function() { + }); + if (delayedStream.pauseStream) { + source.pause(); + } + return delayedStream; + }; + Object.defineProperty(DelayedStream.prototype, "readable", { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; + } + }); + DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); + }; + DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } + this.source.resume(); + }; + DelayedStream.prototype.pause = function() { + this.source.pause(); + }; + DelayedStream.prototype.release = function() { + this._released = true; + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; + }; + DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; + }; + DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; + } + if (args[0] === "data") { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); + } + this._bufferedEvents.push(args); + }; + DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; + } + if (this.dataSize <= this.maxDataSize) { + return; + } + this._maxDataSizeExceeded = true; + var message = "DelayedStream#maxDataSize of " + this.maxDataSize + " bytes exceeded."; + this.emit("error", new Error(message)); + }; + } +}); + +// node_modules/combined-stream/lib/combined_stream.js +var require_combined_stream = __commonJS({ + "node_modules/combined-stream/lib/combined_stream.js"(exports2, module2) { + var util = require("util"); + var Stream = require("stream").Stream; + var DelayedStream = require_delayed_stream(); + module2.exports = CombinedStream; + function CombinedStream() { + this.writable = false; + this.readable = true; + this.dataSize = 0; + this.maxDataSize = 2 * 1024 * 1024; + this.pauseStreams = true; + this._released = false; + this._streams = []; + this._currentStream = null; + this._insideLoop = false; + this._pendingNext = false; + } + util.inherits(CombinedStream, Stream); + CombinedStream.create = function(options) { + var combinedStream = new this(); + options = options || {}; + for (var option in options) { + combinedStream[option] = options[option]; + } + return combinedStream; + }; + CombinedStream.isStreamLike = function(stream) { + return typeof stream !== "function" && typeof stream !== "string" && typeof stream !== "boolean" && typeof stream !== "number" && !Buffer.isBuffer(stream); + }; + CombinedStream.prototype.append = function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + if (!(stream instanceof DelayedStream)) { + var newStream = DelayedStream.create(stream, { + maxDataSize: Infinity, + pauseStream: this.pauseStreams + }); + stream.on("data", this._checkDataSize.bind(this)); + stream = newStream; + } + this._handleErrors(stream); + if (this.pauseStreams) { + stream.pause(); + } + } + this._streams.push(stream); + return this; + }; + CombinedStream.prototype.pipe = function(dest, options) { + Stream.prototype.pipe.call(this, dest, options); + this.resume(); + return dest; + }; + CombinedStream.prototype._getNext = function() { + this._currentStream = null; + if (this._insideLoop) { + this._pendingNext = true; + return; + } + this._insideLoop = true; + try { + do { + this._pendingNext = false; + this._realGetNext(); + } while (this._pendingNext); + } finally { + this._insideLoop = false; + } + }; + CombinedStream.prototype._realGetNext = function() { + var stream = this._streams.shift(); + if (typeof stream == "undefined") { + this.end(); + return; + } + if (typeof stream !== "function") { + this._pipeNext(stream); + return; + } + var getStream = stream; + getStream(function(stream2) { + var isStreamLike = CombinedStream.isStreamLike(stream2); + if (isStreamLike) { + stream2.on("data", this._checkDataSize.bind(this)); + this._handleErrors(stream2); + } + this._pipeNext(stream2); + }.bind(this)); + }; + CombinedStream.prototype._pipeNext = function(stream) { + this._currentStream = stream; + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on("end", this._getNext.bind(this)); + stream.pipe(this, { end: false }); + return; + } + var value = stream; + this.write(value); + this._getNext(); + }; + CombinedStream.prototype._handleErrors = function(stream) { + var self2 = this; + stream.on("error", function(err) { + self2._emitError(err); + }); + }; + CombinedStream.prototype.write = function(data) { + this.emit("data", data); + }; + CombinedStream.prototype.pause = function() { + if (!this.pauseStreams) { + return; + } + if (this.pauseStreams && this._currentStream && typeof this._currentStream.pause == "function") this._currentStream.pause(); + this.emit("pause"); + }; + CombinedStream.prototype.resume = function() { + if (!this._released) { + this._released = true; + this.writable = true; + this._getNext(); + } + if (this.pauseStreams && this._currentStream && typeof this._currentStream.resume == "function") this._currentStream.resume(); + this.emit("resume"); + }; + CombinedStream.prototype.end = function() { + this._reset(); + this.emit("end"); + }; + CombinedStream.prototype.destroy = function() { + this._reset(); + this.emit("close"); + }; + CombinedStream.prototype._reset = function() { + this.writable = false; + this._streams = []; + this._currentStream = null; + }; + CombinedStream.prototype._checkDataSize = function() { + this._updateDataSize(); + if (this.dataSize <= this.maxDataSize) { + return; + } + var message = "DelayedStream#maxDataSize of " + this.maxDataSize + " bytes exceeded."; + this._emitError(new Error(message)); + }; + CombinedStream.prototype._updateDataSize = function() { + this.dataSize = 0; + var self2 = this; + this._streams.forEach(function(stream) { + if (!stream.dataSize) { + return; + } + self2.dataSize += stream.dataSize; + }); + if (this._currentStream && this._currentStream.dataSize) { + this.dataSize += this._currentStream.dataSize; + } + }; + CombinedStream.prototype._emitError = function(err) { + this._reset(); + this.emit("error", err); + }; + } +}); + +// node_modules/asynckit/lib/defer.js +var require_defer = __commonJS({ + "node_modules/asynckit/lib/defer.js"(exports2, module2) { + module2.exports = defer; + function defer(fn) { + var nextTick = typeof setImmediate == "function" ? setImmediate : typeof process == "object" && typeof process.nextTick == "function" ? process.nextTick : null; + if (nextTick) { + nextTick(fn); + } else { + setTimeout(fn, 0); + } + } + } +}); + +// node_modules/asynckit/lib/async.js +var require_async = __commonJS({ + "node_modules/asynckit/lib/async.js"(exports2, module2) { + var defer = require_defer(); + module2.exports = async; + function async(callback) { + var isAsync = false; + defer(function() { + isAsync = true; + }); + return function async_callback(err, result) { + if (isAsync) { + callback(err, result); + } else { + defer(function nextTick_callback() { + callback(err, result); + }); + } + }; + } + } +}); + +// node_modules/asynckit/lib/abort.js +var require_abort = __commonJS({ + "node_modules/asynckit/lib/abort.js"(exports2, module2) { + module2.exports = abort; + function abort(state) { + Object.keys(state.jobs).forEach(clean.bind(state)); + state.jobs = {}; + } + function clean(key) { + if (typeof this.jobs[key] == "function") { + this.jobs[key](); + } + } + } +}); + +// node_modules/asynckit/lib/iterate.js +var require_iterate = __commonJS({ + "node_modules/asynckit/lib/iterate.js"(exports2, module2) { + var async = require_async(); + var abort = require_abort(); + module2.exports = iterate; + function iterate(list, iterator, state, callback) { + var key = state["keyedList"] ? state["keyedList"][state.index] : state.index; + state.jobs[key] = runJob(iterator, key, list[key], function(error, output) { + if (!(key in state.jobs)) { + return; + } + delete state.jobs[key]; + if (error) { + abort(state); + } else { + state.results[key] = output; + } + callback(error, state.results); + }); + } + function runJob(iterator, key, item, callback) { + var aborter; + if (iterator.length == 2) { + aborter = iterator(item, async(callback)); + } else { + aborter = iterator(item, key, async(callback)); + } + return aborter; + } + } +}); + +// node_modules/asynckit/lib/state.js +var require_state3 = __commonJS({ + "node_modules/asynckit/lib/state.js"(exports2, module2) { + module2.exports = state; + function state(list, sortMethod) { + var isNamedList = !Array.isArray(list), initState = { + index: 0, + keyedList: isNamedList || sortMethod ? Object.keys(list) : null, + jobs: {}, + results: isNamedList ? {} : [], + size: isNamedList ? Object.keys(list).length : list.length + }; + if (sortMethod) { + initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) { + return sortMethod(list[a], list[b]); + }); + } + return initState; + } + } +}); + +// node_modules/asynckit/lib/terminator.js +var require_terminator = __commonJS({ + "node_modules/asynckit/lib/terminator.js"(exports2, module2) { + var abort = require_abort(); + var async = require_async(); + module2.exports = terminator; + function terminator(callback) { + if (!Object.keys(this.jobs).length) { + return; + } + this.index = this.size; + abort(this); + async(callback)(null, this.results); + } + } +}); + +// node_modules/asynckit/parallel.js +var require_parallel = __commonJS({ + "node_modules/asynckit/parallel.js"(exports2, module2) { + var iterate = require_iterate(); + var initState = require_state3(); + var terminator = require_terminator(); + module2.exports = parallel; + function parallel(list, iterator, callback) { + var state = initState(list); + while (state.index < (state["keyedList"] || list).length) { + iterate(list, iterator, state, function(error, result) { + if (error) { + callback(error, result); + return; + } + if (Object.keys(state.jobs).length === 0) { + callback(null, state.results); + return; + } + }); + state.index++; + } + return terminator.bind(state, callback); + } + } +}); + +// node_modules/asynckit/serialOrdered.js +var require_serialOrdered = __commonJS({ + "node_modules/asynckit/serialOrdered.js"(exports2, module2) { + var iterate = require_iterate(); + var initState = require_state3(); + var terminator = require_terminator(); + module2.exports = serialOrdered; + module2.exports.ascending = ascending; + module2.exports.descending = descending; + function serialOrdered(list, iterator, sortMethod, callback) { + var state = initState(list, sortMethod); + iterate(list, iterator, state, function iteratorHandler(error, result) { + if (error) { + callback(error, result); + return; + } + state.index++; + if (state.index < (state["keyedList"] || list).length) { + iterate(list, iterator, state, iteratorHandler); + return; + } + callback(null, state.results); + }); + return terminator.bind(state, callback); + } + function ascending(a, b) { + return a < b ? -1 : a > b ? 1 : 0; + } + function descending(a, b) { + return -1 * ascending(a, b); + } + } +}); + +// node_modules/asynckit/serial.js +var require_serial = __commonJS({ + "node_modules/asynckit/serial.js"(exports2, module2) { + var serialOrdered = require_serialOrdered(); + module2.exports = serial; + function serial(list, iterator, callback) { + return serialOrdered(list, iterator, null, callback); + } + } +}); + +// node_modules/asynckit/index.js +var require_asynckit = __commonJS({ + "node_modules/asynckit/index.js"(exports2, module2) { + module2.exports = { + parallel: require_parallel(), + serial: require_serial(), + serialOrdered: require_serialOrdered() + }; + } +}); + +// node_modules/has-tostringtag/shams.js +var require_shams2 = __commonJS({ + "node_modules/has-tostringtag/shams.js"(exports2, module2) { + "use strict"; + var hasSymbols = require_shams(); + module2.exports = function hasToStringTagShams() { + return hasSymbols() && !!Symbol.toStringTag; + }; + } +}); + +// node_modules/es-set-tostringtag/index.js +var require_es_set_tostringtag = __commonJS({ + "node_modules/es-set-tostringtag/index.js"(exports2, module2) { + "use strict"; + var GetIntrinsic = require_get_intrinsic(); + var $defineProperty = GetIntrinsic("%Object.defineProperty%", true); + var hasToStringTag = require_shams2()(); + var hasOwn = require_hasown(); + var $TypeError = require_type(); + var toStringTag = hasToStringTag ? Symbol.toStringTag : null; + module2.exports = function setToStringTag(object, value) { + var overrideIfSet = arguments.length > 2 && !!arguments[2] && arguments[2].force; + var nonConfigurable = arguments.length > 2 && !!arguments[2] && arguments[2].nonConfigurable; + if (typeof overrideIfSet !== "undefined" && typeof overrideIfSet !== "boolean" || typeof nonConfigurable !== "undefined" && typeof nonConfigurable !== "boolean") { + throw new $TypeError("if provided, the `overrideIfSet` and `nonConfigurable` options must be booleans"); + } + if (toStringTag && (overrideIfSet || !hasOwn(object, toStringTag))) { + if ($defineProperty) { + $defineProperty(object, toStringTag, { + configurable: !nonConfigurable, + enumerable: false, + value, + writable: false + }); + } else { + object[toStringTag] = value; + } + } + }; + } +}); + +// node_modules/form-data/lib/populate.js +var require_populate = __commonJS({ + "node_modules/form-data/lib/populate.js"(exports2, module2) { + "use strict"; + module2.exports = function(dst, src) { + Object.keys(src).forEach(function(prop) { + dst[prop] = dst[prop] || src[prop]; + }); + return dst; + }; + } +}); + +// node_modules/form-data/lib/form_data.js +var require_form_data = __commonJS({ + "node_modules/form-data/lib/form_data.js"(exports2, module2) { + "use strict"; + var CombinedStream = require_combined_stream(); + var util = require("util"); + var path3 = require("path"); + var http = require("http"); + var https = require("https"); + var parseUrl = require("url").parse; + var fs6 = require("fs"); + var Stream = require("stream").Stream; + var crypto12 = require("crypto"); + var mime = require_mime_types(); + var asynckit = require_asynckit(); + var setToStringTag = require_es_set_tostringtag(); + var hasOwn = require_hasown(); + var populate = require_populate(); + function FormData2(options) { + if (!(this instanceof FormData2)) { + return new FormData2(options); + } + this._overheadLength = 0; + this._valueLength = 0; + this._valuesToMeasure = []; + CombinedStream.call(this); + options = options || {}; + for (var option in options) { + this[option] = options[option]; + } + } + util.inherits(FormData2, CombinedStream); + FormData2.LINE_BREAK = "\r\n"; + FormData2.DEFAULT_CONTENT_TYPE = "application/octet-stream"; + FormData2.prototype.append = function(field, value, options) { + options = options || {}; + if (typeof options === "string") { + options = { filename: options }; + } + var append = CombinedStream.prototype.append.bind(this); + if (typeof value === "number" || value == null) { + value = String(value); + } + if (Array.isArray(value)) { + this._error(new Error("Arrays are not supported.")); + return; + } + var header = this._multiPartHeader(field, value, options); + var footer = this._multiPartFooter(); + append(header); + append(value); + append(footer); + this._trackLength(header, value, options); + }; + FormData2.prototype._trackLength = function(header, value, options) { + var valueLength = 0; + if (options.knownLength != null) { + valueLength += Number(options.knownLength); + } else if (Buffer.isBuffer(value)) { + valueLength = value.length; + } else if (typeof value === "string") { + valueLength = Buffer.byteLength(value); + } + this._valueLength += valueLength; + this._overheadLength += Buffer.byteLength(header) + FormData2.LINE_BREAK.length; + if (!value || !value.path && !(value.readable && hasOwn(value, "httpVersion")) && !(value instanceof Stream)) { + return; + } + if (!options.knownLength) { + this._valuesToMeasure.push(value); + } + }; + FormData2.prototype._lengthRetriever = function(value, callback) { + if (hasOwn(value, "fd")) { + if (value.end != void 0 && value.end != Infinity && value.start != void 0) { + callback(null, value.end + 1 - (value.start ? value.start : 0)); + } else { + fs6.stat(value.path, function(err, stat) { + if (err) { + callback(err); + return; + } + var fileSize = stat.size - (value.start ? value.start : 0); + callback(null, fileSize); + }); + } + } else if (hasOwn(value, "httpVersion")) { + callback(null, Number(value.headers["content-length"])); + } else if (hasOwn(value, "httpModule")) { + value.on("response", function(response) { + value.pause(); + callback(null, Number(response.headers["content-length"])); + }); + value.resume(); + } else { + callback("Unknown stream"); + } + }; + FormData2.prototype._multiPartHeader = function(field, value, options) { + if (typeof options.header === "string") { + return options.header; + } + var contentDisposition = this._getContentDisposition(value, options); + var contentType = this._getContentType(value, options); + var contents = ""; + var headers = { + // add custom disposition as third element or keep it two elements if not + "Content-Disposition": ["form-data", 'name="' + field + '"'].concat(contentDisposition || []), + // if no content type. allow it to be empty array + "Content-Type": [].concat(contentType || []) + }; + if (typeof options.header === "object") { + populate(headers, options.header); + } + var header; + for (var prop in headers) { + if (hasOwn(headers, prop)) { + header = headers[prop]; + if (header == null) { + continue; + } + if (!Array.isArray(header)) { + header = [header]; + } + if (header.length) { + contents += prop + ": " + header.join("; ") + FormData2.LINE_BREAK; + } + } + } + return "--" + this.getBoundary() + FormData2.LINE_BREAK + contents + FormData2.LINE_BREAK; + }; + FormData2.prototype._getContentDisposition = function(value, options) { + var filename; + if (typeof options.filepath === "string") { + filename = path3.normalize(options.filepath).replace(/\\/g, "/"); + } else if (options.filename || value && (value.name || value.path)) { + filename = path3.basename(options.filename || value && (value.name || value.path)); + } else if (value && value.readable && hasOwn(value, "httpVersion")) { + filename = path3.basename(value.client._httpMessage.path || ""); + } + if (filename) { + return 'filename="' + filename + '"'; + } + }; + FormData2.prototype._getContentType = function(value, options) { + var contentType = options.contentType; + if (!contentType && value && value.name) { + contentType = mime.lookup(value.name); + } + if (!contentType && value && value.path) { + contentType = mime.lookup(value.path); + } + if (!contentType && value && value.readable && hasOwn(value, "httpVersion")) { + contentType = value.headers["content-type"]; + } + if (!contentType && (options.filepath || options.filename)) { + contentType = mime.lookup(options.filepath || options.filename); + } + if (!contentType && value && typeof value === "object") { + contentType = FormData2.DEFAULT_CONTENT_TYPE; + } + return contentType; + }; + FormData2.prototype._multiPartFooter = function() { + return function(next) { + var footer = FormData2.LINE_BREAK; + var lastPart = this._streams.length === 0; + if (lastPart) { + footer += this._lastBoundary(); + } + next(footer); + }.bind(this); + }; + FormData2.prototype._lastBoundary = function() { + return "--" + this.getBoundary() + "--" + FormData2.LINE_BREAK; + }; + FormData2.prototype.getHeaders = function(userHeaders) { + var header; + var formHeaders = { + "content-type": "multipart/form-data; boundary=" + this.getBoundary() + }; + for (header in userHeaders) { + if (hasOwn(userHeaders, header)) { + formHeaders[header.toLowerCase()] = userHeaders[header]; + } + } + return formHeaders; + }; + FormData2.prototype.setBoundary = function(boundary) { + if (typeof boundary !== "string") { + throw new TypeError("FormData boundary must be a string"); + } + this._boundary = boundary; + }; + FormData2.prototype.getBoundary = function() { + if (!this._boundary) { + this._generateBoundary(); + } + return this._boundary; + }; + FormData2.prototype.getBuffer = function() { + var dataBuffer = new Buffer.alloc(0); + var boundary = this.getBoundary(); + for (var i = 0, len = this._streams.length; i < len; i++) { + if (typeof this._streams[i] !== "function") { + if (Buffer.isBuffer(this._streams[i])) { + dataBuffer = Buffer.concat([dataBuffer, this._streams[i]]); + } else { + dataBuffer = Buffer.concat([dataBuffer, Buffer.from(this._streams[i])]); + } + if (typeof this._streams[i] !== "string" || this._streams[i].substring(2, boundary.length + 2) !== boundary) { + dataBuffer = Buffer.concat([dataBuffer, Buffer.from(FormData2.LINE_BREAK)]); + } + } + } + return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]); + }; + FormData2.prototype._generateBoundary = function() { + this._boundary = "--------------------------" + crypto12.randomBytes(12).toString("hex"); + }; + FormData2.prototype.getLengthSync = function() { + var knownLength = this._overheadLength + this._valueLength; + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + if (!this.hasKnownLength()) { + this._error(new Error("Cannot calculate proper length in synchronous way.")); + } + return knownLength; + }; + FormData2.prototype.hasKnownLength = function() { + var hasKnownLength = true; + if (this._valuesToMeasure.length) { + hasKnownLength = false; + } + return hasKnownLength; + }; + FormData2.prototype.getLength = function(cb) { + var knownLength = this._overheadLength + this._valueLength; + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + if (!this._valuesToMeasure.length) { + process.nextTick(cb.bind(this, null, knownLength)); + return; + } + asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { + if (err) { + cb(err); + return; + } + values.forEach(function(length) { + knownLength += length; + }); + cb(null, knownLength); + }); + }; + FormData2.prototype.submit = function(params, cb) { + var request; + var options; + var defaults = { method: "post" }; + if (typeof params === "string") { + params = parseUrl(params); + options = populate({ + port: params.port, + path: params.pathname, + host: params.hostname, + protocol: params.protocol + }, defaults); + } else { + options = populate(params, defaults); + if (!options.port) { + options.port = options.protocol === "https:" ? 443 : 80; + } + } + options.headers = this.getHeaders(params.headers); + if (options.protocol === "https:") { + request = https.request(options); + } else { + request = http.request(options); + } + this.getLength(function(err, length) { + if (err && err !== "Unknown stream") { + this._error(err); + return; + } + if (length) { + request.setHeader("Content-Length", length); + } + this.pipe(request); + if (cb) { + var onResponse; + var callback = function(error, responce) { + request.removeListener("error", callback); + request.removeListener("response", onResponse); + return cb.call(this, error, responce); + }; + onResponse = callback.bind(this, null); + request.on("error", callback); + request.on("response", onResponse); + } + }.bind(this)); + return request; + }; + FormData2.prototype._error = function(err) { + if (!this.error) { + this.error = err; + this.pause(); + this.emit("error", err); + } + }; + FormData2.prototype.toString = function() { + return "[object FormData]"; + }; + setToStringTag(FormData2.prototype, "FormData"); + module2.exports = FormData2; + } +}); + +// node_modules/follow-redirects/debug.js +var require_debug7 = __commonJS({ + "node_modules/follow-redirects/debug.js"(exports2, module2) { + var debug; + module2.exports = function() { + if (!debug) { + try { + debug = require_src5()("follow-redirects"); + } catch (error) { + } + if (typeof debug !== "function") { + debug = function() { + }; + } + } + debug.apply(null, arguments); + }; + } +}); + +// node_modules/follow-redirects/index.js +var require_follow_redirects = __commonJS({ + "node_modules/follow-redirects/index.js"(exports2, module2) { + var url = require("url"); + var URL5 = url.URL; + var http = require("http"); + var https = require("https"); + var Writable = require("stream").Writable; + var assert = require("assert"); + var debug = require_debug7(); + (function detectUnsupportedEnvironment() { + var looksLikeNode = typeof process !== "undefined"; + var looksLikeBrowser = typeof window !== "undefined" && typeof document !== "undefined"; + var looksLikeV8 = isFunction(Error.captureStackTrace); + if (!looksLikeNode && (looksLikeBrowser || !looksLikeV8)) { + console.warn("The follow-redirects package should be excluded from browser builds."); + } + })(); + var useNativeURL = false; + try { + assert(new URL5("")); + } catch (error) { + useNativeURL = error.code === "ERR_INVALID_URL"; + } + var sensitiveHeaders = [ + "Authorization", + "Proxy-Authorization", + "Cookie" + ]; + var preservedUrlFields = [ + "auth", + "host", + "hostname", + "href", + "path", + "pathname", + "port", + "protocol", + "query", + "search", + "hash" + ]; + var events = ["abort", "aborted", "connect", "error", "socket", "timeout"]; + var eventHandlers = /* @__PURE__ */ Object.create(null); + events.forEach(function(event) { + eventHandlers[event] = function(arg1, arg2, arg3) { + this._redirectable.emit(event, arg1, arg2, arg3); + }; + }); + var InvalidUrlError = createErrorType( + "ERR_INVALID_URL", + "Invalid URL", + TypeError + ); + var RedirectionError = createErrorType( + "ERR_FR_REDIRECTION_FAILURE", + "Redirected request failed" + ); + var TooManyRedirectsError = createErrorType( + "ERR_FR_TOO_MANY_REDIRECTS", + "Maximum number of redirects exceeded", + RedirectionError + ); + var MaxBodyLengthExceededError = createErrorType( + "ERR_FR_MAX_BODY_LENGTH_EXCEEDED", + "Request body larger than maxBodyLength limit" + ); + var WriteAfterEndError = createErrorType( + "ERR_STREAM_WRITE_AFTER_END", + "write after end" + ); + var destroy = Writable.prototype.destroy || noop; + function RedirectableRequest(options, responseCallback) { + Writable.call(this); + this._sanitizeOptions(options); + this._options = options; + this._ended = false; + this._ending = false; + this._redirectCount = 0; + this._redirects = []; + this._requestBodyLength = 0; + this._requestBodyBuffers = []; + if (responseCallback) { + this.on("response", responseCallback); + } + var self2 = this; + this._onNativeResponse = function(response) { + try { + self2._processResponse(response); + } catch (cause) { + self2.emit("error", cause instanceof RedirectionError ? cause : new RedirectionError({ cause })); + } + }; + this._headerFilter = new RegExp("^(?:" + sensitiveHeaders.concat(options.sensitiveHeaders).map(escapeRegex).join("|") + ")$", "i"); + this._performRequest(); + } + RedirectableRequest.prototype = Object.create(Writable.prototype); + RedirectableRequest.prototype.abort = function() { + destroyRequest(this._currentRequest); + this._currentRequest.abort(); + this.emit("abort"); + }; + RedirectableRequest.prototype.destroy = function(error) { + destroyRequest(this._currentRequest, error); + destroy.call(this, error); + return this; + }; + RedirectableRequest.prototype.write = function(data, encoding, callback) { + if (this._ending) { + throw new WriteAfterEndError(); + } + if (!isString(data) && !isBuffer(data)) { + throw new TypeError("data should be a string, Buffer or Uint8Array"); + } + if (isFunction(encoding)) { + callback = encoding; + encoding = null; + } + if (data.length === 0) { + if (callback) { + callback(); + } + return; + } + if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { + this._requestBodyLength += data.length; + this._requestBodyBuffers.push({ data, encoding }); + this._currentRequest.write(data, encoding, callback); + } else { + this.emit("error", new MaxBodyLengthExceededError()); + this.abort(); + } + }; + RedirectableRequest.prototype.end = function(data, encoding, callback) { + if (isFunction(data)) { + callback = data; + data = encoding = null; + } else if (isFunction(encoding)) { + callback = encoding; + encoding = null; + } + if (!data) { + this._ended = this._ending = true; + this._currentRequest.end(null, null, callback); + } else { + var self2 = this; + var currentRequest = this._currentRequest; + this.write(data, encoding, function() { + self2._ended = true; + currentRequest.end(null, null, callback); + }); + this._ending = true; + } + }; + RedirectableRequest.prototype.setHeader = function(name, value) { + this._options.headers[name] = value; + this._currentRequest.setHeader(name, value); + }; + RedirectableRequest.prototype.removeHeader = function(name) { + delete this._options.headers[name]; + this._currentRequest.removeHeader(name); + }; + RedirectableRequest.prototype.setTimeout = function(msecs, callback) { + var self2 = this; + function destroyOnTimeout(socket) { + socket.setTimeout(msecs); + socket.removeListener("timeout", socket.destroy); + socket.addListener("timeout", socket.destroy); + } + function startTimer(socket) { + if (self2._timeout) { + clearTimeout(self2._timeout); + } + self2._timeout = setTimeout(function() { + self2.emit("timeout"); + clearTimer(); + }, msecs); + destroyOnTimeout(socket); + } + function clearTimer() { + if (self2._timeout) { + clearTimeout(self2._timeout); + self2._timeout = null; + } + self2.removeListener("abort", clearTimer); + self2.removeListener("error", clearTimer); + self2.removeListener("response", clearTimer); + self2.removeListener("close", clearTimer); + if (callback) { + self2.removeListener("timeout", callback); + } + if (!self2.socket) { + self2._currentRequest.removeListener("socket", startTimer); + } + } + if (callback) { + this.on("timeout", callback); + } + if (this.socket) { + startTimer(this.socket); + } else { + this._currentRequest.once("socket", startTimer); + } + this.on("socket", destroyOnTimeout); + this.on("abort", clearTimer); + this.on("error", clearTimer); + this.on("response", clearTimer); + this.on("close", clearTimer); + return this; + }; + [ + "flushHeaders", + "getHeader", + "setNoDelay", + "setSocketKeepAlive" + ].forEach(function(method) { + RedirectableRequest.prototype[method] = function(a, b) { + return this._currentRequest[method](a, b); + }; + }); + ["aborted", "connection", "socket"].forEach(function(property) { + Object.defineProperty(RedirectableRequest.prototype, property, { + get: function() { + return this._currentRequest[property]; + } + }); + }); + RedirectableRequest.prototype._sanitizeOptions = function(options) { + if (!options.headers) { + options.headers = {}; + } + if (!isArray(options.sensitiveHeaders)) { + options.sensitiveHeaders = []; + } + if (options.host) { + if (!options.hostname) { + options.hostname = options.host; + } + delete options.host; + } + if (!options.pathname && options.path) { + var searchPos = options.path.indexOf("?"); + if (searchPos < 0) { + options.pathname = options.path; + } else { + options.pathname = options.path.substring(0, searchPos); + options.search = options.path.substring(searchPos); + } + } + }; + RedirectableRequest.prototype._performRequest = function() { + var protocol = this._options.protocol; + var nativeProtocol = this._options.nativeProtocols[protocol]; + if (!nativeProtocol) { + throw new TypeError("Unsupported protocol " + protocol); + } + if (this._options.agents) { + var scheme = protocol.slice(0, -1); + this._options.agent = this._options.agents[scheme]; + } + var request = this._currentRequest = nativeProtocol.request(this._options, this._onNativeResponse); + request._redirectable = this; + for (var event of events) { + request.on(event, eventHandlers[event]); + } + this._currentUrl = /^\//.test(this._options.path) ? url.format(this._options) : ( + // When making a request to a proxy, […] + // a client MUST send the target URI in absolute-form […]. + this._options.path + ); + if (this._isRedirect) { + var i = 0; + var self2 = this; + var buffers = this._requestBodyBuffers; + (function writeNext(error) { + if (request === self2._currentRequest) { + if (error) { + self2.emit("error", error); + } else if (i < buffers.length) { + var buffer = buffers[i++]; + if (!request.finished) { + request.write(buffer.data, buffer.encoding, writeNext); + } + } else if (self2._ended) { + request.end(); + } + } + })(); + } + }; + RedirectableRequest.prototype._processResponse = function(response) { + var statusCode = response.statusCode; + if (this._options.trackRedirects) { + this._redirects.push({ + url: this._currentUrl, + headers: response.headers, + statusCode + }); + } + var location = response.headers.location; + if (!location || this._options.followRedirects === false || statusCode < 300 || statusCode >= 400) { + response.responseUrl = this._currentUrl; + response.redirects = this._redirects; + this.emit("response", response); + this._requestBodyBuffers = []; + return; + } + destroyRequest(this._currentRequest); + response.destroy(); + if (++this._redirectCount > this._options.maxRedirects) { + throw new TooManyRedirectsError(); + } + var requestHeaders; + var beforeRedirect = this._options.beforeRedirect; + if (beforeRedirect) { + requestHeaders = Object.assign({ + // The Host header was set by nativeProtocol.request + Host: response.req.getHeader("host") + }, this._options.headers); + } + var method = this._options.method; + if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" || // RFC7231§6.4.4: The 303 (See Other) status code indicates that + // the server is redirecting the user agent to a different resource […] + // A user agent can perform a retrieval request targeting that URI + // (a GET or HEAD request if using HTTP) […] + statusCode === 303 && !/^(?:GET|HEAD)$/.test(this._options.method)) { + this._options.method = "GET"; + this._requestBodyBuffers = []; + removeMatchingHeaders(/^content-/i, this._options.headers); + } + var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers); + var currentUrlParts = parseUrl(this._currentUrl); + var currentHost = currentHostHeader || currentUrlParts.host; + var currentUrl = /^\w+:/.test(location) ? this._currentUrl : url.format(Object.assign(currentUrlParts, { host: currentHost })); + var redirectUrl = resolveUrl(location, currentUrl); + debug("redirecting to", redirectUrl.href); + this._isRedirect = true; + spreadUrlObject(redirectUrl, this._options); + if (redirectUrl.protocol !== currentUrlParts.protocol && redirectUrl.protocol !== "https:" || redirectUrl.host !== currentHost && !isSubdomain(redirectUrl.host, currentHost)) { + removeMatchingHeaders(this._headerFilter, this._options.headers); + } + if (isFunction(beforeRedirect)) { + var responseDetails = { + headers: response.headers, + statusCode + }; + var requestDetails = { + url: currentUrl, + method, + headers: requestHeaders + }; + beforeRedirect(this._options, responseDetails, requestDetails); + this._sanitizeOptions(this._options); + } + this._performRequest(); + }; + function wrap(protocols) { + var exports3 = { + maxRedirects: 21, + maxBodyLength: 10 * 1024 * 1024 + }; + var nativeProtocols = {}; + Object.keys(protocols).forEach(function(scheme) { + var protocol = scheme + ":"; + var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; + var wrappedProtocol = exports3[scheme] = Object.create(nativeProtocol); + function request(input, options, callback) { + if (isURL(input)) { + input = spreadUrlObject(input); + } else if (isString(input)) { + input = spreadUrlObject(parseUrl(input)); + } else { + callback = options; + options = validateUrl(input); + input = { protocol }; + } + if (isFunction(options)) { + callback = options; + options = null; + } + options = Object.assign({ + maxRedirects: exports3.maxRedirects, + maxBodyLength: exports3.maxBodyLength + }, input, options); + options.nativeProtocols = nativeProtocols; + if (!isString(options.host) && !isString(options.hostname)) { + options.hostname = "::1"; + } + assert.equal(options.protocol, protocol, "protocol mismatch"); + debug("options", options); + return new RedirectableRequest(options, callback); + } + function get(input, options, callback) { + var wrappedRequest = wrappedProtocol.request(input, options, callback); + wrappedRequest.end(); + return wrappedRequest; + } + Object.defineProperties(wrappedProtocol, { + request: { value: request, configurable: true, enumerable: true, writable: true }, + get: { value: get, configurable: true, enumerable: true, writable: true } + }); + }); + return exports3; + } + function noop() { + } + function parseUrl(input) { + var parsed; + if (useNativeURL) { + parsed = new URL5(input); + } else { + parsed = validateUrl(url.parse(input)); + if (!isString(parsed.protocol)) { + throw new InvalidUrlError({ input }); + } + } + return parsed; + } + function resolveUrl(relative, base) { + return useNativeURL ? new URL5(relative, base) : parseUrl(url.resolve(base, relative)); + } + function validateUrl(input) { + if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) { + throw new InvalidUrlError({ input: input.href || input }); + } + if (/^\[/.test(input.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input.host)) { + throw new InvalidUrlError({ input: input.href || input }); + } + return input; + } + function spreadUrlObject(urlObject, target) { + var spread = target || {}; + for (var key of preservedUrlFields) { + spread[key] = urlObject[key]; + } + if (spread.hostname.startsWith("[")) { + spread.hostname = spread.hostname.slice(1, -1); + } + if (spread.port !== "") { + spread.port = Number(spread.port); + } + spread.path = spread.search ? spread.pathname + spread.search : spread.pathname; + return spread; + } + function removeMatchingHeaders(regex, headers) { + var lastValue; + for (var header in headers) { + if (regex.test(header)) { + lastValue = headers[header]; + delete headers[header]; + } + } + return lastValue === null || typeof lastValue === "undefined" ? void 0 : String(lastValue).trim(); + } + function createErrorType(code, message, baseClass) { + function CustomError(properties) { + if (isFunction(Error.captureStackTrace)) { + Error.captureStackTrace(this, this.constructor); + } + Object.assign(this, properties || {}); + this.code = code; + this.message = this.cause ? message + ": " + this.cause.message : message; + } + CustomError.prototype = new (baseClass || Error)(); + Object.defineProperties(CustomError.prototype, { + constructor: { + value: CustomError, + enumerable: false + }, + name: { + value: "Error [" + code + "]", + enumerable: false + } + }); + return CustomError; + } + function destroyRequest(request, error) { + for (var event of events) { + request.removeListener(event, eventHandlers[event]); + } + request.on("error", noop); + request.destroy(error); + } + function isSubdomain(subdomain, domain) { + assert(isString(subdomain) && isString(domain)); + var dot = subdomain.length - domain.length - 1; + return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); + } + function isArray(value) { + return value instanceof Array; + } + function isString(value) { + return typeof value === "string" || value instanceof String; + } + function isFunction(value) { + return typeof value === "function"; + } + function isBuffer(value) { + return typeof value === "object" && "length" in value; + } + function isURL(value) { + return URL5 && value instanceof URL5; + } + function escapeRegex(regex) { + return regex.replace(/[\]\\/()*+?.$]/g, "\\$&"); + } + module2.exports = wrap({ http, https }); + module2.exports.wrap = wrap; + } +}); + +// node_modules/axios/dist/node/axios.cjs +var require_axios = __commonJS({ + "node_modules/axios/dist/node/axios.cjs"(exports2, module2) { + "use strict"; + var FormData$1 = require_form_data(); + var crypto12 = require("crypto"); + var url = require("url"); + var http = require("http"); + var https = require("https"); + var http2 = require("http2"); + var util = require("util"); + var followRedirects = require_follow_redirects(); + var zlib = require("zlib"); + var stream = require("stream"); + var events = require("events"); + function bind(fn, thisArg) { + return function wrap() { + return fn.apply(thisArg, arguments); + }; + } + var { + toString + } = Object.prototype; + var { + getPrototypeOf + } = Object; + var { + iterator, + toStringTag + } = Symbol; + var kindOf = /* @__PURE__ */ ((cache) => (thing) => { + const str = toString.call(thing); + return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); + })(/* @__PURE__ */ Object.create(null)); + var kindOfTest = (type) => { + type = type.toLowerCase(); + return (thing) => kindOf(thing) === type; + }; + var typeOfTest = (type) => (thing) => typeof thing === type; + var { + isArray + } = Array; + var isUndefined = typeOfTest("undefined"); + function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && isFunction$1(val.constructor.isBuffer) && val.constructor.isBuffer(val); + } + var isArrayBuffer = kindOfTest("ArrayBuffer"); + function isArrayBufferView(val) { + let result; + if (typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView) { + result = ArrayBuffer.isView(val); + } else { + result = val && val.buffer && isArrayBuffer(val.buffer); + } + return result; + } + var isString = typeOfTest("string"); + var isFunction$1 = typeOfTest("function"); + var isNumber = typeOfTest("number"); + var isObject2 = (thing) => thing !== null && typeof thing === "object"; + var isBoolean = (thing) => thing === true || thing === false; + var isPlainObject = (val) => { + if (kindOf(val) !== "object") { + return false; + } + const prototype2 = getPrototypeOf(val); + return (prototype2 === null || prototype2 === Object.prototype || Object.getPrototypeOf(prototype2) === null) && !(toStringTag in val) && !(iterator in val); + }; + var isEmptyObject = (val) => { + if (!isObject2(val) || isBuffer(val)) { + return false; + } + try { + return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; + } catch (e) { + return false; + } + }; + var isDate = kindOfTest("Date"); + var isFile = kindOfTest("File"); + var isReactNativeBlob = (value) => { + return !!(value && typeof value.uri !== "undefined"); + }; + var isReactNative2 = (formData) => formData && typeof formData.getParts !== "undefined"; + var isBlob = kindOfTest("Blob"); + var isFileList = kindOfTest("FileList"); + var isStream = (val) => isObject2(val) && isFunction$1(val.pipe); + function getGlobal() { + if (typeof globalThis !== "undefined") return globalThis; + if (typeof self !== "undefined") return self; + if (typeof window !== "undefined") return window; + if (typeof global !== "undefined") return global; + return {}; + } + var G = getGlobal(); + var FormDataCtor = typeof G.FormData !== "undefined" ? G.FormData : void 0; + var isFormData = (thing) => { + let kind; + return thing && (FormDataCtor && thing instanceof FormDataCtor || isFunction$1(thing.append) && ((kind = kindOf(thing)) === "formdata" || // detect form-data instance + kind === "object" && isFunction$1(thing.toString) && thing.toString() === "[object FormData]")); + }; + var isURLSearchParams = kindOfTest("URLSearchParams"); + var [isReadableStream, isRequest, isResponse, isHeaders] = ["ReadableStream", "Request", "Response", "Headers"].map(kindOfTest); + var trim = (str) => { + return str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ""); + }; + function forEach(obj, fn, { + allOwnKeys = false + } = {}) { + if (obj === null || typeof obj === "undefined") { + return; + } + let i; + let l; + if (typeof obj !== "object") { + obj = [obj]; + } + if (isArray(obj)) { + for (i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + if (isBuffer(obj)) { + return; + } + const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); + const len = keys.length; + let key; + for (i = 0; i < len; i++) { + key = keys[i]; + fn.call(null, obj[key], key, obj); + } + } + } + function findKey(obj, key) { + if (isBuffer(obj)) { + return null; + } + key = key.toLowerCase(); + const keys = Object.keys(obj); + let i = keys.length; + let _key; + while (i-- > 0) { + _key = keys[i]; + if (key === _key.toLowerCase()) { + return _key; + } + } + return null; + } + var _global = (() => { + if (typeof globalThis !== "undefined") return globalThis; + return typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : global; + })(); + var isContextDefined = (context) => !isUndefined(context) && context !== _global; + function merge() { + const { + caseless, + skipUndefined + } = isContextDefined(this) && this || {}; + const result = {}; + const assignValue = (val, key) => { + if (key === "__proto__" || key === "constructor" || key === "prototype") { + return; + } + const targetKey = caseless && findKey(result, key) || key; + if (isPlainObject(result[targetKey]) && isPlainObject(val)) { + result[targetKey] = merge(result[targetKey], val); + } else if (isPlainObject(val)) { + result[targetKey] = merge({}, val); + } else if (isArray(val)) { + result[targetKey] = val.slice(); + } else if (!skipUndefined || !isUndefined(val)) { + result[targetKey] = val; + } + }; + for (let i = 0, l = arguments.length; i < l; i++) { + arguments[i] && forEach(arguments[i], assignValue); + } + return result; + } + var extend = (a, b, thisArg, { + allOwnKeys + } = {}) => { + forEach(b, (val, key) => { + if (thisArg && isFunction$1(val)) { + Object.defineProperty(a, key, { + value: bind(val, thisArg), + writable: true, + enumerable: true, + configurable: true + }); + } else { + Object.defineProperty(a, key, { + value: val, + writable: true, + enumerable: true, + configurable: true + }); + } + }, { + allOwnKeys + }); + return a; + }; + var stripBOM = (content) => { + if (content.charCodeAt(0) === 65279) { + content = content.slice(1); + } + return content; + }; + var inherits = (constructor, superConstructor, props, descriptors) => { + constructor.prototype = Object.create(superConstructor.prototype, descriptors); + Object.defineProperty(constructor.prototype, "constructor", { + value: constructor, + writable: true, + enumerable: false, + configurable: true + }); + Object.defineProperty(constructor, "super", { + value: superConstructor.prototype + }); + props && Object.assign(constructor.prototype, props); + }; + var toFlatObject = (sourceObj, destObj, filter, propFilter) => { + let props; + let i; + let prop; + const merged = {}; + destObj = destObj || {}; + if (sourceObj == null) return destObj; + do { + props = Object.getOwnPropertyNames(sourceObj); + i = props.length; + while (i-- > 0) { + prop = props[i]; + if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { + destObj[prop] = sourceObj[prop]; + merged[prop] = true; + } + } + sourceObj = filter !== false && getPrototypeOf(sourceObj); + } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); + return destObj; + }; + var endsWith = (str, searchString, position) => { + str = String(str); + if (position === void 0 || position > str.length) { + position = str.length; + } + position -= searchString.length; + const lastIndex = str.indexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + }; + var toArray = (thing) => { + if (!thing) return null; + if (isArray(thing)) return thing; + let i = thing.length; + if (!isNumber(i)) return null; + const arr = new Array(i); + while (i-- > 0) { + arr[i] = thing[i]; + } + return arr; + }; + var isTypedArray = /* @__PURE__ */ ((TypedArray) => { + return (thing) => { + return TypedArray && thing instanceof TypedArray; + }; + })(typeof Uint8Array !== "undefined" && getPrototypeOf(Uint8Array)); + var forEachEntry = (obj, fn) => { + const generator = obj && obj[iterator]; + const _iterator = generator.call(obj); + let result; + while ((result = _iterator.next()) && !result.done) { + const pair = result.value; + fn.call(obj, pair[0], pair[1]); + } + }; + var matchAll = (regExp, str) => { + let matches; + const arr = []; + while ((matches = regExp.exec(str)) !== null) { + arr.push(matches); + } + return arr; + }; + var isHTMLForm = kindOfTest("HTMLFormElement"); + var toCamelCase = (str) => { + return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, function replacer(m, p1, p2) { + return p1.toUpperCase() + p2; + }); + }; + var hasOwnProperty = (({ + hasOwnProperty: hasOwnProperty2 + }) => (obj, prop) => hasOwnProperty2.call(obj, prop))(Object.prototype); + var isRegExp = kindOfTest("RegExp"); + var reduceDescriptors = (obj, reducer) => { + const descriptors = Object.getOwnPropertyDescriptors(obj); + const reducedDescriptors = {}; + forEach(descriptors, (descriptor, name) => { + let ret; + if ((ret = reducer(descriptor, name, obj)) !== false) { + reducedDescriptors[name] = ret || descriptor; + } + }); + Object.defineProperties(obj, reducedDescriptors); + }; + var freezeMethods = (obj) => { + reduceDescriptors(obj, (descriptor, name) => { + if (isFunction$1(obj) && ["arguments", "caller", "callee"].indexOf(name) !== -1) { + return false; + } + const value = obj[name]; + if (!isFunction$1(value)) return; + descriptor.enumerable = false; + if ("writable" in descriptor) { + descriptor.writable = false; + return; + } + if (!descriptor.set) { + descriptor.set = () => { + throw Error("Can not rewrite read-only method '" + name + "'"); + }; + } + }); + }; + var toObjectSet = (arrayOrString, delimiter) => { + const obj = {}; + const define2 = (arr) => { + arr.forEach((value) => { + obj[value] = true; + }); + }; + isArray(arrayOrString) ? define2(arrayOrString) : define2(String(arrayOrString).split(delimiter)); + return obj; + }; + var noop = () => { + }; + var toFiniteNumber = (value, defaultValue) => { + return value != null && Number.isFinite(value = +value) ? value : defaultValue; + }; + function isSpecCompliantForm(thing) { + return !!(thing && isFunction$1(thing.append) && thing[toStringTag] === "FormData" && thing[iterator]); + } + var toJSONObject = (obj) => { + const stack = new Array(10); + const visit = (source, i) => { + if (isObject2(source)) { + if (stack.indexOf(source) >= 0) { + return; + } + if (isBuffer(source)) { + return source; + } + if (!("toJSON" in source)) { + stack[i] = source; + const target = isArray(source) ? [] : {}; + forEach(source, (value, key) => { + const reducedValue = visit(value, i + 1); + !isUndefined(reducedValue) && (target[key] = reducedValue); + }); + stack[i] = void 0; + return target; + } + } + return source; + }; + return visit(obj, 0); + }; + var isAsyncFn = kindOfTest("AsyncFunction"); + var isThenable = (thing) => thing && (isObject2(thing) || isFunction$1(thing)) && isFunction$1(thing.then) && isFunction$1(thing.catch); + var _setImmediate = ((setImmediateSupported, postMessageSupported) => { + if (setImmediateSupported) { + return setImmediate; + } + return postMessageSupported ? ((token, callbacks) => { + _global.addEventListener("message", ({ + source, + data + }) => { + if (source === _global && data === token) { + callbacks.length && callbacks.shift()(); + } + }, false); + return (cb) => { + callbacks.push(cb); + _global.postMessage(token, "*"); + }; + })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb); + })(typeof setImmediate === "function", isFunction$1(_global.postMessage)); + var asap = typeof queueMicrotask !== "undefined" ? queueMicrotask.bind(_global) : typeof process !== "undefined" && process.nextTick || _setImmediate; + var isIterable = (thing) => thing != null && isFunction$1(thing[iterator]); + var utils$1 = { + isArray, + isArrayBuffer, + isBuffer, + isFormData, + isArrayBufferView, + isString, + isNumber, + isBoolean, + isObject: isObject2, + isPlainObject, + isEmptyObject, + isReadableStream, + isRequest, + isResponse, + isHeaders, + isUndefined, + isDate, + isFile, + isReactNativeBlob, + isReactNative: isReactNative2, + isBlob, + isRegExp, + isFunction: isFunction$1, + isStream, + isURLSearchParams, + isTypedArray, + isFileList, + forEach, + merge, + extend, + trim, + stripBOM, + inherits, + toFlatObject, + kindOf, + kindOfTest, + endsWith, + toArray, + forEachEntry, + matchAll, + isHTMLForm, + hasOwnProperty, + hasOwnProp: hasOwnProperty, + // an alias to avoid ESLint no-prototype-builtins detection + reduceDescriptors, + freezeMethods, + toObjectSet, + toCamelCase, + noop, + toFiniteNumber, + findKey, + global: _global, + isContextDefined, + isSpecCompliantForm, + toJSONObject, + isAsyncFn, + isThenable, + setImmediate: _setImmediate, + asap, + isIterable + }; + var AxiosError = class _AxiosError extends Error { + static from(error, code, config, request, response, customProps) { + const axiosError = new _AxiosError(error.message, code || error.code, config, request, response); + axiosError.cause = error; + axiosError.name = error.name; + if (error.status != null && axiosError.status == null) { + axiosError.status = error.status; + } + customProps && Object.assign(axiosError, customProps); + return axiosError; + } + /** + * Create an Error with the specified message, config, error code, request and response. + * + * @param {string} message The error message. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [config] The config. + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * + * @returns {Error} The created error. + */ + constructor(message, code, config, request, response) { + super(message); + Object.defineProperty(this, "message", { + value: message, + enumerable: true, + writable: true, + configurable: true + }); + this.name = "AxiosError"; + this.isAxiosError = true; + code && (this.code = code); + config && (this.config = config); + request && (this.request = request); + if (response) { + this.response = response; + this.status = response.status; + } + } + toJSON() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: utils$1.toJSONObject(this.config), + code: this.code, + status: this.status + }; + } + }; + AxiosError.ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE"; + AxiosError.ERR_BAD_OPTION = "ERR_BAD_OPTION"; + AxiosError.ECONNABORTED = "ECONNABORTED"; + AxiosError.ETIMEDOUT = "ETIMEDOUT"; + AxiosError.ERR_NETWORK = "ERR_NETWORK"; + AxiosError.ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS"; + AxiosError.ERR_DEPRECATED = "ERR_DEPRECATED"; + AxiosError.ERR_BAD_RESPONSE = "ERR_BAD_RESPONSE"; + AxiosError.ERR_BAD_REQUEST = "ERR_BAD_REQUEST"; + AxiosError.ERR_CANCELED = "ERR_CANCELED"; + AxiosError.ERR_NOT_SUPPORT = "ERR_NOT_SUPPORT"; + AxiosError.ERR_INVALID_URL = "ERR_INVALID_URL"; + function isVisitable(thing) { + return utils$1.isPlainObject(thing) || utils$1.isArray(thing); + } + function removeBrackets(key) { + return utils$1.endsWith(key, "[]") ? key.slice(0, -2) : key; + } + function renderKey(path3, key, dots) { + if (!path3) return key; + return path3.concat(key).map(function each(token, i) { + token = removeBrackets(token); + return !dots && i ? "[" + token + "]" : token; + }).join(dots ? "." : ""); + } + function isFlatArray(arr) { + return utils$1.isArray(arr) && !arr.some(isVisitable); + } + var predicates = utils$1.toFlatObject(utils$1, {}, null, function filter(prop) { + return /^is[A-Z]/.test(prop); + }); + function toFormData(obj, formData, options) { + if (!utils$1.isObject(obj)) { + throw new TypeError("target must be an object"); + } + formData = formData || new (FormData$1 || FormData)(); + options = utils$1.toFlatObject(options, { + metaTokens: true, + dots: false, + indexes: false + }, false, function defined(option, source) { + return !utils$1.isUndefined(source[option]); + }); + const metaTokens = options.metaTokens; + const visitor = options.visitor || defaultVisitor; + const dots = options.dots; + const indexes = options.indexes; + const _Blob = options.Blob || typeof Blob !== "undefined" && Blob; + const useBlob = _Blob && utils$1.isSpecCompliantForm(formData); + if (!utils$1.isFunction(visitor)) { + throw new TypeError("visitor must be a function"); + } + function convertValue(value) { + if (value === null) return ""; + if (utils$1.isDate(value)) { + return value.toISOString(); + } + if (utils$1.isBoolean(value)) { + return value.toString(); + } + if (!useBlob && utils$1.isBlob(value)) { + throw new AxiosError("Blob is not supported. Use a Buffer instead."); + } + if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) { + return useBlob && typeof Blob === "function" ? new Blob([value]) : Buffer.from(value); + } + return value; + } + function defaultVisitor(value, key, path3) { + let arr = value; + if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) { + formData.append(renderKey(path3, key, dots), convertValue(value)); + return false; + } + if (value && !path3 && typeof value === "object") { + if (utils$1.endsWith(key, "{}")) { + key = metaTokens ? key : key.slice(0, -2); + value = JSON.stringify(value); + } else if (utils$1.isArray(value) && isFlatArray(value) || (utils$1.isFileList(value) || utils$1.endsWith(key, "[]")) && (arr = utils$1.toArray(value))) { + key = removeBrackets(key); + arr.forEach(function each(el, index) { + !(utils$1.isUndefined(el) || el === null) && formData.append( + // eslint-disable-next-line no-nested-ternary + indexes === true ? renderKey([key], index, dots) : indexes === null ? key : key + "[]", + convertValue(el) + ); + }); + return false; + } + } + if (isVisitable(value)) { + return true; + } + formData.append(renderKey(path3, key, dots), convertValue(value)); + return false; + } + const stack = []; + const exposedHelpers = Object.assign(predicates, { + defaultVisitor, + convertValue, + isVisitable + }); + function build(value, path3) { + if (utils$1.isUndefined(value)) return; + if (stack.indexOf(value) !== -1) { + throw Error("Circular reference detected in " + path3.join(".")); + } + stack.push(value); + utils$1.forEach(value, function each(el, key) { + const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path3, exposedHelpers); + if (result === true) { + build(el, path3 ? path3.concat(key) : [key]); + } + }); + stack.pop(); + } + if (!utils$1.isObject(obj)) { + throw new TypeError("data must be an object"); + } + build(obj); + return formData; + } + function encode$1(str) { + const charMap = { + "!": "%21", + "'": "%27", + "(": "%28", + ")": "%29", + "~": "%7E", + "%20": "+", + "%00": "\0" + }; + return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) { + return charMap[match]; + }); + } + function AxiosURLSearchParams(params, options) { + this._pairs = []; + params && toFormData(params, this, options); + } + var prototype = AxiosURLSearchParams.prototype; + prototype.append = function append(name, value) { + this._pairs.push([name, value]); + }; + prototype.toString = function toString2(encoder) { + const _encode = encoder ? function(value) { + return encoder.call(this, value, encode$1); + } : encode$1; + return this._pairs.map(function each(pair) { + return _encode(pair[0]) + "=" + _encode(pair[1]); + }, "").join("&"); + }; + function encode(val) { + return encodeURIComponent(val).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+"); + } + function buildURL(url2, params, options) { + if (!params) { + return url2; + } + const _encode = options && options.encode || encode; + const _options = utils$1.isFunction(options) ? { + serialize: options + } : options; + const serializeFn = _options && _options.serialize; + let serializedParams; + if (serializeFn) { + serializedParams = serializeFn(params, _options); + } else { + serializedParams = utils$1.isURLSearchParams(params) ? params.toString() : new AxiosURLSearchParams(params, _options).toString(_encode); + } + if (serializedParams) { + const hashmarkIndex = url2.indexOf("#"); + if (hashmarkIndex !== -1) { + url2 = url2.slice(0, hashmarkIndex); + } + url2 += (url2.indexOf("?") === -1 ? "?" : "&") + serializedParams; + } + return url2; + } + var InterceptorManager = class { + constructor() { + this.handlers = []; + } + /** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * @param {Object} options The options for the interceptor, synchronous and runWhen + * + * @return {Number} An ID used to remove interceptor later + */ + use(fulfilled, rejected, options) { + this.handlers.push({ + fulfilled, + rejected, + synchronous: options ? options.synchronous : false, + runWhen: options ? options.runWhen : null + }); + return this.handlers.length - 1; + } + /** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + * + * @returns {void} + */ + eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } + } + /** + * Clear all interceptors from the stack + * + * @returns {void} + */ + clear() { + if (this.handlers) { + this.handlers = []; + } + } + /** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + * + * @returns {void} + */ + forEach(fn) { + utils$1.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); + } + }; + var transitionalDefaults = { + silentJSONParsing: true, + forcedJSONParsing: true, + clarifyTimeoutError: false, + legacyInterceptorReqResOrdering: true + }; + var URLSearchParams2 = url.URLSearchParams; + var ALPHA = "abcdefghijklmnopqrstuvwxyz"; + var DIGIT = "0123456789"; + var ALPHABET = { + DIGIT, + ALPHA, + ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT + }; + var generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => { + let str = ""; + const { + length + } = alphabet; + const randomValues = new Uint32Array(size); + crypto12.randomFillSync(randomValues); + for (let i = 0; i < size; i++) { + str += alphabet[randomValues[i] % length]; + } + return str; + }; + var platform$1 = { + isNode: true, + classes: { + URLSearchParams: URLSearchParams2, + FormData: FormData$1, + Blob: typeof Blob !== "undefined" && Blob || null + }, + ALPHABET, + generateString, + protocols: ["http", "https", "file", "data"] + }; + var hasBrowserEnv = typeof window !== "undefined" && typeof document !== "undefined"; + var _navigator = typeof navigator === "object" && navigator || void 0; + var hasStandardBrowserEnv = hasBrowserEnv && (!_navigator || ["ReactNative", "NativeScript", "NS"].indexOf(_navigator.product) < 0); + var hasStandardBrowserWebWorkerEnv = (() => { + return typeof WorkerGlobalScope !== "undefined" && // eslint-disable-next-line no-undef + self instanceof WorkerGlobalScope && typeof self.importScripts === "function"; + })(); + var origin = hasBrowserEnv && window.location.href || "http://localhost"; + var utils = /* @__PURE__ */ Object.freeze({ + __proto__: null, + hasBrowserEnv, + hasStandardBrowserEnv, + hasStandardBrowserWebWorkerEnv, + navigator: _navigator, + origin + }); + var platform2 = { + ...utils, + ...platform$1 + }; + function toURLEncodedForm(data, options) { + return toFormData(data, new platform2.classes.URLSearchParams(), { + visitor: function(value, key, path3, helpers) { + if (platform2.isNode && utils$1.isBuffer(value)) { + this.append(key, value.toString("base64")); + return false; + } + return helpers.defaultVisitor.apply(this, arguments); + }, + ...options + }); + } + function parsePropPath(name) { + return utils$1.matchAll(/\w+|\[(\w*)]/g, name).map((match) => { + return match[0] === "[]" ? "" : match[1] || match[0]; + }); + } + function arrayToObject(arr) { + const obj = {}; + const keys = Object.keys(arr); + let i; + const len = keys.length; + let key; + for (i = 0; i < len; i++) { + key = keys[i]; + obj[key] = arr[key]; + } + return obj; + } + function formDataToJSON(formData) { + function buildPath(path3, value, target, index) { + let name = path3[index++]; + if (name === "__proto__") return true; + const isNumericKey = Number.isFinite(+name); + const isLast = index >= path3.length; + name = !name && utils$1.isArray(target) ? target.length : name; + if (isLast) { + if (utils$1.hasOwnProp(target, name)) { + target[name] = [target[name], value]; + } else { + target[name] = value; + } + return !isNumericKey; + } + if (!target[name] || !utils$1.isObject(target[name])) { + target[name] = []; + } + const result = buildPath(path3, value, target[name], index); + if (result && utils$1.isArray(target[name])) { + target[name] = arrayToObject(target[name]); + } + return !isNumericKey; + } + if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) { + const obj = {}; + utils$1.forEachEntry(formData, (name, value) => { + buildPath(parsePropPath(name), value, obj, 0); + }); + return obj; + } + return null; + } + function stringifySafely(rawValue, parser, encoder) { + if (utils$1.isString(rawValue)) { + try { + (parser || JSON.parse)(rawValue); + return utils$1.trim(rawValue); + } catch (e) { + if (e.name !== "SyntaxError") { + throw e; + } + } + } + return (encoder || JSON.stringify)(rawValue); + } + var defaults = { + transitional: transitionalDefaults, + adapter: ["xhr", "http", "fetch"], + transformRequest: [function transformRequest(data, headers) { + const contentType = headers.getContentType() || ""; + const hasJSONContentType = contentType.indexOf("application/json") > -1; + const isObjectPayload = utils$1.isObject(data); + if (isObjectPayload && utils$1.isHTMLForm(data)) { + data = new FormData(data); + } + const isFormData2 = utils$1.isFormData(data); + if (isFormData2) { + return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data; + } + if (utils$1.isArrayBuffer(data) || utils$1.isBuffer(data) || utils$1.isStream(data) || utils$1.isFile(data) || utils$1.isBlob(data) || utils$1.isReadableStream(data)) { + return data; + } + if (utils$1.isArrayBufferView(data)) { + return data.buffer; + } + if (utils$1.isURLSearchParams(data)) { + headers.setContentType("application/x-www-form-urlencoded;charset=utf-8", false); + return data.toString(); + } + let isFileList2; + if (isObjectPayload) { + if (contentType.indexOf("application/x-www-form-urlencoded") > -1) { + return toURLEncodedForm(data, this.formSerializer).toString(); + } + if ((isFileList2 = utils$1.isFileList(data)) || contentType.indexOf("multipart/form-data") > -1) { + const _FormData = this.env && this.env.FormData; + return toFormData(isFileList2 ? { + "files[]": data + } : data, _FormData && new _FormData(), this.formSerializer); + } + } + if (isObjectPayload || hasJSONContentType) { + headers.setContentType("application/json", false); + return stringifySafely(data); + } + return data; + }], + transformResponse: [function transformResponse(data) { + const transitional = this.transitional || defaults.transitional; + const forcedJSONParsing = transitional && transitional.forcedJSONParsing; + const JSONRequested = this.responseType === "json"; + if (utils$1.isResponse(data) || utils$1.isReadableStream(data)) { + return data; + } + if (data && utils$1.isString(data) && (forcedJSONParsing && !this.responseType || JSONRequested)) { + const silentJSONParsing = transitional && transitional.silentJSONParsing; + const strictJSONParsing = !silentJSONParsing && JSONRequested; + try { + return JSON.parse(data, this.parseReviver); + } catch (e) { + if (strictJSONParsing) { + if (e.name === "SyntaxError") { + throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response); + } + throw e; + } + } + } + return data; + }], + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, + xsrfCookieName: "XSRF-TOKEN", + xsrfHeaderName: "X-XSRF-TOKEN", + maxContentLength: -1, + maxBodyLength: -1, + env: { + FormData: platform2.classes.FormData, + Blob: platform2.classes.Blob + }, + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; + }, + headers: { + common: { + Accept: "application/json, text/plain, */*", + "Content-Type": void 0 + } + } + }; + utils$1.forEach(["delete", "get", "head", "post", "put", "patch"], (method) => { + defaults.headers[method] = {}; + }); + var ignoreDuplicateOf = utils$1.toObjectSet(["age", "authorization", "content-length", "content-type", "etag", "expires", "from", "host", "if-modified-since", "if-unmodified-since", "last-modified", "location", "max-forwards", "proxy-authorization", "referer", "retry-after", "user-agent"]); + var parseHeaders = (rawHeaders) => { + const parsed = {}; + let key; + let val; + let i; + rawHeaders && rawHeaders.split("\n").forEach(function parser(line) { + i = line.indexOf(":"); + key = line.substring(0, i).trim().toLowerCase(); + val = line.substring(i + 1).trim(); + if (!key || parsed[key] && ignoreDuplicateOf[key]) { + return; + } + if (key === "set-cookie") { + if (parsed[key]) { + parsed[key].push(val); + } else { + parsed[key] = [val]; + } + } else { + parsed[key] = parsed[key] ? parsed[key] + ", " + val : val; + } + }); + return parsed; + }; + var $internals = Symbol("internals"); + var isValidHeaderValue = (value) => !/[\r\n]/.test(value); + function assertValidHeaderValue(value, header) { + if (value === false || value == null) { + return; + } + if (utils$1.isArray(value)) { + value.forEach((v) => assertValidHeaderValue(v, header)); + return; + } + if (!isValidHeaderValue(String(value))) { + throw new Error(`Invalid character in header content ["${header}"]`); + } + } + function normalizeHeader(header) { + return header && String(header).trim().toLowerCase(); + } + function stripTrailingCRLF(str) { + let end = str.length; + while (end > 0) { + const charCode = str.charCodeAt(end - 1); + if (charCode !== 10 && charCode !== 13) { + break; + } + end -= 1; + } + return end === str.length ? str : str.slice(0, end); + } + function normalizeValue(value) { + if (value === false || value == null) { + return value; + } + return utils$1.isArray(value) ? value.map(normalizeValue) : stripTrailingCRLF(String(value)); + } + function parseTokens(str) { + const tokens = /* @__PURE__ */ Object.create(null); + const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; + let match; + while (match = tokensRE.exec(str)) { + tokens[match[1]] = match[2]; + } + return tokens; + } + var isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); + function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { + if (utils$1.isFunction(filter)) { + return filter.call(this, value, header); + } + if (isHeaderNameFilter) { + value = header; + } + if (!utils$1.isString(value)) return; + if (utils$1.isString(filter)) { + return value.indexOf(filter) !== -1; + } + if (utils$1.isRegExp(filter)) { + return filter.test(value); + } + } + function formatHeader(header) { + return header.trim().toLowerCase().replace(/([a-z\d])(\w*)/g, (w, char, str) => { + return char.toUpperCase() + str; + }); + } + function buildAccessors(obj, header) { + const accessorName = utils$1.toCamelCase(" " + header); + ["get", "set", "has"].forEach((methodName) => { + Object.defineProperty(obj, methodName + accessorName, { + value: function(arg1, arg2, arg3) { + return this[methodName].call(this, header, arg1, arg2, arg3); + }, + configurable: true + }); + }); + } + var AxiosHeaders = class { + constructor(headers) { + headers && this.set(headers); + } + set(header, valueOrRewrite, rewrite) { + const self2 = this; + function setHeader(_value, _header, _rewrite) { + const lHeader = normalizeHeader(_header); + if (!lHeader) { + throw new Error("header name must be a non-empty string"); + } + const key = utils$1.findKey(self2, lHeader); + if (!key || self2[key] === void 0 || _rewrite === true || _rewrite === void 0 && self2[key] !== false) { + assertValidHeaderValue(_value, _header); + self2[key || _header] = normalizeValue(_value); + } + } + const setHeaders = (headers, _rewrite) => utils$1.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite)); + if (utils$1.isPlainObject(header) || header instanceof this.constructor) { + setHeaders(header, valueOrRewrite); + } else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { + setHeaders(parseHeaders(header), valueOrRewrite); + } else if (utils$1.isObject(header) && utils$1.isIterable(header)) { + let obj = {}, dest, key; + for (const entry of header) { + if (!utils$1.isArray(entry)) { + throw TypeError("Object iterator must return a key-value pair"); + } + obj[key = entry[0]] = (dest = obj[key]) ? utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]] : entry[1]; + } + setHeaders(obj, valueOrRewrite); + } else { + header != null && setHeader(valueOrRewrite, header, rewrite); + } + return this; + } + get(header, parser) { + header = normalizeHeader(header); + if (header) { + const key = utils$1.findKey(this, header); + if (key) { + const value = this[key]; + if (!parser) { + return value; + } + if (parser === true) { + return parseTokens(value); + } + if (utils$1.isFunction(parser)) { + return parser.call(this, value, key); + } + if (utils$1.isRegExp(parser)) { + return parser.exec(value); + } + throw new TypeError("parser must be boolean|regexp|function"); + } + } + } + has(header, matcher) { + header = normalizeHeader(header); + if (header) { + const key = utils$1.findKey(this, header); + return !!(key && this[key] !== void 0 && (!matcher || matchHeaderValue(this, this[key], key, matcher))); + } + return false; + } + delete(header, matcher) { + const self2 = this; + let deleted = false; + function deleteHeader(_header) { + _header = normalizeHeader(_header); + if (_header) { + const key = utils$1.findKey(self2, _header); + if (key && (!matcher || matchHeaderValue(self2, self2[key], key, matcher))) { + delete self2[key]; + deleted = true; + } + } + } + if (utils$1.isArray(header)) { + header.forEach(deleteHeader); + } else { + deleteHeader(header); + } + return deleted; + } + clear(matcher) { + const keys = Object.keys(this); + let i = keys.length; + let deleted = false; + while (i--) { + const key = keys[i]; + if (!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { + delete this[key]; + deleted = true; + } + } + return deleted; + } + normalize(format) { + const self2 = this; + const headers = {}; + utils$1.forEach(this, (value, header) => { + const key = utils$1.findKey(headers, header); + if (key) { + self2[key] = normalizeValue(value); + delete self2[header]; + return; + } + const normalized = format ? formatHeader(header) : String(header).trim(); + if (normalized !== header) { + delete self2[header]; + } + self2[normalized] = normalizeValue(value); + headers[normalized] = true; + }); + return this; + } + concat(...targets) { + return this.constructor.concat(this, ...targets); + } + toJSON(asStrings) { + const obj = /* @__PURE__ */ Object.create(null); + utils$1.forEach(this, (value, header) => { + value != null && value !== false && (obj[header] = asStrings && utils$1.isArray(value) ? value.join(", ") : value); + }); + return obj; + } + [Symbol.iterator]() { + return Object.entries(this.toJSON())[Symbol.iterator](); + } + toString() { + return Object.entries(this.toJSON()).map(([header, value]) => header + ": " + value).join("\n"); + } + getSetCookie() { + return this.get("set-cookie") || []; + } + get [Symbol.toStringTag]() { + return "AxiosHeaders"; + } + static from(thing) { + return thing instanceof this ? thing : new this(thing); + } + static concat(first, ...targets) { + const computed = new this(first); + targets.forEach((target) => computed.set(target)); + return computed; + } + static accessor(header) { + const internals = this[$internals] = this[$internals] = { + accessors: {} + }; + const accessors = internals.accessors; + const prototype2 = this.prototype; + function defineAccessor(_header) { + const lHeader = normalizeHeader(_header); + if (!accessors[lHeader]) { + buildAccessors(prototype2, _header); + accessors[lHeader] = true; + } + } + utils$1.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); + return this; + } + }; + AxiosHeaders.accessor(["Content-Type", "Content-Length", "Accept", "Accept-Encoding", "User-Agent", "Authorization"]); + utils$1.reduceDescriptors(AxiosHeaders.prototype, ({ + value + }, key) => { + let mapped = key[0].toUpperCase() + key.slice(1); + return { + get: () => value, + set(headerValue) { + this[mapped] = headerValue; + } + }; + }); + utils$1.freezeMethods(AxiosHeaders); + function transformData(fns, response) { + const config = this || defaults; + const context = response || config; + const headers = AxiosHeaders.from(context.headers); + let data = context.data; + utils$1.forEach(fns, function transform(fn) { + data = fn.call(config, data, headers.normalize(), response ? response.status : void 0); + }); + headers.normalize(); + return data; + } + function isCancel(value) { + return !!(value && value.__CANCEL__); + } + var CanceledError = class extends AxiosError { + /** + * A `CanceledError` is an object that is thrown when an operation is canceled. + * + * @param {string=} message The message. + * @param {Object=} config The config. + * @param {Object=} request The request. + * + * @returns {CanceledError} The created error. + */ + constructor(message, config, request) { + super(message == null ? "canceled" : message, AxiosError.ERR_CANCELED, config, request); + this.name = "CanceledError"; + this.__CANCEL__ = true; + } + }; + function settle(resolve, reject, response) { + const validateStatus = response.config.validateStatus; + if (!response.status || !validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(new AxiosError("Request failed with status code " + response.status, [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], response.config, response.request, response)); + } + } + function isAbsoluteURL(url2) { + if (typeof url2 !== "string") { + return false; + } + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url2); + } + function combineURLs(baseURL, relativeURL) { + return relativeURL ? baseURL.replace(/\/?\/$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL; + } + function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) { + let isRelativeUrl = !isAbsoluteURL(requestedURL); + if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) { + return combineURLs(baseURL, requestedURL); + } + return requestedURL; + } + var DEFAULT_PORTS$1 = { + ftp: 21, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443 + }; + function parseUrl(urlString) { + try { + return new URL(urlString); + } catch { + return null; + } + } + function getProxyForUrl(url2) { + var parsedUrl = (typeof url2 === "string" ? parseUrl(url2) : url2) || {}; + var proto = parsedUrl.protocol; + var hostname = parsedUrl.host; + var port = parsedUrl.port; + if (typeof hostname !== "string" || !hostname || typeof proto !== "string") { + return ""; + } + proto = proto.split(":", 1)[0]; + hostname = hostname.replace(/:\d*$/, ""); + port = parseInt(port) || DEFAULT_PORTS$1[proto] || 0; + if (!shouldProxy(hostname, port)) { + return ""; + } + var proxy = getEnv(proto + "_proxy") || getEnv("all_proxy"); + if (proxy && proxy.indexOf("://") === -1) { + proxy = proto + "://" + proxy; + } + return proxy; + } + function shouldProxy(hostname, port) { + var NO_PROXY = getEnv("no_proxy").toLowerCase(); + if (!NO_PROXY) { + return true; + } + if (NO_PROXY === "*") { + return false; + } + return NO_PROXY.split(/[,\s]/).every(function(proxy) { + if (!proxy) { + return true; + } + var parsedProxy = proxy.match(/^(.+):(\d+)$/); + var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy; + var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0; + if (parsedProxyPort && parsedProxyPort !== port) { + return true; + } + if (!/^[.*]/.test(parsedProxyHostname)) { + return hostname !== parsedProxyHostname; + } + if (parsedProxyHostname.charAt(0) === "*") { + parsedProxyHostname = parsedProxyHostname.slice(1); + } + return !hostname.endsWith(parsedProxyHostname); + }); + } + function getEnv(key) { + return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || ""; + } + var VERSION = "1.15.0"; + function parseProtocol(url2) { + const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url2); + return match && match[1] || ""; + } + var DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/; + function fromDataURI(uri, asBlob, options) { + const _Blob = options && options.Blob || platform2.classes.Blob; + const protocol = parseProtocol(uri); + if (asBlob === void 0 && _Blob) { + asBlob = true; + } + if (protocol === "data") { + uri = protocol.length ? uri.slice(protocol.length + 1) : uri; + const match = DATA_URL_PATTERN.exec(uri); + if (!match) { + throw new AxiosError("Invalid URL", AxiosError.ERR_INVALID_URL); + } + const mime = match[1]; + const isBase64 = match[2]; + const body = match[3]; + const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? "base64" : "utf8"); + if (asBlob) { + if (!_Blob) { + throw new AxiosError("Blob is not supported", AxiosError.ERR_NOT_SUPPORT); + } + return new _Blob([buffer], { + type: mime + }); + } + return buffer; + } + throw new AxiosError("Unsupported protocol " + protocol, AxiosError.ERR_NOT_SUPPORT); + } + var kInternals = Symbol("internals"); + var AxiosTransformStream = class extends stream.Transform { + constructor(options) { + options = utils$1.toFlatObject(options, { + maxRate: 0, + chunkSize: 64 * 1024, + minChunkSize: 100, + timeWindow: 500, + ticksRate: 2, + samplesCount: 15 + }, null, (prop, source) => { + return !utils$1.isUndefined(source[prop]); + }); + super({ + readableHighWaterMark: options.chunkSize + }); + const internals = this[kInternals] = { + timeWindow: options.timeWindow, + chunkSize: options.chunkSize, + maxRate: options.maxRate, + minChunkSize: options.minChunkSize, + bytesSeen: 0, + isCaptured: false, + notifiedBytesLoaded: 0, + ts: Date.now(), + bytes: 0, + onReadCallback: null + }; + this.on("newListener", (event) => { + if (event === "progress") { + if (!internals.isCaptured) { + internals.isCaptured = true; + } + } + }); + } + _read(size) { + const internals = this[kInternals]; + if (internals.onReadCallback) { + internals.onReadCallback(); + } + return super._read(size); + } + _transform(chunk, encoding, callback) { + const internals = this[kInternals]; + const maxRate = internals.maxRate; + const readableHighWaterMark = this.readableHighWaterMark; + const timeWindow = internals.timeWindow; + const divider = 1e3 / timeWindow; + const bytesThreshold = maxRate / divider; + const minChunkSize = internals.minChunkSize !== false ? Math.max(internals.minChunkSize, bytesThreshold * 0.01) : 0; + const pushChunk = (_chunk, _callback) => { + const bytes = Buffer.byteLength(_chunk); + internals.bytesSeen += bytes; + internals.bytes += bytes; + internals.isCaptured && this.emit("progress", internals.bytesSeen); + if (this.push(_chunk)) { + process.nextTick(_callback); + } else { + internals.onReadCallback = () => { + internals.onReadCallback = null; + process.nextTick(_callback); + }; + } + }; + const transformChunk = (_chunk, _callback) => { + const chunkSize = Buffer.byteLength(_chunk); + let chunkRemainder = null; + let maxChunkSize = readableHighWaterMark; + let bytesLeft; + let passed = 0; + if (maxRate) { + const now = Date.now(); + if (!internals.ts || (passed = now - internals.ts) >= timeWindow) { + internals.ts = now; + bytesLeft = bytesThreshold - internals.bytes; + internals.bytes = bytesLeft < 0 ? -bytesLeft : 0; + passed = 0; + } + bytesLeft = bytesThreshold - internals.bytes; + } + if (maxRate) { + if (bytesLeft <= 0) { + return setTimeout(() => { + _callback(null, _chunk); + }, timeWindow - passed); + } + if (bytesLeft < maxChunkSize) { + maxChunkSize = bytesLeft; + } + } + if (maxChunkSize && chunkSize > maxChunkSize && chunkSize - maxChunkSize > minChunkSize) { + chunkRemainder = _chunk.subarray(maxChunkSize); + _chunk = _chunk.subarray(0, maxChunkSize); + } + pushChunk(_chunk, chunkRemainder ? () => { + process.nextTick(_callback, null, chunkRemainder); + } : _callback); + }; + transformChunk(chunk, function transformNextChunk(err, _chunk) { + if (err) { + return callback(err); + } + if (_chunk) { + transformChunk(_chunk, transformNextChunk); + } else { + callback(null); + } + }); + } + }; + var { + asyncIterator + } = Symbol; + var readBlob = async function* (blob) { + if (blob.stream) { + yield* blob.stream(); + } else if (blob.arrayBuffer) { + yield await blob.arrayBuffer(); + } else if (blob[asyncIterator]) { + yield* blob[asyncIterator](); + } else { + yield blob; + } + }; + var BOUNDARY_ALPHABET = platform2.ALPHABET.ALPHA_DIGIT + "-_"; + var textEncoder = typeof TextEncoder === "function" ? new TextEncoder() : new util.TextEncoder(); + var CRLF = "\r\n"; + var CRLF_BYTES = textEncoder.encode(CRLF); + var CRLF_BYTES_COUNT = 2; + var FormDataPart = class { + constructor(name, value) { + const { + escapeName + } = this.constructor; + const isStringValue = utils$1.isString(value); + let headers = `Content-Disposition: form-data; name="${escapeName(name)}"${!isStringValue && value.name ? `; filename="${escapeName(value.name)}"` : ""}${CRLF}`; + if (isStringValue) { + value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF)); + } else { + headers += `Content-Type: ${value.type || "application/octet-stream"}${CRLF}`; + } + this.headers = textEncoder.encode(headers + CRLF); + this.contentLength = isStringValue ? value.byteLength : value.size; + this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT; + this.name = name; + this.value = value; + } + async *encode() { + yield this.headers; + const { + value + } = this; + if (utils$1.isTypedArray(value)) { + yield value; + } else { + yield* readBlob(value); + } + yield CRLF_BYTES; + } + static escapeName(name) { + return String(name).replace(/[\r\n"]/g, (match) => ({ + "\r": "%0D", + "\n": "%0A", + '"': "%22" + })[match]); + } + }; + var formDataToStream = (form, headersHandler, options) => { + const { + tag = "form-data-boundary", + size = 25, + boundary = tag + "-" + platform2.generateString(size, BOUNDARY_ALPHABET) + } = options || {}; + if (!utils$1.isFormData(form)) { + throw TypeError("FormData instance required"); + } + if (boundary.length < 1 || boundary.length > 70) { + throw Error("boundary must be 10-70 characters long"); + } + const boundaryBytes = textEncoder.encode("--" + boundary + CRLF); + const footerBytes = textEncoder.encode("--" + boundary + "--" + CRLF); + let contentLength = footerBytes.byteLength; + const parts = Array.from(form.entries()).map(([name, value]) => { + const part = new FormDataPart(name, value); + contentLength += part.size; + return part; + }); + contentLength += boundaryBytes.byteLength * parts.length; + contentLength = utils$1.toFiniteNumber(contentLength); + const computedHeaders = { + "Content-Type": `multipart/form-data; boundary=${boundary}` + }; + if (Number.isFinite(contentLength)) { + computedHeaders["Content-Length"] = contentLength; + } + headersHandler && headersHandler(computedHeaders); + return stream.Readable.from((async function* () { + for (const part of parts) { + yield boundaryBytes; + yield* part.encode(); + } + yield footerBytes; + })()); + }; + var ZlibHeaderTransformStream = class extends stream.Transform { + __transform(chunk, encoding, callback) { + this.push(chunk); + callback(); + } + _transform(chunk, encoding, callback) { + if (chunk.length !== 0) { + this._transform = this.__transform; + if (chunk[0] !== 120) { + const header = Buffer.alloc(2); + header[0] = 120; + header[1] = 156; + this.push(header, encoding); + } + } + this.__transform(chunk, encoding, callback); + } + }; + var callbackify = (fn, reducer) => { + return utils$1.isAsyncFn(fn) ? function(...args) { + const cb = args.pop(); + fn.apply(this, args).then((value) => { + try { + reducer ? cb(null, ...reducer(value)) : cb(null, value); + } catch (err) { + cb(err); + } + }, cb); + } : fn; + }; + var DEFAULT_PORTS = { + http: 80, + https: 443, + ws: 80, + wss: 443, + ftp: 21 + }; + var parseNoProxyEntry = (entry) => { + let entryHost = entry; + let entryPort = 0; + if (entryHost.charAt(0) === "[") { + const bracketIndex = entryHost.indexOf("]"); + if (bracketIndex !== -1) { + const host = entryHost.slice(1, bracketIndex); + const rest = entryHost.slice(bracketIndex + 1); + if (rest.charAt(0) === ":" && /^\d+$/.test(rest.slice(1))) { + entryPort = Number.parseInt(rest.slice(1), 10); + } + return [host, entryPort]; + } + } + const firstColon = entryHost.indexOf(":"); + const lastColon = entryHost.lastIndexOf(":"); + if (firstColon !== -1 && firstColon === lastColon && /^\d+$/.test(entryHost.slice(lastColon + 1))) { + entryPort = Number.parseInt(entryHost.slice(lastColon + 1), 10); + entryHost = entryHost.slice(0, lastColon); + } + return [entryHost, entryPort]; + }; + var normalizeNoProxyHost = (hostname) => { + if (!hostname) { + return hostname; + } + if (hostname.charAt(0) === "[" && hostname.charAt(hostname.length - 1) === "]") { + hostname = hostname.slice(1, -1); + } + return hostname.replace(/\.+$/, ""); + }; + function shouldBypassProxy(location) { + let parsed; + try { + parsed = new URL(location); + } catch (_err) { + return false; + } + const noProxy = (process.env.no_proxy || process.env.NO_PROXY || "").toLowerCase(); + if (!noProxy) { + return false; + } + if (noProxy === "*") { + return true; + } + const port = Number.parseInt(parsed.port, 10) || DEFAULT_PORTS[parsed.protocol.split(":", 1)[0]] || 0; + const hostname = normalizeNoProxyHost(parsed.hostname.toLowerCase()); + return noProxy.split(/[\s,]+/).some((entry) => { + if (!entry) { + return false; + } + let [entryHost, entryPort] = parseNoProxyEntry(entry); + entryHost = normalizeNoProxyHost(entryHost); + if (!entryHost) { + return false; + } + if (entryPort && entryPort !== port) { + return false; + } + if (entryHost.charAt(0) === "*") { + entryHost = entryHost.slice(1); + } + if (entryHost.charAt(0) === ".") { + return hostname.endsWith(entryHost); + } + return hostname === entryHost; + }); + } + function speedometer(samplesCount, min) { + samplesCount = samplesCount || 10; + const bytes = new Array(samplesCount); + const timestamps = new Array(samplesCount); + let head = 0; + let tail = 0; + let firstSampleTS; + min = min !== void 0 ? min : 1e3; + return function push(chunkLength) { + const now = Date.now(); + const startedAt = timestamps[tail]; + if (!firstSampleTS) { + firstSampleTS = now; + } + bytes[head] = chunkLength; + timestamps[head] = now; + let i = tail; + let bytesCount = 0; + while (i !== head) { + bytesCount += bytes[i++]; + i = i % samplesCount; + } + head = (head + 1) % samplesCount; + if (head === tail) { + tail = (tail + 1) % samplesCount; + } + if (now - firstSampleTS < min) { + return; + } + const passed = startedAt && now - startedAt; + return passed ? Math.round(bytesCount * 1e3 / passed) : void 0; + }; + } + function throttle(fn, freq) { + let timestamp = 0; + let threshold = 1e3 / freq; + let lastArgs; + let timer; + const invoke = (args, now = Date.now()) => { + timestamp = now; + lastArgs = null; + if (timer) { + clearTimeout(timer); + timer = null; + } + fn(...args); + }; + const throttled = (...args) => { + const now = Date.now(); + const passed = now - timestamp; + if (passed >= threshold) { + invoke(args, now); + } else { + lastArgs = args; + if (!timer) { + timer = setTimeout(() => { + timer = null; + invoke(lastArgs); + }, threshold - passed); + } + } + }; + const flush = () => lastArgs && invoke(lastArgs); + return [throttled, flush]; + } + var progressEventReducer = (listener, isDownloadStream, freq = 3) => { + let bytesNotified = 0; + const _speedometer = speedometer(50, 250); + return throttle((e) => { + const loaded = e.loaded; + const total = e.lengthComputable ? e.total : void 0; + const progressBytes = loaded - bytesNotified; + const rate = _speedometer(progressBytes); + const inRange = loaded <= total; + bytesNotified = loaded; + const data = { + loaded, + total, + progress: total ? loaded / total : void 0, + bytes: progressBytes, + rate: rate ? rate : void 0, + estimated: rate && total && inRange ? (total - loaded) / rate : void 0, + event: e, + lengthComputable: total != null, + [isDownloadStream ? "download" : "upload"]: true + }; + listener(data); + }, freq); + }; + var progressEventDecorator = (total, throttled) => { + const lengthComputable = total != null; + return [(loaded) => throttled[0]({ + lengthComputable, + total, + loaded + }), throttled[1]]; + }; + var asyncDecorator = (fn) => (...args) => utils$1.asap(() => fn(...args)); + function estimateDataURLDecodedBytes(url2) { + if (!url2 || typeof url2 !== "string") return 0; + if (!url2.startsWith("data:")) return 0; + const comma = url2.indexOf(","); + if (comma < 0) return 0; + const meta = url2.slice(5, comma); + const body = url2.slice(comma + 1); + const isBase64 = /;base64/i.test(meta); + if (isBase64) { + let effectiveLen = body.length; + const len = body.length; + for (let i = 0; i < len; i++) { + if (body.charCodeAt(i) === 37 && i + 2 < len) { + const a = body.charCodeAt(i + 1); + const b = body.charCodeAt(i + 2); + const isHex = (a >= 48 && a <= 57 || a >= 65 && a <= 70 || a >= 97 && a <= 102) && (b >= 48 && b <= 57 || b >= 65 && b <= 70 || b >= 97 && b <= 102); + if (isHex) { + effectiveLen -= 2; + i += 2; + } + } + } + let pad = 0; + let idx = len - 1; + const tailIsPct3D = (j) => j >= 2 && body.charCodeAt(j - 2) === 37 && // '%' + body.charCodeAt(j - 1) === 51 && // '3' + (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); + if (idx >= 0) { + if (body.charCodeAt(idx) === 61) { + pad++; + idx--; + } else if (tailIsPct3D(idx)) { + pad++; + idx -= 3; + } + } + if (pad === 1 && idx >= 0) { + if (body.charCodeAt(idx) === 61) { + pad++; + } else if (tailIsPct3D(idx)) { + pad++; + } + } + const groups = Math.floor(effectiveLen / 4); + const bytes = groups * 3 - (pad || 0); + return bytes > 0 ? bytes : 0; + } + return Buffer.byteLength(body, "utf8"); + } + var zlibOptions = { + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH + }; + var brotliOptions = { + flush: zlib.constants.BROTLI_OPERATION_FLUSH, + finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH + }; + var isBrotliSupported = utils$1.isFunction(zlib.createBrotliDecompress); + var { + http: httpFollow, + https: httpsFollow + } = followRedirects; + var isHttps = /https:?/; + var supportedProtocols = platform2.protocols.map((protocol) => { + return protocol + ":"; + }); + var flushOnFinish = (stream2, [throttled, flush]) => { + stream2.on("end", flush).on("error", flush); + return throttled; + }; + var Http2Sessions = class { + constructor() { + this.sessions = /* @__PURE__ */ Object.create(null); + } + getSession(authority, options) { + options = Object.assign({ + sessionTimeout: 1e3 + }, options); + let authoritySessions = this.sessions[authority]; + if (authoritySessions) { + let len = authoritySessions.length; + for (let i = 0; i < len; i++) { + const [sessionHandle, sessionOptions] = authoritySessions[i]; + if (!sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options)) { + return sessionHandle; + } + } + } + const session = http2.connect(authority, options); + let removed; + const removeSession = () => { + if (removed) { + return; + } + removed = true; + let entries = authoritySessions, len = entries.length, i = len; + while (i--) { + if (entries[i][0] === session) { + if (len === 1) { + delete this.sessions[authority]; + } else { + entries.splice(i, 1); + } + if (!session.closed) { + session.close(); + } + return; + } + } + }; + const originalRequestFn = session.request; + const { + sessionTimeout + } = options; + if (sessionTimeout != null) { + let timer; + let streamsCount = 0; + session.request = function() { + const stream2 = originalRequestFn.apply(this, arguments); + streamsCount++; + if (timer) { + clearTimeout(timer); + timer = null; + } + stream2.once("close", () => { + if (!--streamsCount) { + timer = setTimeout(() => { + timer = null; + removeSession(); + }, sessionTimeout); + } + }); + return stream2; + }; + } + session.once("close", removeSession); + let entry = [session, options]; + authoritySessions ? authoritySessions.push(entry) : authoritySessions = this.sessions[authority] = [entry]; + return session; + } + }; + var http2Sessions = new Http2Sessions(); + function dispatchBeforeRedirect(options, responseDetails) { + if (options.beforeRedirects.proxy) { + options.beforeRedirects.proxy(options); + } + if (options.beforeRedirects.config) { + options.beforeRedirects.config(options, responseDetails); + } + } + function setProxy(options, configProxy, location) { + let proxy = configProxy; + if (!proxy && proxy !== false) { + const proxyUrl = getProxyForUrl(location); + if (proxyUrl) { + if (!shouldBypassProxy(location)) { + proxy = new URL(proxyUrl); + } + } + } + if (proxy) { + if (proxy.username) { + proxy.auth = (proxy.username || "") + ":" + (proxy.password || ""); + } + if (proxy.auth) { + const validProxyAuth = Boolean(proxy.auth.username || proxy.auth.password); + if (validProxyAuth) { + proxy.auth = (proxy.auth.username || "") + ":" + (proxy.auth.password || ""); + } else if (typeof proxy.auth === "object") { + throw new AxiosError("Invalid proxy authorization", AxiosError.ERR_BAD_OPTION, { + proxy + }); + } + const base64 = Buffer.from(proxy.auth, "utf8").toString("base64"); + options.headers["Proxy-Authorization"] = "Basic " + base64; + } + options.headers.host = options.hostname + (options.port ? ":" + options.port : ""); + const proxyHost = proxy.hostname || proxy.host; + options.hostname = proxyHost; + options.host = proxyHost; + options.port = proxy.port; + options.path = location; + if (proxy.protocol) { + options.protocol = proxy.protocol.includes(":") ? proxy.protocol : `${proxy.protocol}:`; + } + } + options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) { + setProxy(redirectOptions, configProxy, redirectOptions.href); + }; + } + var isHttpAdapterSupported = typeof process !== "undefined" && utils$1.kindOf(process) === "process"; + var wrapAsync = (asyncExecutor) => { + return new Promise((resolve, reject) => { + let onDone; + let isDone; + const done = (value, isRejected) => { + if (isDone) return; + isDone = true; + onDone && onDone(value, isRejected); + }; + const _resolve = (value) => { + done(value); + resolve(value); + }; + const _reject = (reason) => { + done(reason, true); + reject(reason); + }; + asyncExecutor(_resolve, _reject, (onDoneHandler) => onDone = onDoneHandler).catch(_reject); + }); + }; + var resolveFamily = ({ + address, + family + }) => { + if (!utils$1.isString(address)) { + throw TypeError("address must be a string"); + } + return { + address, + family: family || (address.indexOf(".") < 0 ? 6 : 4) + }; + }; + var buildAddressEntry = (address, family) => resolveFamily(utils$1.isObject(address) ? address : { + address, + family + }); + var http2Transport = { + request(options, cb) { + const authority = options.protocol + "//" + options.hostname + ":" + (options.port || (options.protocol === "https:" ? 443 : 80)); + const { + http2Options, + headers + } = options; + const session = http2Sessions.getSession(authority, http2Options); + const { + HTTP2_HEADER_SCHEME, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_STATUS + } = http2.constants; + const http2Headers = { + [HTTP2_HEADER_SCHEME]: options.protocol.replace(":", ""), + [HTTP2_HEADER_METHOD]: options.method, + [HTTP2_HEADER_PATH]: options.path + }; + utils$1.forEach(headers, (header, name) => { + name.charAt(0) !== ":" && (http2Headers[name] = header); + }); + const req = session.request(http2Headers); + req.once("response", (responseHeaders) => { + const response = req; + responseHeaders = Object.assign({}, responseHeaders); + const status = responseHeaders[HTTP2_HEADER_STATUS]; + delete responseHeaders[HTTP2_HEADER_STATUS]; + response.headers = responseHeaders; + response.statusCode = +status; + cb(response); + }); + return req; + } + }; + var httpAdapter = isHttpAdapterSupported && function httpAdapter2(config) { + return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) { + let { + data, + lookup, + family, + httpVersion = 1, + http2Options + } = config; + const { + responseType, + responseEncoding + } = config; + const method = config.method.toUpperCase(); + let isDone; + let rejected = false; + let req; + httpVersion = +httpVersion; + if (Number.isNaN(httpVersion)) { + throw TypeError(`Invalid protocol version: '${config.httpVersion}' is not a number`); + } + if (httpVersion !== 1 && httpVersion !== 2) { + throw TypeError(`Unsupported protocol version '${httpVersion}'`); + } + const isHttp2 = httpVersion === 2; + if (lookup) { + const _lookup = callbackify(lookup, (value) => utils$1.isArray(value) ? value : [value]); + lookup = (hostname, opt, cb) => { + _lookup(hostname, opt, (err, arg0, arg1) => { + if (err) { + return cb(err); + } + const addresses = utils$1.isArray(arg0) ? arg0.map((addr) => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)]; + opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family); + }); + }; + } + const abortEmitter = new events.EventEmitter(); + function abort(reason) { + try { + abortEmitter.emit("abort", !reason || reason.type ? new CanceledError(null, config, req) : reason); + } catch (err) { + console.warn("emit error", err); + } + } + abortEmitter.once("abort", reject); + const onFinished = () => { + if (config.cancelToken) { + config.cancelToken.unsubscribe(abort); + } + if (config.signal) { + config.signal.removeEventListener("abort", abort); + } + abortEmitter.removeAllListeners(); + }; + if (config.cancelToken || config.signal) { + config.cancelToken && config.cancelToken.subscribe(abort); + if (config.signal) { + config.signal.aborted ? abort() : config.signal.addEventListener("abort", abort); + } + } + onDone((response, isRejected) => { + isDone = true; + if (isRejected) { + rejected = true; + onFinished(); + return; + } + const { + data: data2 + } = response; + if (data2 instanceof stream.Readable || data2 instanceof stream.Duplex) { + const offListeners = stream.finished(data2, () => { + offListeners(); + onFinished(); + }); + } else { + onFinished(); + } + }); + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + const parsed = new URL(fullPath, platform2.hasBrowserEnv ? platform2.origin : void 0); + const protocol = parsed.protocol || supportedProtocols[0]; + if (protocol === "data:") { + if (config.maxContentLength > -1) { + const dataUrl = String(config.url || fullPath || ""); + const estimated = estimateDataURLDecodedBytes(dataUrl); + if (estimated > config.maxContentLength) { + return reject(new AxiosError("maxContentLength size of " + config.maxContentLength + " exceeded", AxiosError.ERR_BAD_RESPONSE, config)); + } + } + let convertedData; + if (method !== "GET") { + return settle(resolve, reject, { + status: 405, + statusText: "method not allowed", + headers: {}, + config + }); + } + try { + convertedData = fromDataURI(config.url, responseType === "blob", { + Blob: config.env && config.env.Blob + }); + } catch (err) { + throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config); + } + if (responseType === "text") { + convertedData = convertedData.toString(responseEncoding); + if (!responseEncoding || responseEncoding === "utf8") { + convertedData = utils$1.stripBOM(convertedData); + } + } else if (responseType === "stream") { + convertedData = stream.Readable.from(convertedData); + } + return settle(resolve, reject, { + data: convertedData, + status: 200, + statusText: "OK", + headers: new AxiosHeaders(), + config + }); + } + if (supportedProtocols.indexOf(protocol) === -1) { + return reject(new AxiosError("Unsupported protocol " + protocol, AxiosError.ERR_BAD_REQUEST, config)); + } + const headers = AxiosHeaders.from(config.headers).normalize(); + headers.set("User-Agent", "axios/" + VERSION, false); + const { + onUploadProgress, + onDownloadProgress + } = config; + const maxRate = config.maxRate; + let maxUploadRate = void 0; + let maxDownloadRate = void 0; + if (utils$1.isSpecCompliantForm(data)) { + const userBoundary = headers.getContentType(/boundary=([-_\w\d]{10,70})/i); + data = formDataToStream(data, (formHeaders) => { + headers.set(formHeaders); + }, { + tag: `axios-${VERSION}-boundary`, + boundary: userBoundary && userBoundary[1] || void 0 + }); + } else if (utils$1.isFormData(data) && utils$1.isFunction(data.getHeaders)) { + headers.set(data.getHeaders()); + if (!headers.hasContentLength()) { + try { + const knownLength = await util.promisify(data.getLength).call(data); + Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength); + } catch (e) { + } + } + } else if (utils$1.isBlob(data) || utils$1.isFile(data)) { + data.size && headers.setContentType(data.type || "application/octet-stream"); + headers.setContentLength(data.size || 0); + data = stream.Readable.from(readBlob(data)); + } else if (data && !utils$1.isStream(data)) { + if (Buffer.isBuffer(data)) ; + else if (utils$1.isArrayBuffer(data)) { + data = Buffer.from(new Uint8Array(data)); + } else if (utils$1.isString(data)) { + data = Buffer.from(data, "utf-8"); + } else { + return reject(new AxiosError("Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream", AxiosError.ERR_BAD_REQUEST, config)); + } + headers.setContentLength(data.length, false); + if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) { + return reject(new AxiosError("Request body larger than maxBodyLength limit", AxiosError.ERR_BAD_REQUEST, config)); + } + } + const contentLength = utils$1.toFiniteNumber(headers.getContentLength()); + if (utils$1.isArray(maxRate)) { + maxUploadRate = maxRate[0]; + maxDownloadRate = maxRate[1]; + } else { + maxUploadRate = maxDownloadRate = maxRate; + } + if (data && (onUploadProgress || maxUploadRate)) { + if (!utils$1.isStream(data)) { + data = stream.Readable.from(data, { + objectMode: false + }); + } + data = stream.pipeline([data, new AxiosTransformStream({ + maxRate: utils$1.toFiniteNumber(maxUploadRate) + })], utils$1.noop); + onUploadProgress && data.on("progress", flushOnFinish(data, progressEventDecorator(contentLength, progressEventReducer(asyncDecorator(onUploadProgress), false, 3)))); + } + let auth = void 0; + if (config.auth) { + const username = config.auth.username || ""; + const password = config.auth.password || ""; + auth = username + ":" + password; + } + if (!auth && parsed.username) { + const urlUsername = parsed.username; + const urlPassword = parsed.password; + auth = urlUsername + ":" + urlPassword; + } + auth && headers.delete("authorization"); + let path3; + try { + path3 = buildURL(parsed.pathname + parsed.search, config.params, config.paramsSerializer).replace(/^\?/, ""); + } catch (err) { + const customErr = new Error(err.message); + customErr.config = config; + customErr.url = config.url; + customErr.exists = true; + return reject(customErr); + } + headers.set("Accept-Encoding", "gzip, compress, deflate" + (isBrotliSupported ? ", br" : ""), false); + const options = { + path: path3, + method, + headers: headers.toJSON(), + agents: { + http: config.httpAgent, + https: config.httpsAgent + }, + auth, + protocol, + family, + beforeRedirect: dispatchBeforeRedirect, + beforeRedirects: {}, + http2Options + }; + !utils$1.isUndefined(lookup) && (options.lookup = lookup); + if (config.socketPath) { + options.socketPath = config.socketPath; + } else { + options.hostname = parsed.hostname.startsWith("[") ? parsed.hostname.slice(1, -1) : parsed.hostname; + options.port = parsed.port; + setProxy(options, config.proxy, protocol + "//" + parsed.hostname + (parsed.port ? ":" + parsed.port : "") + options.path); + } + let transport; + const isHttpsRequest = isHttps.test(options.protocol); + options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent; + if (isHttp2) { + transport = http2Transport; + } else { + if (config.transport) { + transport = config.transport; + } else if (config.maxRedirects === 0) { + transport = isHttpsRequest ? https : http; + } else { + if (config.maxRedirects) { + options.maxRedirects = config.maxRedirects; + } + if (config.beforeRedirect) { + options.beforeRedirects.config = config.beforeRedirect; + } + transport = isHttpsRequest ? httpsFollow : httpFollow; + } + } + if (config.maxBodyLength > -1) { + options.maxBodyLength = config.maxBodyLength; + } else { + options.maxBodyLength = Infinity; + } + if (config.insecureHTTPParser) { + options.insecureHTTPParser = config.insecureHTTPParser; + } + req = transport.request(options, function handleResponse(res) { + if (req.destroyed) return; + const streams = [res]; + const responseLength = utils$1.toFiniteNumber(res.headers["content-length"]); + if (onDownloadProgress || maxDownloadRate) { + const transformStream = new AxiosTransformStream({ + maxRate: utils$1.toFiniteNumber(maxDownloadRate) + }); + onDownloadProgress && transformStream.on("progress", flushOnFinish(transformStream, progressEventDecorator(responseLength, progressEventReducer(asyncDecorator(onDownloadProgress), true, 3)))); + streams.push(transformStream); + } + let responseStream = res; + const lastRequest = res.req || req; + if (config.decompress !== false && res.headers["content-encoding"]) { + if (method === "HEAD" || res.statusCode === 204) { + delete res.headers["content-encoding"]; + } + switch ((res.headers["content-encoding"] || "").toLowerCase()) { + /*eslint default-case:0*/ + case "gzip": + case "x-gzip": + case "compress": + case "x-compress": + streams.push(zlib.createUnzip(zlibOptions)); + delete res.headers["content-encoding"]; + break; + case "deflate": + streams.push(new ZlibHeaderTransformStream()); + streams.push(zlib.createUnzip(zlibOptions)); + delete res.headers["content-encoding"]; + break; + case "br": + if (isBrotliSupported) { + streams.push(zlib.createBrotliDecompress(brotliOptions)); + delete res.headers["content-encoding"]; + } + } + } + responseStream = streams.length > 1 ? stream.pipeline(streams, utils$1.noop) : streams[0]; + const response = { + status: res.statusCode, + statusText: res.statusMessage, + headers: new AxiosHeaders(res.headers), + config, + request: lastRequest + }; + if (responseType === "stream") { + response.data = responseStream; + settle(resolve, reject, response); + } else { + const responseBuffer = []; + let totalResponseBytes = 0; + responseStream.on("data", function handleStreamData(chunk) { + responseBuffer.push(chunk); + totalResponseBytes += chunk.length; + if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) { + rejected = true; + responseStream.destroy(); + abort(new AxiosError("maxContentLength size of " + config.maxContentLength + " exceeded", AxiosError.ERR_BAD_RESPONSE, config, lastRequest)); + } + }); + responseStream.on("aborted", function handlerStreamAborted() { + if (rejected) { + return; + } + const err = new AxiosError("stream has been aborted", AxiosError.ERR_BAD_RESPONSE, config, lastRequest); + responseStream.destroy(err); + reject(err); + }); + responseStream.on("error", function handleStreamError(err) { + if (req.destroyed) return; + reject(AxiosError.from(err, null, config, lastRequest)); + }); + responseStream.on("end", function handleStreamEnd() { + try { + let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer); + if (responseType !== "arraybuffer") { + responseData = responseData.toString(responseEncoding); + if (!responseEncoding || responseEncoding === "utf8") { + responseData = utils$1.stripBOM(responseData); + } + } + response.data = responseData; + } catch (err) { + return reject(AxiosError.from(err, null, config, response.request, response)); + } + settle(resolve, reject, response); + }); + } + abortEmitter.once("abort", (err) => { + if (!responseStream.destroyed) { + responseStream.emit("error", err); + responseStream.destroy(); + } + }); + }); + abortEmitter.once("abort", (err) => { + if (req.close) { + req.close(); + } else { + req.destroy(err); + } + }); + req.on("error", function handleRequestError(err) { + reject(AxiosError.from(err, null, config, req)); + }); + req.on("socket", function handleRequestSocket(socket) { + socket.setKeepAlive(true, 1e3 * 60); + }); + if (config.timeout) { + const timeout = parseInt(config.timeout, 10); + if (Number.isNaN(timeout)) { + abort(new AxiosError("error trying to parse `config.timeout` to int", AxiosError.ERR_BAD_OPTION_VALUE, config, req)); + return; + } + req.setTimeout(timeout, function handleRequestTimeout() { + if (isDone) return; + let timeoutErrorMessage = config.timeout ? "timeout of " + config.timeout + "ms exceeded" : "timeout exceeded"; + const transitional = config.transitional || transitionalDefaults; + if (config.timeoutErrorMessage) { + timeoutErrorMessage = config.timeoutErrorMessage; + } + abort(new AxiosError(timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, req)); + }); + } else { + req.setTimeout(0); + } + if (utils$1.isStream(data)) { + let ended = false; + let errored = false; + data.on("end", () => { + ended = true; + }); + data.once("error", (err) => { + errored = true; + req.destroy(err); + }); + data.on("close", () => { + if (!ended && !errored) { + abort(new CanceledError("Request stream has been aborted", config, req)); + } + }); + data.pipe(req); + } else { + data && req.write(data); + req.end(); + } + }); + }; + var isURLSameOrigin = platform2.hasStandardBrowserEnv ? /* @__PURE__ */ ((origin2, isMSIE) => (url2) => { + url2 = new URL(url2, platform2.origin); + return origin2.protocol === url2.protocol && origin2.host === url2.host && (isMSIE || origin2.port === url2.port); + })(new URL(platform2.origin), platform2.navigator && /(msie|trident)/i.test(platform2.navigator.userAgent)) : () => true; + var cookies = platform2.hasStandardBrowserEnv ? ( + // Standard browser envs support document.cookie + { + write(name, value, expires, path3, domain, secure, sameSite) { + if (typeof document === "undefined") return; + const cookie = [`${name}=${encodeURIComponent(value)}`]; + if (utils$1.isNumber(expires)) { + cookie.push(`expires=${new Date(expires).toUTCString()}`); + } + if (utils$1.isString(path3)) { + cookie.push(`path=${path3}`); + } + if (utils$1.isString(domain)) { + cookie.push(`domain=${domain}`); + } + if (secure === true) { + cookie.push("secure"); + } + if (utils$1.isString(sameSite)) { + cookie.push(`SameSite=${sameSite}`); + } + document.cookie = cookie.join("; "); + }, + read(name) { + if (typeof document === "undefined") return null; + const match = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]*)")); + return match ? decodeURIComponent(match[1]) : null; + }, + remove(name) { + this.write(name, "", Date.now() - 864e5, "/"); + } + } + ) : ( + // Non-standard browser env (web workers, react-native) lack needed support. + { + write() { + }, + read() { + return null; + }, + remove() { + } + } + ); + var headersToObject = (thing) => thing instanceof AxiosHeaders ? { + ...thing + } : thing; + function mergeConfig(config1, config2) { + config2 = config2 || {}; + const config = {}; + function getMergedValue(target, source, prop, caseless) { + if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) { + return utils$1.merge.call({ + caseless + }, target, source); + } else if (utils$1.isPlainObject(source)) { + return utils$1.merge({}, source); + } else if (utils$1.isArray(source)) { + return source.slice(); + } + return source; + } + function mergeDeepProperties(a, b, prop, caseless) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(a, b, prop, caseless); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(void 0, a, prop, caseless); + } + } + function valueFromConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(void 0, b); + } + } + function defaultToConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(void 0, b); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(void 0, a); + } + } + function mergeDirectKeys(a, b, prop) { + if (prop in config2) { + return getMergedValue(a, b); + } else if (prop in config1) { + return getMergedValue(void 0, a); + } + } + const mergeMap = { + url: valueFromConfig2, + method: valueFromConfig2, + data: valueFromConfig2, + baseURL: defaultToConfig2, + transformRequest: defaultToConfig2, + transformResponse: defaultToConfig2, + paramsSerializer: defaultToConfig2, + timeout: defaultToConfig2, + timeoutMessage: defaultToConfig2, + withCredentials: defaultToConfig2, + withXSRFToken: defaultToConfig2, + adapter: defaultToConfig2, + responseType: defaultToConfig2, + xsrfCookieName: defaultToConfig2, + xsrfHeaderName: defaultToConfig2, + onUploadProgress: defaultToConfig2, + onDownloadProgress: defaultToConfig2, + decompress: defaultToConfig2, + maxContentLength: defaultToConfig2, + maxBodyLength: defaultToConfig2, + beforeRedirect: defaultToConfig2, + transport: defaultToConfig2, + httpAgent: defaultToConfig2, + httpsAgent: defaultToConfig2, + cancelToken: defaultToConfig2, + socketPath: defaultToConfig2, + responseEncoding: defaultToConfig2, + validateStatus: mergeDirectKeys, + headers: (a, b, prop) => mergeDeepProperties(headersToObject(a), headersToObject(b), prop, true) + }; + utils$1.forEach(Object.keys({ + ...config1, + ...config2 + }), function computeConfigValue(prop) { + if (prop === "__proto__" || prop === "constructor" || prop === "prototype") return; + const merge2 = utils$1.hasOwnProp(mergeMap, prop) ? mergeMap[prop] : mergeDeepProperties; + const configValue = merge2(config1[prop], config2[prop], prop); + utils$1.isUndefined(configValue) && merge2 !== mergeDirectKeys || (config[prop] = configValue); + }); + return config; + } + var resolveConfig = (config) => { + const newConfig = mergeConfig({}, config); + let { + data, + withXSRFToken, + xsrfHeaderName, + xsrfCookieName, + headers, + auth + } = newConfig; + newConfig.headers = headers = AxiosHeaders.from(headers); + newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer); + if (auth) { + headers.set("Authorization", "Basic " + btoa((auth.username || "") + ":" + (auth.password ? unescape(encodeURIComponent(auth.password)) : ""))); + } + if (utils$1.isFormData(data)) { + if (platform2.hasStandardBrowserEnv || platform2.hasStandardBrowserWebWorkerEnv) { + headers.setContentType(void 0); + } else if (utils$1.isFunction(data.getHeaders)) { + const formHeaders = data.getHeaders(); + const allowedHeaders = ["content-type", "content-length"]; + Object.entries(formHeaders).forEach(([key, val]) => { + if (allowedHeaders.includes(key.toLowerCase())) { + headers.set(key, val); + } + }); + } + } + if (platform2.hasStandardBrowserEnv) { + withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); + if (withXSRFToken || withXSRFToken !== false && isURLSameOrigin(newConfig.url)) { + const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); + if (xsrfValue) { + headers.set(xsrfHeaderName, xsrfValue); + } + } + } + return newConfig; + }; + var isXHRAdapterSupported = typeof XMLHttpRequest !== "undefined"; + var xhrAdapter = isXHRAdapterSupported && function(config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + const _config = resolveConfig(config); + let requestData = _config.data; + const requestHeaders = AxiosHeaders.from(_config.headers).normalize(); + let { + responseType, + onUploadProgress, + onDownloadProgress + } = _config; + let onCanceled; + let uploadThrottled, downloadThrottled; + let flushUpload, flushDownload; + function done() { + flushUpload && flushUpload(); + flushDownload && flushDownload(); + _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled); + _config.signal && _config.signal.removeEventListener("abort", onCanceled); + } + let request = new XMLHttpRequest(); + request.open(_config.method.toUpperCase(), _config.url, true); + request.timeout = _config.timeout; + function onloadend() { + if (!request) { + return; + } + const responseHeaders = AxiosHeaders.from("getAllResponseHeaders" in request && request.getAllResponseHeaders()); + const responseData = !responseType || responseType === "text" || responseType === "json" ? request.responseText : request.response; + const response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config, + request + }; + settle(function _resolve(value) { + resolve(value); + done(); + }, function _reject(err) { + reject(err); + done(); + }, response); + request = null; + } + if ("onloadend" in request) { + request.onloadend = onloadend; + } else { + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf("file:") === 0)) { + return; + } + setTimeout(onloadend); + }; + } + request.onabort = function handleAbort() { + if (!request) { + return; + } + reject(new AxiosError("Request aborted", AxiosError.ECONNABORTED, config, request)); + request = null; + }; + request.onerror = function handleError(event) { + const msg = event && event.message ? event.message : "Network Error"; + const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request); + err.event = event || null; + reject(err); + request = null; + }; + request.ontimeout = function handleTimeout() { + let timeoutErrorMessage = _config.timeout ? "timeout of " + _config.timeout + "ms exceeded" : "timeout exceeded"; + const transitional = _config.transitional || transitionalDefaults; + if (_config.timeoutErrorMessage) { + timeoutErrorMessage = _config.timeoutErrorMessage; + } + reject(new AxiosError(timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, request)); + request = null; + }; + requestData === void 0 && requestHeaders.setContentType(null); + if ("setRequestHeader" in request) { + utils$1.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { + request.setRequestHeader(key, val); + }); + } + if (!utils$1.isUndefined(_config.withCredentials)) { + request.withCredentials = !!_config.withCredentials; + } + if (responseType && responseType !== "json") { + request.responseType = _config.responseType; + } + if (onDownloadProgress) { + [downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true); + request.addEventListener("progress", downloadThrottled); + } + if (onUploadProgress && request.upload) { + [uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress); + request.upload.addEventListener("progress", uploadThrottled); + request.upload.addEventListener("loadend", flushUpload); + } + if (_config.cancelToken || _config.signal) { + onCanceled = (cancel) => { + if (!request) { + return; + } + reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel); + request.abort(); + request = null; + }; + _config.cancelToken && _config.cancelToken.subscribe(onCanceled); + if (_config.signal) { + _config.signal.aborted ? onCanceled() : _config.signal.addEventListener("abort", onCanceled); + } + } + const protocol = parseProtocol(_config.url); + if (protocol && platform2.protocols.indexOf(protocol) === -1) { + reject(new AxiosError("Unsupported protocol " + protocol + ":", AxiosError.ERR_BAD_REQUEST, config)); + return; + } + request.send(requestData || null); + }); + }; + var composeSignals = (signals, timeout) => { + const { + length + } = signals = signals ? signals.filter(Boolean) : []; + if (timeout || length) { + let controller = new AbortController(); + let aborted; + const onabort = function(reason) { + if (!aborted) { + aborted = true; + unsubscribe(); + const err = reason instanceof Error ? reason : this.reason; + controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err)); + } + }; + let timer = timeout && setTimeout(() => { + timer = null; + onabort(new AxiosError(`timeout of ${timeout}ms exceeded`, AxiosError.ETIMEDOUT)); + }, timeout); + const unsubscribe = () => { + if (signals) { + timer && clearTimeout(timer); + timer = null; + signals.forEach((signal2) => { + signal2.unsubscribe ? signal2.unsubscribe(onabort) : signal2.removeEventListener("abort", onabort); + }); + signals = null; + } + }; + signals.forEach((signal2) => signal2.addEventListener("abort", onabort)); + const { + signal + } = controller; + signal.unsubscribe = () => utils$1.asap(unsubscribe); + return signal; + } + }; + var streamChunk = function* (chunk, chunkSize) { + let len = chunk.byteLength; + if (len < chunkSize) { + yield chunk; + return; + } + let pos = 0; + let end; + while (pos < len) { + end = pos + chunkSize; + yield chunk.slice(pos, end); + pos = end; + } + }; + var readBytes = async function* (iterable, chunkSize) { + for await (const chunk of readStream(iterable)) { + yield* streamChunk(chunk, chunkSize); + } + }; + var readStream = async function* (stream2) { + if (stream2[Symbol.asyncIterator]) { + yield* stream2; + return; + } + const reader = stream2.getReader(); + try { + for (; ; ) { + const { + done, + value + } = await reader.read(); + if (done) { + break; + } + yield value; + } + } finally { + await reader.cancel(); + } + }; + var trackStream = (stream2, chunkSize, onProgress, onFinish) => { + const iterator2 = readBytes(stream2, chunkSize); + let bytes = 0; + let done; + let _onFinish = (e) => { + if (!done) { + done = true; + onFinish && onFinish(e); + } + }; + return new ReadableStream({ + async pull(controller) { + try { + const { + done: done2, + value + } = await iterator2.next(); + if (done2) { + _onFinish(); + controller.close(); + return; + } + let len = value.byteLength; + if (onProgress) { + let loadedBytes = bytes += len; + onProgress(loadedBytes); + } + controller.enqueue(new Uint8Array(value)); + } catch (err) { + _onFinish(err); + throw err; + } + }, + cancel(reason) { + _onFinish(reason); + return iterator2.return(); + } + }, { + highWaterMark: 2 + }); + }; + var DEFAULT_CHUNK_SIZE = 64 * 1024; + var { + isFunction + } = utils$1; + var globalFetchAPI = (({ + Request, + Response + }) => ({ + Request, + Response + }))(utils$1.global); + var { + ReadableStream: ReadableStream$1, + TextEncoder: TextEncoder$1 + } = utils$1.global; + var test = (fn, ...args) => { + try { + return !!fn(...args); + } catch (e) { + return false; + } + }; + var factory = (env) => { + env = utils$1.merge.call({ + skipUndefined: true + }, globalFetchAPI, env); + const { + fetch: envFetch, + Request, + Response + } = env; + const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === "function"; + const isRequestSupported = isFunction(Request); + const isResponseSupported = isFunction(Response); + if (!isFetchSupported) { + return false; + } + const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream$1); + const encodeText = isFetchSupported && (typeof TextEncoder$1 === "function" ? /* @__PURE__ */ ((encoder) => (str) => encoder.encode(str))(new TextEncoder$1()) : async (str) => new Uint8Array(await new Request(str).arrayBuffer())); + const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => { + let duplexAccessed = false; + const body = new ReadableStream$1(); + const hasContentType = new Request(platform2.origin, { + body, + method: "POST", + get duplex() { + duplexAccessed = true; + return "half"; + } + }).headers.has("Content-Type"); + body.cancel(); + return duplexAccessed && !hasContentType; + }); + const supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(() => utils$1.isReadableStream(new Response("").body)); + const resolvers = { + stream: supportsResponseStream && ((res) => res.body) + }; + isFetchSupported && (() => { + ["text", "arrayBuffer", "blob", "formData", "stream"].forEach((type) => { + !resolvers[type] && (resolvers[type] = (res, config) => { + let method = res && res[type]; + if (method) { + return method.call(res); + } + throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config); + }); + }); + })(); + const getBodyLength = async (body) => { + if (body == null) { + return 0; + } + if (utils$1.isBlob(body)) { + return body.size; + } + if (utils$1.isSpecCompliantForm(body)) { + const _request = new Request(platform2.origin, { + method: "POST", + body + }); + return (await _request.arrayBuffer()).byteLength; + } + if (utils$1.isArrayBufferView(body) || utils$1.isArrayBuffer(body)) { + return body.byteLength; + } + if (utils$1.isURLSearchParams(body)) { + body = body + ""; + } + if (utils$1.isString(body)) { + return (await encodeText(body)).byteLength; + } + }; + const resolveBodyLength = async (headers, body) => { + const length = utils$1.toFiniteNumber(headers.getContentLength()); + return length == null ? getBodyLength(body) : length; + }; + return async (config) => { + let { + url: url2, + method, + data, + signal, + cancelToken, + timeout, + onDownloadProgress, + onUploadProgress, + responseType, + headers, + withCredentials = "same-origin", + fetchOptions + } = resolveConfig(config); + let _fetch = envFetch || fetch; + responseType = responseType ? (responseType + "").toLowerCase() : "text"; + let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout); + let request = null; + const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => { + composedSignal.unsubscribe(); + }); + let requestContentLength; + try { + if (onUploadProgress && supportsRequestStream && method !== "get" && method !== "head" && (requestContentLength = await resolveBodyLength(headers, data)) !== 0) { + let _request = new Request(url2, { + method: "POST", + body: data, + duplex: "half" + }); + let contentTypeHeader; + if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get("content-type"))) { + headers.setContentType(contentTypeHeader); + } + if (_request.body) { + const [onProgress, flush] = progressEventDecorator(requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress))); + data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush); + } + } + if (!utils$1.isString(withCredentials)) { + withCredentials = withCredentials ? "include" : "omit"; + } + const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype; + const resolvedOptions = { + ...fetchOptions, + signal: composedSignal, + method: method.toUpperCase(), + headers: headers.normalize().toJSON(), + body: data, + duplex: "half", + credentials: isCredentialsSupported ? withCredentials : void 0 + }; + request = isRequestSupported && new Request(url2, resolvedOptions); + let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url2, resolvedOptions)); + const isStreamResponse = supportsResponseStream && (responseType === "stream" || responseType === "response"); + if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) { + const options = {}; + ["status", "statusText", "headers"].forEach((prop) => { + options[prop] = response[prop]; + }); + const responseContentLength = utils$1.toFiniteNumber(response.headers.get("content-length")); + const [onProgress, flush] = onDownloadProgress && progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true)) || []; + response = new Response(trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => { + flush && flush(); + unsubscribe && unsubscribe(); + }), options); + } + responseType = responseType || "text"; + let responseData = await resolvers[utils$1.findKey(resolvers, responseType) || "text"](response, config); + !isStreamResponse && unsubscribe && unsubscribe(); + return await new Promise((resolve, reject) => { + settle(resolve, reject, { + data: responseData, + headers: AxiosHeaders.from(response.headers), + status: response.status, + statusText: response.statusText, + config, + request + }); + }); + } catch (err) { + unsubscribe && unsubscribe(); + if (err && err.name === "TypeError" && /Load failed|fetch/i.test(err.message)) { + throw Object.assign(new AxiosError("Network Error", AxiosError.ERR_NETWORK, config, request, err && err.response), { + cause: err.cause || err + }); + } + throw AxiosError.from(err, err && err.code, config, request, err && err.response); + } + }; + }; + var seedCache = /* @__PURE__ */ new Map(); + var getFetch = (config) => { + let env = config && config.env || {}; + const { + fetch: fetch2, + Request, + Response + } = env; + const seeds = [Request, Response, fetch2]; + let len = seeds.length, i = len, seed, target, map = seedCache; + while (i--) { + seed = seeds[i]; + target = map.get(seed); + target === void 0 && map.set(seed, target = i ? /* @__PURE__ */ new Map() : factory(env)); + map = target; + } + return target; + }; + getFetch(); + var knownAdapters = { + http: httpAdapter, + xhr: xhrAdapter, + fetch: { + get: getFetch + } + }; + utils$1.forEach(knownAdapters, (fn, value) => { + if (fn) { + try { + Object.defineProperty(fn, "name", { + value + }); + } catch (e) { + } + Object.defineProperty(fn, "adapterName", { + value + }); + } + }); + var renderReason = (reason) => `- ${reason}`; + var isResolvedHandle = (adapter) => utils$1.isFunction(adapter) || adapter === null || adapter === false; + function getAdapter(adapters2, config) { + adapters2 = utils$1.isArray(adapters2) ? adapters2 : [adapters2]; + const { + length + } = adapters2; + let nameOrAdapter; + let adapter; + const rejectedReasons = {}; + for (let i = 0; i < length; i++) { + nameOrAdapter = adapters2[i]; + let id; + adapter = nameOrAdapter; + if (!isResolvedHandle(nameOrAdapter)) { + adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()]; + if (adapter === void 0) { + throw new AxiosError(`Unknown adapter '${id}'`); + } + } + if (adapter && (utils$1.isFunction(adapter) || (adapter = adapter.get(config)))) { + break; + } + rejectedReasons[id || "#" + i] = adapter; + } + if (!adapter) { + const reasons = Object.entries(rejectedReasons).map(([id, state]) => `adapter ${id} ` + (state === false ? "is not supported by the environment" : "is not available in the build")); + let s = length ? reasons.length > 1 ? "since :\n" + reasons.map(renderReason).join("\n") : " " + renderReason(reasons[0]) : "as no adapter specified"; + throw new AxiosError(`There is no suitable adapter to dispatch the request ` + s, "ERR_NOT_SUPPORT"); + } + return adapter; + } + var adapters = { + /** + * Resolve an adapter from a list of adapter names or functions. + * @type {Function} + */ + getAdapter, + /** + * Exposes all known adapters + * @type {Object} + */ + adapters: knownAdapters + }; + function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); + } + if (config.signal && config.signal.aborted) { + throw new CanceledError(null, config); + } + } + function dispatchRequest(config) { + throwIfCancellationRequested(config); + config.headers = AxiosHeaders.from(config.headers); + config.data = transformData.call(config, config.transformRequest); + if (["post", "put", "patch"].indexOf(config.method) !== -1) { + config.headers.setContentType("application/x-www-form-urlencoded", false); + } + const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config); + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); + response.data = transformData.call(config, config.transformResponse, response); + response.headers = AxiosHeaders.from(response.headers); + return response; + }, function onAdapterRejection(reason) { + if (!isCancel(reason)) { + throwIfCancellationRequested(config); + if (reason && reason.response) { + reason.response.data = transformData.call(config, config.transformResponse, reason.response); + reason.response.headers = AxiosHeaders.from(reason.response.headers); + } + } + return Promise.reject(reason); + }); + } + var validators$1 = {}; + ["object", "boolean", "number", "function", "string", "symbol"].forEach((type, i) => { + validators$1[type] = function validator2(thing) { + return typeof thing === type || "a" + (i < 1 ? "n " : " ") + type; + }; + }); + var deprecatedWarnings = {}; + validators$1.transitional = function transitional(validator2, version4, message) { + function formatMessage(opt, desc) { + return "[Axios v" + VERSION + "] Transitional option '" + opt + "'" + desc + (message ? ". " + message : ""); + } + return (value, opt, opts) => { + if (validator2 === false) { + throw new AxiosError(formatMessage(opt, " has been removed" + (version4 ? " in " + version4 : "")), AxiosError.ERR_DEPRECATED); + } + if (version4 && !deprecatedWarnings[opt]) { + deprecatedWarnings[opt] = true; + console.warn(formatMessage(opt, " has been deprecated since v" + version4 + " and will be removed in the near future")); + } + return validator2 ? validator2(value, opt, opts) : true; + }; + }; + validators$1.spelling = function spelling(correctSpelling) { + return (value, opt) => { + console.warn(`${opt} is likely a misspelling of ${correctSpelling}`); + return true; + }; + }; + function assertOptions(options, schema, allowUnknown) { + if (typeof options !== "object") { + throw new AxiosError("options must be an object", AxiosError.ERR_BAD_OPTION_VALUE); + } + const keys = Object.keys(options); + let i = keys.length; + while (i-- > 0) { + const opt = keys[i]; + const validator2 = schema[opt]; + if (validator2) { + const value = options[opt]; + const result = value === void 0 || validator2(value, opt, options); + if (result !== true) { + throw new AxiosError("option " + opt + " must be " + result, AxiosError.ERR_BAD_OPTION_VALUE); + } + continue; + } + if (allowUnknown !== true) { + throw new AxiosError("Unknown option " + opt, AxiosError.ERR_BAD_OPTION); + } + } + } + var validator = { + assertOptions, + validators: validators$1 + }; + var validators = validator.validators; + var Axios = class { + constructor(instanceConfig) { + this.defaults = instanceConfig || {}; + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager() + }; + } + /** + * Dispatch a request + * + * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults) + * @param {?Object} config + * + * @returns {Promise} The Promise to be fulfilled + */ + async request(configOrUrl, config) { + try { + return await this._request(configOrUrl, config); + } catch (err) { + if (err instanceof Error) { + let dummy = {}; + Error.captureStackTrace ? Error.captureStackTrace(dummy) : dummy = new Error(); + const stack = (() => { + if (!dummy.stack) { + return ""; + } + const firstNewlineIndex = dummy.stack.indexOf("\n"); + return firstNewlineIndex === -1 ? "" : dummy.stack.slice(firstNewlineIndex + 1); + })(); + try { + if (!err.stack) { + err.stack = stack; + } else if (stack) { + const firstNewlineIndex = stack.indexOf("\n"); + const secondNewlineIndex = firstNewlineIndex === -1 ? -1 : stack.indexOf("\n", firstNewlineIndex + 1); + const stackWithoutTwoTopLines = secondNewlineIndex === -1 ? "" : stack.slice(secondNewlineIndex + 1); + if (!String(err.stack).endsWith(stackWithoutTwoTopLines)) { + err.stack += "\n" + stack; + } + } + } catch (e) { + } + } + throw err; + } + } + _request(configOrUrl, config) { + if (typeof configOrUrl === "string") { + config = config || {}; + config.url = configOrUrl; + } else { + config = configOrUrl || {}; + } + config = mergeConfig(this.defaults, config); + const { + transitional, + paramsSerializer, + headers + } = config; + if (transitional !== void 0) { + validator.assertOptions(transitional, { + silentJSONParsing: validators.transitional(validators.boolean), + forcedJSONParsing: validators.transitional(validators.boolean), + clarifyTimeoutError: validators.transitional(validators.boolean), + legacyInterceptorReqResOrdering: validators.transitional(validators.boolean) + }, false); + } + if (paramsSerializer != null) { + if (utils$1.isFunction(paramsSerializer)) { + config.paramsSerializer = { + serialize: paramsSerializer + }; + } else { + validator.assertOptions(paramsSerializer, { + encode: validators.function, + serialize: validators.function + }, true); + } + } + if (config.allowAbsoluteUrls !== void 0) ; + else if (this.defaults.allowAbsoluteUrls !== void 0) { + config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls; + } else { + config.allowAbsoluteUrls = true; + } + validator.assertOptions(config, { + baseUrl: validators.spelling("baseURL"), + withXsrfToken: validators.spelling("withXSRFToken") + }, true); + config.method = (config.method || this.defaults.method || "get").toLowerCase(); + let contextHeaders = headers && utils$1.merge(headers.common, headers[config.method]); + headers && utils$1.forEach(["delete", "get", "head", "post", "put", "patch", "common"], (method) => { + delete headers[method]; + }); + config.headers = AxiosHeaders.concat(contextHeaders, headers); + const requestInterceptorChain = []; + let synchronousRequestInterceptors = true; + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + if (typeof interceptor.runWhen === "function" && interceptor.runWhen(config) === false) { + return; + } + synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; + const transitional2 = config.transitional || transitionalDefaults; + const legacyInterceptorReqResOrdering = transitional2 && transitional2.legacyInterceptorReqResOrdering; + if (legacyInterceptorReqResOrdering) { + requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); + } else { + requestInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); + } + }); + const responseInterceptorChain = []; + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); + }); + let promise; + let i = 0; + let len; + if (!synchronousRequestInterceptors) { + const chain = [dispatchRequest.bind(this), void 0]; + chain.unshift(...requestInterceptorChain); + chain.push(...responseInterceptorChain); + len = chain.length; + promise = Promise.resolve(config); + while (i < len) { + promise = promise.then(chain[i++], chain[i++]); + } + return promise; + } + len = requestInterceptorChain.length; + let newConfig = config; + while (i < len) { + const onFulfilled = requestInterceptorChain[i++]; + const onRejected = requestInterceptorChain[i++]; + try { + newConfig = onFulfilled(newConfig); + } catch (error) { + onRejected.call(this, error); + break; + } + } + try { + promise = dispatchRequest.call(this, newConfig); + } catch (error) { + return Promise.reject(error); + } + i = 0; + len = responseInterceptorChain.length; + while (i < len) { + promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]); + } + return promise; + } + getUri(config) { + config = mergeConfig(this.defaults, config); + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + return buildURL(fullPath, config.params, config.paramsSerializer); + } + }; + utils$1.forEach(["delete", "get", "head", "options"], function forEachMethodNoData(method) { + Axios.prototype[method] = function(url2, config) { + return this.request(mergeConfig(config || {}, { + method, + url: url2, + data: (config || {}).data + })); + }; + }); + utils$1.forEach(["post", "put", "patch"], function forEachMethodWithData(method) { + function generateHTTPMethod(isForm) { + return function httpMethod(url2, data, config) { + return this.request(mergeConfig(config || {}, { + method, + headers: isForm ? { + "Content-Type": "multipart/form-data" + } : {}, + url: url2, + data + })); + }; + } + Axios.prototype[method] = generateHTTPMethod(); + Axios.prototype[method + "Form"] = generateHTTPMethod(true); + }); + var CancelToken = class _CancelToken { + constructor(executor) { + if (typeof executor !== "function") { + throw new TypeError("executor must be a function."); + } + let resolvePromise; + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); + const token = this; + this.promise.then((cancel) => { + if (!token._listeners) return; + let i = token._listeners.length; + while (i-- > 0) { + token._listeners[i](cancel); + } + token._listeners = null; + }); + this.promise.then = (onfulfilled) => { + let _resolve; + const promise = new Promise((resolve) => { + token.subscribe(resolve); + _resolve = resolve; + }).then(onfulfilled); + promise.cancel = function reject() { + token.unsubscribe(_resolve); + }; + return promise; + }; + executor(function cancel(message, config, request) { + if (token.reason) { + return; + } + token.reason = new CanceledError(message, config, request); + resolvePromise(token.reason); + }); + } + /** + * Throws a `CanceledError` if cancellation has been requested. + */ + throwIfRequested() { + if (this.reason) { + throw this.reason; + } + } + /** + * Subscribe to the cancel signal + */ + subscribe(listener) { + if (this.reason) { + listener(this.reason); + return; + } + if (this._listeners) { + this._listeners.push(listener); + } else { + this._listeners = [listener]; + } + } + /** + * Unsubscribe from the cancel signal + */ + unsubscribe(listener) { + if (!this._listeners) { + return; + } + const index = this._listeners.indexOf(listener); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + toAbortSignal() { + const controller = new AbortController(); + const abort = (err) => { + controller.abort(err); + }; + this.subscribe(abort); + controller.signal.unsubscribe = () => this.unsubscribe(abort); + return controller.signal; + } + /** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ + static source() { + let cancel; + const token = new _CancelToken(function executor(c) { + cancel = c; + }); + return { + token, + cancel + }; + } + }; + function spread(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; + } + function isAxiosError(payload) { + return utils$1.isObject(payload) && payload.isAxiosError === true; + } + var HttpStatusCode = { + Continue: 100, + SwitchingProtocols: 101, + Processing: 102, + EarlyHints: 103, + Ok: 200, + Created: 201, + Accepted: 202, + NonAuthoritativeInformation: 203, + NoContent: 204, + ResetContent: 205, + PartialContent: 206, + MultiStatus: 207, + AlreadyReported: 208, + ImUsed: 226, + MultipleChoices: 300, + MovedPermanently: 301, + Found: 302, + SeeOther: 303, + NotModified: 304, + UseProxy: 305, + Unused: 306, + TemporaryRedirect: 307, + PermanentRedirect: 308, + BadRequest: 400, + Unauthorized: 401, + PaymentRequired: 402, + Forbidden: 403, + NotFound: 404, + MethodNotAllowed: 405, + NotAcceptable: 406, + ProxyAuthenticationRequired: 407, + RequestTimeout: 408, + Conflict: 409, + Gone: 410, + LengthRequired: 411, + PreconditionFailed: 412, + PayloadTooLarge: 413, + UriTooLong: 414, + UnsupportedMediaType: 415, + RangeNotSatisfiable: 416, + ExpectationFailed: 417, + ImATeapot: 418, + MisdirectedRequest: 421, + UnprocessableEntity: 422, + Locked: 423, + FailedDependency: 424, + TooEarly: 425, + UpgradeRequired: 426, + PreconditionRequired: 428, + TooManyRequests: 429, + RequestHeaderFieldsTooLarge: 431, + UnavailableForLegalReasons: 451, + InternalServerError: 500, + NotImplemented: 501, + BadGateway: 502, + ServiceUnavailable: 503, + GatewayTimeout: 504, + HttpVersionNotSupported: 505, + VariantAlsoNegotiates: 506, + InsufficientStorage: 507, + LoopDetected: 508, + NotExtended: 510, + NetworkAuthenticationRequired: 511, + WebServerIsDown: 521, + ConnectionTimedOut: 522, + OriginIsUnreachable: 523, + TimeoutOccurred: 524, + SslHandshakeFailed: 525, + InvalidSslCertificate: 526 + }; + Object.entries(HttpStatusCode).forEach(([key, value]) => { + HttpStatusCode[value] = key; + }); + function createInstance(defaultConfig) { + const context = new Axios(defaultConfig); + const instance = bind(Axios.prototype.request, context); + utils$1.extend(instance, Axios.prototype, context, { + allOwnKeys: true + }); + utils$1.extend(instance, context, null, { + allOwnKeys: true + }); + instance.create = function create(instanceConfig) { + return createInstance(mergeConfig(defaultConfig, instanceConfig)); + }; + return instance; + } + var axios = createInstance(defaults); + axios.Axios = Axios; + axios.CanceledError = CanceledError; + axios.CancelToken = CancelToken; + axios.isCancel = isCancel; + axios.VERSION = VERSION; + axios.toFormData = toFormData; + axios.AxiosError = AxiosError; + axios.Cancel = axios.CanceledError; + axios.all = function all(promises) { + return Promise.all(promises); + }; + axios.spread = spread; + axios.isAxiosError = isAxiosError; + axios.mergeConfig = mergeConfig; + axios.AxiosHeaders = AxiosHeaders; + axios.formToJSON = (thing) => formDataToJSON(utils$1.isHTMLForm(thing) ? new FormData(thing) : thing); + axios.getAdapter = adapters.getAdapter; + axios.HttpStatusCode = HttpStatusCode; + axios.default = axios; + module2.exports = axios; + } +}); + +// node_modules/botframework-connector/lib/auth/botFrameworkClientImpl.js +var require_botFrameworkClientImpl = __commonJS({ + "node_modules/botframework-connector/lib/auth/botFrameworkClientImpl.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __rest2 = exports2 && exports2.__rest || function(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotFrameworkClientImpl = void 0; + var z = __importStar2(require_zod()); + var botframework_schema_1 = require_lib4(); + var conversationConstants_1 = require_conversationConstants(); + var connectorFactoryImpl_1 = require_connectorFactoryImpl(); + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var core_rest_pipeline_1 = require_commonjs6(); + var assert_1 = require("assert"); + var axios_1 = __importDefault2(require_axios()); + var botFrameworkClientFetchImpl = (connectorClientOptions) => { + var _a; + const { http: httpAgent, https: httpsAgent } = (_a = connectorClientOptions === null || connectorClientOptions === void 0 ? void 0 : connectorClientOptions.agentSettings) !== null && _a !== void 0 ? _a : { + http: void 0, + https: void 0 + }; + const axiosInstance = axios_1.default.create({ + httpAgent, + httpsAgent, + validateStatus: () => true + }); + return (input, init) => __awaiter2(void 0, void 0, void 0, function* () { + const url = z.string().parse(input); + const { body, headers } = z.object({ body: z.string(), headers: z.record(z.string()).optional() }).parse(init); + const response = yield axiosInstance.post(url, body, { + headers + }); + return { + status: response.status, + json: () => response.data + }; + }); + }; + var BotFrameworkClientImpl = class { + /** + * @param credentialsFactory A [ServiceClientCredentialsFactory](xref:botframework-connector.ServiceClientCredentialsFactory) instance. + * @param loginEndpoint The login url. + * @param botFrameworkClientFetch A custom Fetch implementation to be used in the [BotFrameworkClient](xref:botframework-connector.BotFrameworkClient). + * @param connectorClientOptions A [ConnectorClientOptions](xref:botframework-connector.ConnectorClientOptions) object. + */ + constructor(credentialsFactory, loginEndpoint, botFrameworkClientFetch, connectorClientOptions) { + var _a; + this.credentialsFactory = credentialsFactory; + this.loginEndpoint = loginEndpoint; + this.botFrameworkClientFetch = botFrameworkClientFetch; + this.connectorClientOptions = connectorClientOptions; + (_a = this.botFrameworkClientFetch) !== null && _a !== void 0 ? _a : this.botFrameworkClientFetch = botFrameworkClientFetchImpl(this.connectorClientOptions); + (0, assert_1.ok)(typeof this.botFrameworkClientFetch === "function"); + } + toJSON() { + const _a = this, { connectorClientOptions } = _a, rest = __rest2(_a, ["connectorClientOptions"]); + return rest; + } + /** + * @template T The type of body in the InvokeResponse. + * @param fromBotId The MicrosoftAppId of the bot sending the activity. + * @param toBotId The MicrosoftAppId of the bot receiving the activity. + * @param toUrl The URL of the bot receiving the activity. + * @param serviceUrl The callback Url for the skill host. + * @param conversationId A conversation ID to use for the conversation with the skill. + * @param activity The Activity to send to forward. + * @returns {Promise>} A promise representing the asynchronous operation. + */ + postActivity(fromBotId, toBotId, toUrl, serviceUrl, conversationId, activity) { + return __awaiter2(this, void 0, void 0, function* () { + z.object({ + fromBotId: z.string().optional(), + toBotId: z.string().optional(), + toUrl: z.string(), + serviceUrl: z.string(), + conversationId: z.string(), + activity: z.record(z.unknown()) + }).parse({ + fromBotId, + toBotId, + toUrl, + serviceUrl, + conversationId, + activity + }); + const credentials = yield this.credentialsFactory.createCredentials(fromBotId, toBotId, this.loginEndpoint, true); + const originalConversationId = activity.conversation.id; + const originalServiceUrl = activity.serviceUrl; + const originalRelatesTo = activity.relatesTo; + const originalRecipient = activity.recipient; + try { + activity.relatesTo = { + serviceUrl: activity.serviceUrl, + activityId: activity.id, + channelId: activity.channelId, + conversation: { + id: activity.conversation.id, + name: activity.conversation.name, + conversationType: activity.conversation.conversationType, + aadObjectId: activity.conversation.aadObjectId, + isGroup: activity.conversation.isGroup, + properties: activity.conversation.properties, + role: activity.conversation.role, + tenantId: activity.conversation.tenantId + }, + bot: null + }; + activity.conversation.id = conversationId; + activity.serviceUrl = serviceUrl; + if (!activity.recipient) { + activity.recipient = {}; + } + activity.recipient.role = botframework_schema_1.RoleTypes.Skill; + const webRequest = (0, azureCoreHttpCompat_1.createWebResource)({ + url: toUrl, + method: "POST", + body: JSON.stringify(activity), + headers: (0, core_rest_pipeline_1.createHttpHeaders)({ + Accept: "application/json", + [conversationConstants_1.ConversationIdHttpHeaderName]: conversationId, + "Content-Type": "application/json", + "User-Agent": connectorFactoryImpl_1.USER_AGENT + }) + }); + const request = yield credentials.signRequest(webRequest); + const config = { + body: request.body, + headers: request.headers.rawHeaders() + }; + const response = yield this.botFrameworkClientFetch(request.url, config); + return { status: response.status, body: yield response.json() }; + } finally { + activity.conversation.id = originalConversationId; + activity.serviceUrl = originalServiceUrl; + activity.relatesTo = originalRelatesTo; + activity.recipient = originalRecipient; + } + }); + } + }; + exports2.BotFrameworkClientImpl = BotFrameworkClientImpl; + } +}); + +// node_modules/botframework-connector/lib/tokenApi/models/index.js +var require_models2 = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/models/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-connector/lib/tokenApi/models/mappers.js +var require_mappers2 = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/models/mappers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TokenExchangeRequest = exports2.TokenStatus = exports2.AadResourceUrls = exports2.ErrorResponse = exports2.ErrorModel = exports2.InnerHttpError = exports2.TokenResponse = exports2.SignInUrlResponse = exports2.TokenExchangeResource = void 0; + exports2.TokenExchangeResource = { + serializedName: "TokenExchangeResource", + type: { + name: "Composite", + className: "TokenExchangeResource", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + uri: { + serializedName: "uri", + type: { + name: "String" + } + }, + providerId: { + serializedName: "providerId", + type: { + name: "String" + } + } + } + } + }; + exports2.SignInUrlResponse = { + serializedName: "SignInUrlResponse", + type: { + name: "Composite", + className: "SignInUrlResponse", + modelProperties: { + signInLink: { + serializedName: "signInLink", + type: { + name: "String" + } + }, + tokenExchangeResource: { + serializedName: "tokenExchangeResource", + type: { + name: "Composite", + className: "TokenExchangeResource" + } + } + } + } + }; + exports2.TokenResponse = { + serializedName: "TokenResponse", + type: { + name: "Composite", + className: "TokenResponse", + modelProperties: { + channelId: { + serializedName: "channelId", + type: { + name: "String" + } + }, + connectionName: { + serializedName: "connectionName", + type: { + name: "String" + } + }, + token: { + serializedName: "token", + type: { + name: "String" + } + }, + expiration: { + serializedName: "expiration", + type: { + name: "String" + } + } + } + } + }; + exports2.InnerHttpError = { + serializedName: "InnerHttpError", + type: { + name: "Composite", + className: "InnerHttpError", + modelProperties: { + statusCode: { + serializedName: "statusCode", + type: { + name: "Number" + } + }, + body: { + serializedName: "body", + type: { + name: "Object" + } + } + } + } + }; + exports2.ErrorModel = { + serializedName: "Error", + type: { + name: "Composite", + className: "ErrorModel", + modelProperties: { + code: { + serializedName: "code", + type: { + name: "String" + } + }, + message: { + serializedName: "message", + type: { + name: "String" + } + }, + innerHttpError: { + serializedName: "innerHttpError", + type: { + name: "Composite", + className: "InnerHttpError" + } + } + } + } + }; + exports2.ErrorResponse = { + serializedName: "ErrorResponse", + type: { + name: "Composite", + className: "ErrorResponse", + modelProperties: { + error: { + serializedName: "error", + type: { + name: "Composite", + className: "ErrorModel" + } + } + } + } + }; + exports2.AadResourceUrls = { + serializedName: "AadResourceUrls", + type: { + name: "Composite", + className: "AadResourceUrls", + modelProperties: { + resourceUrls: { + serializedName: "resourceUrls", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + } + } + } + }; + exports2.TokenStatus = { + serializedName: "TokenStatus", + type: { + name: "Composite", + className: "TokenStatus", + modelProperties: { + channelId: { + serializedName: "channelId", + type: { + name: "String" + } + }, + connectionName: { + serializedName: "connectionName", + type: { + name: "String" + } + }, + hasToken: { + serializedName: "hasToken", + type: { + name: "Boolean" + } + }, + serviceProviderDisplayName: { + serializedName: "serviceProviderDisplayName", + type: { + name: "String" + } + } + } + } + }; + exports2.TokenExchangeRequest = { + serializedName: "TokenExchangeRequest", + type: { + name: "Composite", + className: "TokenExchangeRequest", + modelProperties: { + uri: { + serializedName: "uri", + type: { + name: "String" + } + }, + token: { + serializedName: "token", + type: { + name: "String" + } + } + } + } + }; + } +}); + +// node_modules/botframework-connector/lib/tokenApi/models/botSignInMappers.js +var require_botSignInMappers = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/models/botSignInMappers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TokenExchangeResource = exports2.SignInUrlResponse = void 0; + var mappers_1 = require_mappers2(); + Object.defineProperty(exports2, "SignInUrlResponse", { enumerable: true, get: function() { + return mappers_1.SignInUrlResponse; + } }); + Object.defineProperty(exports2, "TokenExchangeResource", { enumerable: true, get: function() { + return mappers_1.TokenExchangeResource; + } }); + } +}); + +// node_modules/botframework-connector/lib/tokenApi/models/parameters.js +var require_parameters2 = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/models/parameters.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.userId = exports2.state = exports2.include = exports2.finalRedirect = exports2.emulatorUrl = exports2.connectionName1 = exports2.connectionName0 = exports2.codeChallenge = exports2.code = exports2.channelId1 = exports2.channelId0 = void 0; + exports2.channelId0 = { + parameterPath: [ + "options", + "channelId" + ], + mapper: { + serializedName: "channelId", + type: { + name: "String" + } + } + }; + exports2.channelId1 = { + parameterPath: "channelId", + mapper: { + required: true, + serializedName: "channelId", + type: { + name: "String" + } + } + }; + exports2.code = { + parameterPath: [ + "options", + "code" + ], + mapper: { + serializedName: "code", + type: { + name: "String" + } + } + }; + exports2.codeChallenge = { + parameterPath: [ + "options", + "codeChallenge" + ], + mapper: { + serializedName: "code_challenge", + type: { + name: "String" + } + } + }; + exports2.connectionName0 = { + parameterPath: "connectionName", + mapper: { + required: true, + serializedName: "connectionName", + type: { + name: "String" + } + } + }; + exports2.connectionName1 = { + parameterPath: [ + "options", + "connectionName" + ], + mapper: { + serializedName: "connectionName", + type: { + name: "String" + } + } + }; + exports2.emulatorUrl = { + parameterPath: [ + "options", + "emulatorUrl" + ], + mapper: { + serializedName: "emulatorUrl", + type: { + name: "String" + } + } + }; + exports2.finalRedirect = { + parameterPath: [ + "options", + "finalRedirect" + ], + mapper: { + serializedName: "finalRedirect", + type: { + name: "String" + } + } + }; + exports2.include = { + parameterPath: [ + "options", + "include" + ], + mapper: { + serializedName: "include", + type: { + name: "String" + } + } + }; + exports2.state = { + parameterPath: "state", + mapper: { + required: true, + serializedName: "state", + type: { + name: "String" + } + } + }; + exports2.userId = { + parameterPath: "userId", + mapper: { + required: true, + serializedName: "userId", + type: { + name: "String" + } + } + }; + } +}); + +// node_modules/botframework-connector/lib/tokenApi/operations/botSignIn.js +var require_botSignIn = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/operations/botSignIn.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotSignIn = void 0; + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var Mappers = __importStar2(require_botSignInMappers()); + var Parameters = __importStar2(require_parameters2()); + var BotSignIn = class { + /** + * Create a BotSignIn. + * @param {TokenApiClientContext} client Reference to the service client. + */ + constructor(client) { + this.client = client; + } + getSignInUrl(state, options, callback) { + return this.client.sendOperationRequest({ + state, + options + }, getSignInUrlOperationSpec, callback); + } + getSignInResource(state, options, callback) { + return this.client.sendOperationRequest({ + state, + options + }, getSignInResourceOperationSpec, callback); + } + }; + exports2.BotSignIn = BotSignIn; + var serializer = (0, azureCoreHttpCompat_1.createSerializer)(Mappers); + var getSignInUrlOperationSpec = { + httpMethod: "GET", + path: "api/botsignin/GetSignInUrl", + queryParameters: [ + Parameters.state, + Parameters.codeChallenge, + Parameters.emulatorUrl, + Parameters.finalRedirect + ], + responses: { + 200: { + bodyMapper: { + serializedName: "parsedResponse", + type: { + name: "String" + } + } + }, + default: {} + }, + serializer + }; + var getSignInResourceOperationSpec = { + httpMethod: "GET", + path: "api/botsignin/GetSignInResource", + queryParameters: [ + Parameters.state, + Parameters.codeChallenge, + Parameters.emulatorUrl, + Parameters.finalRedirect + ], + responses: { + 200: { + bodyMapper: Mappers.SignInUrlResponse + }, + default: {} + }, + serializer + }; + } +}); + +// node_modules/botframework-connector/lib/tokenApi/models/userTokenMappers.js +var require_userTokenMappers = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/models/userTokenMappers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TokenExchangeRequest = exports2.TokenStatus = exports2.AadResourceUrls = exports2.InnerHttpError = exports2.ErrorModel = exports2.ErrorResponse = exports2.TokenResponse = void 0; + var mappers_1 = require_mappers2(); + Object.defineProperty(exports2, "TokenResponse", { enumerable: true, get: function() { + return mappers_1.TokenResponse; + } }); + Object.defineProperty(exports2, "ErrorResponse", { enumerable: true, get: function() { + return mappers_1.ErrorResponse; + } }); + Object.defineProperty(exports2, "ErrorModel", { enumerable: true, get: function() { + return mappers_1.ErrorModel; + } }); + Object.defineProperty(exports2, "InnerHttpError", { enumerable: true, get: function() { + return mappers_1.InnerHttpError; + } }); + Object.defineProperty(exports2, "AadResourceUrls", { enumerable: true, get: function() { + return mappers_1.AadResourceUrls; + } }); + Object.defineProperty(exports2, "TokenStatus", { enumerable: true, get: function() { + return mappers_1.TokenStatus; + } }); + Object.defineProperty(exports2, "TokenExchangeRequest", { enumerable: true, get: function() { + return mappers_1.TokenExchangeRequest; + } }); + } +}); + +// node_modules/botframework-connector/lib/tokenApi/operations/userToken.js +var require_userToken = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/operations/userToken.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.UserToken = void 0; + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var Mappers = __importStar2(require_userTokenMappers()); + var Parameters = __importStar2(require_parameters2()); + var UserToken = class { + /** + * Create a UserToken. + * + * @param {TokenApiClientContext} client Reference to the service client. + */ + constructor(client) { + this.client = client; + } + getToken(userId, connectionName, options, callback) { + return this.client.sendOperationRequest({ + userId, + connectionName, + options + }, getTokenOperationSpec, callback); + } + getAadTokens(userId, connectionName, aadResourceUrls, options, callback) { + return this.client.sendOperationRequest({ + userId, + connectionName, + aadResourceUrls, + options + }, getAadTokensOperationSpec, callback); + } + signOut(userId, options, callback) { + return this.client.sendOperationRequest({ + userId, + options + }, signOutOperationSpec, callback); + } + getTokenStatus(userId, options, callback) { + return this.client.sendOperationRequest({ + userId, + options + }, getTokenStatusOperationSpec, callback); + } + exchangeAsync(userId, connectionName, channelId, exchangeRequest, options, callback) { + return this.client.sendOperationRequest({ + userId, + connectionName, + channelId, + exchangeRequest, + options + }, exchangeAsyncOperationSpec, callback); + } + }; + exports2.UserToken = UserToken; + var serializer = (0, azureCoreHttpCompat_1.createSerializer)(Mappers); + var getTokenOperationSpec = { + httpMethod: "GET", + path: "api/usertoken/GetToken", + queryParameters: [Parameters.userId, Parameters.connectionName0, Parameters.channelId0, Parameters.code], + responses: { + 200: { + bodyMapper: Mappers.TokenResponse + }, + 404: { + bodyMapper: Mappers.TokenResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getAadTokensOperationSpec = { + httpMethod: "POST", + path: "api/usertoken/GetAadTokens", + queryParameters: [Parameters.userId, Parameters.connectionName0, Parameters.channelId0], + requestBody: { + parameterPath: "aadResourceUrls", + mapper: Object.assign(Object.assign({}, Mappers.AadResourceUrls), { required: true }) + }, + responses: { + 200: { + bodyMapper: { + serializedName: "parsedResponse", + type: { + name: "Dictionary", + value: { + type: { + name: "Composite", + className: "TokenResponse" + } + } + } + } + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var signOutOperationSpec = { + httpMethod: "DELETE", + path: "api/usertoken/SignOut", + queryParameters: [Parameters.userId, Parameters.connectionName1, Parameters.channelId0], + responses: { + 200: { + bodyMapper: { + serializedName: "parsedResponse", + type: { + name: "Object" + } + } + }, + 204: {}, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getTokenStatusOperationSpec = { + httpMethod: "GET", + path: "api/usertoken/GetTokenStatus", + queryParameters: [Parameters.userId, Parameters.channelId0, Parameters.include], + responses: { + 200: { + bodyMapper: { + serializedName: "parsedResponse", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "TokenStatus" + } + } + } + } + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var exchangeAsyncOperationSpec = { + httpMethod: "POST", + path: "api/usertoken/exchange", + queryParameters: [Parameters.userId, Parameters.connectionName0, Parameters.channelId1], + requestBody: { + parameterPath: "exchangeRequest", + mapper: Object.assign(Object.assign({}, Mappers.TokenExchangeRequest), { required: true }) + }, + responses: { + 200: { + bodyMapper: Mappers.TokenResponse + }, + 400: { + bodyMapper: Mappers.ErrorResponse + }, + 404: { + bodyMapper: Mappers.TokenResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + } +}); + +// node_modules/botframework-connector/lib/tokenApi/operations/index.js +var require_operations2 = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/operations/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_botSignIn(), exports2); + __exportStar2(require_userToken(), exports2); + } +}); + +// node_modules/botframework-connector/lib/tokenApi/tokenApiClientContext.js +var require_tokenApiClientContext = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/tokenApiClientContext.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TokenApiClientContext = void 0; + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var packageName = "botframework-token"; + var packageVersion = "4.0.0"; + var TokenApiClientContext = class extends azureCoreHttpCompat_1.ServiceClientContext { + /** + * Initializes a new instance of the TokenApiClientContext class. + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials, options) { + super(credentials, Object.assign(Object.assign({}, options), { baseUri: (options === null || options === void 0 ? void 0 : options.baseUri) || "https://token.botframework.com", userAgent: `${packageName}/${packageVersion} ${(options === null || options === void 0 ? void 0 : options.userAgent) || ""}` })); + } + }; + exports2.TokenApiClientContext = TokenApiClientContext; + } +}); + +// node_modules/botframework-connector/lib/tokenApi/tokenApiClient.js +var require_tokenApiClient = __commonJS({ + "node_modules/botframework-connector/lib/tokenApi/tokenApiClient.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TokenApiMappers = exports2.TokenApiModels = exports2.TokenApiClientContext = exports2.TokenApiClient = void 0; + var Models = __importStar2(require_models2()); + exports2.TokenApiModels = Models; + var Mappers = __importStar2(require_mappers2()); + exports2.TokenApiMappers = Mappers; + var operations = __importStar2(require_operations2()); + var tokenApiClientContext_1 = require_tokenApiClientContext(); + Object.defineProperty(exports2, "TokenApiClientContext", { enumerable: true, get: function() { + return tokenApiClientContext_1.TokenApiClientContext; + } }); + var TokenApiClient = class extends tokenApiClientContext_1.TokenApiClientContext { + /** + * Initializes a new instance of the TokenApiClient class. + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials, options) { + super(credentials, options); + this.botSignIn = new operations.BotSignIn(this); + this.userToken = new operations.UserToken(this); + } + }; + exports2.TokenApiClient = TokenApiClient; + __exportStar2(require_operations2(), exports2); + } +}); + +// node_modules/botframework-connector/lib/auth/userTokenClient.js +var require_userTokenClient = __commonJS({ + "node_modules/botframework-connector/lib/auth/userTokenClient.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.UserTokenClient = void 0; + var z = __importStar2(require_zod()); + var botframework_schema_1 = require_lib4(); + var UserTokenClient = class { + /** + * Helper function to create the Base64 encoded token exchange state used in getSignInResource calls. + * + * @param appId The appId to include in the token exchange state. + * @param connectionName The connectionName to include in the token exchange state. + * @param activity The [Activity](xref:botframework-schema.Activity) from which to derive the token exchange state. + * @returns Base64 encoded token exchange state. + */ + static createTokenExchangeState(appId, connectionName, activity) { + z.object({ + appId: z.string(), + connectionName: z.string(), + activity: z.record(z.unknown()) + }).parse({ + appId, + connectionName, + activity + }); + const tokenExchangeState = { + connectionName, + conversation: botframework_schema_1.ActivityEx.getConversationReference(activity), + relatesTo: activity.relatesTo, + msAppId: appId + }; + return Buffer.from(JSON.stringify(tokenExchangeState)).toString("base64"); + } + }; + exports2.UserTokenClient = UserTokenClient; + } +}); + +// node_modules/botframework-connector/lib/auth/userTokenClientImpl.js +var require_userTokenClientImpl = __commonJS({ + "node_modules/botframework-connector/lib/auth/userTokenClientImpl.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.UserTokenClientImpl = void 0; + var z = __importStar2(require_zod()); + var tokenApiClient_1 = require_tokenApiClient(); + var userTokenClient_1 = require_userTokenClient(); + var UserTokenClientImpl = class extends userTokenClient_1.UserTokenClient { + /** + * @param appId The appId. + * @param credentials AppCredentials for OAuth. + * @param oauthEndpoint The OAuth API endpoint. + * @param connectorClientOptions A ConnectorClientOptions object. + */ + constructor(appId, credentials, oauthEndpoint, connectorClientOptions = {}) { + super(); + this.appId = appId; + this.client = new tokenApiClient_1.TokenApiClient(credentials, Object.assign({ baseUri: oauthEndpoint }, connectorClientOptions)); + } + /** + * Attempts to retrieve the token for a user that's in a login flow. + * + * @param userId The user id that will be associated with the token. + * @param connectionName Name of the auth connection to use. + * @param channelId The channel Id that will be associated with the token. + * @param magicCode (Optional) Optional user entered code to validate. + * @returns The token Response. + */ + getUserToken(userId, connectionName, channelId, magicCode) { + return __awaiter2(this, void 0, void 0, function* () { + z.object({ + userId: z.string(), + connectionName: z.string(), + channelId: z.string() + }).parse({ + userId, + connectionName, + channelId + }); + const result = yield this.client.userToken.getToken(userId, connectionName, { channelId, code: magicCode }); + return result._response.parsedBody; + }); + } + /** + * Asynchronously Get the raw signin resource to be sent to the user for signin. + * + * @param connectionName Name of the auth connection to use. + * @param activity The Activity from which to derive the token exchange state. + * @param finalRedirect The final URL that the OAuth flow will redirect to. + * @returns The [SignInUrlResponse](xref:botframework-schema.SignInUrlResponse) resource. + */ + getSignInResource(connectionName, activity, finalRedirect) { + return __awaiter2(this, void 0, void 0, function* () { + z.object({ + activity: z.record(z.unknown()), + connectionName: z.string() + }).parse({ + activity, + connectionName + }); + const result = yield this.client.botSignIn.getSignInResource(userTokenClient_1.UserTokenClient.createTokenExchangeState(this.appId, connectionName, activity), { finalRedirect }); + return result._response.parsedBody; + }); + } + /** + * Signs the user out with the token server. + * + * @param userId The user id that will be associated with the token. + * @param connectionName Name of the auth connection to use. + * @param channelId The channel Id that will be associated with the token. + */ + signOutUser(userId, connectionName, channelId) { + return __awaiter2(this, void 0, void 0, function* () { + z.object({ + userId: z.string(), + connectionName: z.string(), + channelId: z.string() + }).parse({ + userId, + connectionName, + channelId + }); + yield this.client.userToken.signOut(userId, { channelId, connectionName }); + }); + } + /** + * Retrieves the token status for each configured connection for the given user. + * + * @param userId The user id that will be associated with the token. + * @param channelId The channel Id that will be associated with the token. + * @param includeFilter The includeFilter. + * @returns A promise with an Array of the Token Status. + */ + getTokenStatus(userId, channelId, includeFilter) { + return __awaiter2(this, void 0, void 0, function* () { + z.object({ + userId: z.string(), + channelId: z.string() + }).parse({ + userId, + channelId + }); + const result = yield this.client.userToken.getTokenStatus(userId, { + channelId, + include: includeFilter + }); + return result._response.parsedBody; + }); + } + /** + * Retrieves Azure Active Directory tokens for particular resources on a configured connection. + * + * @param userId The user id that will be associated with the token. + * @param connectionName Name of the auth connection to use. + * @param resourceUrls The list of resource URLs to retrieve tokens for. + * @param channelId The channel Id that will be associated with the token. + * @returns A promise of Dictionary of resourceUrl to the corresponding TokenResponse. + */ + getAadTokens(userId, connectionName, resourceUrls, channelId) { + return __awaiter2(this, void 0, void 0, function* () { + z.object({ + userId: z.string(), + connectionName: z.string(), + channelId: z.string() + }).parse({ + userId, + connectionName, + channelId + }); + const result = yield this.client.userToken.getAadTokens(userId, connectionName, { resourceUrls }, { channelId }); + return result._response.parsedBody; + }); + } + /** + * Performs a token exchange operation such as for single sign-on. + * + * @param userId The user id that will be associated with the token. + * @param connectionName Name of the auth connection to use. + * @param channelId The channel Id that will be associated with the token. + * @param exchangeRequest The exchange request details, either a token to exchange or a uri to exchange. + * @returns A promise representing the result of the operation. + */ + exchangeToken(userId, connectionName, channelId, exchangeRequest) { + return __awaiter2(this, void 0, void 0, function* () { + z.object({ + userId: z.string(), + connectionName: z.string(), + channelId: z.string() + }).parse({ + userId, + connectionName, + channelId + }); + const result = yield this.client.userToken.exchangeAsync(userId, connectionName, channelId, exchangeRequest); + return result._response.parsedBody; + }); + } + }; + exports2.UserTokenClientImpl = UserTokenClientImpl; + } +}); + +// node_modules/botframework-connector/lib/auth/parameterizedBotFrameworkAuthentication.js +var require_parameterizedBotFrameworkAuthentication = __commonJS({ + "node_modules/botframework-connector/lib/auth/parameterizedBotFrameworkAuthentication.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ParameterizedBotFrameworkAuthentication = void 0; + var botframework_schema_1 = require_lib4(); + var authenticationConstants_1 = require_authenticationConstants(); + var authenticationError_1 = require_authenticationError(); + var botFrameworkAuthentication_1 = require_botFrameworkAuthentication(); + var connectorFactoryImpl_1 = require_connectorFactoryImpl(); + var botFrameworkClientImpl_1 = require_botFrameworkClientImpl(); + var claimsIdentity_1 = require_claimsIdentity(); + var emulatorValidation_1 = require_emulatorValidation(); + var jwtTokenExtractor_1 = require_jwtTokenExtractor(); + var jwtTokenValidation_1 = require_jwtTokenValidation(); + var skillValidation_1 = require_skillValidation(); + var tokenValidationParameters_1 = require_tokenValidationParameters(); + var userTokenClientImpl_1 = require_userTokenClientImpl(); + var aseChannelValidation_1 = require_aseChannelValidation(); + function getAppId(claimsIdentity) { + var _a, _b; + return (_b = (_a = claimsIdentity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim)) !== null && _a !== void 0 ? _a : claimsIdentity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AppIdClaim)) !== null && _b !== void 0 ? _b : void 0; + } + var ParameterizedBotFrameworkAuthentication = class extends botFrameworkAuthentication_1.BotFrameworkAuthentication { + /** + * @param validateAuthority The validate authority value to use. + * @param toChannelFromBotLoginUrl The to Channel from bot login url. + * @param toChannelFromBotOAuthScope The to Channel from bot oauth scope. + * @param toBotFromChannelTokenIssuer The to bot from Channel Token Issuer. + * @param oAuthUrl The OAuth url. + * @param toBotFromChannelOpenIdMetadataUrl The to bot from Channel Open Id Metadata url. + * @param toBotFromEmulatorOpenIdMetadataUrl The to bot from Emulator Open Id Metadata url. + * @param callerId The callerId set on an authenticated [Activities](xref:botframework-schema.Activity). + * @param credentialsFactory The [ServiceClientCredentialsFactory](xref:botframework-connector.ServiceClientCredentialsFactory) to use to create credentials. + * @param authConfiguration The [AuthenticationConfiguration](xref:botframework-connector.AuthenticationConfiguration) to use. + * @param botFrameworkClientFetch The fetch to use in BotFrameworkClient. + * @param connectorClientOptions The [ConnectorClientOptions](xref:botframework-connector.ConnectorClientOptions) to use when creating ConnectorClients. + */ + constructor(validateAuthority, toChannelFromBotLoginUrl, toChannelFromBotOAuthScope, toBotFromChannelTokenIssuer, oAuthUrl, toBotFromChannelOpenIdMetadataUrl, toBotFromEmulatorOpenIdMetadataUrl, callerId, credentialsFactory, authConfiguration, botFrameworkClientFetch, connectorClientOptions = {}) { + super(); + this.validateAuthority = validateAuthority; + this.toChannelFromBotLoginUrl = toChannelFromBotLoginUrl; + this.toChannelFromBotOAuthScope = toChannelFromBotOAuthScope; + this.toBotFromChannelTokenIssuer = toBotFromChannelTokenIssuer; + this.oAuthUrl = oAuthUrl; + this.toBotFromChannelOpenIdMetadataUrl = toBotFromChannelOpenIdMetadataUrl; + this.toBotFromEmulatorOpenIdMetadataUrl = toBotFromEmulatorOpenIdMetadataUrl; + this.callerId = callerId; + this.credentialsFactory = credentialsFactory; + this.authConfiguration = authConfiguration; + this.botFrameworkClientFetch = botFrameworkClientFetch; + this.connectorClientOptions = connectorClientOptions; + } + /** + * Gets the originating audience from Bot OAuth scope. + * + * @returns The originating audience. + */ + getOriginatingAudience() { + return this.toChannelFromBotOAuthScope; + } + /** + * @param authHeader The http auth header received in the skill request. + * @returns The identity validation result. + */ + authenticateChannelRequest(authHeader) { + return __awaiter2(this, void 0, void 0, function* () { + if (yield this.credentialsFactory.isAuthenticationDisabled()) { + return skillValidation_1.SkillValidation.createAnonymousSkillClaim(); + } else { + if (!authHeader.trim()) { + throw new authenticationError_1.AuthenticationError("Unauthorized Access. Request is not authorized", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return this.JwtTokenValidation_validateAuthHeader(authHeader, "unknown", null); + } + }); + } + /** + * Validate Bot Framework Protocol requests. + * + * @param activity The inbound Activity. + * @param authHeader The http auth header received in the skill request. + * @returns Promise with AuthenticateRequestResult. + */ + authenticateRequest(activity, authHeader) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.JwtTokenValidation_authenticateRequest(activity, authHeader); + const outboundAudience = skillValidation_1.SkillValidation.isSkillClaim(claimsIdentity.claims) ? jwtTokenValidation_1.JwtTokenValidation.getAppIdFromClaims(claimsIdentity.claims) : this.toChannelFromBotOAuthScope; + const callerId = yield this.generateCallerId(this.credentialsFactory, claimsIdentity, this.callerId); + const connectorFactory = new connectorFactoryImpl_1.ConnectorFactoryImpl(getAppId(claimsIdentity), this.toChannelFromBotOAuthScope, this.toChannelFromBotLoginUrl, this.validateAuthority, this.credentialsFactory, this.connectorClientOptions); + return { + audience: outboundAudience, + callerId, + claimsIdentity, + connectorFactory + }; + }); + } + /** + * Validate Bot Framework Protocol requests. + * + * @param authHeader The http auth header received in the skill request. + * @param channelIdHeader The channel Id HTTP header. + * @returns Promise with AuthenticateRequestResult. + */ + authenticateStreamingRequest(authHeader, channelIdHeader) { + return __awaiter2(this, void 0, void 0, function* () { + if (!(channelIdHeader === null || channelIdHeader === void 0 ? void 0 : channelIdHeader.trim()) && !(yield this.credentialsFactory.isAuthenticationDisabled())) { + throw new authenticationError_1.AuthenticationError("'channelIdHeader' required.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const claimsIdentity = yield this.JwtTokenValidation_validateAuthHeader(authHeader, channelIdHeader, null); + const outboundAudience = skillValidation_1.SkillValidation.isSkillClaim(claimsIdentity.claims) ? jwtTokenValidation_1.JwtTokenValidation.getAppIdFromClaims(claimsIdentity.claims) : this.toChannelFromBotOAuthScope; + const callerId = yield this.generateCallerId(this.credentialsFactory, claimsIdentity, this.callerId); + return { audience: outboundAudience, callerId, claimsIdentity }; + }); + } + /** + * Creates the appropriate UserTokenClient instance. + * + * @param claimsIdentity The inbound Activity's ClaimsIdentity. + * @returns Promise with UserTokenClient instance. + */ + createUserTokenClient(claimsIdentity) { + return __awaiter2(this, void 0, void 0, function* () { + const appId = getAppId(claimsIdentity); + const credentials = yield this.credentialsFactory.createCredentials(appId, this.toChannelFromBotOAuthScope, this.toChannelFromBotLoginUrl, this.validateAuthority); + return new userTokenClientImpl_1.UserTokenClientImpl(appId, credentials, this.oAuthUrl, this.connectorClientOptions); + }); + } + /** + * Creates a ConnectorFactory that can be used to create ConnectorClients that can use credentials from this particular Cloud Environment. + * + * @param claimsIdentity The inbound Activity's ClaimsIdentity. + * @returns A ConnectorFactory. + */ + createConnectorFactory(claimsIdentity) { + return new connectorFactoryImpl_1.ConnectorFactoryImpl(getAppId(claimsIdentity), this.toChannelFromBotOAuthScope, this.toChannelFromBotLoginUrl, this.validateAuthority, this.credentialsFactory, this.connectorClientOptions); + } + /** + * Creates a BotFrameworkClient used for calling Skills. + * + * @returns A BotFrameworkClient instance to call Skills. + */ + createBotFrameworkClient() { + return new botFrameworkClientImpl_1.BotFrameworkClientImpl(this.credentialsFactory, this.toChannelFromBotLoginUrl, this.botFrameworkClientFetch, this.connectorClientOptions); + } + JwtTokenValidation_authenticateRequest(activity, authHeader) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + if (yield this.credentialsFactory.isAuthenticationDisabled()) { + if (activity.channelId === botframework_schema_1.Channels.Emulator && ((_a = activity.recipient) === null || _a === void 0 ? void 0 : _a.role) === botframework_schema_1.RoleTypes.Skill) { + return skillValidation_1.SkillValidation.createAnonymousSkillClaim(); + } + return new claimsIdentity_1.ClaimsIdentity([], authenticationConstants_1.AuthenticationConstants.AnonymousAuthType); + } else { + if (!authHeader.trim()) { + throw new authenticationError_1.AuthenticationError("Unauthorized Access. Request is not authorized", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const claimsIdentity = yield this.JwtTokenValidation_validateAuthHeader(authHeader, activity.channelId, activity.serviceUrl); + return claimsIdentity; + } + }); + } + JwtTokenValidation_validateAuthHeader(authHeader, channelId, serviceUrl = "") { + return __awaiter2(this, void 0, void 0, function* () { + const identity = yield this.JwtTokenValidation_authenticateToken(authHeader, channelId, serviceUrl); + yield this.JwtTokenValidation_validateClaims(identity.claims); + return identity; + }); + } + JwtTokenValidation_validateClaims(claims = []) { + return __awaiter2(this, void 0, void 0, function* () { + if (this.authConfiguration.validateClaims) { + yield this.authConfiguration.validateClaims(claims); + } else if (skillValidation_1.SkillValidation.isSkillClaim(claims)) { + throw new authenticationError_1.AuthenticationError("Unauthorized Access. Request is not authorized. Skill Claims require validation.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + }); + } + JwtTokenValidation_authenticateToken(authHeader, channelId, serviceUrl) { + return __awaiter2(this, void 0, void 0, function* () { + if (aseChannelValidation_1.AseChannelValidation.isTokenFromAseChannel(channelId)) { + return aseChannelValidation_1.AseChannelValidation.authenticateAseChannelToken(authHeader); + } + if (skillValidation_1.SkillValidation.isSkillToken(authHeader)) { + return this.SkillValidation_authenticateChannelToken(authHeader, channelId); + } + if (emulatorValidation_1.EmulatorValidation.isTokenFromEmulator(authHeader)) { + return this.EmulatorValidation_authenticateEmulatorToken(authHeader, channelId); + } + return this.ChannelValidation_authenticateChannelToken(authHeader, serviceUrl, channelId); + }); + } + SkillValidation_authenticateChannelToken(authHeader, channelId) { + var _a, _b, _c; + return __awaiter2(this, void 0, void 0, function* () { + const verifyOptions = Object.assign(Object.assign({}, tokenValidationParameters_1.ToBotFromBotOrEmulatorTokenValidationParameters), { issuer: [ + ...tokenValidationParameters_1.ToBotFromBotOrEmulatorTokenValidationParameters.issuer, + ...(_a = this.authConfiguration.validTokenIssuers) !== null && _a !== void 0 ? _a : [] + ] }); + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(verifyOptions, this.toBotFromEmulatorOpenIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms, (_b = this.connectorClientOptions) === null || _b === void 0 ? void 0 : _b.proxySettings, (_c = this.connectorClientOptions) === null || _c === void 0 ? void 0 : _c.tokenRefreshInterval); + const parts = authHeader.split(" "); + const identity = yield tokenExtractor.getIdentity(parts[0], parts[1], channelId, this.authConfiguration.requiredEndorsements); + yield this.SkillValidation_ValidateIdentity(identity); + return identity; + }); + } + SkillValidation_ValidateIdentity(identity) { + return __awaiter2(this, void 0, void 0, function* () { + if (!identity) { + throw new authenticationError_1.AuthenticationError("SkillValidation.validateIdentity(): Invalid identity", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("SkillValidation.validateIdentity(): Token not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const versionClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.VersionClaim); + if (!versionClaim) { + throw new authenticationError_1.AuthenticationError(`SkillValidation.validateIdentity(): '${authenticationConstants_1.AuthenticationConstants.VersionClaim}' claim is required on skill Tokens.`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const audienceClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim); + if (!audienceClaim) { + throw new authenticationError_1.AuthenticationError(`SkillValidation.validateIdentity(): '${authenticationConstants_1.AuthenticationConstants.AudienceClaim}' claim is required on skill Tokens.`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!(yield this.credentialsFactory.isValidAppId(audienceClaim))) { + throw new authenticationError_1.AuthenticationError("SkillValidation.validateIdentity(): Invalid audience.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const appId = jwtTokenValidation_1.JwtTokenValidation.getAppIdFromClaims(identity.claims); + if (!appId) { + throw new authenticationError_1.AuthenticationError("SkillValidation.validateIdentity(): Invalid appId.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + }); + } + EmulatorValidation_authenticateEmulatorToken(authHeader, channelId) { + var _a, _b, _c; + return __awaiter2(this, void 0, void 0, function* () { + const verifyOptions = Object.assign(Object.assign({}, tokenValidationParameters_1.ToBotFromBotOrEmulatorTokenValidationParameters), { issuer: [ + ...tokenValidationParameters_1.ToBotFromBotOrEmulatorTokenValidationParameters.issuer, + ...(_a = this.authConfiguration.validTokenIssuers) !== null && _a !== void 0 ? _a : [] + ] }); + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(verifyOptions, this.toBotFromEmulatorOpenIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms, (_b = this.connectorClientOptions) === null || _b === void 0 ? void 0 : _b.proxySettings, (_c = this.connectorClientOptions) === null || _c === void 0 ? void 0 : _c.tokenRefreshInterval); + const identity = yield tokenExtractor.getIdentityFromAuthHeader(authHeader, channelId, this.authConfiguration.requiredEndorsements); + if (!identity) { + throw new authenticationError_1.AuthenticationError("Unauthorized. No valid identity.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Is not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const versionClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.VersionClaim); + if (versionClaim === null) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "ver" claim is required on Emulator Tokens.', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + let appId = ""; + if (!versionClaim || versionClaim === "1.0") { + const appIdClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AppIdClaim); + if (!appIdClaim) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "appid" claim is required on Emulator Token version "1.0".', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + appId = appIdClaim; + } else if (versionClaim === "2.0") { + const appZClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AuthorizedParty); + if (!appZClaim) { + throw new authenticationError_1.AuthenticationError('Unauthorized. "azp" claim is required on Emulator Token version "2.0".', botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + appId = appZClaim; + } else { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Unknown Emulator Token version "${versionClaim}".`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!(yield this.credentialsFactory.isValidAppId(appId))) { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Invalid AppId passed on token: ${appId}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + return identity; + }); + } + ChannelValidation_authenticateChannelToken(authHeader, serviceUrl, channelId) { + var _a, _b; + return __awaiter2(this, void 0, void 0, function* () { + const tokenValidationParameters = this.ChannelValidation_GetTokenValidationParameters(); + const tokenExtractor = new jwtTokenExtractor_1.JwtTokenExtractor(tokenValidationParameters, this.toBotFromChannelOpenIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.AllowedSigningAlgorithms, (_a = this.connectorClientOptions) === null || _a === void 0 ? void 0 : _a.proxySettings, (_b = this.connectorClientOptions) === null || _b === void 0 ? void 0 : _b.tokenRefreshInterval); + const identity = yield tokenExtractor.getIdentityFromAuthHeader(authHeader, channelId, this.authConfiguration.requiredEndorsements); + return this.governmentChannelValidation_ValidateIdentity(identity, serviceUrl); + }); + } + ChannelValidation_GetTokenValidationParameters() { + return { + issuer: [this.toBotFromChannelTokenIssuer], + audience: void 0, + clockTolerance: 5 * 60, + ignoreExpiration: false + }; + } + governmentChannelValidation_ValidateIdentity(identity, serviceUrl) { + return __awaiter2(this, void 0, void 0, function* () { + if (!identity) { + throw new authenticationError_1.AuthenticationError("Unauthorized. No valid identity.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (!identity.isAuthenticated) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Is not authenticated", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.IssuerClaim) !== this.toBotFromChannelTokenIssuer) { + throw new authenticationError_1.AuthenticationError("Unauthorized. Issuer Claim MUST be present.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + const audClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim); + if (!(yield this.credentialsFactory.isValidAppId(audClaim || ""))) { + throw new authenticationError_1.AuthenticationError(`Unauthorized. Invalid AppId passed on token: ${audClaim}`, botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + if (serviceUrl) { + const serviceUrlClaim = identity.getClaimValue(authenticationConstants_1.AuthenticationConstants.ServiceUrlClaim); + if (serviceUrlClaim !== serviceUrl) { + throw new authenticationError_1.AuthenticationError("Unauthorized. ServiceUrl claim do not match.", botframework_schema_1.StatusCodes.UNAUTHORIZED); + } + } + return identity; + }); + } + }; + exports2.ParameterizedBotFrameworkAuthentication = ParameterizedBotFrameworkAuthentication; + } +}); + +// node_modules/botframework-connector/lib/auth/botFrameworkAuthenticationFactory.js +var require_botFrameworkAuthenticationFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/botFrameworkAuthenticationFactory.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotFrameworkAuthenticationFactory = void 0; + var authenticationConstants_1 = require_authenticationConstants(); + var botframework_schema_1 = require_lib4(); + var governmentConstants_1 = require_governmentConstants(); + var parameterizedBotFrameworkAuthentication_1 = require_parameterizedBotFrameworkAuthentication(); + var botbuilder_stdlib_1 = require_lib5(); + var BotFrameworkAuthenticationFactory = class { + /** + * @param maybeChannelService The Channel Service. + * @param maybeValidateAuthority The validate authority value to use. + * @param maybeToChannelFromBotLoginUrl The to Channel from bot login url. + * @param maybeToChannelFromBotOAuthScope The to Channel from bot oauth scope. + * @param maybeToBotFromChannelTokenIssuer The to bot from Channel Token Issuer. + * @param maybeOAuthUrl The oAuth url. + * @param maybeToBotFromChannelOpenIdMetadataUrl The to bot from Channel Open Id Metadata url. + * @param maybeToBotFromEmulatorOpenIdMetadataUrl The to bot from Emulator Open Id Metadata url. + * @param maybeCallerId The callerId set on on authenticated [Activities](xref:botframework-schema.Activity). + * @param maybeCredentialFactory The [ServiceClientCredentialsFactory](xref:botframework-connector.ServiceClientCredentialsFactory) to use to create credentials. + * @param maybeAuthConfiguration The [AuthenticationConfiguration](xref:botframework-connector.AuthenticationConfiguration) to use. + * @param maybeBotFrameworkClientFetch The fetch to use in BotFrameworkClient. + * @param maybeConnectorClientOptions The [ConnectorClientOptions](xref:botframework-connector.ConnectorClientOptions) to use when creating ConnectorClients. + * @returns A new [BotFrameworkAuthentication](xref:botframework-connector.BotFrameworkAuthentication) instance. + */ + static create(maybeChannelService, maybeValidateAuthority, maybeToChannelFromBotLoginUrl, maybeToChannelFromBotOAuthScope, maybeToBotFromChannelTokenIssuer, maybeOAuthUrl, maybeToBotFromChannelOpenIdMetadataUrl, maybeToBotFromEmulatorOpenIdMetadataUrl, maybeCallerId, maybeCredentialFactory, maybeAuthConfiguration, maybeBotFrameworkClientFetch, maybeConnectorClientOptions = {}) { + if (!botbuilder_stdlib_1.stringExt.isNilOrEmpty(maybeToChannelFromBotLoginUrl) || !botbuilder_stdlib_1.stringExt.isNilOrEmpty(maybeToChannelFromBotOAuthScope) || !botbuilder_stdlib_1.stringExt.isNilOrEmpty(maybeToBotFromChannelTokenIssuer) || !botbuilder_stdlib_1.stringExt.isNilOrEmpty(maybeOAuthUrl) || !botbuilder_stdlib_1.stringExt.isNilOrEmpty(maybeToBotFromChannelOpenIdMetadataUrl) || !botbuilder_stdlib_1.stringExt.isNilOrEmpty(maybeToBotFromEmulatorOpenIdMetadataUrl) || !botbuilder_stdlib_1.stringExt.isNilOrEmpty(maybeCallerId)) { + return new parameterizedBotFrameworkAuthentication_1.ParameterizedBotFrameworkAuthentication(maybeValidateAuthority, maybeToChannelFromBotLoginUrl, maybeToChannelFromBotOAuthScope, maybeToBotFromChannelTokenIssuer, maybeOAuthUrl, maybeToBotFromChannelOpenIdMetadataUrl, maybeToBotFromEmulatorOpenIdMetadataUrl, maybeCallerId, maybeCredentialFactory, maybeAuthConfiguration, maybeBotFrameworkClientFetch, maybeConnectorClientOptions); + } else { + if (botbuilder_stdlib_1.stringExt.isNilOrEmpty(maybeChannelService)) { + return new parameterizedBotFrameworkAuthentication_1.ParameterizedBotFrameworkAuthentication(true, authenticationConstants_1.AuthenticationConstants.ToChannelFromBotLoginUrl, authenticationConstants_1.AuthenticationConstants.ToChannelFromBotOAuthScope, authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer, authenticationConstants_1.AuthenticationConstants.OAuthUrl, authenticationConstants_1.AuthenticationConstants.ToBotFromChannelOpenIdMetadataUrl, authenticationConstants_1.AuthenticationConstants.ToBotFromEmulatorOpenIdMetadataUrl, botframework_schema_1.CallerIdConstants.PublicAzureChannel, maybeCredentialFactory, maybeAuthConfiguration, maybeBotFrameworkClientFetch, maybeConnectorClientOptions); + } else if (maybeChannelService === governmentConstants_1.GovernmentConstants.ChannelService) { + return new parameterizedBotFrameworkAuthentication_1.ParameterizedBotFrameworkAuthentication(true, governmentConstants_1.GovernmentConstants.ToChannelFromBotLoginUrl, governmentConstants_1.GovernmentConstants.ToChannelFromBotOAuthScope, governmentConstants_1.GovernmentConstants.ToBotFromChannelTokenIssuer, governmentConstants_1.GovernmentConstants.OAuthUrl, governmentConstants_1.GovernmentConstants.ToBotFromChannelOpenIdMetadataUrl, governmentConstants_1.GovernmentConstants.ToBotFromEmulatorOpenIdMetadataUrl, botframework_schema_1.CallerIdConstants.USGovChannel, maybeCredentialFactory, maybeAuthConfiguration, maybeBotFrameworkClientFetch, maybeConnectorClientOptions); + } else { + throw new Error("The provided ChannelService value is not supported."); + } + } + } + }; + exports2.BotFrameworkAuthenticationFactory = BotFrameworkAuthenticationFactory; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/rng.js +function rng2() { + if (poolPtr2 > rnds8Pool2.length - 16) { + import_crypto.default.randomFillSync(rnds8Pool2); + poolPtr2 = 0; + } + return rnds8Pool2.slice(poolPtr2, poolPtr2 += 16); +} +var import_crypto, rnds8Pool2, poolPtr2; +var init_rng2 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/rng.js"() { + import_crypto = __toESM(require("crypto")); + rnds8Pool2 = new Uint8Array(256); + poolPtr2 = rnds8Pool2.length; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/regex.js +var regex_default2; +var init_regex2 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/regex.js"() { + regex_default2 = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/validate.js +function validate2(uuid) { + return typeof uuid === "string" && regex_default2.test(uuid); +} +var validate_default2; +var init_validate2 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/validate.js"() { + init_regex2(); + validate_default2 = validate2; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/stringify.js +function stringify2(arr, offset = 0) { + const uuid = (byteToHex2[arr[offset + 0]] + byteToHex2[arr[offset + 1]] + byteToHex2[arr[offset + 2]] + byteToHex2[arr[offset + 3]] + "-" + byteToHex2[arr[offset + 4]] + byteToHex2[arr[offset + 5]] + "-" + byteToHex2[arr[offset + 6]] + byteToHex2[arr[offset + 7]] + "-" + byteToHex2[arr[offset + 8]] + byteToHex2[arr[offset + 9]] + "-" + byteToHex2[arr[offset + 10]] + byteToHex2[arr[offset + 11]] + byteToHex2[arr[offset + 12]] + byteToHex2[arr[offset + 13]] + byteToHex2[arr[offset + 14]] + byteToHex2[arr[offset + 15]]).toLowerCase(); + if (!validate_default2(uuid)) { + throw TypeError("Stringified UUID is invalid"); + } + return uuid; +} +var byteToHex2, stringify_default2; +var init_stringify2 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/stringify.js"() { + init_validate2(); + byteToHex2 = []; + for (let i = 0; i < 256; ++i) { + byteToHex2.push((i + 256).toString(16).substr(1)); + } + stringify_default2 = stringify2; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v1.js +function v12(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId2; + let clockseq = options.clockseq !== void 0 ? options.clockseq : _clockseq2; + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || rng2)(); + if (node == null) { + node = _nodeId2 = [seedBytes[0] | 1, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + if (clockseq == null) { + clockseq = _clockseq2 = (seedBytes[6] << 8 | seedBytes[7]) & 16383; + } + } + let msecs = options.msecs !== void 0 ? options.msecs : Date.now(); + let nsecs = options.nsecs !== void 0 ? options.nsecs : _lastNSecs2 + 1; + const dt = msecs - _lastMSecs2 + (nsecs - _lastNSecs2) / 1e4; + if (dt < 0 && options.clockseq === void 0) { + clockseq = clockseq + 1 & 16383; + } + if ((dt < 0 || msecs > _lastMSecs2) && options.nsecs === void 0) { + nsecs = 0; + } + if (nsecs >= 1e4) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + _lastMSecs2 = msecs; + _lastNSecs2 = nsecs; + _clockseq2 = clockseq; + msecs += 122192928e5; + const tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296; + b[i++] = tl >>> 24 & 255; + b[i++] = tl >>> 16 & 255; + b[i++] = tl >>> 8 & 255; + b[i++] = tl & 255; + const tmh = msecs / 4294967296 * 1e4 & 268435455; + b[i++] = tmh >>> 8 & 255; + b[i++] = tmh & 255; + b[i++] = tmh >>> 24 & 15 | 16; + b[i++] = tmh >>> 16 & 255; + b[i++] = clockseq >>> 8 | 128; + b[i++] = clockseq & 255; + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + return buf || stringify_default2(b); +} +var _nodeId2, _clockseq2, _lastMSecs2, _lastNSecs2, v1_default2; +var init_v12 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v1.js"() { + init_rng2(); + init_stringify2(); + _lastMSecs2 = 0; + _lastNSecs2 = 0; + v1_default2 = v12; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/parse.js +function parse2(uuid) { + if (!validate_default2(uuid)) { + throw TypeError("Invalid UUID"); + } + let v; + const arr = new Uint8Array(16); + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 255; + arr[2] = v >>> 8 & 255; + arr[3] = v & 255; + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 255; + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 255; + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 255; + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255; + arr[11] = v / 4294967296 & 255; + arr[12] = v >>> 24 & 255; + arr[13] = v >>> 16 & 255; + arr[14] = v >>> 8 & 255; + arr[15] = v & 255; + return arr; +} +var parse_default2; +var init_parse2 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/parse.js"() { + init_validate2(); + parse_default2 = parse2; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v35.js +function stringToBytes2(str) { + str = unescape(encodeURIComponent(str)); + const bytes = []; + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + return bytes; +} +function v35_default(name, version4, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === "string") { + value = stringToBytes2(value); + } + if (typeof namespace === "string") { + namespace = parse_default2(namespace); + } + if (namespace.length !== 16) { + throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)"); + } + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 15 | version4; + bytes[8] = bytes[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + return buf; + } + return stringify_default2(bytes); + } + try { + generateUUID.name = name; + } catch (err) { + } + generateUUID.DNS = DNS2; + generateUUID.URL = URL3; + return generateUUID; +} +var DNS2, URL3; +var init_v352 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v35.js"() { + init_stringify2(); + init_parse2(); + DNS2 = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; + URL3 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/md5.js +function md52(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return import_crypto2.default.createHash("md5").update(bytes).digest(); +} +var import_crypto2, md5_default2; +var init_md52 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/md5.js"() { + import_crypto2 = __toESM(require("crypto")); + md5_default2 = md52; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v3.js +var v32, v3_default2; +var init_v32 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v3.js"() { + init_v352(); + init_md52(); + v32 = v35_default("v3", 48, md5_default2); + v3_default2 = v32; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v4.js +function v42(options, buf, offset) { + options = options || {}; + const rnds = options.random || (options.rng || rng2)(); + rnds[6] = rnds[6] & 15 | 64; + rnds[8] = rnds[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + return buf; + } + return stringify_default2(rnds); +} +var v4_default2; +var init_v42 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v4.js"() { + init_rng2(); + init_stringify2(); + v4_default2 = v42; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/sha1.js +function sha12(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return import_crypto3.default.createHash("sha1").update(bytes).digest(); +} +var import_crypto3, sha1_default2; +var init_sha12 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/sha1.js"() { + import_crypto3 = __toESM(require("crypto")); + sha1_default2 = sha12; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v5.js +var v52, v5_default2; +var init_v52 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/v5.js"() { + init_v352(); + init_sha12(); + v52 = v35_default("v5", 80, sha1_default2); + v5_default2 = v52; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/nil.js +var nil_default2; +var init_nil2 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/nil.js"() { + nil_default2 = "00000000-0000-0000-0000-000000000000"; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/version.js +function version2(uuid) { + if (!validate_default2(uuid)) { + throw TypeError("Invalid UUID"); + } + return parseInt(uuid.substr(14, 1), 16); +} +var version_default2; +var init_version2 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/version.js"() { + init_validate2(); + version_default2 = version2; + } +}); + +// node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/index.js +var esm_node_exports2 = {}; +__export(esm_node_exports2, { + NIL: () => nil_default2, + parse: () => parse_default2, + stringify: () => stringify_default2, + v1: () => v1_default2, + v3: () => v3_default2, + v4: () => v4_default2, + v5: () => v5_default2, + validate: () => validate_default2, + version: () => version_default2 +}); +var init_esm_node2 = __esm({ + "node_modules/@azure/msal-node/node_modules/uuid/dist/esm-node/index.js"() { + init_v12(); + init_v32(); + init_v42(); + init_v52(); + init_nil2(); + init_version2(); + init_validate2(); + init_stringify2(); + init_parse2(); + } +}); + +// node_modules/@azure/msal-node/lib/msal-node.cjs +var require_msal_node = __commonJS({ + "node_modules/@azure/msal-node/lib/msal-node.cjs"(exports2) { + "use strict"; + var http = require("http"); + var https = require("https"); + var uuid = (init_esm_node2(), __toCommonJS(esm_node_exports2)); + var crypto12 = require("crypto"); + var jwt = require_jsonwebtoken(); + var fs6 = require("fs"); + var path3 = require("path"); + var Serializer = class { + /** + * serialize the JSON blob + * @param data - JSON blob cache + */ + static serializeJSONBlob(data) { + return JSON.stringify(data); + } + /** + * Serialize Accounts + * @param accCache - cache of accounts + */ + static serializeAccounts(accCache) { + const accounts = {}; + Object.keys(accCache).map(function(key) { + const accountEntity = accCache[key]; + accounts[key] = { + home_account_id: accountEntity.homeAccountId, + environment: accountEntity.environment, + realm: accountEntity.realm, + local_account_id: accountEntity.localAccountId, + username: accountEntity.username, + authority_type: accountEntity.authorityType, + name: accountEntity.name, + client_info: accountEntity.clientInfo, + last_modification_time: accountEntity.lastModificationTime, + last_modification_app: accountEntity.lastModificationApp, + tenantProfiles: accountEntity.tenantProfiles?.map((tenantProfile) => { + return JSON.stringify(tenantProfile); + }) + }; + }); + return accounts; + } + /** + * Serialize IdTokens + * @param idTCache - cache of ID tokens + */ + static serializeIdTokens(idTCache) { + const idTokens = {}; + Object.keys(idTCache).map(function(key) { + const idTEntity = idTCache[key]; + idTokens[key] = { + home_account_id: idTEntity.homeAccountId, + environment: idTEntity.environment, + credential_type: idTEntity.credentialType, + client_id: idTEntity.clientId, + secret: idTEntity.secret, + realm: idTEntity.realm + }; + }); + return idTokens; + } + /** + * Serializes AccessTokens + * @param atCache - cache of access tokens + */ + static serializeAccessTokens(atCache) { + const accessTokens = {}; + Object.keys(atCache).map(function(key) { + const atEntity = atCache[key]; + accessTokens[key] = { + home_account_id: atEntity.homeAccountId, + environment: atEntity.environment, + credential_type: atEntity.credentialType, + client_id: atEntity.clientId, + secret: atEntity.secret, + realm: atEntity.realm, + target: atEntity.target, + cached_at: atEntity.cachedAt, + expires_on: atEntity.expiresOn, + extended_expires_on: atEntity.extendedExpiresOn, + refresh_on: atEntity.refreshOn, + key_id: atEntity.keyId, + token_type: atEntity.tokenType, + requestedClaims: atEntity.requestedClaims, + requestedClaimsHash: atEntity.requestedClaimsHash, + userAssertionHash: atEntity.userAssertionHash + }; + }); + return accessTokens; + } + /** + * Serialize refreshTokens + * @param rtCache - cache of refresh tokens + */ + static serializeRefreshTokens(rtCache) { + const refreshTokens = {}; + Object.keys(rtCache).map(function(key) { + const rtEntity = rtCache[key]; + refreshTokens[key] = { + home_account_id: rtEntity.homeAccountId, + environment: rtEntity.environment, + credential_type: rtEntity.credentialType, + client_id: rtEntity.clientId, + secret: rtEntity.secret, + family_id: rtEntity.familyId, + target: rtEntity.target, + realm: rtEntity.realm + }; + }); + return refreshTokens; + } + /** + * Serialize amdtCache + * @param amdtCache - cache of app metadata + */ + static serializeAppMetadata(amdtCache) { + const appMetadata = {}; + Object.keys(amdtCache).map(function(key) { + const amdtEntity = amdtCache[key]; + appMetadata[key] = { + client_id: amdtEntity.clientId, + environment: amdtEntity.environment, + family_id: amdtEntity.familyId + }; + }); + return appMetadata; + } + /** + * Serialize the cache + * @param inMemCache - itemised cache read from the JSON + */ + static serializeAllCache(inMemCache) { + return { + Account: this.serializeAccounts(inMemCache.accounts), + IdToken: this.serializeIdTokens(inMemCache.idTokens), + AccessToken: this.serializeAccessTokens(inMemCache.accessTokens), + RefreshToken: this.serializeRefreshTokens(inMemCache.refreshTokens), + AppMetadata: this.serializeAppMetadata(inMemCache.appMetadata) + }; + } + }; + var Constants$1 = { + LIBRARY_NAME: "MSAL.JS", + SKU: "msal.js.common", + // Prefix for all library cache entries + CACHE_PREFIX: "msal", + // default authority + DEFAULT_AUTHORITY: "https://login.microsoftonline.com/common/", + DEFAULT_AUTHORITY_HOST: "login.microsoftonline.com", + DEFAULT_COMMON_TENANT: "common", + // ADFS String + ADFS: "adfs", + DSTS: "dstsv2", + // Default AAD Instance Discovery Endpoint + AAD_INSTANCE_DISCOVERY_ENDPT: "https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=", + // CIAM URL + CIAM_AUTH_URL: ".ciamlogin.com", + AAD_TENANT_DOMAIN_SUFFIX: ".onmicrosoft.com", + // Resource delimiter - used for certain cache entries + RESOURCE_DELIM: "|", + // Placeholder for non-existent account ids/objects + NO_ACCOUNT: "NO_ACCOUNT", + // Claims + CLAIMS: "claims", + // Consumer UTID + CONSUMER_UTID: "9188040d-6c67-4c5b-b112-36a304b66dad", + // Default scopes + OPENID_SCOPE: "openid", + PROFILE_SCOPE: "profile", + OFFLINE_ACCESS_SCOPE: "offline_access", + EMAIL_SCOPE: "email", + // Default response type for authorization code flow + CODE_RESPONSE_TYPE: "code", + CODE_GRANT_TYPE: "authorization_code", + RT_GRANT_TYPE: "refresh_token", + FRAGMENT_RESPONSE_MODE: "fragment", + S256_CODE_CHALLENGE_METHOD: "S256", + URL_FORM_CONTENT_TYPE: "application/x-www-form-urlencoded;charset=utf-8", + AUTHORIZATION_PENDING: "authorization_pending", + NOT_DEFINED: "not_defined", + EMPTY_STRING: "", + NOT_APPLICABLE: "N/A", + NOT_AVAILABLE: "Not Available", + FORWARD_SLASH: "/", + IMDS_ENDPOINT: "http://169.254.169.254/metadata/instance/compute/location", + IMDS_VERSION: "2020-06-01", + IMDS_TIMEOUT: 2e3, + AZURE_REGION_AUTO_DISCOVER_FLAG: "TryAutoDetect", + REGIONAL_AUTH_PUBLIC_CLOUD_SUFFIX: "login.microsoft.com", + KNOWN_PUBLIC_CLOUDS: [ + "login.microsoftonline.com", + "login.windows.net", + "login.microsoft.com", + "sts.windows.net" + ], + TOKEN_RESPONSE_TYPE: "token", + ID_TOKEN_RESPONSE_TYPE: "id_token", + SHR_NONCE_VALIDITY: 240, + INVALID_INSTANCE: "invalid_instance" + }; + var HttpStatus = { + SUCCESS_RANGE_START: 200, + SUCCESS_RANGE_END: 299, + REDIRECT: 302, + CLIENT_ERROR_RANGE_START: 400, + UNAUTHORIZED: 401, + NOT_FOUND: 404, + REQUEST_TIMEOUT: 408, + TOO_MANY_REQUESTS: 429, + CLIENT_ERROR_RANGE_END: 499, + SERVER_ERROR: 500, + SERVER_ERROR_RANGE_START: 500, + SERVICE_UNAVAILABLE: 503, + GATEWAY_TIMEOUT: 504, + SERVER_ERROR_RANGE_END: 599 + }; + var OIDC_DEFAULT_SCOPES = [ + Constants$1.OPENID_SCOPE, + Constants$1.PROFILE_SCOPE, + Constants$1.OFFLINE_ACCESS_SCOPE + ]; + var OIDC_SCOPES = [...OIDC_DEFAULT_SCOPES, Constants$1.EMAIL_SCOPE]; + var HeaderNames = { + CONTENT_TYPE: "Content-Type", + CONTENT_LENGTH: "Content-Length", + RETRY_AFTER: "Retry-After", + CCS_HEADER: "X-AnchorMailbox", + WWWAuthenticate: "WWW-Authenticate", + AuthenticationInfo: "Authentication-Info", + X_MS_REQUEST_ID: "x-ms-request-id", + X_MS_HTTP_VERSION: "x-ms-httpver" + }; + var AADAuthorityConstants = { + COMMON: "common", + ORGANIZATIONS: "organizations", + CONSUMERS: "consumers" + }; + var ClaimsRequestKeys = { + ACCESS_TOKEN: "access_token", + XMS_CC: "xms_cc" + }; + var PromptValue = { + LOGIN: "login", + SELECT_ACCOUNT: "select_account", + CONSENT: "consent", + NONE: "none", + CREATE: "create", + NO_SESSION: "no_session" + }; + var CodeChallengeMethodValues = { + PLAIN: "plain", + S256: "S256" + }; + var ServerResponseType = { + QUERY: "query", + FRAGMENT: "fragment" + }; + var ResponseMode = { + ...ServerResponseType, + FORM_POST: "form_post" + }; + var GrantType = { + AUTHORIZATION_CODE_GRANT: "authorization_code", + CLIENT_CREDENTIALS_GRANT: "client_credentials", + RESOURCE_OWNER_PASSWORD_GRANT: "password", + REFRESH_TOKEN_GRANT: "refresh_token", + DEVICE_CODE_GRANT: "device_code", + JWT_BEARER: "urn:ietf:params:oauth:grant-type:jwt-bearer" + }; + var CacheAccountType = { + MSSTS_ACCOUNT_TYPE: "MSSTS", + ADFS_ACCOUNT_TYPE: "ADFS", + GENERIC_ACCOUNT_TYPE: "Generic" + // NTLM, Kerberos, FBA, Basic etc + }; + var Separators = { + CACHE_KEY_SEPARATOR: "-", + CLIENT_INFO_SEPARATOR: "." + }; + var CredentialType = { + ID_TOKEN: "IdToken", + ACCESS_TOKEN: "AccessToken", + ACCESS_TOKEN_WITH_AUTH_SCHEME: "AccessToken_With_AuthScheme", + REFRESH_TOKEN: "RefreshToken" + }; + var APP_METADATA = "appmetadata"; + var CLIENT_INFO = "client_info"; + var THE_FAMILY_ID = "1"; + var AUTHORITY_METADATA_CONSTANTS = { + CACHE_KEY: "authority-metadata", + REFRESH_TIME_SECONDS: 3600 * 24 + // 24 Hours + }; + var AuthorityMetadataSource = { + CONFIG: "config", + CACHE: "cache", + NETWORK: "network", + HARDCODED_VALUES: "hardcoded_values" + }; + var SERVER_TELEM_CONSTANTS = { + SCHEMA_VERSION: 5, + MAX_LAST_HEADER_BYTES: 330, + MAX_CACHED_ERRORS: 50, + CACHE_KEY: "server-telemetry", + CATEGORY_SEPARATOR: "|", + VALUE_SEPARATOR: ",", + OVERFLOW_TRUE: "1", + OVERFLOW_FALSE: "0", + UNKNOWN_ERROR: "unknown_error" + }; + var AuthenticationScheme = { + BEARER: "Bearer", + POP: "pop", + SSH: "ssh-cert" + }; + var ThrottlingConstants = { + // Default time to throttle RequestThumbprint in seconds + DEFAULT_THROTTLE_TIME_SECONDS: 60, + // Default maximum time to throttle in seconds, overrides what the server sends back + DEFAULT_MAX_THROTTLE_TIME_SECONDS: 3600, + // Prefix for storing throttling entries + THROTTLING_PREFIX: "throttling", + // Value assigned to the x-ms-lib-capability header to indicate to the server the library supports throttling + X_MS_LIB_CAPABILITY_VALUE: "retry-after, h429" + }; + var Errors = { + INVALID_GRANT_ERROR: "invalid_grant", + CLIENT_MISMATCH_ERROR: "client_mismatch" + }; + var PasswordGrantConstants = { + username: "username", + password: "password" + }; + var ResponseCodes = { + httpSuccess: 200, + httpBadRequest: 400 + }; + var RegionDiscoverySources = { + FAILED_AUTO_DETECTION: "1", + INTERNAL_CACHE: "2", + ENVIRONMENT_VARIABLE: "3", + IMDS: "4" + }; + var RegionDiscoveryOutcomes = { + CONFIGURED_NO_AUTO_DETECTION: "2", + AUTO_DETECTION_REQUESTED_SUCCESSFUL: "4", + AUTO_DETECTION_REQUESTED_FAILED: "5" + }; + var CacheOutcome = { + // When a token is found in the cache or the cache is not supposed to be hit when making the request + NOT_APPLICABLE: "0", + // When the token request goes to the identity provider because force_refresh was set to true. Also occurs if claims were requested + FORCE_REFRESH_OR_CLAIMS: "1", + // When the token request goes to the identity provider because no cached access token exists + NO_CACHED_ACCESS_TOKEN: "2", + // When the token request goes to the identity provider because cached access token expired + CACHED_ACCESS_TOKEN_EXPIRED: "3", + // When the token request goes to the identity provider because refresh_in was used and the existing token needs to be refreshed + PROACTIVELY_REFRESHED: "4" + }; + var DEFAULT_TOKEN_RENEWAL_OFFSET_SEC = 300; + var unexpectedError = "unexpected_error"; + var postRequestFailed = "post_request_failed"; + var AuthErrorCodes = /* @__PURE__ */ Object.freeze({ + __proto__: null, + postRequestFailed, + unexpectedError + }); + var AuthErrorMessages = { + [unexpectedError]: "Unexpected error in authentication.", + [postRequestFailed]: "Post request failed from the network, could be a 4xx/5xx or a network unavailability. Please check the exact error code for details." + }; + var AuthErrorMessage = { + unexpectedError: { + code: unexpectedError, + desc: AuthErrorMessages[unexpectedError] + }, + postRequestFailed: { + code: postRequestFailed, + desc: AuthErrorMessages[postRequestFailed] + } + }; + var AuthError = class _AuthError extends Error { + constructor(errorCode, errorMessage, suberror) { + const errorString = errorMessage ? `${errorCode}: ${errorMessage}` : errorCode; + super(errorString); + Object.setPrototypeOf(this, _AuthError.prototype); + this.errorCode = errorCode || Constants$1.EMPTY_STRING; + this.errorMessage = errorMessage || Constants$1.EMPTY_STRING; + this.subError = suberror || Constants$1.EMPTY_STRING; + this.name = "AuthError"; + } + setCorrelationId(correlationId) { + this.correlationId = correlationId; + } + }; + function createAuthError(code, additionalMessage) { + return new AuthError(code, additionalMessage ? `${AuthErrorMessages[code]} ${additionalMessage}` : AuthErrorMessages[code]); + } + var clientInfoDecodingError = "client_info_decoding_error"; + var clientInfoEmptyError = "client_info_empty_error"; + var tokenParsingError = "token_parsing_error"; + var nullOrEmptyToken = "null_or_empty_token"; + var endpointResolutionError = "endpoints_resolution_error"; + var networkError = "network_error"; + var openIdConfigError = "openid_config_error"; + var hashNotDeserialized = "hash_not_deserialized"; + var invalidState = "invalid_state"; + var stateMismatch = "state_mismatch"; + var stateNotFound = "state_not_found"; + var nonceMismatch = "nonce_mismatch"; + var authTimeNotFound = "auth_time_not_found"; + var maxAgeTranspired = "max_age_transpired"; + var multipleMatchingTokens = "multiple_matching_tokens"; + var multipleMatchingAccounts = "multiple_matching_accounts"; + var multipleMatchingAppMetadata = "multiple_matching_appMetadata"; + var requestCannotBeMade = "request_cannot_be_made"; + var cannotRemoveEmptyScope = "cannot_remove_empty_scope"; + var cannotAppendScopeSet = "cannot_append_scopeset"; + var emptyInputScopeSet = "empty_input_scopeset"; + var deviceCodePollingCancelled = "device_code_polling_cancelled"; + var deviceCodeExpired = "device_code_expired"; + var deviceCodeUnknownError = "device_code_unknown_error"; + var noAccountInSilentRequest = "no_account_in_silent_request"; + var invalidCacheRecord = "invalid_cache_record"; + var invalidCacheEnvironment = "invalid_cache_environment"; + var noAccountFound = "no_account_found"; + var noCryptoObject = "no_crypto_object"; + var unexpectedCredentialType = "unexpected_credential_type"; + var invalidAssertion = "invalid_assertion"; + var invalidClientCredential = "invalid_client_credential"; + var tokenRefreshRequired = "token_refresh_required"; + var userTimeoutReached = "user_timeout_reached"; + var tokenClaimsCnfRequiredForSignedJwt = "token_claims_cnf_required_for_signedjwt"; + var authorizationCodeMissingFromServerResponse = "authorization_code_missing_from_server_response"; + var bindingKeyNotRemoved = "binding_key_not_removed"; + var endSessionEndpointNotSupported = "end_session_endpoint_not_supported"; + var keyIdMissing = "key_id_missing"; + var noNetworkConnectivity = "no_network_connectivity"; + var userCanceled = "user_canceled"; + var missingTenantIdError = "missing_tenant_id_error"; + var methodNotImplemented = "method_not_implemented"; + var nestedAppAuthBridgeDisabled = "nested_app_auth_bridge_disabled"; + var ClientAuthErrorCodes = /* @__PURE__ */ Object.freeze({ + __proto__: null, + authTimeNotFound, + authorizationCodeMissingFromServerResponse, + bindingKeyNotRemoved, + cannotAppendScopeSet, + cannotRemoveEmptyScope, + clientInfoDecodingError, + clientInfoEmptyError, + deviceCodeExpired, + deviceCodePollingCancelled, + deviceCodeUnknownError, + emptyInputScopeSet, + endSessionEndpointNotSupported, + endpointResolutionError, + hashNotDeserialized, + invalidAssertion, + invalidCacheEnvironment, + invalidCacheRecord, + invalidClientCredential, + invalidState, + keyIdMissing, + maxAgeTranspired, + methodNotImplemented, + missingTenantIdError, + multipleMatchingAccounts, + multipleMatchingAppMetadata, + multipleMatchingTokens, + nestedAppAuthBridgeDisabled, + networkError, + noAccountFound, + noAccountInSilentRequest, + noCryptoObject, + noNetworkConnectivity, + nonceMismatch, + nullOrEmptyToken, + openIdConfigError, + requestCannotBeMade, + stateMismatch, + stateNotFound, + tokenClaimsCnfRequiredForSignedJwt, + tokenParsingError, + tokenRefreshRequired, + unexpectedCredentialType, + userCanceled, + userTimeoutReached + }); + var ClientAuthErrorMessages = { + [clientInfoDecodingError]: "The client info could not be parsed/decoded correctly", + [clientInfoEmptyError]: "The client info was empty", + [tokenParsingError]: "Token cannot be parsed", + [nullOrEmptyToken]: "The token is null or empty", + [endpointResolutionError]: "Endpoints cannot be resolved", + [networkError]: "Network request failed", + [openIdConfigError]: "Could not retrieve endpoints. Check your authority and verify the .well-known/openid-configuration endpoint returns the required endpoints.", + [hashNotDeserialized]: "The hash parameters could not be deserialized", + [invalidState]: "State was not the expected format", + [stateMismatch]: "State mismatch error", + [stateNotFound]: "State not found", + [nonceMismatch]: "Nonce mismatch error", + [authTimeNotFound]: "Max Age was requested and the ID token is missing the auth_time variable. auth_time is an optional claim and is not enabled by default - it must be enabled. See https://aka.ms/msaljs/optional-claims for more information.", + [maxAgeTranspired]: "Max Age is set to 0, or too much time has elapsed since the last end-user authentication.", + [multipleMatchingTokens]: "The cache contains multiple tokens satisfying the requirements. Call AcquireToken again providing more requirements such as authority or account.", + [multipleMatchingAccounts]: "The cache contains multiple accounts satisfying the given parameters. Please pass more info to obtain the correct account", + [multipleMatchingAppMetadata]: "The cache contains multiple appMetadata satisfying the given parameters. Please pass more info to obtain the correct appMetadata", + [requestCannotBeMade]: "Token request cannot be made without authorization code or refresh token.", + [cannotRemoveEmptyScope]: "Cannot remove null or empty scope from ScopeSet", + [cannotAppendScopeSet]: "Cannot append ScopeSet", + [emptyInputScopeSet]: "Empty input ScopeSet cannot be processed", + [deviceCodePollingCancelled]: "Caller has cancelled token endpoint polling during device code flow by setting DeviceCodeRequest.cancel = true.", + [deviceCodeExpired]: "Device code is expired.", + [deviceCodeUnknownError]: "Device code stopped polling for unknown reasons.", + [noAccountInSilentRequest]: "Please pass an account object, silent flow is not supported without account information", + [invalidCacheRecord]: "Cache record object was null or undefined.", + [invalidCacheEnvironment]: "Invalid environment when attempting to create cache entry", + [noAccountFound]: "No account found in cache for given key.", + [noCryptoObject]: "No crypto object detected.", + [unexpectedCredentialType]: "Unexpected credential type.", + [invalidAssertion]: "Client assertion must meet requirements described in https://tools.ietf.org/html/rfc7515", + [invalidClientCredential]: "Client credential (secret, certificate, or assertion) must not be empty when creating a confidential client. An application should at most have one credential", + [tokenRefreshRequired]: "Cannot return token from cache because it must be refreshed. This may be due to one of the following reasons: forceRefresh parameter is set to true, claims have been requested, there is no cached access token or it is expired.", + [userTimeoutReached]: "User defined timeout for device code polling reached", + [tokenClaimsCnfRequiredForSignedJwt]: "Cannot generate a POP jwt if the token_claims are not populated", + [authorizationCodeMissingFromServerResponse]: "Server response does not contain an authorization code to proceed", + [bindingKeyNotRemoved]: "Could not remove the credential's binding key from storage.", + [endSessionEndpointNotSupported]: "The provided authority does not support logout", + [keyIdMissing]: "A keyId value is missing from the requested bound token's cache record and is required to match the token to it's stored binding key.", + [noNetworkConnectivity]: "No network connectivity. Check your internet connection.", + [userCanceled]: "User cancelled the flow.", + [missingTenantIdError]: "A tenant id - not common, organizations, or consumers - must be specified when using the client_credentials flow.", + [methodNotImplemented]: "This method has not been implemented", + [nestedAppAuthBridgeDisabled]: "The nested app auth bridge is disabled" + }; + var ClientAuthErrorMessage = { + clientInfoDecodingError: { + code: clientInfoDecodingError, + desc: ClientAuthErrorMessages[clientInfoDecodingError] + }, + clientInfoEmptyError: { + code: clientInfoEmptyError, + desc: ClientAuthErrorMessages[clientInfoEmptyError] + }, + tokenParsingError: { + code: tokenParsingError, + desc: ClientAuthErrorMessages[tokenParsingError] + }, + nullOrEmptyToken: { + code: nullOrEmptyToken, + desc: ClientAuthErrorMessages[nullOrEmptyToken] + }, + endpointResolutionError: { + code: endpointResolutionError, + desc: ClientAuthErrorMessages[endpointResolutionError] + }, + networkError: { + code: networkError, + desc: ClientAuthErrorMessages[networkError] + }, + unableToGetOpenidConfigError: { + code: openIdConfigError, + desc: ClientAuthErrorMessages[openIdConfigError] + }, + hashNotDeserialized: { + code: hashNotDeserialized, + desc: ClientAuthErrorMessages[hashNotDeserialized] + }, + invalidStateError: { + code: invalidState, + desc: ClientAuthErrorMessages[invalidState] + }, + stateMismatchError: { + code: stateMismatch, + desc: ClientAuthErrorMessages[stateMismatch] + }, + stateNotFoundError: { + code: stateNotFound, + desc: ClientAuthErrorMessages[stateNotFound] + }, + nonceMismatchError: { + code: nonceMismatch, + desc: ClientAuthErrorMessages[nonceMismatch] + }, + authTimeNotFoundError: { + code: authTimeNotFound, + desc: ClientAuthErrorMessages[authTimeNotFound] + }, + maxAgeTranspired: { + code: maxAgeTranspired, + desc: ClientAuthErrorMessages[maxAgeTranspired] + }, + multipleMatchingTokens: { + code: multipleMatchingTokens, + desc: ClientAuthErrorMessages[multipleMatchingTokens] + }, + multipleMatchingAccounts: { + code: multipleMatchingAccounts, + desc: ClientAuthErrorMessages[multipleMatchingAccounts] + }, + multipleMatchingAppMetadata: { + code: multipleMatchingAppMetadata, + desc: ClientAuthErrorMessages[multipleMatchingAppMetadata] + }, + tokenRequestCannotBeMade: { + code: requestCannotBeMade, + desc: ClientAuthErrorMessages[requestCannotBeMade] + }, + removeEmptyScopeError: { + code: cannotRemoveEmptyScope, + desc: ClientAuthErrorMessages[cannotRemoveEmptyScope] + }, + appendScopeSetError: { + code: cannotAppendScopeSet, + desc: ClientAuthErrorMessages[cannotAppendScopeSet] + }, + emptyInputScopeSetError: { + code: emptyInputScopeSet, + desc: ClientAuthErrorMessages[emptyInputScopeSet] + }, + DeviceCodePollingCancelled: { + code: deviceCodePollingCancelled, + desc: ClientAuthErrorMessages[deviceCodePollingCancelled] + }, + DeviceCodeExpired: { + code: deviceCodeExpired, + desc: ClientAuthErrorMessages[deviceCodeExpired] + }, + DeviceCodeUnknownError: { + code: deviceCodeUnknownError, + desc: ClientAuthErrorMessages[deviceCodeUnknownError] + }, + NoAccountInSilentRequest: { + code: noAccountInSilentRequest, + desc: ClientAuthErrorMessages[noAccountInSilentRequest] + }, + invalidCacheRecord: { + code: invalidCacheRecord, + desc: ClientAuthErrorMessages[invalidCacheRecord] + }, + invalidCacheEnvironment: { + code: invalidCacheEnvironment, + desc: ClientAuthErrorMessages[invalidCacheEnvironment] + }, + noAccountFound: { + code: noAccountFound, + desc: ClientAuthErrorMessages[noAccountFound] + }, + noCryptoObj: { + code: noCryptoObject, + desc: ClientAuthErrorMessages[noCryptoObject] + }, + unexpectedCredentialType: { + code: unexpectedCredentialType, + desc: ClientAuthErrorMessages[unexpectedCredentialType] + }, + invalidAssertion: { + code: invalidAssertion, + desc: ClientAuthErrorMessages[invalidAssertion] + }, + invalidClientCredential: { + code: invalidClientCredential, + desc: ClientAuthErrorMessages[invalidClientCredential] + }, + tokenRefreshRequired: { + code: tokenRefreshRequired, + desc: ClientAuthErrorMessages[tokenRefreshRequired] + }, + userTimeoutReached: { + code: userTimeoutReached, + desc: ClientAuthErrorMessages[userTimeoutReached] + }, + tokenClaimsRequired: { + code: tokenClaimsCnfRequiredForSignedJwt, + desc: ClientAuthErrorMessages[tokenClaimsCnfRequiredForSignedJwt] + }, + noAuthorizationCodeFromServer: { + code: authorizationCodeMissingFromServerResponse, + desc: ClientAuthErrorMessages[authorizationCodeMissingFromServerResponse] + }, + bindingKeyNotRemovedError: { + code: bindingKeyNotRemoved, + desc: ClientAuthErrorMessages[bindingKeyNotRemoved] + }, + logoutNotSupported: { + code: endSessionEndpointNotSupported, + desc: ClientAuthErrorMessages[endSessionEndpointNotSupported] + }, + keyIdMissing: { + code: keyIdMissing, + desc: ClientAuthErrorMessages[keyIdMissing] + }, + noNetworkConnectivity: { + code: noNetworkConnectivity, + desc: ClientAuthErrorMessages[noNetworkConnectivity] + }, + userCanceledError: { + code: userCanceled, + desc: ClientAuthErrorMessages[userCanceled] + }, + missingTenantIdError: { + code: missingTenantIdError, + desc: ClientAuthErrorMessages[missingTenantIdError] + }, + nestedAppAuthBridgeDisabled: { + code: nestedAppAuthBridgeDisabled, + desc: ClientAuthErrorMessages[nestedAppAuthBridgeDisabled] + } + }; + var ClientAuthError = class _ClientAuthError extends AuthError { + constructor(errorCode, additionalMessage) { + super(errorCode, additionalMessage ? `${ClientAuthErrorMessages[errorCode]}: ${additionalMessage}` : ClientAuthErrorMessages[errorCode]); + this.name = "ClientAuthError"; + Object.setPrototypeOf(this, _ClientAuthError.prototype); + } + }; + function createClientAuthError(errorCode, additionalMessage) { + return new ClientAuthError(errorCode, additionalMessage); + } + var DEFAULT_CRYPTO_IMPLEMENTATION = { + createNewGuid: () => { + throw createClientAuthError(methodNotImplemented); + }, + base64Decode: () => { + throw createClientAuthError(methodNotImplemented); + }, + base64Encode: () => { + throw createClientAuthError(methodNotImplemented); + }, + base64UrlEncode: () => { + throw createClientAuthError(methodNotImplemented); + }, + encodeKid: () => { + throw createClientAuthError(methodNotImplemented); + }, + async getPublicKeyThumbprint() { + throw createClientAuthError(methodNotImplemented); + }, + async removeTokenBindingKey() { + throw createClientAuthError(methodNotImplemented); + }, + async clearKeystore() { + throw createClientAuthError(methodNotImplemented); + }, + async signJwt() { + throw createClientAuthError(methodNotImplemented); + }, + async hashString() { + throw createClientAuthError(methodNotImplemented); + } + }; + exports2.LogLevel = void 0; + (function(LogLevel) { + LogLevel[LogLevel["Error"] = 0] = "Error"; + LogLevel[LogLevel["Warning"] = 1] = "Warning"; + LogLevel[LogLevel["Info"] = 2] = "Info"; + LogLevel[LogLevel["Verbose"] = 3] = "Verbose"; + LogLevel[LogLevel["Trace"] = 4] = "Trace"; + })(exports2.LogLevel || (exports2.LogLevel = {})); + var Logger = class _Logger { + constructor(loggerOptions, packageName, packageVersion) { + this.level = exports2.LogLevel.Info; + const defaultLoggerCallback = () => { + return; + }; + const setLoggerOptions = loggerOptions || _Logger.createDefaultLoggerOptions(); + this.localCallback = setLoggerOptions.loggerCallback || defaultLoggerCallback; + this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false; + this.level = typeof setLoggerOptions.logLevel === "number" ? setLoggerOptions.logLevel : exports2.LogLevel.Info; + this.correlationId = setLoggerOptions.correlationId || Constants$1.EMPTY_STRING; + this.packageName = packageName || Constants$1.EMPTY_STRING; + this.packageVersion = packageVersion || Constants$1.EMPTY_STRING; + } + static createDefaultLoggerOptions() { + return { + loggerCallback: () => { + }, + piiLoggingEnabled: false, + logLevel: exports2.LogLevel.Info + }; + } + /** + * Create new Logger with existing configurations. + */ + clone(packageName, packageVersion, correlationId) { + return new _Logger({ + loggerCallback: this.localCallback, + piiLoggingEnabled: this.piiLoggingEnabled, + logLevel: this.level, + correlationId: correlationId || this.correlationId + }, packageName, packageVersion); + } + /** + * Log message with required options. + */ + logMessage(logMessage, options) { + if (options.logLevel > this.level || !this.piiLoggingEnabled && options.containsPii) { + return; + } + const timestamp = (/* @__PURE__ */ new Date()).toUTCString(); + const logHeader = `[${timestamp}] : [${options.correlationId || this.correlationId || ""}]`; + const log = `${logHeader} : ${this.packageName}@${this.packageVersion} : ${exports2.LogLevel[options.logLevel]} - ${logMessage}`; + this.executeCallback(options.logLevel, log, options.containsPii || false); + } + /** + * Execute callback with message. + */ + executeCallback(level, message, containsPii) { + if (this.localCallback) { + this.localCallback(level, message, containsPii); + } + } + /** + * Logs error messages. + */ + error(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Error, + containsPii: false, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs error messages with PII. + */ + errorPii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Error, + containsPii: true, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs warning messages. + */ + warning(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Warning, + containsPii: false, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs warning messages with PII. + */ + warningPii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Warning, + containsPii: true, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs info messages. + */ + info(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Info, + containsPii: false, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs info messages with PII. + */ + infoPii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Info, + containsPii: true, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs verbose messages. + */ + verbose(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Verbose, + containsPii: false, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs verbose messages with PII. + */ + verbosePii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Verbose, + containsPii: true, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs trace messages. + */ + trace(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Trace, + containsPii: false, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Logs trace messages with PII. + */ + tracePii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Trace, + containsPii: true, + correlationId: correlationId || Constants$1.EMPTY_STRING + }); + } + /** + * Returns whether PII Logging is enabled or not. + */ + isPiiLoggingEnabled() { + return this.piiLoggingEnabled || false; + } + }; + var name$1 = "@azure/msal-common"; + var version$1 = "14.16.1"; + var AzureCloudInstance = { + // AzureCloudInstance is not specified. + None: "none", + // Microsoft Azure public cloud + AzurePublic: "https://login.microsoftonline.com", + // Microsoft PPE + AzurePpe: "https://login.windows-ppe.net", + // Microsoft Chinese national/regional cloud + AzureChina: "https://login.chinacloudapi.cn", + // Microsoft German national/regional cloud ("Black Forest") + AzureGermany: "https://login.microsoftonline.de", + // US Government cloud + AzureUsGovernment: "https://login.microsoftonline.us" + }; + function extractTokenClaims(encodedToken, base64Decode) { + const jswPayload = getJWSPayload(encodedToken); + try { + const base64Decoded = base64Decode(jswPayload); + return JSON.parse(base64Decoded); + } catch (err) { + throw createClientAuthError(tokenParsingError); + } + } + function getJWSPayload(authToken) { + if (!authToken) { + throw createClientAuthError(nullOrEmptyToken); + } + const tokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/; + const matches = tokenPartsRegex.exec(authToken); + if (!matches || matches.length < 4) { + throw createClientAuthError(tokenParsingError); + } + return matches[2]; + } + function checkMaxAge(authTime, maxAge) { + const fiveMinuteSkew = 3e5; + if (maxAge === 0 || Date.now() - fiveMinuteSkew > authTime + maxAge) { + throw createClientAuthError(maxAgeTranspired); + } + } + function nowSeconds() { + return Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3); + } + function isTokenExpired(expiresOn, offset) { + const expirationSec = Number(expiresOn) || 0; + const offsetCurrentTimeSec = nowSeconds() + offset; + return offsetCurrentTimeSec > expirationSec; + } + function wasClockTurnedBack(cachedAt) { + const cachedAtSec = Number(cachedAt); + return cachedAtSec > nowSeconds(); + } + function delay(t, value) { + return new Promise((resolve) => setTimeout(() => resolve(value), t)); + } + function generateCredentialKey(credentialEntity) { + const credentialKey = [ + generateAccountId(credentialEntity), + generateCredentialId(credentialEntity), + generateTarget(credentialEntity), + generateClaimsHash(credentialEntity), + generateScheme(credentialEntity) + ]; + return credentialKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase(); + } + function createIdTokenEntity(homeAccountId, environment, idToken, clientId, tenantId) { + const idTokenEntity = { + credentialType: CredentialType.ID_TOKEN, + homeAccountId, + environment, + clientId, + secret: idToken, + realm: tenantId + }; + return idTokenEntity; + } + function createAccessTokenEntity(homeAccountId, environment, accessToken, clientId, tenantId, scopes, expiresOn, extExpiresOn, base64Decode, refreshOn, tokenType, userAssertionHash, keyId, requestedClaims, requestedClaimsHash) { + const atEntity = { + homeAccountId, + credentialType: CredentialType.ACCESS_TOKEN, + secret: accessToken, + cachedAt: nowSeconds().toString(), + expiresOn: expiresOn.toString(), + extendedExpiresOn: extExpiresOn.toString(), + environment, + clientId, + realm: tenantId, + target: scopes, + tokenType: tokenType || AuthenticationScheme.BEARER + }; + if (userAssertionHash) { + atEntity.userAssertionHash = userAssertionHash; + } + if (refreshOn) { + atEntity.refreshOn = refreshOn.toString(); + } + if (requestedClaims) { + atEntity.requestedClaims = requestedClaims; + atEntity.requestedClaimsHash = requestedClaimsHash; + } + if (atEntity.tokenType?.toLowerCase() !== AuthenticationScheme.BEARER.toLowerCase()) { + atEntity.credentialType = CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME; + switch (atEntity.tokenType) { + case AuthenticationScheme.POP: + const tokenClaims = extractTokenClaims(accessToken, base64Decode); + if (!tokenClaims?.cnf?.kid) { + throw createClientAuthError(tokenClaimsCnfRequiredForSignedJwt); + } + atEntity.keyId = tokenClaims.cnf.kid; + break; + case AuthenticationScheme.SSH: + atEntity.keyId = keyId; + } + } + return atEntity; + } + function createRefreshTokenEntity(homeAccountId, environment, refreshToken, clientId, familyId, userAssertionHash, expiresOn) { + const rtEntity = { + credentialType: CredentialType.REFRESH_TOKEN, + homeAccountId, + environment, + clientId, + secret: refreshToken + }; + if (userAssertionHash) { + rtEntity.userAssertionHash = userAssertionHash; + } + if (familyId) { + rtEntity.familyId = familyId; + } + if (expiresOn) { + rtEntity.expiresOn = expiresOn.toString(); + } + return rtEntity; + } + function isCredentialEntity(entity) { + return entity.hasOwnProperty("homeAccountId") && entity.hasOwnProperty("environment") && entity.hasOwnProperty("credentialType") && entity.hasOwnProperty("clientId") && entity.hasOwnProperty("secret"); + } + function isAccessTokenEntity(entity) { + if (!entity) { + return false; + } + return isCredentialEntity(entity) && entity.hasOwnProperty("realm") && entity.hasOwnProperty("target") && (entity["credentialType"] === CredentialType.ACCESS_TOKEN || entity["credentialType"] === CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME); + } + function isIdTokenEntity(entity) { + if (!entity) { + return false; + } + return isCredentialEntity(entity) && entity.hasOwnProperty("realm") && entity["credentialType"] === CredentialType.ID_TOKEN; + } + function isRefreshTokenEntity(entity) { + if (!entity) { + return false; + } + return isCredentialEntity(entity) && entity["credentialType"] === CredentialType.REFRESH_TOKEN; + } + function generateAccountId(credentialEntity) { + const accountId = [ + credentialEntity.homeAccountId, + credentialEntity.environment + ]; + return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase(); + } + function generateCredentialId(credentialEntity) { + const clientOrFamilyId = credentialEntity.credentialType === CredentialType.REFRESH_TOKEN ? credentialEntity.familyId || credentialEntity.clientId : credentialEntity.clientId; + const credentialId = [ + credentialEntity.credentialType, + clientOrFamilyId, + credentialEntity.realm || "" + ]; + return credentialId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase(); + } + function generateTarget(credentialEntity) { + return (credentialEntity.target || "").toLowerCase(); + } + function generateClaimsHash(credentialEntity) { + return (credentialEntity.requestedClaimsHash || "").toLowerCase(); + } + function generateScheme(credentialEntity) { + return credentialEntity.tokenType && credentialEntity.tokenType.toLowerCase() !== AuthenticationScheme.BEARER.toLowerCase() ? credentialEntity.tokenType.toLowerCase() : ""; + } + function isServerTelemetryEntity(key, entity) { + const validateKey = key.indexOf(SERVER_TELEM_CONSTANTS.CACHE_KEY) === 0; + let validateEntity = true; + if (entity) { + validateEntity = entity.hasOwnProperty("failedRequests") && entity.hasOwnProperty("errors") && entity.hasOwnProperty("cacheHits"); + } + return validateKey && validateEntity; + } + function isThrottlingEntity(key, entity) { + let validateKey = false; + if (key) { + validateKey = key.indexOf(ThrottlingConstants.THROTTLING_PREFIX) === 0; + } + let validateEntity = true; + if (entity) { + validateEntity = entity.hasOwnProperty("throttleTime"); + } + return validateKey && validateEntity; + } + function generateAppMetadataKey({ environment, clientId }) { + const appMetaDataKeyArray = [ + APP_METADATA, + environment, + clientId + ]; + return appMetaDataKeyArray.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase(); + } + function isAppMetadataEntity(key, entity) { + if (!entity) { + return false; + } + return key.indexOf(APP_METADATA) === 0 && entity.hasOwnProperty("clientId") && entity.hasOwnProperty("environment"); + } + function isAuthorityMetadataEntity(key, entity) { + if (!entity) { + return false; + } + return key.indexOf(AUTHORITY_METADATA_CONSTANTS.CACHE_KEY) === 0 && entity.hasOwnProperty("aliases") && entity.hasOwnProperty("preferred_cache") && entity.hasOwnProperty("preferred_network") && entity.hasOwnProperty("canonical_authority") && entity.hasOwnProperty("authorization_endpoint") && entity.hasOwnProperty("token_endpoint") && entity.hasOwnProperty("issuer") && entity.hasOwnProperty("aliasesFromNetwork") && entity.hasOwnProperty("endpointsFromNetwork") && entity.hasOwnProperty("expiresAt") && entity.hasOwnProperty("jwks_uri"); + } + function generateAuthorityMetadataExpiresAt() { + return nowSeconds() + AUTHORITY_METADATA_CONSTANTS.REFRESH_TIME_SECONDS; + } + function updateAuthorityEndpointMetadata(authorityMetadata, updatedValues, fromNetwork) { + authorityMetadata.authorization_endpoint = updatedValues.authorization_endpoint; + authorityMetadata.token_endpoint = updatedValues.token_endpoint; + authorityMetadata.end_session_endpoint = updatedValues.end_session_endpoint; + authorityMetadata.issuer = updatedValues.issuer; + authorityMetadata.endpointsFromNetwork = fromNetwork; + authorityMetadata.jwks_uri = updatedValues.jwks_uri; + } + function updateCloudDiscoveryMetadata(authorityMetadata, updatedValues, fromNetwork) { + authorityMetadata.aliases = updatedValues.aliases; + authorityMetadata.preferred_cache = updatedValues.preferred_cache; + authorityMetadata.preferred_network = updatedValues.preferred_network; + authorityMetadata.aliasesFromNetwork = fromNetwork; + } + function isAuthorityMetadataExpired(metadata) { + return metadata.expiresAt <= nowSeconds(); + } + var redirectUriEmpty = "redirect_uri_empty"; + var claimsRequestParsingError = "claims_request_parsing_error"; + var authorityUriInsecure = "authority_uri_insecure"; + var urlParseError = "url_parse_error"; + var urlEmptyError = "empty_url_error"; + var emptyInputScopesError = "empty_input_scopes_error"; + var invalidPromptValue = "invalid_prompt_value"; + var invalidClaims = "invalid_claims"; + var tokenRequestEmpty = "token_request_empty"; + var logoutRequestEmpty = "logout_request_empty"; + var invalidCodeChallengeMethod = "invalid_code_challenge_method"; + var pkceParamsMissing = "pkce_params_missing"; + var invalidCloudDiscoveryMetadata = "invalid_cloud_discovery_metadata"; + var invalidAuthorityMetadata = "invalid_authority_metadata"; + var untrustedAuthority = "untrusted_authority"; + var missingSshJwk = "missing_ssh_jwk"; + var missingSshKid = "missing_ssh_kid"; + var missingNonceAuthenticationHeader = "missing_nonce_authentication_header"; + var invalidAuthenticationHeader = "invalid_authentication_header"; + var cannotSetOIDCOptions = "cannot_set_OIDCOptions"; + var cannotAllowNativeBroker = "cannot_allow_native_broker"; + var authorityMismatch = "authority_mismatch"; + var ClientConfigurationErrorCodes = /* @__PURE__ */ Object.freeze({ + __proto__: null, + authorityMismatch, + authorityUriInsecure, + cannotAllowNativeBroker, + cannotSetOIDCOptions, + claimsRequestParsingError, + emptyInputScopesError, + invalidAuthenticationHeader, + invalidAuthorityMetadata, + invalidClaims, + invalidCloudDiscoveryMetadata, + invalidCodeChallengeMethod, + invalidPromptValue, + logoutRequestEmpty, + missingNonceAuthenticationHeader, + missingSshJwk, + missingSshKid, + pkceParamsMissing, + redirectUriEmpty, + tokenRequestEmpty, + untrustedAuthority, + urlEmptyError, + urlParseError + }); + var ClientConfigurationErrorMessages = { + [redirectUriEmpty]: "A redirect URI is required for all calls, and none has been set.", + [claimsRequestParsingError]: "Could not parse the given claims request object.", + [authorityUriInsecure]: "Authority URIs must use https. Please see here for valid authority configuration options: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications#configuration-options", + [urlParseError]: "URL could not be parsed into appropriate segments.", + [urlEmptyError]: "URL was empty or null.", + [emptyInputScopesError]: "Scopes cannot be passed as null, undefined or empty array because they are required to obtain an access token.", + [invalidPromptValue]: "Please see here for valid configuration options: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_common.html#commonauthorizationurlrequest", + [invalidClaims]: "Given claims parameter must be a stringified JSON object.", + [tokenRequestEmpty]: "Token request was empty and not found in cache.", + [logoutRequestEmpty]: "The logout request was null or undefined.", + [invalidCodeChallengeMethod]: 'code_challenge_method passed is invalid. Valid values are "plain" and "S256".', + [pkceParamsMissing]: "Both params: code_challenge and code_challenge_method are to be passed if to be sent in the request", + [invalidCloudDiscoveryMetadata]: "Invalid cloudDiscoveryMetadata provided. Must be a stringified JSON object containing tenant_discovery_endpoint and metadata fields", + [invalidAuthorityMetadata]: "Invalid authorityMetadata provided. Must by a stringified JSON object containing authorization_endpoint, token_endpoint, issuer fields.", + [untrustedAuthority]: "The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter.", + [missingSshJwk]: "Missing sshJwk in SSH certificate request. A stringified JSON Web Key is required when using the SSH authentication scheme.", + [missingSshKid]: "Missing sshKid in SSH certificate request. A string that uniquely identifies the public SSH key is required when using the SSH authentication scheme.", + [missingNonceAuthenticationHeader]: "Unable to find an authentication header containing server nonce. Either the Authentication-Info or WWW-Authenticate headers must be present in order to obtain a server nonce.", + [invalidAuthenticationHeader]: "Invalid authentication header provided", + [cannotSetOIDCOptions]: "Cannot set OIDCOptions parameter. Please change the protocol mode to OIDC or use a non-Microsoft authority.", + [cannotAllowNativeBroker]: "Cannot set allowNativeBroker parameter to true when not in AAD protocol mode.", + [authorityMismatch]: "Authority mismatch error. Authority provided in login request or PublicClientApplication config does not match the environment of the provided account. Please use a matching account or make an interactive request to login to this authority." + }; + var ClientConfigurationErrorMessage = { + redirectUriNotSet: { + code: redirectUriEmpty, + desc: ClientConfigurationErrorMessages[redirectUriEmpty] + }, + claimsRequestParsingError: { + code: claimsRequestParsingError, + desc: ClientConfigurationErrorMessages[claimsRequestParsingError] + }, + authorityUriInsecure: { + code: authorityUriInsecure, + desc: ClientConfigurationErrorMessages[authorityUriInsecure] + }, + urlParseError: { + code: urlParseError, + desc: ClientConfigurationErrorMessages[urlParseError] + }, + urlEmptyError: { + code: urlEmptyError, + desc: ClientConfigurationErrorMessages[urlEmptyError] + }, + emptyScopesError: { + code: emptyInputScopesError, + desc: ClientConfigurationErrorMessages[emptyInputScopesError] + }, + invalidPrompt: { + code: invalidPromptValue, + desc: ClientConfigurationErrorMessages[invalidPromptValue] + }, + invalidClaimsRequest: { + code: invalidClaims, + desc: ClientConfigurationErrorMessages[invalidClaims] + }, + tokenRequestEmptyError: { + code: tokenRequestEmpty, + desc: ClientConfigurationErrorMessages[tokenRequestEmpty] + }, + logoutRequestEmptyError: { + code: logoutRequestEmpty, + desc: ClientConfigurationErrorMessages[logoutRequestEmpty] + }, + invalidCodeChallengeMethod: { + code: invalidCodeChallengeMethod, + desc: ClientConfigurationErrorMessages[invalidCodeChallengeMethod] + }, + invalidCodeChallengeParams: { + code: pkceParamsMissing, + desc: ClientConfigurationErrorMessages[pkceParamsMissing] + }, + invalidCloudDiscoveryMetadata: { + code: invalidCloudDiscoveryMetadata, + desc: ClientConfigurationErrorMessages[invalidCloudDiscoveryMetadata] + }, + invalidAuthorityMetadata: { + code: invalidAuthorityMetadata, + desc: ClientConfigurationErrorMessages[invalidAuthorityMetadata] + }, + untrustedAuthority: { + code: untrustedAuthority, + desc: ClientConfigurationErrorMessages[untrustedAuthority] + }, + missingSshJwk: { + code: missingSshJwk, + desc: ClientConfigurationErrorMessages[missingSshJwk] + }, + missingSshKid: { + code: missingSshKid, + desc: ClientConfigurationErrorMessages[missingSshKid] + }, + missingNonceAuthenticationHeader: { + code: missingNonceAuthenticationHeader, + desc: ClientConfigurationErrorMessages[missingNonceAuthenticationHeader] + }, + invalidAuthenticationHeader: { + code: invalidAuthenticationHeader, + desc: ClientConfigurationErrorMessages[invalidAuthenticationHeader] + }, + cannotSetOIDCOptions: { + code: cannotSetOIDCOptions, + desc: ClientConfigurationErrorMessages[cannotSetOIDCOptions] + }, + cannotAllowNativeBroker: { + code: cannotAllowNativeBroker, + desc: ClientConfigurationErrorMessages[cannotAllowNativeBroker] + }, + authorityMismatch: { + code: authorityMismatch, + desc: ClientConfigurationErrorMessages[authorityMismatch] + } + }; + var ClientConfigurationError = class _ClientConfigurationError extends AuthError { + constructor(errorCode) { + super(errorCode, ClientConfigurationErrorMessages[errorCode]); + this.name = "ClientConfigurationError"; + Object.setPrototypeOf(this, _ClientConfigurationError.prototype); + } + }; + function createClientConfigurationError(errorCode) { + return new ClientConfigurationError(errorCode); + } + var StringUtils = class { + /** + * Check if stringified object is empty + * @param strObj + */ + static isEmptyObj(strObj) { + if (strObj) { + try { + const obj = JSON.parse(strObj); + return Object.keys(obj).length === 0; + } catch (e) { + } + } + return true; + } + static startsWith(str, search) { + return str.indexOf(search) === 0; + } + static endsWith(str, search) { + return str.length >= search.length && str.lastIndexOf(search) === str.length - search.length; + } + /** + * Parses string into an object. + * + * @param query + */ + static queryStringToObject(query) { + const obj = {}; + const params = query.split("&"); + const decode = (s) => decodeURIComponent(s.replace(/\+/g, " ")); + params.forEach((pair) => { + if (pair.trim()) { + const [key, value] = pair.split(/=(.+)/g, 2); + if (key && value) { + obj[decode(key)] = decode(value); + } + } + }); + return obj; + } + /** + * Trims entries in an array. + * + * @param arr + */ + static trimArrayEntries(arr) { + return arr.map((entry) => entry.trim()); + } + /** + * Removes empty strings from array + * @param arr + */ + static removeEmptyStringsFromArray(arr) { + return arr.filter((entry) => { + return !!entry; + }); + } + /** + * Attempts to parse a string into JSON + * @param str + */ + static jsonParseHelper(str) { + try { + return JSON.parse(str); + } catch (e) { + return null; + } + } + /** + * Tests if a given string matches a given pattern, with support for wildcards and queries. + * @param pattern Wildcard pattern to string match. Supports "*" for wildcards and "?" for queries + * @param input String to match against + */ + static matchPattern(pattern, input) { + const regex = new RegExp(pattern.replace(/\\/g, "\\\\").replace(/\*/g, "[^ ]*").replace(/\?/g, "\\?")); + return regex.test(input); + } + }; + var ScopeSet = class _ScopeSet { + constructor(inputScopes) { + const scopeArr = inputScopes ? StringUtils.trimArrayEntries([...inputScopes]) : []; + const filteredInput = scopeArr ? StringUtils.removeEmptyStringsFromArray(scopeArr) : []; + this.validateInputScopes(filteredInput); + this.scopes = /* @__PURE__ */ new Set(); + filteredInput.forEach((scope) => this.scopes.add(scope)); + } + /** + * Factory method to create ScopeSet from space-delimited string + * @param inputScopeString + * @param appClientId + * @param scopesRequired + */ + static fromString(inputScopeString) { + const scopeString = inputScopeString || Constants$1.EMPTY_STRING; + const inputScopes = scopeString.split(" "); + return new _ScopeSet(inputScopes); + } + /** + * Creates the set of scopes to search for in cache lookups + * @param inputScopeString + * @returns + */ + static createSearchScopes(inputScopeString) { + const scopeSet = new _ScopeSet(inputScopeString); + if (!scopeSet.containsOnlyOIDCScopes()) { + scopeSet.removeOIDCScopes(); + } else { + scopeSet.removeScope(Constants$1.OFFLINE_ACCESS_SCOPE); + } + return scopeSet; + } + /** + * Used to validate the scopes input parameter requested by the developer. + * @param {Array} inputScopes - Developer requested permissions. Not all scopes are guaranteed to be included in the access token returned. + * @param {boolean} scopesRequired - Boolean indicating whether the scopes array is required or not + */ + validateInputScopes(inputScopes) { + if (!inputScopes || inputScopes.length < 1) { + throw createClientConfigurationError(emptyInputScopesError); + } + } + /** + * Check if a given scope is present in this set of scopes. + * @param scope + */ + containsScope(scope) { + const lowerCaseScopes = this.printScopesLowerCase().split(" "); + const lowerCaseScopesSet = new _ScopeSet(lowerCaseScopes); + return scope ? lowerCaseScopesSet.scopes.has(scope.toLowerCase()) : false; + } + /** + * Check if a set of scopes is present in this set of scopes. + * @param scopeSet + */ + containsScopeSet(scopeSet) { + if (!scopeSet || scopeSet.scopes.size <= 0) { + return false; + } + return this.scopes.size >= scopeSet.scopes.size && scopeSet.asArray().every((scope) => this.containsScope(scope)); + } + /** + * Check if set of scopes contains only the defaults + */ + containsOnlyOIDCScopes() { + let defaultScopeCount = 0; + OIDC_SCOPES.forEach((defaultScope) => { + if (this.containsScope(defaultScope)) { + defaultScopeCount += 1; + } + }); + return this.scopes.size === defaultScopeCount; + } + /** + * Appends single scope if passed + * @param newScope + */ + appendScope(newScope) { + if (newScope) { + this.scopes.add(newScope.trim()); + } + } + /** + * Appends multiple scopes if passed + * @param newScopes + */ + appendScopes(newScopes) { + try { + newScopes.forEach((newScope) => this.appendScope(newScope)); + } catch (e) { + throw createClientAuthError(cannotAppendScopeSet); + } + } + /** + * Removes element from set of scopes. + * @param scope + */ + removeScope(scope) { + if (!scope) { + throw createClientAuthError(cannotRemoveEmptyScope); + } + this.scopes.delete(scope.trim()); + } + /** + * Removes default scopes from set of scopes + * Primarily used to prevent cache misses if the default scopes are not returned from the server + */ + removeOIDCScopes() { + OIDC_SCOPES.forEach((defaultScope) => { + this.scopes.delete(defaultScope); + }); + } + /** + * Combines an array of scopes with the current set of scopes. + * @param otherScopes + */ + unionScopeSets(otherScopes) { + if (!otherScopes) { + throw createClientAuthError(emptyInputScopeSet); + } + const unionScopes = /* @__PURE__ */ new Set(); + otherScopes.scopes.forEach((scope) => unionScopes.add(scope.toLowerCase())); + this.scopes.forEach((scope) => unionScopes.add(scope.toLowerCase())); + return unionScopes; + } + /** + * Check if scopes intersect between this set and another. + * @param otherScopes + */ + intersectingScopeSets(otherScopes) { + if (!otherScopes) { + throw createClientAuthError(emptyInputScopeSet); + } + if (!otherScopes.containsOnlyOIDCScopes()) { + otherScopes.removeOIDCScopes(); + } + const unionScopes = this.unionScopeSets(otherScopes); + const sizeOtherScopes = otherScopes.getScopeCount(); + const sizeThisScopes = this.getScopeCount(); + const sizeUnionScopes = unionScopes.size; + return sizeUnionScopes < sizeThisScopes + sizeOtherScopes; + } + /** + * Returns size of set of scopes. + */ + getScopeCount() { + return this.scopes.size; + } + /** + * Returns the scopes as an array of string values + */ + asArray() { + const array = []; + this.scopes.forEach((val) => array.push(val)); + return array; + } + /** + * Prints scopes into a space-delimited string + */ + printScopes() { + if (this.scopes) { + const scopeArr = this.asArray(); + return scopeArr.join(" "); + } + return Constants$1.EMPTY_STRING; + } + /** + * Prints scopes into a space-delimited lower-case string (used for caching) + */ + printScopesLowerCase() { + return this.printScopes().toLowerCase(); + } + }; + function buildClientInfo(rawClientInfo, base64Decode) { + if (!rawClientInfo) { + throw createClientAuthError(clientInfoEmptyError); + } + try { + const decodedClientInfo = base64Decode(rawClientInfo); + return JSON.parse(decodedClientInfo); + } catch (e) { + throw createClientAuthError(clientInfoDecodingError); + } + } + function buildClientInfoFromHomeAccountId(homeAccountId) { + if (!homeAccountId) { + throw createClientAuthError(clientInfoDecodingError); + } + const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2); + return { + uid: clientInfoParts[0], + utid: clientInfoParts.length < 2 ? Constants$1.EMPTY_STRING : clientInfoParts[1] + }; + } + function tenantIdMatchesHomeTenant(tenantId, homeAccountId) { + return !!tenantId && !!homeAccountId && tenantId === homeAccountId.split(".")[1]; + } + function buildTenantProfile(homeAccountId, localAccountId, tenantId, idTokenClaims) { + if (idTokenClaims) { + const { oid, sub, tid, name: name2, tfp, acr } = idTokenClaims; + const tenantId2 = tid || tfp || acr || ""; + return { + tenantId: tenantId2, + localAccountId: oid || sub || "", + name: name2, + isHomeTenant: tenantIdMatchesHomeTenant(tenantId2, homeAccountId) + }; + } else { + return { + tenantId, + localAccountId, + isHomeTenant: tenantIdMatchesHomeTenant(tenantId, homeAccountId) + }; + } + } + function updateAccountTenantProfileData(baseAccountInfo, tenantProfile, idTokenClaims, idTokenSecret) { + let updatedAccountInfo = baseAccountInfo; + if (tenantProfile) { + const { isHomeTenant, ...tenantProfileOverride } = tenantProfile; + updatedAccountInfo = { ...baseAccountInfo, ...tenantProfileOverride }; + } + if (idTokenClaims) { + const { isHomeTenant, ...claimsSourcedTenantProfile } = buildTenantProfile(baseAccountInfo.homeAccountId, baseAccountInfo.localAccountId, baseAccountInfo.tenantId, idTokenClaims); + updatedAccountInfo = { + ...updatedAccountInfo, + ...claimsSourcedTenantProfile, + idTokenClaims, + idToken: idTokenSecret + }; + return updatedAccountInfo; + } + return updatedAccountInfo; + } + var AuthorityType = { + Default: 0, + Adfs: 1, + Dsts: 2, + Ciam: 3 + }; + function getTenantIdFromIdTokenClaims(idTokenClaims) { + if (idTokenClaims) { + const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr; + return tenantId || null; + } + return null; + } + var ProtocolMode = { + AAD: "AAD", + OIDC: "OIDC" + }; + var AccountEntity = class _AccountEntity { + /** + * Generate Account Id key component as per the schema: - + */ + generateAccountId() { + const accountId = [this.homeAccountId, this.environment]; + return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase(); + } + /** + * Generate Account Cache Key as per the schema: -- + */ + generateAccountKey() { + return _AccountEntity.generateAccountCacheKey({ + homeAccountId: this.homeAccountId, + environment: this.environment, + tenantId: this.realm, + username: this.username, + localAccountId: this.localAccountId + }); + } + /** + * Returns the AccountInfo interface for this account. + */ + getAccountInfo() { + return { + homeAccountId: this.homeAccountId, + environment: this.environment, + tenantId: this.realm, + username: this.username, + localAccountId: this.localAccountId, + name: this.name, + nativeAccountId: this.nativeAccountId, + authorityType: this.authorityType, + // Deserialize tenant profiles array into a Map + tenantProfiles: new Map((this.tenantProfiles || []).map((tenantProfile) => { + return [tenantProfile.tenantId, tenantProfile]; + })) + }; + } + /** + * Returns true if the account entity is in single tenant format (outdated), false otherwise + */ + isSingleTenant() { + return !this.tenantProfiles; + } + /** + * Generates account key from interface + * @param accountInterface + */ + static generateAccountCacheKey(accountInterface) { + const homeTenantId = accountInterface.homeAccountId.split(".")[1]; + const accountKey = [ + accountInterface.homeAccountId, + accountInterface.environment || "", + homeTenantId || accountInterface.tenantId || "" + ]; + return accountKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase(); + } + /** + * Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD. + * @param accountDetails + */ + static createAccount(accountDetails, authority, base64Decode) { + const account = new _AccountEntity(); + if (authority.authorityType === AuthorityType.Adfs) { + account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE; + } else if (authority.protocolMode === ProtocolMode.AAD) { + account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE; + } else { + account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE; + } + let clientInfo; + if (accountDetails.clientInfo && base64Decode) { + clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode); + } + account.clientInfo = accountDetails.clientInfo; + account.homeAccountId = accountDetails.homeAccountId; + account.nativeAccountId = accountDetails.nativeAccountId; + const env = accountDetails.environment || authority && authority.getPreferredCache(); + if (!env) { + throw createClientAuthError(invalidCacheEnvironment); + } + account.environment = env; + account.realm = clientInfo?.utid || getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) || ""; + account.localAccountId = clientInfo?.uid || accountDetails.idTokenClaims?.oid || accountDetails.idTokenClaims?.sub || ""; + const preferredUsername = accountDetails.idTokenClaims?.preferred_username || accountDetails.idTokenClaims?.upn; + const email = accountDetails.idTokenClaims?.emails ? accountDetails.idTokenClaims.emails[0] : null; + account.username = preferredUsername || email || ""; + account.name = accountDetails.idTokenClaims?.name || ""; + account.cloudGraphHostName = accountDetails.cloudGraphHostName; + account.msGraphHost = accountDetails.msGraphHost; + if (accountDetails.tenantProfiles) { + account.tenantProfiles = accountDetails.tenantProfiles; + } else { + const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims); + account.tenantProfiles = [tenantProfile]; + } + return account; + } + /** + * Creates an AccountEntity object from AccountInfo + * @param accountInfo + * @param cloudGraphHostName + * @param msGraphHost + * @returns + */ + static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) { + const account = new _AccountEntity(); + account.authorityType = accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE; + account.homeAccountId = accountInfo.homeAccountId; + account.localAccountId = accountInfo.localAccountId; + account.nativeAccountId = accountInfo.nativeAccountId; + account.realm = accountInfo.tenantId; + account.environment = accountInfo.environment; + account.username = accountInfo.username; + account.name = accountInfo.name; + account.cloudGraphHostName = cloudGraphHostName; + account.msGraphHost = msGraphHost; + account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []); + return account; + } + /** + * Generate HomeAccountId from server response + * @param serverClientInfo + * @param authType + */ + static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) { + if (!(authType === AuthorityType.Adfs || authType === AuthorityType.Dsts)) { + if (serverClientInfo) { + try { + const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode); + if (clientInfo.uid && clientInfo.utid) { + return `${clientInfo.uid}.${clientInfo.utid}`; + } + } catch (e) { + } + } + logger.warning("No client info in response"); + } + return idTokenClaims?.sub || ""; + } + /** + * Validates an entity: checks for all expected params + * @param entity + */ + static isAccountEntity(entity) { + if (!entity) { + return false; + } + return entity.hasOwnProperty("homeAccountId") && entity.hasOwnProperty("environment") && entity.hasOwnProperty("realm") && entity.hasOwnProperty("localAccountId") && entity.hasOwnProperty("username") && entity.hasOwnProperty("authorityType"); + } + /** + * Helper function to determine whether 2 accountInfo objects represent the same account + * @param accountA + * @param accountB + * @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality + */ + static accountInfoIsEqual(accountA, accountB, compareClaims) { + if (!accountA || !accountB) { + return false; + } + let claimsMatch = true; + if (compareClaims) { + const accountAClaims = accountA.idTokenClaims || {}; + const accountBClaims = accountB.idTokenClaims || {}; + claimsMatch = accountAClaims.iat === accountBClaims.iat && accountAClaims.nonce === accountBClaims.nonce; + } + return accountA.homeAccountId === accountB.homeAccountId && accountA.localAccountId === accountB.localAccountId && accountA.username === accountB.username && accountA.tenantId === accountB.tenantId && accountA.environment === accountB.environment && accountA.nativeAccountId === accountB.nativeAccountId && claimsMatch; + } + }; + function stripLeadingHashOrQuery(responseString) { + if (responseString.startsWith("#/")) { + return responseString.substring(2); + } else if (responseString.startsWith("#") || responseString.startsWith("?")) { + return responseString.substring(1); + } + return responseString; + } + function getDeserializedResponse(responseString) { + if (!responseString || responseString.indexOf("=") < 0) { + return null; + } + try { + const normalizedResponse = stripLeadingHashOrQuery(responseString); + const deserializedHash = Object.fromEntries(new URLSearchParams(normalizedResponse)); + if (deserializedHash.code || deserializedHash.error || deserializedHash.error_description || deserializedHash.state) { + return deserializedHash; + } + } catch (e) { + throw createClientAuthError(hashNotDeserialized); + } + return null; + } + var UrlString = class _UrlString { + get urlString() { + return this._urlString; + } + constructor(url) { + this._urlString = url; + if (!this._urlString) { + throw createClientConfigurationError(urlEmptyError); + } + if (!url.includes("#")) { + this._urlString = _UrlString.canonicalizeUri(url); + } + } + /** + * Ensure urls are lower case and end with a / character. + * @param url + */ + static canonicalizeUri(url) { + if (url) { + let lowerCaseUrl = url.toLowerCase(); + if (StringUtils.endsWith(lowerCaseUrl, "?")) { + lowerCaseUrl = lowerCaseUrl.slice(0, -1); + } else if (StringUtils.endsWith(lowerCaseUrl, "?/")) { + lowerCaseUrl = lowerCaseUrl.slice(0, -2); + } + if (!StringUtils.endsWith(lowerCaseUrl, "/")) { + lowerCaseUrl += "/"; + } + return lowerCaseUrl; + } + return url; + } + /** + * Throws if urlString passed is not a valid authority URI string. + */ + validateAsUri() { + let components; + try { + components = this.getUrlComponents(); + } catch (e) { + throw createClientConfigurationError(urlParseError); + } + if (!components.HostNameAndPort || !components.PathSegments) { + throw createClientConfigurationError(urlParseError); + } + if (!components.Protocol || components.Protocol.toLowerCase() !== "https:") { + throw createClientConfigurationError(authorityUriInsecure); + } + } + /** + * Given a url and a query string return the url with provided query string appended + * @param url + * @param queryString + */ + static appendQueryString(url, queryString) { + if (!queryString) { + return url; + } + return url.indexOf("?") < 0 ? `${url}?${queryString}` : `${url}&${queryString}`; + } + /** + * Returns a url with the hash removed + * @param url + */ + static removeHashFromUrl(url) { + return _UrlString.canonicalizeUri(url.split("#")[0]); + } + /** + * Given a url like https://a:b/common/d?e=f#g, and a tenantId, returns https://a:b/tenantId/d + * @param href The url + * @param tenantId The tenant id to replace + */ + replaceTenantPath(tenantId) { + const urlObject = this.getUrlComponents(); + const pathArray = urlObject.PathSegments; + if (tenantId && pathArray.length !== 0 && (pathArray[0] === AADAuthorityConstants.COMMON || pathArray[0] === AADAuthorityConstants.ORGANIZATIONS)) { + pathArray[0] = tenantId; + } + return _UrlString.constructAuthorityUriFromObject(urlObject); + } + /** + * Parses out the components from a url string. + * @returns An object with the various components. Please cache this value insted of calling this multiple times on the same url. + */ + getUrlComponents() { + const regEx = RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"); + const match = this.urlString.match(regEx); + if (!match) { + throw createClientConfigurationError(urlParseError); + } + const urlComponents = { + Protocol: match[1], + HostNameAndPort: match[4], + AbsolutePath: match[5], + QueryString: match[7] + }; + let pathSegments = urlComponents.AbsolutePath.split("/"); + pathSegments = pathSegments.filter((val) => val && val.length > 0); + urlComponents.PathSegments = pathSegments; + if (urlComponents.QueryString && urlComponents.QueryString.endsWith("/")) { + urlComponents.QueryString = urlComponents.QueryString.substring(0, urlComponents.QueryString.length - 1); + } + return urlComponents; + } + static getDomainFromUrl(url) { + const regEx = RegExp("^([^:/?#]+://)?([^/?#]*)"); + const match = url.match(regEx); + if (!match) { + throw createClientConfigurationError(urlParseError); + } + return match[2]; + } + static getAbsoluteUrl(relativeUrl, baseUrl) { + if (relativeUrl[0] === Constants$1.FORWARD_SLASH) { + const url = new _UrlString(baseUrl); + const baseComponents = url.getUrlComponents(); + return baseComponents.Protocol + "//" + baseComponents.HostNameAndPort + relativeUrl; + } + return relativeUrl; + } + static constructAuthorityUriFromObject(urlObject) { + return new _UrlString(urlObject.Protocol + "//" + urlObject.HostNameAndPort + "/" + urlObject.PathSegments.join("/")); + } + /** + * Check if the hash of the URL string contains known properties + * @deprecated This API will be removed in a future version + */ + static hashContainsKnownProperties(response) { + return !!getDeserializedResponse(response); + } + }; + var rawMetdataJSON = { + endpointMetadata: { + "login.microsoftonline.com": { + token_endpoint: "https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token", + jwks_uri: "https://login.microsoftonline.com/{tenantid}/discovery/v2.0/keys", + issuer: "https://login.microsoftonline.com/{tenantid}/v2.0", + authorization_endpoint: "https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize", + end_session_endpoint: "https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/logout" + }, + "login.chinacloudapi.cn": { + token_endpoint: "https://login.chinacloudapi.cn/{tenantid}/oauth2/v2.0/token", + jwks_uri: "https://login.chinacloudapi.cn/{tenantid}/discovery/v2.0/keys", + issuer: "https://login.partner.microsoftonline.cn/{tenantid}/v2.0", + authorization_endpoint: "https://login.chinacloudapi.cn/{tenantid}/oauth2/v2.0/authorize", + end_session_endpoint: "https://login.chinacloudapi.cn/{tenantid}/oauth2/v2.0/logout" + }, + "login.microsoftonline.us": { + token_endpoint: "https://login.microsoftonline.us/{tenantid}/oauth2/v2.0/token", + jwks_uri: "https://login.microsoftonline.us/{tenantid}/discovery/v2.0/keys", + issuer: "https://login.microsoftonline.us/{tenantid}/v2.0", + authorization_endpoint: "https://login.microsoftonline.us/{tenantid}/oauth2/v2.0/authorize", + end_session_endpoint: "https://login.microsoftonline.us/{tenantid}/oauth2/v2.0/logout" + } + }, + instanceDiscoveryMetadata: { + metadata: [ + { + preferred_network: "login.microsoftonline.com", + preferred_cache: "login.windows.net", + aliases: [ + "login.microsoftonline.com", + "login.windows.net", + "login.microsoft.com", + "sts.windows.net" + ] + }, + { + preferred_network: "login.partner.microsoftonline.cn", + preferred_cache: "login.partner.microsoftonline.cn", + aliases: [ + "login.partner.microsoftonline.cn", + "login.chinacloudapi.cn" + ] + }, + { + preferred_network: "login.microsoftonline.de", + preferred_cache: "login.microsoftonline.de", + aliases: ["login.microsoftonline.de"] + }, + { + preferred_network: "login.microsoftonline.us", + preferred_cache: "login.microsoftonline.us", + aliases: [ + "login.microsoftonline.us", + "login.usgovcloudapi.net" + ] + }, + { + preferred_network: "login-us.microsoftonline.com", + preferred_cache: "login-us.microsoftonline.com", + aliases: ["login-us.microsoftonline.com"] + } + ] + } + }; + var EndpointMetadata = rawMetdataJSON.endpointMetadata; + var InstanceDiscoveryMetadata = rawMetdataJSON.instanceDiscoveryMetadata; + var InstanceDiscoveryMetadataAliases = /* @__PURE__ */ new Set(); + InstanceDiscoveryMetadata.metadata.forEach((metadataEntry) => { + metadataEntry.aliases.forEach((alias) => { + InstanceDiscoveryMetadataAliases.add(alias); + }); + }); + function getAliasesFromStaticSources(staticAuthorityOptions, logger) { + let staticAliases; + const canonicalAuthority = staticAuthorityOptions.canonicalAuthority; + if (canonicalAuthority) { + const authorityHost = new UrlString(canonicalAuthority).getUrlComponents().HostNameAndPort; + staticAliases = getAliasesFromMetadata(authorityHost, staticAuthorityOptions.cloudDiscoveryMetadata?.metadata, AuthorityMetadataSource.CONFIG, logger) || getAliasesFromMetadata(authorityHost, InstanceDiscoveryMetadata.metadata, AuthorityMetadataSource.HARDCODED_VALUES, logger) || staticAuthorityOptions.knownAuthorities; + } + return staticAliases || []; + } + function getAliasesFromMetadata(authorityHost, cloudDiscoveryMetadata, source, logger) { + logger?.trace(`getAliasesFromMetadata called with source: ${source}`); + if (authorityHost && cloudDiscoveryMetadata) { + const metadata = getCloudDiscoveryMetadataFromNetworkResponse(cloudDiscoveryMetadata, authorityHost); + if (metadata) { + logger?.trace(`getAliasesFromMetadata: found cloud discovery metadata in ${source}, returning aliases`); + return metadata.aliases; + } else { + logger?.trace(`getAliasesFromMetadata: did not find cloud discovery metadata in ${source}`); + } + } + return null; + } + function getCloudDiscoveryMetadataFromHardcodedValues(authorityHost) { + const metadata = getCloudDiscoveryMetadataFromNetworkResponse(InstanceDiscoveryMetadata.metadata, authorityHost); + return metadata; + } + function getCloudDiscoveryMetadataFromNetworkResponse(response, authorityHost) { + for (let i = 0; i < response.length; i++) { + const metadata = response[i]; + if (metadata.aliases.includes(authorityHost)) { + return metadata; + } + } + return null; + } + var cacheQuotaExceeded = "cache_quota_exceeded"; + var cacheErrorUnknown = "cache_error_unknown"; + var CacheErrorMessages = { + [cacheQuotaExceeded]: "Exceeded cache storage capacity.", + [cacheErrorUnknown]: "Unexpected error occurred when using cache storage." + }; + var CacheError = class _CacheError extends Error { + constructor(errorCode, errorMessage) { + const message = errorMessage || (CacheErrorMessages[errorCode] ? CacheErrorMessages[errorCode] : CacheErrorMessages[cacheErrorUnknown]); + super(`${errorCode}: ${message}`); + Object.setPrototypeOf(this, _CacheError.prototype); + this.name = "CacheError"; + this.errorCode = errorCode; + this.errorMessage = message; + } + }; + function createCacheError(e) { + if (!(e instanceof Error)) { + return new CacheError(cacheErrorUnknown); + } + if (e.name === "QuotaExceededError" || e.name === "NS_ERROR_DOM_QUOTA_REACHED" || e.message.includes("exceeded the quota")) { + return new CacheError(cacheQuotaExceeded); + } else { + return new CacheError(e.name, e.message); + } + } + var CacheManager = class _CacheManager { + constructor(clientId, cryptoImpl, logger, staticAuthorityOptions) { + this.clientId = clientId; + this.cryptoImpl = cryptoImpl; + this.commonLogger = logger.clone(name$1, version$1); + this.staticAuthorityOptions = staticAuthorityOptions; + } + /** + * Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned. + * @param accountFilter - (Optional) filter to narrow down the accounts returned + * @returns Array of AccountInfo objects in cache + */ + getAllAccounts(correlationId, accountFilter) { + return this.buildTenantProfiles(this.getAccountsFilteredBy(accountFilter || {}, correlationId), correlationId, accountFilter); + } + /** + * Gets first tenanted AccountInfo object found based on provided filters + */ + getAccountInfoFilteredBy(accountFilter, correlationId) { + const allAccounts = this.getAllAccounts(correlationId, accountFilter); + if (allAccounts.length > 1) { + const sortedAccounts = allAccounts.sort((account) => { + return account.idTokenClaims ? -1 : 1; + }); + return sortedAccounts[0]; + } else if (allAccounts.length === 1) { + return allAccounts[0]; + } else { + return null; + } + } + /** + * Returns a single matching + * @param accountFilter + * @returns + */ + getBaseAccountInfo(accountFilter, correlationId) { + const accountEntities = this.getAccountsFilteredBy(accountFilter, correlationId); + if (accountEntities.length > 0) { + return accountEntities[0].getAccountInfo(); + } else { + return null; + } + } + /** + * Matches filtered account entities with cached ID tokens that match the tenant profile-specific account filters + * and builds the account info objects from the matching ID token's claims + * @param cachedAccounts + * @param accountFilter + * @returns Array of AccountInfo objects that match account and tenant profile filters + */ + buildTenantProfiles(cachedAccounts, correlationId, accountFilter) { + return cachedAccounts.flatMap((accountEntity) => { + return this.getTenantProfilesFromAccountEntity(accountEntity, correlationId, accountFilter?.tenantId, accountFilter); + }); + } + getTenantedAccountInfoByFilter(accountInfo, tokenKeys, tenantProfile, correlationId, tenantProfileFilter) { + let tenantedAccountInfo = null; + let idTokenClaims; + if (tenantProfileFilter) { + if (!this.tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter)) { + return null; + } + } + const idToken = this.getIdToken(accountInfo, correlationId, tokenKeys, tenantProfile.tenantId); + if (idToken) { + idTokenClaims = extractTokenClaims(idToken.secret, this.cryptoImpl.base64Decode); + if (!this.idTokenClaimsMatchTenantProfileFilter(idTokenClaims, tenantProfileFilter)) { + return null; + } + } + tenantedAccountInfo = updateAccountTenantProfileData(accountInfo, tenantProfile, idTokenClaims, idToken?.secret); + return tenantedAccountInfo; + } + getTenantProfilesFromAccountEntity(accountEntity, correlationId, targetTenantId, tenantProfileFilter) { + const accountInfo = accountEntity.getAccountInfo(); + let searchTenantProfiles = accountInfo.tenantProfiles || /* @__PURE__ */ new Map(); + const tokenKeys = this.getTokenKeys(); + if (targetTenantId) { + const tenantProfile = searchTenantProfiles.get(targetTenantId); + if (tenantProfile) { + searchTenantProfiles = /* @__PURE__ */ new Map([ + [targetTenantId, tenantProfile] + ]); + } else { + return []; + } + } + const matchingTenantProfiles = []; + searchTenantProfiles.forEach((tenantProfile) => { + const tenantedAccountInfo = this.getTenantedAccountInfoByFilter(accountInfo, tokenKeys, tenantProfile, correlationId, tenantProfileFilter); + if (tenantedAccountInfo) { + matchingTenantProfiles.push(tenantedAccountInfo); + } + }); + return matchingTenantProfiles; + } + tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter) { + if (!!tenantProfileFilter.localAccountId && !this.matchLocalAccountIdFromTenantProfile(tenantProfile, tenantProfileFilter.localAccountId)) { + return false; + } + if (!!tenantProfileFilter.name && !(tenantProfile.name === tenantProfileFilter.name)) { + return false; + } + if (tenantProfileFilter.isHomeTenant !== void 0 && !(tenantProfile.isHomeTenant === tenantProfileFilter.isHomeTenant)) { + return false; + } + return true; + } + idTokenClaimsMatchTenantProfileFilter(idTokenClaims, tenantProfileFilter) { + if (tenantProfileFilter) { + if (!!tenantProfileFilter.localAccountId && !this.matchLocalAccountIdFromTokenClaims(idTokenClaims, tenantProfileFilter.localAccountId)) { + return false; + } + if (!!tenantProfileFilter.loginHint && !this.matchLoginHintFromTokenClaims(idTokenClaims, tenantProfileFilter.loginHint)) { + return false; + } + if (!!tenantProfileFilter.username && !this.matchUsername(idTokenClaims.preferred_username, tenantProfileFilter.username)) { + return false; + } + if (!!tenantProfileFilter.name && !this.matchName(idTokenClaims, tenantProfileFilter.name)) { + return false; + } + if (!!tenantProfileFilter.sid && !this.matchSid(idTokenClaims, tenantProfileFilter.sid)) { + return false; + } + } + return true; + } + /** + * saves a cache record + * @param cacheRecord {CacheRecord} + * @param storeInCache {?StoreInCache} + * @param correlationId {?string} correlation id + */ + async saveCacheRecord(cacheRecord, correlationId, storeInCache) { + if (!cacheRecord) { + throw createClientAuthError(invalidCacheRecord); + } + try { + if (!!cacheRecord.account) { + this.setAccount(cacheRecord.account, correlationId); + } + if (!!cacheRecord.idToken && storeInCache?.idToken !== false) { + this.setIdTokenCredential(cacheRecord.idToken, correlationId); + } + if (!!cacheRecord.accessToken && storeInCache?.accessToken !== false) { + await this.saveAccessToken(cacheRecord.accessToken, correlationId); + } + if (!!cacheRecord.refreshToken && storeInCache?.refreshToken !== false) { + this.setRefreshTokenCredential(cacheRecord.refreshToken, correlationId); + } + if (!!cacheRecord.appMetadata) { + this.setAppMetadata(cacheRecord.appMetadata, correlationId); + } + } catch (e) { + this.commonLogger?.error(`CacheManager.saveCacheRecord: failed`); + if (e instanceof AuthError) { + throw e; + } else { + throw createCacheError(e); + } + } + } + /** + * saves access token credential + * @param credential + */ + async saveAccessToken(credential, correlationId) { + const accessTokenFilter = { + clientId: credential.clientId, + credentialType: credential.credentialType, + environment: credential.environment, + homeAccountId: credential.homeAccountId, + realm: credential.realm, + tokenType: credential.tokenType, + requestedClaimsHash: credential.requestedClaimsHash + }; + const tokenKeys = this.getTokenKeys(); + const currentScopes = ScopeSet.fromString(credential.target); + tokenKeys.accessToken.forEach((key) => { + if (!this.accessTokenKeyMatchesFilter(key, accessTokenFilter, false)) { + return; + } + const tokenEntity = this.getAccessTokenCredential(key, correlationId); + if (tokenEntity && this.credentialMatchesFilter(tokenEntity, accessTokenFilter)) { + const tokenScopeSet = ScopeSet.fromString(tokenEntity.target); + if (tokenScopeSet.intersectingScopeSets(currentScopes)) { + this.removeAccessToken(key, correlationId); + } + } + }); + this.setAccessTokenCredential(credential, correlationId); + } + /** + * Retrieve account entities matching all provided tenant-agnostic filters; if no filter is set, get all account entities in the cache + * Not checking for casing as keys are all generated in lower case, remember to convert to lower case if object properties are compared + * @param accountFilter - An object containing Account properties to filter by + */ + getAccountsFilteredBy(accountFilter, correlationId) { + const allAccountKeys = this.getAccountKeys(); + const matchingAccounts = []; + allAccountKeys.forEach((cacheKey) => { + if (!this.isAccountKey(cacheKey, accountFilter.homeAccountId)) { + return; + } + const entity = this.getAccount(cacheKey, correlationId, this.commonLogger); + if (!entity) { + return; + } + if (!!accountFilter.homeAccountId && !this.matchHomeAccountId(entity, accountFilter.homeAccountId)) { + return; + } + if (!!accountFilter.username && !this.matchUsername(entity.username, accountFilter.username)) { + return; + } + if (!!accountFilter.environment && !this.matchEnvironment(entity, accountFilter.environment)) { + return; + } + if (!!accountFilter.realm && !this.matchRealm(entity, accountFilter.realm)) { + return; + } + if (!!accountFilter.nativeAccountId && !this.matchNativeAccountId(entity, accountFilter.nativeAccountId)) { + return; + } + if (!!accountFilter.authorityType && !this.matchAuthorityType(entity, accountFilter.authorityType)) { + return; + } + const tenantProfileFilter = { + localAccountId: accountFilter?.localAccountId, + name: accountFilter?.name + }; + const matchingTenantProfiles = entity.tenantProfiles?.filter((tenantProfile) => { + return this.tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter); + }); + if (matchingTenantProfiles && matchingTenantProfiles.length === 0) { + return; + } + matchingAccounts.push(entity); + }); + return matchingAccounts; + } + /** + * Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided + * @param key + * @param homeAccountId + * @param tenantId + * @returns + */ + isAccountKey(key, homeAccountId, tenantId) { + if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 3) { + return false; + } + if (homeAccountId && !key.toLowerCase().includes(homeAccountId.toLowerCase())) { + return false; + } + if (tenantId && !key.toLowerCase().includes(tenantId.toLowerCase())) { + return false; + } + return true; + } + /** + * Returns true if the given key matches our credential key schema. + * @param key + */ + isCredentialKey(key) { + if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 6) { + return false; + } + const lowerCaseKey = key.toLowerCase(); + if (lowerCaseKey.indexOf(CredentialType.ID_TOKEN.toLowerCase()) === -1 && lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN.toLowerCase()) === -1 && lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) === -1 && lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) === -1) { + return false; + } + if (lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) > -1) { + const clientIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${this.clientId}${Separators.CACHE_KEY_SEPARATOR}`; + const familyIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${THE_FAMILY_ID}${Separators.CACHE_KEY_SEPARATOR}`; + if (lowerCaseKey.indexOf(clientIdValidation.toLowerCase()) === -1 && lowerCaseKey.indexOf(familyIdValidation.toLowerCase()) === -1) { + return false; + } + } else if (lowerCaseKey.indexOf(this.clientId.toLowerCase()) === -1) { + return false; + } + return true; + } + /** + * Returns whether or not the given credential entity matches the filter + * @param entity + * @param filter + * @returns + */ + credentialMatchesFilter(entity, filter) { + if (!!filter.clientId && !this.matchClientId(entity, filter.clientId)) { + return false; + } + if (!!filter.userAssertionHash && !this.matchUserAssertionHash(entity, filter.userAssertionHash)) { + return false; + } + if (typeof filter.homeAccountId === "string" && !this.matchHomeAccountId(entity, filter.homeAccountId)) { + return false; + } + if (!!filter.environment && !this.matchEnvironment(entity, filter.environment)) { + return false; + } + if (!!filter.realm && !this.matchRealm(entity, filter.realm)) { + return false; + } + if (!!filter.credentialType && !this.matchCredentialType(entity, filter.credentialType)) { + return false; + } + if (!!filter.familyId && !this.matchFamilyId(entity, filter.familyId)) { + return false; + } + if (!!filter.target && !this.matchTarget(entity, filter.target)) { + return false; + } + if (filter.requestedClaimsHash || entity.requestedClaimsHash) { + if (entity.requestedClaimsHash !== filter.requestedClaimsHash) { + return false; + } + } + if (entity.credentialType === CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME) { + if (!!filter.tokenType && !this.matchTokenType(entity, filter.tokenType)) { + return false; + } + if (filter.tokenType === AuthenticationScheme.SSH) { + if (filter.keyId && !this.matchKeyId(entity, filter.keyId)) { + return false; + } + } + } + return true; + } + /** + * retrieve appMetadata matching all provided filters; if no filter is set, get all appMetadata + * @param filter + */ + getAppMetadataFilteredBy(filter) { + const allCacheKeys = this.getKeys(); + const matchingAppMetadata = {}; + allCacheKeys.forEach((cacheKey) => { + if (!this.isAppMetadata(cacheKey)) { + return; + } + const entity = this.getAppMetadata(cacheKey); + if (!entity) { + return; + } + if (!!filter.environment && !this.matchEnvironment(entity, filter.environment)) { + return; + } + if (!!filter.clientId && !this.matchClientId(entity, filter.clientId)) { + return; + } + matchingAppMetadata[cacheKey] = entity; + }); + return matchingAppMetadata; + } + /** + * retrieve authorityMetadata that contains a matching alias + * @param filter + */ + getAuthorityMetadataByAlias(host) { + const allCacheKeys = this.getAuthorityMetadataKeys(); + let matchedEntity = null; + allCacheKeys.forEach((cacheKey) => { + if (!this.isAuthorityMetadata(cacheKey) || cacheKey.indexOf(this.clientId) === -1) { + return; + } + const entity = this.getAuthorityMetadata(cacheKey); + if (!entity) { + return; + } + if (entity.aliases.indexOf(host) === -1) { + return; + } + matchedEntity = entity; + }); + return matchedEntity; + } + /** + * Removes all accounts and related tokens from cache. + */ + async removeAllAccounts(correlationId) { + const allAccountKeys = this.getAccountKeys(); + const removedAccounts = []; + allAccountKeys.forEach((cacheKey) => { + removedAccounts.push(this.removeAccount(cacheKey, correlationId)); + }); + await Promise.all(removedAccounts); + } + /** + * Removes the account and related tokens for a given account key + * @param account + */ + async removeAccount(accountKey, correlationId) { + const account = this.getAccount(accountKey, correlationId, this.commonLogger); + if (!account) { + return; + } + await this.removeAccountContext(account, correlationId); + this.removeItem(accountKey, correlationId); + } + /** + * Removes credentials associated with the provided account + * @param account + */ + async removeAccountContext(account, correlationId) { + const allTokenKeys = this.getTokenKeys(); + const accountId = account.generateAccountId(); + allTokenKeys.idToken.forEach((key) => { + if (key.indexOf(accountId) === 0) { + this.removeIdToken(key, correlationId); + } + }); + allTokenKeys.accessToken.forEach((key) => { + if (key.indexOf(accountId) === 0) { + this.removeAccessToken(key, correlationId); + } + }); + allTokenKeys.refreshToken.forEach((key) => { + if (key.indexOf(accountId) === 0) { + this.removeRefreshToken(key, correlationId); + } + }); + this.getKeys().forEach((key) => { + if (key.includes(accountId)) { + this.removeItem(key, correlationId); + } + }); + } + /** + * Migrates a single-tenant account and all it's associated alternate cross-tenant account objects in the + * cache into a condensed multi-tenant account object with tenant profiles. + * @param accountKey + * @param accountEntity + * @param logger + * @returns + */ + updateOutdatedCachedAccount(accountKey, accountEntity, correlationId, logger) { + if (accountEntity && accountEntity.isSingleTenant()) { + this.commonLogger?.verbose("updateOutdatedCachedAccount: Found a single-tenant (outdated) account entity in the cache, migrating to multi-tenant account entity"); + const matchingAccountKeys = this.getAccountKeys().filter((key) => { + return key.startsWith(accountEntity.homeAccountId); + }); + const accountsToMerge = []; + matchingAccountKeys.forEach((key) => { + const account = this.getCachedAccountEntity(key, correlationId); + if (account) { + accountsToMerge.push(account); + } + }); + const baseAccount = accountsToMerge.find((account) => { + return tenantIdMatchesHomeTenant(account.realm, account.homeAccountId); + }) || accountsToMerge[0]; + baseAccount.tenantProfiles = accountsToMerge.map((account) => { + return { + tenantId: account.realm, + localAccountId: account.localAccountId, + name: account.name, + isHomeTenant: tenantIdMatchesHomeTenant(account.realm, account.homeAccountId) + }; + }); + const updatedAccount = _CacheManager.toObject(new AccountEntity(), { + ...baseAccount + }); + const newAccountKey = updatedAccount.generateAccountKey(); + matchingAccountKeys.forEach((key) => { + if (key !== newAccountKey) { + this.removeOutdatedAccount(accountKey, correlationId); + } + }); + this.setAccount(updatedAccount, correlationId); + logger?.verbose("Updated an outdated account entity in the cache"); + return updatedAccount; + } + return accountEntity; + } + /** + * returns a boolean if the given credential is removed + * @param credential + */ + removeAccessToken(key, correlationId) { + const credential = this.getAccessTokenCredential(key, correlationId); + this.removeItem(key, correlationId); + if (!credential || credential.credentialType.toLowerCase() !== CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase() || credential.tokenType !== AuthenticationScheme.POP) { + return; + } + const kid = credential.keyId; + if (kid) { + void this.cryptoImpl.removeTokenBindingKey(kid).catch(() => { + this.commonLogger.error("Binding key could not be removed"); + }); + } + } + /** + * Removes all app metadata objects from cache. + */ + removeAppMetadata(correlationId) { + const allCacheKeys = this.getKeys(); + allCacheKeys.forEach((cacheKey) => { + if (this.isAppMetadata(cacheKey)) { + this.removeItem(cacheKey, correlationId); + } + }); + return true; + } + /** + * Retrieve AccountEntity from cache + * @param account + */ + readAccountFromCache(account, correlationId) { + const accountKey = AccountEntity.generateAccountCacheKey(account); + return this.getAccount(accountKey, correlationId, this.commonLogger); + } + /** + * Retrieve IdTokenEntity from cache + * @param account {AccountInfo} + * @param tokenKeys {?TokenKeys} + * @param targetRealm {?string} + * @param performanceClient {?IPerformanceClient} + * @param correlationId {?string} + */ + getIdToken(account, correlationId, tokenKeys, targetRealm, performanceClient) { + this.commonLogger.trace("CacheManager - getIdToken called"); + const idTokenFilter = { + homeAccountId: account.homeAccountId, + environment: account.environment, + credentialType: CredentialType.ID_TOKEN, + clientId: this.clientId, + realm: targetRealm + }; + const idTokenMap = this.getIdTokensByFilter(idTokenFilter, correlationId, tokenKeys); + const numIdTokens = idTokenMap.size; + if (numIdTokens < 1) { + this.commonLogger.info("CacheManager:getIdToken - No token found"); + return null; + } else if (numIdTokens > 1) { + let tokensToBeRemoved = idTokenMap; + if (!targetRealm) { + const homeIdTokenMap = /* @__PURE__ */ new Map(); + idTokenMap.forEach((idToken, key) => { + if (idToken.realm === account.tenantId) { + homeIdTokenMap.set(key, idToken); + } + }); + const numHomeIdTokens = homeIdTokenMap.size; + if (numHomeIdTokens < 1) { + this.commonLogger.info("CacheManager:getIdToken - Multiple ID tokens found for account but none match account entity tenant id, returning first result"); + return idTokenMap.values().next().value; + } else if (numHomeIdTokens === 1) { + this.commonLogger.info("CacheManager:getIdToken - Multiple ID tokens found for account, defaulting to home tenant profile"); + return homeIdTokenMap.values().next().value; + } else { + tokensToBeRemoved = homeIdTokenMap; + } + } + this.commonLogger.info("CacheManager:getIdToken - Multiple matching ID tokens found, clearing them"); + tokensToBeRemoved.forEach((idToken, key) => { + this.removeIdToken(key, correlationId); + }); + if (performanceClient && correlationId) { + performanceClient.addFields({ multiMatchedID: idTokenMap.size }, correlationId); + } + return null; + } + this.commonLogger.info("CacheManager:getIdToken - Returning ID token"); + return idTokenMap.values().next().value; + } + /** + * Gets all idTokens matching the given filter + * @param filter + * @returns + */ + getIdTokensByFilter(filter, correlationId, tokenKeys) { + const idTokenKeys = tokenKeys && tokenKeys.idToken || this.getTokenKeys().idToken; + const idTokens = /* @__PURE__ */ new Map(); + idTokenKeys.forEach((key) => { + if (!this.idTokenKeyMatchesFilter(key, { + clientId: this.clientId, + ...filter + })) { + return; + } + const idToken = this.getIdTokenCredential(key, correlationId); + if (idToken && this.credentialMatchesFilter(idToken, filter)) { + idTokens.set(key, idToken); + } + }); + return idTokens; + } + /** + * Validate the cache key against filter before retrieving and parsing cache value + * @param key + * @param filter + * @returns + */ + idTokenKeyMatchesFilter(inputKey, filter) { + const key = inputKey.toLowerCase(); + if (filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) { + return false; + } + if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) { + return false; + } + return true; + } + /** + * Removes idToken from the cache + * @param key + */ + removeIdToken(key, correlationId) { + this.removeItem(key, correlationId); + } + /** + * Removes refresh token from the cache + * @param key + */ + removeRefreshToken(key, correlationId) { + this.removeItem(key, correlationId); + } + /** + * Retrieve AccessTokenEntity from cache + * @param account {AccountInfo} + * @param request {BaseAuthRequest} + * @param tokenKeys {?TokenKeys} + * @param performanceClient {?IPerformanceClient} + * @param correlationId {?string} + */ + getAccessToken(account, request, tokenKeys, targetRealm, performanceClient) { + this.commonLogger.trace("CacheManager - getAccessToken called"); + const scopes = ScopeSet.createSearchScopes(request.scopes); + const authScheme = request.authenticationScheme || AuthenticationScheme.BEARER; + const credentialType = authScheme.toLowerCase() !== AuthenticationScheme.BEARER.toLowerCase() ? CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME : CredentialType.ACCESS_TOKEN; + const accessTokenFilter = { + homeAccountId: account.homeAccountId, + environment: account.environment, + credentialType, + clientId: this.clientId, + realm: targetRealm || account.tenantId, + target: scopes, + tokenType: authScheme, + keyId: request.sshKid, + requestedClaimsHash: request.requestedClaimsHash + }; + const accessTokenKeys = tokenKeys && tokenKeys.accessToken || this.getTokenKeys().accessToken; + const accessTokens = []; + accessTokenKeys.forEach((key) => { + if (this.accessTokenKeyMatchesFilter(key, accessTokenFilter, true)) { + const accessToken = this.getAccessTokenCredential(key, request.correlationId); + if (accessToken && this.credentialMatchesFilter(accessToken, accessTokenFilter)) { + accessTokens.push(accessToken); + } + } + }); + const numAccessTokens = accessTokens.length; + if (numAccessTokens < 1) { + this.commonLogger.info("CacheManager:getAccessToken - No token found"); + return null; + } else if (numAccessTokens > 1) { + this.commonLogger.info("CacheManager:getAccessToken - Multiple access tokens found, clearing them"); + accessTokens.forEach((accessToken) => { + void this.removeAccessToken(generateCredentialKey(accessToken), request.correlationId); + }); + if (performanceClient && request.correlationId) { + performanceClient.addFields({ multiMatchedAT: accessTokens.length }, request.correlationId); + } + return null; + } + this.commonLogger.info("CacheManager:getAccessToken - Returning access token"); + return accessTokens[0]; + } + /** + * Validate the cache key against filter before retrieving and parsing cache value + * @param key + * @param filter + * @param keyMustContainAllScopes + * @returns + */ + accessTokenKeyMatchesFilter(inputKey, filter, keyMustContainAllScopes) { + const key = inputKey.toLowerCase(); + if (filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) { + return false; + } + if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) { + return false; + } + if (filter.realm && key.indexOf(filter.realm.toLowerCase()) === -1) { + return false; + } + if (filter.requestedClaimsHash && key.indexOf(filter.requestedClaimsHash.toLowerCase()) === -1) { + return false; + } + if (filter.target) { + const scopes = filter.target.asArray(); + for (let i = 0; i < scopes.length; i++) { + if (keyMustContainAllScopes && !key.includes(scopes[i].toLowerCase())) { + return false; + } else if (!keyMustContainAllScopes && key.includes(scopes[i].toLowerCase())) { + return true; + } + } + } + return true; + } + /** + * Gets all access tokens matching the filter + * @param filter + * @returns + */ + getAccessTokensByFilter(filter, correlationId) { + const tokenKeys = this.getTokenKeys(); + const accessTokens = []; + tokenKeys.accessToken.forEach((key) => { + if (!this.accessTokenKeyMatchesFilter(key, filter, true)) { + return; + } + const accessToken = this.getAccessTokenCredential(key, correlationId); + if (accessToken && this.credentialMatchesFilter(accessToken, filter)) { + accessTokens.push(accessToken); + } + }); + return accessTokens; + } + /** + * Helper to retrieve the appropriate refresh token from cache + * @param account {AccountInfo} + * @param familyRT {boolean} + * @param tokenKeys {?TokenKeys} + * @param performanceClient {?IPerformanceClient} + * @param correlationId {?string} + */ + getRefreshToken(account, familyRT, correlationId, tokenKeys, performanceClient) { + this.commonLogger.trace("CacheManager - getRefreshToken called"); + const id = familyRT ? THE_FAMILY_ID : void 0; + const refreshTokenFilter = { + homeAccountId: account.homeAccountId, + environment: account.environment, + credentialType: CredentialType.REFRESH_TOKEN, + clientId: this.clientId, + familyId: id + }; + const refreshTokenKeys = tokenKeys && tokenKeys.refreshToken || this.getTokenKeys().refreshToken; + const refreshTokens = []; + refreshTokenKeys.forEach((key) => { + if (this.refreshTokenKeyMatchesFilter(key, refreshTokenFilter)) { + const refreshToken = this.getRefreshTokenCredential(key, correlationId); + if (refreshToken && this.credentialMatchesFilter(refreshToken, refreshTokenFilter)) { + refreshTokens.push(refreshToken); + } + } + }); + const numRefreshTokens = refreshTokens.length; + if (numRefreshTokens < 1) { + this.commonLogger.info("CacheManager:getRefreshToken - No refresh token found."); + return null; + } + if (numRefreshTokens > 1 && performanceClient && correlationId) { + performanceClient.addFields({ multiMatchedRT: numRefreshTokens }, correlationId); + } + this.commonLogger.info("CacheManager:getRefreshToken - returning refresh token"); + return refreshTokens[0]; + } + /** + * Validate the cache key against filter before retrieving and parsing cache value + * @param key + * @param filter + */ + refreshTokenKeyMatchesFilter(inputKey, filter) { + const key = inputKey.toLowerCase(); + if (filter.familyId && key.indexOf(filter.familyId.toLowerCase()) === -1) { + return false; + } + if (!filter.familyId && filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) { + return false; + } + if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) { + return false; + } + return true; + } + /** + * Retrieve AppMetadataEntity from cache + */ + readAppMetadataFromCache(environment) { + const appMetadataFilter = { + environment, + clientId: this.clientId + }; + const appMetadata = this.getAppMetadataFilteredBy(appMetadataFilter); + const appMetadataEntries = Object.keys(appMetadata).map((key) => appMetadata[key]); + const numAppMetadata = appMetadataEntries.length; + if (numAppMetadata < 1) { + return null; + } else if (numAppMetadata > 1) { + throw createClientAuthError(multipleMatchingAppMetadata); + } + return appMetadataEntries[0]; + } + /** + * Return the family_id value associated with FOCI + * @param environment + * @param clientId + */ + isAppMetadataFOCI(environment) { + const appMetadata = this.readAppMetadataFromCache(environment); + return !!(appMetadata && appMetadata.familyId === THE_FAMILY_ID); + } + /** + * helper to match account ids + * @param value + * @param homeAccountId + */ + matchHomeAccountId(entity, homeAccountId) { + return !!(typeof entity.homeAccountId === "string" && homeAccountId === entity.homeAccountId); + } + /** + * helper to match account ids + * @param entity + * @param localAccountId + * @returns + */ + matchLocalAccountIdFromTokenClaims(tokenClaims, localAccountId) { + const idTokenLocalAccountId = tokenClaims.oid || tokenClaims.sub; + return localAccountId === idTokenLocalAccountId; + } + matchLocalAccountIdFromTenantProfile(tenantProfile, localAccountId) { + return tenantProfile.localAccountId === localAccountId; + } + /** + * helper to match names + * @param entity + * @param name + * @returns true if the downcased name properties are present and match in the filter and the entity + */ + matchName(claims, name2) { + return !!(name2.toLowerCase() === claims.name?.toLowerCase()); + } + /** + * helper to match usernames + * @param entity + * @param username + * @returns + */ + matchUsername(cachedUsername, filterUsername) { + return !!(cachedUsername && typeof cachedUsername === "string" && filterUsername?.toLowerCase() === cachedUsername.toLowerCase()); + } + /** + * helper to match assertion + * @param value + * @param oboAssertion + */ + matchUserAssertionHash(entity, userAssertionHash) { + return !!(entity.userAssertionHash && userAssertionHash === entity.userAssertionHash); + } + /** + * helper to match environment + * @param value + * @param environment + */ + matchEnvironment(entity, environment) { + if (this.staticAuthorityOptions) { + const staticAliases = getAliasesFromStaticSources(this.staticAuthorityOptions, this.commonLogger); + if (staticAliases.includes(environment) && staticAliases.includes(entity.environment)) { + return true; + } + } + const cloudMetadata = this.getAuthorityMetadataByAlias(environment); + if (cloudMetadata && cloudMetadata.aliases.indexOf(entity.environment) > -1) { + return true; + } + return false; + } + /** + * helper to match credential type + * @param entity + * @param credentialType + */ + matchCredentialType(entity, credentialType) { + return entity.credentialType && credentialType.toLowerCase() === entity.credentialType.toLowerCase(); + } + /** + * helper to match client ids + * @param entity + * @param clientId + */ + matchClientId(entity, clientId) { + return !!(entity.clientId && clientId === entity.clientId); + } + /** + * helper to match family ids + * @param entity + * @param familyId + */ + matchFamilyId(entity, familyId) { + return !!(entity.familyId && familyId === entity.familyId); + } + /** + * helper to match realm + * @param entity + * @param realm + */ + matchRealm(entity, realm) { + return !!(entity.realm?.toLowerCase() === realm.toLowerCase()); + } + /** + * helper to match nativeAccountId + * @param entity + * @param nativeAccountId + * @returns boolean indicating the match result + */ + matchNativeAccountId(entity, nativeAccountId) { + return !!(entity.nativeAccountId && nativeAccountId === entity.nativeAccountId); + } + /** + * helper to match loginHint which can be either: + * 1. login_hint ID token claim + * 2. username in cached account object + * 3. upn in ID token claims + * @param entity + * @param loginHint + * @returns + */ + matchLoginHintFromTokenClaims(tokenClaims, loginHint) { + if (tokenClaims.login_hint === loginHint) { + return true; + } + if (tokenClaims.preferred_username === loginHint) { + return true; + } + if (tokenClaims.upn === loginHint) { + return true; + } + return false; + } + /** + * Helper to match sid + * @param entity + * @param sid + * @returns true if the sid claim is present and matches the filter + */ + matchSid(idTokenClaims, sid) { + return idTokenClaims.sid === sid; + } + matchAuthorityType(entity, authorityType) { + return !!(entity.authorityType && authorityType.toLowerCase() === entity.authorityType.toLowerCase()); + } + /** + * Returns true if the target scopes are a subset of the current entity's scopes, false otherwise. + * @param entity + * @param target + */ + matchTarget(entity, target) { + const isNotAccessTokenCredential = entity.credentialType !== CredentialType.ACCESS_TOKEN && entity.credentialType !== CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME; + if (isNotAccessTokenCredential || !entity.target) { + return false; + } + const entityScopeSet = ScopeSet.fromString(entity.target); + return entityScopeSet.containsScopeSet(target); + } + /** + * Returns true if the credential's tokenType or Authentication Scheme matches the one in the request, false otherwise + * @param entity + * @param tokenType + */ + matchTokenType(entity, tokenType) { + return !!(entity.tokenType && entity.tokenType === tokenType); + } + /** + * Returns true if the credential's keyId matches the one in the request, false otherwise + * @param entity + * @param keyId + */ + matchKeyId(entity, keyId) { + return !!(entity.keyId && entity.keyId === keyId); + } + /** + * returns if a given cache entity is of the type appmetadata + * @param key + */ + isAppMetadata(key) { + return key.indexOf(APP_METADATA) !== -1; + } + /** + * returns if a given cache entity is of the type authoritymetadata + * @param key + */ + isAuthorityMetadata(key) { + return key.indexOf(AUTHORITY_METADATA_CONSTANTS.CACHE_KEY) !== -1; + } + /** + * returns cache key used for cloud instance metadata + */ + generateAuthorityMetadataCacheKey(authority) { + return `${AUTHORITY_METADATA_CONSTANTS.CACHE_KEY}-${this.clientId}-${authority}`; + } + /** + * Helper to convert serialized data to object + * @param obj + * @param json + */ + static toObject(obj, json) { + for (const propertyName in json) { + obj[propertyName] = json[propertyName]; + } + return obj; + } + }; + var DefaultStorageClass = class extends CacheManager { + setAccount() { + throw createClientAuthError(methodNotImplemented); + } + getAccount() { + throw createClientAuthError(methodNotImplemented); + } + getCachedAccountEntity() { + throw createClientAuthError(methodNotImplemented); + } + setIdTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + getIdTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + setAccessTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + getAccessTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + setRefreshTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + getRefreshTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + setAppMetadata() { + throw createClientAuthError(methodNotImplemented); + } + getAppMetadata() { + throw createClientAuthError(methodNotImplemented); + } + setServerTelemetry() { + throw createClientAuthError(methodNotImplemented); + } + getServerTelemetry() { + throw createClientAuthError(methodNotImplemented); + } + setAuthorityMetadata() { + throw createClientAuthError(methodNotImplemented); + } + getAuthorityMetadata() { + throw createClientAuthError(methodNotImplemented); + } + getAuthorityMetadataKeys() { + throw createClientAuthError(methodNotImplemented); + } + setThrottlingCache() { + throw createClientAuthError(methodNotImplemented); + } + getThrottlingCache() { + throw createClientAuthError(methodNotImplemented); + } + removeItem() { + throw createClientAuthError(methodNotImplemented); + } + getKeys() { + throw createClientAuthError(methodNotImplemented); + } + getAccountKeys() { + throw createClientAuthError(methodNotImplemented); + } + getTokenKeys() { + throw createClientAuthError(methodNotImplemented); + } + updateCredentialCacheKey() { + throw createClientAuthError(methodNotImplemented); + } + removeOutdatedAccount() { + throw createClientAuthError(methodNotImplemented); + } + }; + var DEFAULT_SYSTEM_OPTIONS$1 = { + tokenRenewalOffsetSeconds: DEFAULT_TOKEN_RENEWAL_OFFSET_SEC, + preventCorsPreflight: false + }; + var DEFAULT_LOGGER_IMPLEMENTATION = { + loggerCallback: () => { + }, + piiLoggingEnabled: false, + logLevel: exports2.LogLevel.Info, + correlationId: Constants$1.EMPTY_STRING + }; + var DEFAULT_CACHE_OPTIONS$1 = { + claimsBasedCachingEnabled: false + }; + var DEFAULT_NETWORK_IMPLEMENTATION = { + async sendGetRequestAsync() { + throw createClientAuthError(methodNotImplemented); + }, + async sendPostRequestAsync() { + throw createClientAuthError(methodNotImplemented); + } + }; + var DEFAULT_LIBRARY_INFO = { + sku: Constants$1.SKU, + version: version$1, + cpu: Constants$1.EMPTY_STRING, + os: Constants$1.EMPTY_STRING + }; + var DEFAULT_CLIENT_CREDENTIALS = { + clientSecret: Constants$1.EMPTY_STRING, + clientAssertion: void 0 + }; + var DEFAULT_AZURE_CLOUD_OPTIONS = { + azureCloudInstance: AzureCloudInstance.None, + tenant: `${Constants$1.DEFAULT_COMMON_TENANT}` + }; + var DEFAULT_TELEMETRY_OPTIONS$1 = { + application: { + appName: "", + appVersion: "" + } + }; + function buildClientConfiguration({ authOptions: userAuthOptions, systemOptions: userSystemOptions, loggerOptions: userLoggerOption, cacheOptions: userCacheOptions, storageInterface: storageImplementation, networkInterface: networkImplementation, cryptoInterface: cryptoImplementation, clientCredentials, libraryInfo, telemetry, serverTelemetryManager, persistencePlugin, serializableCache }) { + const loggerOptions = { + ...DEFAULT_LOGGER_IMPLEMENTATION, + ...userLoggerOption + }; + return { + authOptions: buildAuthOptions(userAuthOptions), + systemOptions: { ...DEFAULT_SYSTEM_OPTIONS$1, ...userSystemOptions }, + loggerOptions, + cacheOptions: { ...DEFAULT_CACHE_OPTIONS$1, ...userCacheOptions }, + storageInterface: storageImplementation || new DefaultStorageClass(userAuthOptions.clientId, DEFAULT_CRYPTO_IMPLEMENTATION, new Logger(loggerOptions)), + networkInterface: networkImplementation || DEFAULT_NETWORK_IMPLEMENTATION, + cryptoInterface: cryptoImplementation || DEFAULT_CRYPTO_IMPLEMENTATION, + clientCredentials: clientCredentials || DEFAULT_CLIENT_CREDENTIALS, + libraryInfo: { ...DEFAULT_LIBRARY_INFO, ...libraryInfo }, + telemetry: { ...DEFAULT_TELEMETRY_OPTIONS$1, ...telemetry }, + serverTelemetryManager: serverTelemetryManager || null, + persistencePlugin: persistencePlugin || null, + serializableCache: serializableCache || null + }; + } + function buildAuthOptions(authOptions) { + return { + clientCapabilities: [], + azureCloudOptions: DEFAULT_AZURE_CLOUD_OPTIONS, + skipAuthorityMetadataCache: false, + instanceAware: false, + ...authOptions + }; + } + function isOidcProtocolMode(config) { + return config.authOptions.authority.options.protocolMode === ProtocolMode.OIDC; + } + var CcsCredentialType = { + HOME_ACCOUNT_ID: "home_account_id", + UPN: "UPN" + }; + var CLIENT_ID = "client_id"; + var REDIRECT_URI = "redirect_uri"; + var RESPONSE_TYPE = "response_type"; + var RESPONSE_MODE = "response_mode"; + var GRANT_TYPE = "grant_type"; + var CLAIMS = "claims"; + var SCOPE = "scope"; + var REFRESH_TOKEN = "refresh_token"; + var STATE = "state"; + var NONCE = "nonce"; + var PROMPT = "prompt"; + var CODE = "code"; + var CODE_CHALLENGE = "code_challenge"; + var CODE_CHALLENGE_METHOD = "code_challenge_method"; + var CODE_VERIFIER = "code_verifier"; + var CLIENT_REQUEST_ID = "client-request-id"; + var X_CLIENT_SKU = "x-client-SKU"; + var X_CLIENT_VER = "x-client-VER"; + var X_CLIENT_OS = "x-client-OS"; + var X_CLIENT_CPU = "x-client-CPU"; + var X_CLIENT_CURR_TELEM = "x-client-current-telemetry"; + var X_CLIENT_LAST_TELEM = "x-client-last-telemetry"; + var X_MS_LIB_CAPABILITY = "x-ms-lib-capability"; + var X_APP_NAME = "x-app-name"; + var X_APP_VER = "x-app-ver"; + var POST_LOGOUT_URI = "post_logout_redirect_uri"; + var ID_TOKEN_HINT = "id_token_hint"; + var DEVICE_CODE = "device_code"; + var CLIENT_SECRET = "client_secret"; + var CLIENT_ASSERTION = "client_assertion"; + var CLIENT_ASSERTION_TYPE = "client_assertion_type"; + var TOKEN_TYPE = "token_type"; + var REQ_CNF = "req_cnf"; + var OBO_ASSERTION = "assertion"; + var REQUESTED_TOKEN_USE = "requested_token_use"; + var ON_BEHALF_OF = "on_behalf_of"; + var RETURN_SPA_CODE = "return_spa_code"; + var NATIVE_BROKER = "nativebroker"; + var LOGOUT_HINT = "logout_hint"; + var SID = "sid"; + var LOGIN_HINT = "login_hint"; + var DOMAIN_HINT = "domain_hint"; + var X_CLIENT_EXTRA_SKU = "x-client-xtra-sku"; + var BROKER_CLIENT_ID = "brk_client_id"; + var BROKER_REDIRECT_URI = "brk_redirect_uri"; + var RequestValidator = class { + /** + * Utility to check if the `redirectUri` in the request is a non-null value + * @param redirectUri + */ + static validateRedirectUri(redirectUri) { + if (!redirectUri) { + throw createClientConfigurationError(redirectUriEmpty); + } + } + /** + * Utility to validate prompt sent by the user in the request + * @param prompt + */ + static validatePrompt(prompt) { + const promptValues = []; + for (const value in PromptValue) { + promptValues.push(PromptValue[value]); + } + if (promptValues.indexOf(prompt) < 0) { + throw createClientConfigurationError(invalidPromptValue); + } + } + static validateClaims(claims) { + try { + JSON.parse(claims); + } catch (e) { + throw createClientConfigurationError(invalidClaims); + } + } + /** + * Utility to validate code_challenge and code_challenge_method + * @param codeChallenge + * @param codeChallengeMethod + */ + static validateCodeChallengeParams(codeChallenge, codeChallengeMethod) { + if (!codeChallenge || !codeChallengeMethod) { + throw createClientConfigurationError(pkceParamsMissing); + } else { + this.validateCodeChallengeMethod(codeChallengeMethod); + } + } + /** + * Utility to validate code_challenge_method + * @param codeChallengeMethod + */ + static validateCodeChallengeMethod(codeChallengeMethod) { + if ([ + CodeChallengeMethodValues.PLAIN, + CodeChallengeMethodValues.S256 + ].indexOf(codeChallengeMethod) < 0) { + throw createClientConfigurationError(invalidCodeChallengeMethod); + } + } + }; + function instrumentBrokerParams(parameters, correlationId, performanceClient) { + if (!correlationId) { + return; + } + const clientId = parameters.get(CLIENT_ID); + if (clientId && parameters.has(BROKER_CLIENT_ID)) { + performanceClient?.addFields({ + embeddedClientId: clientId, + embeddedRedirectUri: parameters.get(REDIRECT_URI) + }, correlationId); + } + } + var RequestParameterBuilder = class { + constructor(correlationId, performanceClient) { + this.parameters = /* @__PURE__ */ new Map(); + this.performanceClient = performanceClient; + this.correlationId = correlationId; + } + /** + * add response_type = code + */ + addResponseTypeCode() { + this.parameters.set(RESPONSE_TYPE, encodeURIComponent(Constants$1.CODE_RESPONSE_TYPE)); + } + /** + * add response_type = token id_token + */ + addResponseTypeForTokenAndIdToken() { + this.parameters.set(RESPONSE_TYPE, encodeURIComponent(`${Constants$1.TOKEN_RESPONSE_TYPE} ${Constants$1.ID_TOKEN_RESPONSE_TYPE}`)); + } + /** + * add response_mode. defaults to query. + * @param responseMode + */ + addResponseMode(responseMode) { + this.parameters.set(RESPONSE_MODE, encodeURIComponent(responseMode ? responseMode : ResponseMode.QUERY)); + } + /** + * Add flag to indicate STS should attempt to use WAM if available + */ + addNativeBroker() { + this.parameters.set(NATIVE_BROKER, encodeURIComponent("1")); + } + /** + * add scopes. set addOidcScopes to false to prevent default scopes in non-user scenarios + * @param scopeSet + * @param addOidcScopes + */ + addScopes(scopes, addOidcScopes = true, defaultScopes = OIDC_DEFAULT_SCOPES) { + if (addOidcScopes && !defaultScopes.includes("openid") && !scopes.includes("openid")) { + defaultScopes.push("openid"); + } + const requestScopes = addOidcScopes ? [...scopes || [], ...defaultScopes] : scopes || []; + const scopeSet = new ScopeSet(requestScopes); + this.parameters.set(SCOPE, encodeURIComponent(scopeSet.printScopes())); + } + /** + * add clientId + * @param clientId + */ + addClientId(clientId) { + this.parameters.set(CLIENT_ID, encodeURIComponent(clientId)); + } + /** + * add redirect_uri + * @param redirectUri + */ + addRedirectUri(redirectUri) { + RequestValidator.validateRedirectUri(redirectUri); + this.parameters.set(REDIRECT_URI, encodeURIComponent(redirectUri)); + } + /** + * add post logout redirectUri + * @param redirectUri + */ + addPostLogoutRedirectUri(redirectUri) { + RequestValidator.validateRedirectUri(redirectUri); + this.parameters.set(POST_LOGOUT_URI, encodeURIComponent(redirectUri)); + } + /** + * add id_token_hint to logout request + * @param idTokenHint + */ + addIdTokenHint(idTokenHint) { + this.parameters.set(ID_TOKEN_HINT, encodeURIComponent(idTokenHint)); + } + /** + * add domain_hint + * @param domainHint + */ + addDomainHint(domainHint) { + this.parameters.set(DOMAIN_HINT, encodeURIComponent(domainHint)); + } + /** + * add login_hint + * @param loginHint + */ + addLoginHint(loginHint) { + this.parameters.set(LOGIN_HINT, encodeURIComponent(loginHint)); + } + /** + * Adds the CCS (Cache Credential Service) query parameter for login_hint + * @param loginHint + */ + addCcsUpn(loginHint) { + this.parameters.set(HeaderNames.CCS_HEADER, encodeURIComponent(`UPN:${loginHint}`)); + } + /** + * Adds the CCS (Cache Credential Service) query parameter for account object + * @param loginHint + */ + addCcsOid(clientInfo) { + this.parameters.set(HeaderNames.CCS_HEADER, encodeURIComponent(`Oid:${clientInfo.uid}@${clientInfo.utid}`)); + } + /** + * add sid + * @param sid + */ + addSid(sid) { + this.parameters.set(SID, encodeURIComponent(sid)); + } + /** + * add claims + * @param claims + */ + addClaims(claims, clientCapabilities) { + const mergedClaims = this.addClientCapabilitiesToClaims(claims, clientCapabilities); + RequestValidator.validateClaims(mergedClaims); + this.parameters.set(CLAIMS, encodeURIComponent(mergedClaims)); + } + /** + * add correlationId + * @param correlationId + */ + addCorrelationId(correlationId) { + this.parameters.set(CLIENT_REQUEST_ID, encodeURIComponent(correlationId)); + } + /** + * add library info query params + * @param libraryInfo + */ + addLibraryInfo(libraryInfo) { + this.parameters.set(X_CLIENT_SKU, libraryInfo.sku); + this.parameters.set(X_CLIENT_VER, libraryInfo.version); + if (libraryInfo.os) { + this.parameters.set(X_CLIENT_OS, libraryInfo.os); + } + if (libraryInfo.cpu) { + this.parameters.set(X_CLIENT_CPU, libraryInfo.cpu); + } + } + /** + * Add client telemetry parameters + * @param appTelemetry + */ + addApplicationTelemetry(appTelemetry) { + if (appTelemetry?.appName) { + this.parameters.set(X_APP_NAME, appTelemetry.appName); + } + if (appTelemetry?.appVersion) { + this.parameters.set(X_APP_VER, appTelemetry.appVersion); + } + } + /** + * add prompt + * @param prompt + */ + addPrompt(prompt) { + RequestValidator.validatePrompt(prompt); + this.parameters.set(`${PROMPT}`, encodeURIComponent(prompt)); + } + /** + * add state + * @param state + */ + addState(state) { + if (state) { + this.parameters.set(STATE, encodeURIComponent(state)); + } + } + /** + * add nonce + * @param nonce + */ + addNonce(nonce) { + this.parameters.set(NONCE, encodeURIComponent(nonce)); + } + /** + * add code_challenge and code_challenge_method + * - throw if either of them are not passed + * @param codeChallenge + * @param codeChallengeMethod + */ + addCodeChallengeParams(codeChallenge, codeChallengeMethod) { + RequestValidator.validateCodeChallengeParams(codeChallenge, codeChallengeMethod); + if (codeChallenge && codeChallengeMethod) { + this.parameters.set(CODE_CHALLENGE, encodeURIComponent(codeChallenge)); + this.parameters.set(CODE_CHALLENGE_METHOD, encodeURIComponent(codeChallengeMethod)); + } else { + throw createClientConfigurationError(pkceParamsMissing); + } + } + /** + * add the `authorization_code` passed by the user to exchange for a token + * @param code + */ + addAuthorizationCode(code) { + this.parameters.set(CODE, encodeURIComponent(code)); + } + /** + * add the `authorization_code` passed by the user to exchange for a token + * @param code + */ + addDeviceCode(code) { + this.parameters.set(DEVICE_CODE, encodeURIComponent(code)); + } + /** + * add the `refreshToken` passed by the user + * @param refreshToken + */ + addRefreshToken(refreshToken) { + this.parameters.set(REFRESH_TOKEN, encodeURIComponent(refreshToken)); + } + /** + * add the `code_verifier` passed by the user to exchange for a token + * @param codeVerifier + */ + addCodeVerifier(codeVerifier) { + this.parameters.set(CODE_VERIFIER, encodeURIComponent(codeVerifier)); + } + /** + * add client_secret + * @param clientSecret + */ + addClientSecret(clientSecret) { + this.parameters.set(CLIENT_SECRET, encodeURIComponent(clientSecret)); + } + /** + * add clientAssertion for confidential client flows + * @param clientAssertion + */ + addClientAssertion(clientAssertion) { + if (clientAssertion) { + this.parameters.set(CLIENT_ASSERTION, encodeURIComponent(clientAssertion)); + } + } + /** + * add clientAssertionType for confidential client flows + * @param clientAssertionType + */ + addClientAssertionType(clientAssertionType) { + if (clientAssertionType) { + this.parameters.set(CLIENT_ASSERTION_TYPE, encodeURIComponent(clientAssertionType)); + } + } + /** + * add OBO assertion for confidential client flows + * @param clientAssertion + */ + addOboAssertion(oboAssertion) { + this.parameters.set(OBO_ASSERTION, encodeURIComponent(oboAssertion)); + } + /** + * add grant type + * @param grantType + */ + addRequestTokenUse(tokenUse) { + this.parameters.set(REQUESTED_TOKEN_USE, encodeURIComponent(tokenUse)); + } + /** + * add grant type + * @param grantType + */ + addGrantType(grantType) { + this.parameters.set(GRANT_TYPE, encodeURIComponent(grantType)); + } + /** + * add client info + * + */ + addClientInfo() { + this.parameters.set(CLIENT_INFO, "1"); + } + /** + * add extraQueryParams + * @param eQParams + */ + addExtraQueryParameters(eQParams) { + Object.entries(eQParams).forEach(([key, value]) => { + if (!this.parameters.has(key) && value) { + this.parameters.set(key, value); + } + }); + } + addClientCapabilitiesToClaims(claims, clientCapabilities) { + let mergedClaims; + if (!claims) { + mergedClaims = {}; + } else { + try { + mergedClaims = JSON.parse(claims); + } catch (e) { + throw createClientConfigurationError(invalidClaims); + } + } + if (clientCapabilities && clientCapabilities.length > 0) { + if (!mergedClaims.hasOwnProperty(ClaimsRequestKeys.ACCESS_TOKEN)) { + mergedClaims[ClaimsRequestKeys.ACCESS_TOKEN] = {}; + } + mergedClaims[ClaimsRequestKeys.ACCESS_TOKEN][ClaimsRequestKeys.XMS_CC] = { + values: clientCapabilities + }; + } + return JSON.stringify(mergedClaims); + } + /** + * adds `username` for Password Grant flow + * @param username + */ + addUsername(username) { + this.parameters.set(PasswordGrantConstants.username, encodeURIComponent(username)); + } + /** + * adds `password` for Password Grant flow + * @param password + */ + addPassword(password) { + this.parameters.set(PasswordGrantConstants.password, encodeURIComponent(password)); + } + /** + * add pop_jwk to query params + * @param cnfString + */ + addPopToken(cnfString) { + if (cnfString) { + this.parameters.set(TOKEN_TYPE, AuthenticationScheme.POP); + this.parameters.set(REQ_CNF, encodeURIComponent(cnfString)); + } + } + /** + * add SSH JWK and key ID to query params + */ + addSshJwk(sshJwkString) { + if (sshJwkString) { + this.parameters.set(TOKEN_TYPE, AuthenticationScheme.SSH); + this.parameters.set(REQ_CNF, encodeURIComponent(sshJwkString)); + } + } + /** + * add server telemetry fields + * @param serverTelemetryManager + */ + addServerTelemetry(serverTelemetryManager) { + this.parameters.set(X_CLIENT_CURR_TELEM, serverTelemetryManager.generateCurrentRequestHeaderValue()); + this.parameters.set(X_CLIENT_LAST_TELEM, serverTelemetryManager.generateLastRequestHeaderValue()); + } + /** + * Adds parameter that indicates to the server that throttling is supported + */ + addThrottling() { + this.parameters.set(X_MS_LIB_CAPABILITY, ThrottlingConstants.X_MS_LIB_CAPABILITY_VALUE); + } + /** + * Adds logout_hint parameter for "silent" logout which prevent server account picker + */ + addLogoutHint(logoutHint) { + this.parameters.set(LOGOUT_HINT, encodeURIComponent(logoutHint)); + } + addBrokerParameters(params) { + const brokerParams = {}; + brokerParams[BROKER_CLIENT_ID] = params.brokerClientId; + brokerParams[BROKER_REDIRECT_URI] = params.brokerRedirectUri; + this.addExtraQueryParameters(brokerParams); + } + /** + * Utility to create a URL from the params map + */ + createQueryString() { + const queryParameterArray = new Array(); + this.parameters.forEach((value, key) => { + queryParameterArray.push(`${key}=${value}`); + }); + instrumentBrokerParams(this.parameters, this.correlationId, this.performanceClient); + return queryParameterArray.join("&"); + } + }; + function isOpenIdConfigResponse(response) { + return response.hasOwnProperty("authorization_endpoint") && response.hasOwnProperty("token_endpoint") && response.hasOwnProperty("issuer") && response.hasOwnProperty("jwks_uri"); + } + function isCloudInstanceDiscoveryResponse(response) { + return response.hasOwnProperty("tenant_discovery_endpoint") && response.hasOwnProperty("metadata"); + } + function isCloudInstanceDiscoveryErrorResponse(response) { + return response.hasOwnProperty("error") && response.hasOwnProperty("error_description"); + } + var PerformanceEvents = { + /** + * acquireTokenByCode API (msal-browser and msal-node). + * Used to acquire tokens by trading an authorization code against the token endpoint. + */ + AcquireTokenByCode: "acquireTokenByCode", + /** + * acquireTokenByRefreshToken API (msal-browser and msal-node). + * Used to renew an access token using a refresh token against the token endpoint. + */ + AcquireTokenByRefreshToken: "acquireTokenByRefreshToken", + /** + * acquireTokenSilent API (msal-browser and msal-node). + * Used to silently acquire a new access token (from the cache or the network). + */ + AcquireTokenSilent: "acquireTokenSilent", + /** + * acquireTokenSilentAsync (msal-browser). + * Internal API for acquireTokenSilent. + */ + AcquireTokenSilentAsync: "acquireTokenSilentAsync", + /** + * acquireTokenPopup (msal-browser). + * Used to acquire a new access token interactively through pop ups + */ + AcquireTokenPopup: "acquireTokenPopup", + /** + * acquireTokenPreRedirect (msal-browser). + * First part of the redirect flow. + * Used to acquire a new access token interactively through redirects. + */ + AcquireTokenPreRedirect: "acquireTokenPreRedirect", + /** + * acquireTokenRedirect (msal-browser). + * Second part of the redirect flow. + * Used to acquire a new access token interactively through redirects. + */ + AcquireTokenRedirect: "acquireTokenRedirect", + /** + * getPublicKeyThumbprint API in CryptoOpts class (msal-browser). + * Used to generate a public/private keypair and generate a public key thumbprint for pop requests. + */ + CryptoOptsGetPublicKeyThumbprint: "cryptoOptsGetPublicKeyThumbprint", + /** + * signJwt API in CryptoOpts class (msal-browser). + * Used to signed a pop token. + */ + CryptoOptsSignJwt: "cryptoOptsSignJwt", + /** + * acquireToken API in the SilentCacheClient class (msal-browser). + * Used to read access tokens from the cache. + */ + SilentCacheClientAcquireToken: "silentCacheClientAcquireToken", + /** + * acquireToken API in the SilentIframeClient class (msal-browser). + * Used to acquire a new set of tokens from the authorize endpoint in a hidden iframe. + */ + SilentIframeClientAcquireToken: "silentIframeClientAcquireToken", + AwaitConcurrentIframe: "awaitConcurrentIframe", + /** + * acquireToken API in SilentRereshClient (msal-browser). + * Used to acquire a new set of tokens from the token endpoint using a refresh token. + */ + SilentRefreshClientAcquireToken: "silentRefreshClientAcquireToken", + /** + * ssoSilent API (msal-browser). + * Used to silently acquire an authorization code and set of tokens using a hidden iframe. + */ + SsoSilent: "ssoSilent", + /** + * getDiscoveredAuthority API in StandardInteractionClient class (msal-browser). + * Used to load authority metadata for a request. + */ + StandardInteractionClientGetDiscoveredAuthority: "standardInteractionClientGetDiscoveredAuthority", + /** + * acquireToken APIs in msal-browser. + * Used to make an /authorize endpoint call with native brokering enabled. + */ + FetchAccountIdWithNativeBroker: "fetchAccountIdWithNativeBroker", + /** + * acquireToken API in NativeInteractionClient class (msal-browser). + * Used to acquire a token from Native component when native brokering is enabled. + */ + NativeInteractionClientAcquireToken: "nativeInteractionClientAcquireToken", + /** + * Time spent creating default headers for requests to token endpoint + */ + BaseClientCreateTokenRequestHeaders: "baseClientCreateTokenRequestHeaders", + /** + * Time spent sending/waiting for the response of a request to the token endpoint + */ + NetworkClientSendPostRequestAsync: "networkClientSendPostRequestAsync", + RefreshTokenClientExecutePostToTokenEndpoint: "refreshTokenClientExecutePostToTokenEndpoint", + AuthorizationCodeClientExecutePostToTokenEndpoint: "authorizationCodeClientExecutePostToTokenEndpoint", + /** + * Used to measure the time taken for completing embedded-broker handshake (PW-Broker). + */ + BrokerHandhshake: "brokerHandshake", + /** + * acquireTokenByRefreshToken API in BrokerClientApplication (PW-Broker) . + */ + AcquireTokenByRefreshTokenInBroker: "acquireTokenByRefreshTokenInBroker", + /** + * Time taken for token acquisition by broker + */ + AcquireTokenByBroker: "acquireTokenByBroker", + /** + * Time spent on the network for refresh token acquisition + */ + RefreshTokenClientExecuteTokenRequest: "refreshTokenClientExecuteTokenRequest", + /** + * Time taken for acquiring refresh token , records RT size + */ + RefreshTokenClientAcquireToken: "refreshTokenClientAcquireToken", + /** + * Time taken for acquiring cached refresh token + */ + RefreshTokenClientAcquireTokenWithCachedRefreshToken: "refreshTokenClientAcquireTokenWithCachedRefreshToken", + /** + * acquireTokenByRefreshToken API in RefreshTokenClient (msal-common). + */ + RefreshTokenClientAcquireTokenByRefreshToken: "refreshTokenClientAcquireTokenByRefreshToken", + /** + * Helper function to create token request body in RefreshTokenClient (msal-common). + */ + RefreshTokenClientCreateTokenRequestBody: "refreshTokenClientCreateTokenRequestBody", + /** + * acquireTokenFromCache (msal-browser). + * Internal API for acquiring token from cache + */ + AcquireTokenFromCache: "acquireTokenFromCache", + SilentFlowClientAcquireCachedToken: "silentFlowClientAcquireCachedToken", + SilentFlowClientGenerateResultFromCacheRecord: "silentFlowClientGenerateResultFromCacheRecord", + /** + * acquireTokenBySilentIframe (msal-browser). + * Internal API for acquiring token by silent Iframe + */ + AcquireTokenBySilentIframe: "acquireTokenBySilentIframe", + /** + * Internal API for initializing base request in BaseInteractionClient (msal-browser) + */ + InitializeBaseRequest: "initializeBaseRequest", + /** + * Internal API for initializing silent request in SilentCacheClient (msal-browser) + */ + InitializeSilentRequest: "initializeSilentRequest", + InitializeClientApplication: "initializeClientApplication", + /** + * Helper function in SilentIframeClient class (msal-browser). + */ + SilentIframeClientTokenHelper: "silentIframeClientTokenHelper", + /** + * SilentHandler + */ + SilentHandlerInitiateAuthRequest: "silentHandlerInitiateAuthRequest", + SilentHandlerMonitorIframeForHash: "silentHandlerMonitorIframeForHash", + SilentHandlerLoadFrame: "silentHandlerLoadFrame", + SilentHandlerLoadFrameSync: "silentHandlerLoadFrameSync", + /** + * Helper functions in StandardInteractionClient class (msal-browser) + */ + StandardInteractionClientCreateAuthCodeClient: "standardInteractionClientCreateAuthCodeClient", + StandardInteractionClientGetClientConfiguration: "standardInteractionClientGetClientConfiguration", + StandardInteractionClientInitializeAuthorizationRequest: "standardInteractionClientInitializeAuthorizationRequest", + StandardInteractionClientInitializeAuthorizationCodeRequest: "standardInteractionClientInitializeAuthorizationCodeRequest", + /** + * getAuthCodeUrl API (msal-browser and msal-node). + */ + GetAuthCodeUrl: "getAuthCodeUrl", + /** + * Functions from InteractionHandler (msal-browser) + */ + HandleCodeResponseFromServer: "handleCodeResponseFromServer", + HandleCodeResponse: "handleCodeResponse", + UpdateTokenEndpointAuthority: "updateTokenEndpointAuthority", + /** + * APIs in Authorization Code Client (msal-common) + */ + AuthClientAcquireToken: "authClientAcquireToken", + AuthClientExecuteTokenRequest: "authClientExecuteTokenRequest", + AuthClientCreateTokenRequestBody: "authClientCreateTokenRequestBody", + AuthClientCreateQueryString: "authClientCreateQueryString", + /** + * Generate functions in PopTokenGenerator (msal-common) + */ + PopTokenGenerateCnf: "popTokenGenerateCnf", + PopTokenGenerateKid: "popTokenGenerateKid", + /** + * handleServerTokenResponse API in ResponseHandler (msal-common) + */ + HandleServerTokenResponse: "handleServerTokenResponse", + DeserializeResponse: "deserializeResponse", + /** + * Authority functions + */ + AuthorityFactoryCreateDiscoveredInstance: "authorityFactoryCreateDiscoveredInstance", + AuthorityResolveEndpointsAsync: "authorityResolveEndpointsAsync", + AuthorityResolveEndpointsFromLocalSources: "authorityResolveEndpointsFromLocalSources", + AuthorityGetCloudDiscoveryMetadataFromNetwork: "authorityGetCloudDiscoveryMetadataFromNetwork", + AuthorityUpdateCloudDiscoveryMetadata: "authorityUpdateCloudDiscoveryMetadata", + AuthorityGetEndpointMetadataFromNetwork: "authorityGetEndpointMetadataFromNetwork", + AuthorityUpdateEndpointMetadata: "authorityUpdateEndpointMetadata", + AuthorityUpdateMetadataWithRegionalInformation: "authorityUpdateMetadataWithRegionalInformation", + /** + * Region Discovery functions + */ + RegionDiscoveryDetectRegion: "regionDiscoveryDetectRegion", + RegionDiscoveryGetRegionFromIMDS: "regionDiscoveryGetRegionFromIMDS", + RegionDiscoveryGetCurrentVersion: "regionDiscoveryGetCurrentVersion", + AcquireTokenByCodeAsync: "acquireTokenByCodeAsync", + GetEndpointMetadataFromNetwork: "getEndpointMetadataFromNetwork", + GetCloudDiscoveryMetadataFromNetworkMeasurement: "getCloudDiscoveryMetadataFromNetworkMeasurement", + HandleRedirectPromiseMeasurement: "handleRedirectPromise", + HandleNativeRedirectPromiseMeasurement: "handleNativeRedirectPromise", + UpdateCloudDiscoveryMetadataMeasurement: "updateCloudDiscoveryMetadataMeasurement", + UsernamePasswordClientAcquireToken: "usernamePasswordClientAcquireToken", + NativeMessageHandlerHandshake: "nativeMessageHandlerHandshake", + NativeGenerateAuthResult: "nativeGenerateAuthResult", + RemoveHiddenIframe: "removeHiddenIframe", + /** + * Cache operations + */ + ClearTokensAndKeysWithClaims: "clearTokensAndKeysWithClaims", + CacheManagerGetRefreshToken: "cacheManagerGetRefreshToken", + /** + * Crypto Operations + */ + GeneratePkceCodes: "generatePkceCodes", + GenerateCodeVerifier: "generateCodeVerifier", + GenerateCodeChallengeFromVerifier: "generateCodeChallengeFromVerifier", + Sha256Digest: "sha256Digest", + GetRandomValues: "getRandomValues" + }; + var invoke = (callback, eventName, logger, telemetryClient, correlationId) => { + return (...args) => { + logger.trace(`Executing function ${eventName}`); + const inProgressEvent = telemetryClient?.startMeasurement(eventName, correlationId); + if (correlationId) { + const eventCount = eventName + "CallCount"; + telemetryClient?.incrementFields({ [eventCount]: 1 }, correlationId); + } + try { + const result = callback(...args); + inProgressEvent?.end({ + success: true + }); + logger.trace(`Returning result from ${eventName}`); + return result; + } catch (e) { + logger.trace(`Error occurred in ${eventName}`); + try { + logger.trace(JSON.stringify(e)); + } catch (e2) { + logger.trace("Unable to print error message."); + } + inProgressEvent?.end({ + success: false + }, e); + throw e; + } + }; + }; + var invokeAsync = (callback, eventName, logger, telemetryClient, correlationId) => { + return (...args) => { + logger.trace(`Executing function ${eventName}`); + const inProgressEvent = telemetryClient?.startMeasurement(eventName, correlationId); + if (correlationId) { + const eventCount = eventName + "CallCount"; + telemetryClient?.incrementFields({ [eventCount]: 1 }, correlationId); + } + telemetryClient?.setPreQueueTime(eventName, correlationId); + return callback(...args).then((response) => { + logger.trace(`Returning result from ${eventName}`); + inProgressEvent?.end({ + success: true + }); + return response; + }).catch((e) => { + logger.trace(`Error occurred in ${eventName}`); + try { + logger.trace(JSON.stringify(e)); + } catch (e2) { + logger.trace("Unable to print error message."); + } + inProgressEvent?.end({ + success: false + }, e); + throw e; + }); + }; + }; + var RegionDiscovery = class _RegionDiscovery { + constructor(networkInterface, logger, performanceClient, correlationId) { + this.networkInterface = networkInterface; + this.logger = logger; + this.performanceClient = performanceClient; + this.correlationId = correlationId; + } + /** + * Detect the region from the application's environment. + * + * @returns Promise + */ + async detectRegion(environmentRegion, regionDiscoveryMetadata) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.RegionDiscoveryDetectRegion, this.correlationId); + let autodetectedRegionName = environmentRegion; + if (!autodetectedRegionName) { + const options = _RegionDiscovery.IMDS_OPTIONS; + try { + const localIMDSVersionResponse = await invokeAsync(this.getRegionFromIMDS.bind(this), PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.logger, this.performanceClient, this.correlationId)(Constants$1.IMDS_VERSION, options); + if (localIMDSVersionResponse.status === ResponseCodes.httpSuccess) { + autodetectedRegionName = localIMDSVersionResponse.body; + regionDiscoveryMetadata.region_source = RegionDiscoverySources.IMDS; + } + if (localIMDSVersionResponse.status === ResponseCodes.httpBadRequest) { + const currentIMDSVersion = await invokeAsync(this.getCurrentVersion.bind(this), PerformanceEvents.RegionDiscoveryGetCurrentVersion, this.logger, this.performanceClient, this.correlationId)(options); + if (!currentIMDSVersion) { + regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION; + return null; + } + const currentIMDSVersionResponse = await invokeAsync(this.getRegionFromIMDS.bind(this), PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.logger, this.performanceClient, this.correlationId)(currentIMDSVersion, options); + if (currentIMDSVersionResponse.status === ResponseCodes.httpSuccess) { + autodetectedRegionName = currentIMDSVersionResponse.body; + regionDiscoveryMetadata.region_source = RegionDiscoverySources.IMDS; + } + } + } catch (e) { + regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION; + return null; + } + } else { + regionDiscoveryMetadata.region_source = RegionDiscoverySources.ENVIRONMENT_VARIABLE; + } + if (!autodetectedRegionName) { + regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION; + } + return autodetectedRegionName || null; + } + /** + * Make the call to the IMDS endpoint + * + * @param imdsEndpointUrl + * @returns Promise> + */ + async getRegionFromIMDS(version5, options) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.correlationId); + return this.networkInterface.sendGetRequestAsync(`${Constants$1.IMDS_ENDPOINT}?api-version=${version5}&format=text`, options, Constants$1.IMDS_TIMEOUT); + } + /** + * Get the most recent version of the IMDS endpoint available + * + * @returns Promise + */ + async getCurrentVersion(options) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.RegionDiscoveryGetCurrentVersion, this.correlationId); + try { + const response = await this.networkInterface.sendGetRequestAsync(`${Constants$1.IMDS_ENDPOINT}?format=json`, options); + if (response.status === ResponseCodes.httpBadRequest && response.body && response.body["newest-versions"] && response.body["newest-versions"].length > 0) { + return response.body["newest-versions"][0]; + } + return null; + } catch (e) { + return null; + } + } + }; + RegionDiscovery.IMDS_OPTIONS = { + headers: { + Metadata: "true" + } + }; + var Authority = class _Authority { + constructor(authority, networkInterface, cacheManager, authorityOptions, logger, correlationId, performanceClient, managedIdentity) { + this.canonicalAuthority = authority; + this._canonicalAuthority.validateAsUri(); + this.networkInterface = networkInterface; + this.cacheManager = cacheManager; + this.authorityOptions = authorityOptions; + this.regionDiscoveryMetadata = { + region_used: void 0, + region_source: void 0, + region_outcome: void 0 + }; + this.logger = logger; + this.performanceClient = performanceClient; + this.correlationId = correlationId; + this.managedIdentity = managedIdentity || false; + this.regionDiscovery = new RegionDiscovery(networkInterface, this.logger, this.performanceClient, this.correlationId); + } + /** + * Get {@link AuthorityType} + * @param authorityUri {@link IUri} + * @private + */ + getAuthorityType(authorityUri) { + if (authorityUri.HostNameAndPort.endsWith(Constants$1.CIAM_AUTH_URL)) { + return AuthorityType.Ciam; + } + const pathSegments = authorityUri.PathSegments; + if (pathSegments.length) { + switch (pathSegments[0].toLowerCase()) { + case Constants$1.ADFS: + return AuthorityType.Adfs; + case Constants$1.DSTS: + return AuthorityType.Dsts; + } + } + return AuthorityType.Default; + } + // See above for AuthorityType + get authorityType() { + return this.getAuthorityType(this.canonicalAuthorityUrlComponents); + } + /** + * ProtocolMode enum representing the way endpoints are constructed. + */ + get protocolMode() { + return this.authorityOptions.protocolMode; + } + /** + * Returns authorityOptions which can be used to reinstantiate a new authority instance + */ + get options() { + return this.authorityOptions; + } + /** + * A URL that is the authority set by the developer + */ + get canonicalAuthority() { + return this._canonicalAuthority.urlString; + } + /** + * Sets canonical authority. + */ + set canonicalAuthority(url) { + this._canonicalAuthority = new UrlString(url); + this._canonicalAuthority.validateAsUri(); + this._canonicalAuthorityUrlComponents = null; + } + /** + * Get authority components. + */ + get canonicalAuthorityUrlComponents() { + if (!this._canonicalAuthorityUrlComponents) { + this._canonicalAuthorityUrlComponents = this._canonicalAuthority.getUrlComponents(); + } + return this._canonicalAuthorityUrlComponents; + } + /** + * Get hostname and port i.e. login.microsoftonline.com + */ + get hostnameAndPort() { + return this.canonicalAuthorityUrlComponents.HostNameAndPort.toLowerCase(); + } + /** + * Get tenant for authority. + */ + get tenant() { + return this.canonicalAuthorityUrlComponents.PathSegments[0]; + } + /** + * OAuth /authorize endpoint for requests + */ + get authorizationEndpoint() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.authorization_endpoint); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * OAuth /token endpoint for requests + */ + get tokenEndpoint() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.token_endpoint); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + get deviceCodeEndpoint() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.token_endpoint.replace("/token", "/devicecode")); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * OAuth logout endpoint for requests + */ + get endSessionEndpoint() { + if (this.discoveryComplete()) { + if (!this.metadata.end_session_endpoint) { + throw createClientAuthError(endSessionEndpointNotSupported); + } + return this.replacePath(this.metadata.end_session_endpoint); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * OAuth issuer for requests + */ + get selfSignedJwtAudience() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.issuer); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * Jwks_uri for token signing keys + */ + get jwksUri() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.jwks_uri); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * Returns a flag indicating that tenant name can be replaced in authority {@link IUri} + * @param authorityUri {@link IUri} + * @private + */ + canReplaceTenant(authorityUri) { + return authorityUri.PathSegments.length === 1 && !_Authority.reservedTenantDomains.has(authorityUri.PathSegments[0]) && this.getAuthorityType(authorityUri) === AuthorityType.Default && this.protocolMode === ProtocolMode.AAD; + } + /** + * Replaces tenant in url path with current tenant. Defaults to common. + * @param urlString + */ + replaceTenant(urlString) { + return urlString.replace(/{tenant}|{tenantid}/g, this.tenant); + } + /** + * Replaces path such as tenant or policy with the current tenant or policy. + * @param urlString + */ + replacePath(urlString) { + let endpoint = urlString; + const cachedAuthorityUrl = new UrlString(this.metadata.canonical_authority); + const cachedAuthorityUrlComponents = cachedAuthorityUrl.getUrlComponents(); + const cachedAuthorityParts = cachedAuthorityUrlComponents.PathSegments; + const currentAuthorityParts = this.canonicalAuthorityUrlComponents.PathSegments; + currentAuthorityParts.forEach((currentPart, index) => { + let cachedPart = cachedAuthorityParts[index]; + if (index === 0 && this.canReplaceTenant(cachedAuthorityUrlComponents)) { + const tenantId = new UrlString(this.metadata.authorization_endpoint).getUrlComponents().PathSegments[0]; + if (cachedPart !== tenantId) { + this.logger.verbose(`Replacing tenant domain name ${cachedPart} with id ${tenantId}`); + cachedPart = tenantId; + } + } + if (currentPart !== cachedPart) { + endpoint = endpoint.replace(`/${cachedPart}/`, `/${currentPart}/`); + } + }); + return this.replaceTenant(endpoint); + } + /** + * The default open id configuration endpoint for any canonical authority. + */ + get defaultOpenIdConfigurationEndpoint() { + const canonicalAuthorityHost = this.hostnameAndPort; + if (this.canonicalAuthority.endsWith("v2.0/") || this.authorityType === AuthorityType.Adfs || this.protocolMode !== ProtocolMode.AAD && !this.isAliasOfKnownMicrosoftAuthority(canonicalAuthorityHost)) { + return `${this.canonicalAuthority}.well-known/openid-configuration`; + } + return `${this.canonicalAuthority}v2.0/.well-known/openid-configuration`; + } + /** + * Boolean that returns whether or not tenant discovery has been completed. + */ + discoveryComplete() { + return !!this.metadata; + } + /** + * Perform endpoint discovery to discover aliases, preferred_cache, preferred_network + * and the /authorize, /token and logout endpoints. + */ + async resolveEndpointsAsync() { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthorityResolveEndpointsAsync, this.correlationId); + const metadataEntity = this.getCurrentMetadataEntity(); + const cloudDiscoverySource = await invokeAsync(this.updateCloudDiscoveryMetadata.bind(this), PerformanceEvents.AuthorityUpdateCloudDiscoveryMetadata, this.logger, this.performanceClient, this.correlationId)(metadataEntity); + this.canonicalAuthority = this.canonicalAuthority.replace(this.hostnameAndPort, metadataEntity.preferred_network); + const endpointSource = await invokeAsync(this.updateEndpointMetadata.bind(this), PerformanceEvents.AuthorityUpdateEndpointMetadata, this.logger, this.performanceClient, this.correlationId)(metadataEntity); + this.updateCachedMetadata(metadataEntity, cloudDiscoverySource, { + source: endpointSource + }); + this.performanceClient?.addFields({ + cloudDiscoverySource, + authorityEndpointSource: endpointSource + }, this.correlationId); + } + /** + * Returns metadata entity from cache if it exists, otherwiser returns a new metadata entity built + * from the configured canonical authority + * @returns + */ + getCurrentMetadataEntity() { + let metadataEntity = this.cacheManager.getAuthorityMetadataByAlias(this.hostnameAndPort); + if (!metadataEntity) { + metadataEntity = { + aliases: [], + preferred_cache: this.hostnameAndPort, + preferred_network: this.hostnameAndPort, + canonical_authority: this.canonicalAuthority, + authorization_endpoint: "", + token_endpoint: "", + end_session_endpoint: "", + issuer: "", + aliasesFromNetwork: false, + endpointsFromNetwork: false, + expiresAt: generateAuthorityMetadataExpiresAt(), + jwks_uri: "" + }; + } + return metadataEntity; + } + /** + * Updates cached metadata based on metadata source and sets the instance's metadata + * property to the same value + * @param metadataEntity + * @param cloudDiscoverySource + * @param endpointMetadataResult + */ + updateCachedMetadata(metadataEntity, cloudDiscoverySource, endpointMetadataResult) { + if (cloudDiscoverySource !== AuthorityMetadataSource.CACHE && endpointMetadataResult?.source !== AuthorityMetadataSource.CACHE) { + metadataEntity.expiresAt = generateAuthorityMetadataExpiresAt(); + metadataEntity.canonical_authority = this.canonicalAuthority; + } + const cacheKey = this.cacheManager.generateAuthorityMetadataCacheKey(metadataEntity.preferred_cache); + this.cacheManager.setAuthorityMetadata(cacheKey, metadataEntity); + this.metadata = metadataEntity; + } + /** + * Update AuthorityMetadataEntity with new endpoints and return where the information came from + * @param metadataEntity + */ + async updateEndpointMetadata(metadataEntity) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthorityUpdateEndpointMetadata, this.correlationId); + const localMetadata = this.updateEndpointMetadataFromLocalSources(metadataEntity); + if (localMetadata) { + if (localMetadata.source === AuthorityMetadataSource.HARDCODED_VALUES) { + if (this.authorityOptions.azureRegionConfiguration?.azureRegion) { + if (localMetadata.metadata) { + const hardcodedMetadata = await invokeAsync(this.updateMetadataWithRegionalInformation.bind(this), PerformanceEvents.AuthorityUpdateMetadataWithRegionalInformation, this.logger, this.performanceClient, this.correlationId)(localMetadata.metadata); + updateAuthorityEndpointMetadata(metadataEntity, hardcodedMetadata, false); + metadataEntity.canonical_authority = this.canonicalAuthority; + } + } + } + return localMetadata.source; + } + let metadata = await invokeAsync(this.getEndpointMetadataFromNetwork.bind(this), PerformanceEvents.AuthorityGetEndpointMetadataFromNetwork, this.logger, this.performanceClient, this.correlationId)(); + if (metadata) { + if (this.authorityOptions.azureRegionConfiguration?.azureRegion) { + metadata = await invokeAsync(this.updateMetadataWithRegionalInformation.bind(this), PerformanceEvents.AuthorityUpdateMetadataWithRegionalInformation, this.logger, this.performanceClient, this.correlationId)(metadata); + } + updateAuthorityEndpointMetadata(metadataEntity, metadata, true); + return AuthorityMetadataSource.NETWORK; + } else { + throw createClientAuthError(openIdConfigError, this.defaultOpenIdConfigurationEndpoint); + } + } + /** + * Updates endpoint metadata from local sources and returns where the information was retrieved from and the metadata config + * response if the source is hardcoded metadata + * @param metadataEntity + * @returns + */ + updateEndpointMetadataFromLocalSources(metadataEntity) { + this.logger.verbose("Attempting to get endpoint metadata from authority configuration"); + const configMetadata = this.getEndpointMetadataFromConfig(); + if (configMetadata) { + this.logger.verbose("Found endpoint metadata in authority configuration"); + updateAuthorityEndpointMetadata(metadataEntity, configMetadata, false); + return { + source: AuthorityMetadataSource.CONFIG + }; + } + this.logger.verbose("Did not find endpoint metadata in the config... Attempting to get endpoint metadata from the hardcoded values."); + if (this.authorityOptions.skipAuthorityMetadataCache) { + this.logger.verbose("Skipping hardcoded metadata cache since skipAuthorityMetadataCache is set to true. Attempting to get endpoint metadata from the network metadata cache."); + } else { + const hardcodedMetadata = this.getEndpointMetadataFromHardcodedValues(); + if (hardcodedMetadata) { + updateAuthorityEndpointMetadata(metadataEntity, hardcodedMetadata, false); + return { + source: AuthorityMetadataSource.HARDCODED_VALUES, + metadata: hardcodedMetadata + }; + } else { + this.logger.verbose("Did not find endpoint metadata in hardcoded values... Attempting to get endpoint metadata from the network metadata cache."); + } + } + const metadataEntityExpired = isAuthorityMetadataExpired(metadataEntity); + if (this.isAuthoritySameType(metadataEntity) && metadataEntity.endpointsFromNetwork && !metadataEntityExpired) { + this.logger.verbose("Found endpoint metadata in the cache."); + return { source: AuthorityMetadataSource.CACHE }; + } else if (metadataEntityExpired) { + this.logger.verbose("The metadata entity is expired."); + } + return null; + } + /** + * Compares the number of url components after the domain to determine if the cached + * authority metadata can be used for the requested authority. Protects against same domain different + * authority such as login.microsoftonline.com/tenant and login.microsoftonline.com/tfp/tenant/policy + * @param metadataEntity + */ + isAuthoritySameType(metadataEntity) { + const cachedAuthorityUrl = new UrlString(metadataEntity.canonical_authority); + const cachedParts = cachedAuthorityUrl.getUrlComponents().PathSegments; + return cachedParts.length === this.canonicalAuthorityUrlComponents.PathSegments.length; + } + /** + * Parse authorityMetadata config option + */ + getEndpointMetadataFromConfig() { + if (this.authorityOptions.authorityMetadata) { + try { + return JSON.parse(this.authorityOptions.authorityMetadata); + } catch (e) { + throw createClientConfigurationError(invalidAuthorityMetadata); + } + } + return null; + } + /** + * Gets OAuth endpoints from the given OpenID configuration endpoint. + * + * @param hasHardcodedMetadata boolean + */ + async getEndpointMetadataFromNetwork() { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthorityGetEndpointMetadataFromNetwork, this.correlationId); + const options = {}; + const openIdConfigurationEndpoint = this.defaultOpenIdConfigurationEndpoint; + this.logger.verbose(`Authority.getEndpointMetadataFromNetwork: attempting to retrieve OAuth endpoints from ${openIdConfigurationEndpoint}`); + try { + const response = await this.networkInterface.sendGetRequestAsync(openIdConfigurationEndpoint, options); + const isValidResponse = isOpenIdConfigResponse(response.body); + if (isValidResponse) { + return response.body; + } else { + this.logger.verbose(`Authority.getEndpointMetadataFromNetwork: could not parse response as OpenID configuration`); + return null; + } + } catch (e) { + this.logger.verbose(`Authority.getEndpointMetadataFromNetwork: ${e}`); + return null; + } + } + /** + * Get OAuth endpoints for common authorities. + */ + getEndpointMetadataFromHardcodedValues() { + if (this.hostnameAndPort in EndpointMetadata) { + return EndpointMetadata[this.hostnameAndPort]; + } + return null; + } + /** + * Update the retrieved metadata with regional information. + * User selected Azure region will be used if configured. + */ + async updateMetadataWithRegionalInformation(metadata) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthorityUpdateMetadataWithRegionalInformation, this.correlationId); + const userConfiguredAzureRegion = this.authorityOptions.azureRegionConfiguration?.azureRegion; + if (userConfiguredAzureRegion) { + if (userConfiguredAzureRegion !== Constants$1.AZURE_REGION_AUTO_DISCOVER_FLAG) { + this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.CONFIGURED_NO_AUTO_DETECTION; + this.regionDiscoveryMetadata.region_used = userConfiguredAzureRegion; + return _Authority.replaceWithRegionalInformation(metadata, userConfiguredAzureRegion); + } + const autodetectedRegionName = await invokeAsync(this.regionDiscovery.detectRegion.bind(this.regionDiscovery), PerformanceEvents.RegionDiscoveryDetectRegion, this.logger, this.performanceClient, this.correlationId)(this.authorityOptions.azureRegionConfiguration?.environmentRegion, this.regionDiscoveryMetadata); + if (autodetectedRegionName) { + this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.AUTO_DETECTION_REQUESTED_SUCCESSFUL; + this.regionDiscoveryMetadata.region_used = autodetectedRegionName; + return _Authority.replaceWithRegionalInformation(metadata, autodetectedRegionName); + } + this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.AUTO_DETECTION_REQUESTED_FAILED; + } + return metadata; + } + /** + * Updates the AuthorityMetadataEntity with new aliases, preferred_network and preferred_cache + * and returns where the information was retrieved from + * @param metadataEntity + * @returns AuthorityMetadataSource + */ + async updateCloudDiscoveryMetadata(metadataEntity) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthorityUpdateCloudDiscoveryMetadata, this.correlationId); + const localMetadataSource = this.updateCloudDiscoveryMetadataFromLocalSources(metadataEntity); + if (localMetadataSource) { + return localMetadataSource; + } + const metadata = await invokeAsync(this.getCloudDiscoveryMetadataFromNetwork.bind(this), PerformanceEvents.AuthorityGetCloudDiscoveryMetadataFromNetwork, this.logger, this.performanceClient, this.correlationId)(); + if (metadata) { + updateCloudDiscoveryMetadata(metadataEntity, metadata, true); + return AuthorityMetadataSource.NETWORK; + } + throw createClientConfigurationError(untrustedAuthority); + } + updateCloudDiscoveryMetadataFromLocalSources(metadataEntity) { + this.logger.verbose("Attempting to get cloud discovery metadata from authority configuration"); + this.logger.verbosePii(`Known Authorities: ${this.authorityOptions.knownAuthorities || Constants$1.NOT_APPLICABLE}`); + this.logger.verbosePii(`Authority Metadata: ${this.authorityOptions.authorityMetadata || Constants$1.NOT_APPLICABLE}`); + this.logger.verbosePii(`Canonical Authority: ${metadataEntity.canonical_authority || Constants$1.NOT_APPLICABLE}`); + const metadata = this.getCloudDiscoveryMetadataFromConfig(); + if (metadata) { + this.logger.verbose("Found cloud discovery metadata in authority configuration"); + updateCloudDiscoveryMetadata(metadataEntity, metadata, false); + return AuthorityMetadataSource.CONFIG; + } + this.logger.verbose("Did not find cloud discovery metadata in the config... Attempting to get cloud discovery metadata from the hardcoded values."); + if (this.options.skipAuthorityMetadataCache) { + this.logger.verbose("Skipping hardcoded cloud discovery metadata cache since skipAuthorityMetadataCache is set to true. Attempting to get cloud discovery metadata from the network metadata cache."); + } else { + const hardcodedMetadata = getCloudDiscoveryMetadataFromHardcodedValues(this.hostnameAndPort); + if (hardcodedMetadata) { + this.logger.verbose("Found cloud discovery metadata from hardcoded values."); + updateCloudDiscoveryMetadata(metadataEntity, hardcodedMetadata, false); + return AuthorityMetadataSource.HARDCODED_VALUES; + } + this.logger.verbose("Did not find cloud discovery metadata in hardcoded values... Attempting to get cloud discovery metadata from the network metadata cache."); + } + const metadataEntityExpired = isAuthorityMetadataExpired(metadataEntity); + if (this.isAuthoritySameType(metadataEntity) && metadataEntity.aliasesFromNetwork && !metadataEntityExpired) { + this.logger.verbose("Found cloud discovery metadata in the cache."); + return AuthorityMetadataSource.CACHE; + } else if (metadataEntityExpired) { + this.logger.verbose("The metadata entity is expired."); + } + return null; + } + /** + * Parse cloudDiscoveryMetadata config or check knownAuthorities + */ + getCloudDiscoveryMetadataFromConfig() { + if (this.authorityType === AuthorityType.Ciam) { + this.logger.verbose("CIAM authorities do not support cloud discovery metadata, generate the aliases from authority host."); + return _Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort); + } + if (this.authorityOptions.cloudDiscoveryMetadata) { + this.logger.verbose("The cloud discovery metadata has been provided as a network response, in the config."); + try { + this.logger.verbose("Attempting to parse the cloud discovery metadata."); + const parsedResponse = JSON.parse(this.authorityOptions.cloudDiscoveryMetadata); + const metadata = getCloudDiscoveryMetadataFromNetworkResponse(parsedResponse.metadata, this.hostnameAndPort); + this.logger.verbose("Parsed the cloud discovery metadata."); + if (metadata) { + this.logger.verbose("There is returnable metadata attached to the parsed cloud discovery metadata."); + return metadata; + } else { + this.logger.verbose("There is no metadata attached to the parsed cloud discovery metadata."); + } + } catch (e) { + this.logger.verbose("Unable to parse the cloud discovery metadata. Throwing Invalid Cloud Discovery Metadata Error."); + throw createClientConfigurationError(invalidCloudDiscoveryMetadata); + } + } + if (this.isInKnownAuthorities()) { + this.logger.verbose("The host is included in knownAuthorities. Creating new cloud discovery metadata from the host."); + return _Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort); + } + return null; + } + /** + * Called to get metadata from network if CloudDiscoveryMetadata was not populated by config + * + * @param hasHardcodedMetadata boolean + */ + async getCloudDiscoveryMetadataFromNetwork() { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthorityGetCloudDiscoveryMetadataFromNetwork, this.correlationId); + const instanceDiscoveryEndpoint = `${Constants$1.AAD_INSTANCE_DISCOVERY_ENDPT}${this.canonicalAuthority}oauth2/v2.0/authorize`; + const options = {}; + let match = null; + try { + const response = await this.networkInterface.sendGetRequestAsync(instanceDiscoveryEndpoint, options); + let typedResponseBody; + let metadata; + if (isCloudInstanceDiscoveryResponse(response.body)) { + typedResponseBody = response.body; + metadata = typedResponseBody.metadata; + this.logger.verbosePii(`tenant_discovery_endpoint is: ${typedResponseBody.tenant_discovery_endpoint}`); + } else if (isCloudInstanceDiscoveryErrorResponse(response.body)) { + this.logger.warning(`A CloudInstanceDiscoveryErrorResponse was returned. The cloud instance discovery network request's status code is: ${response.status}`); + typedResponseBody = response.body; + if (typedResponseBody.error === Constants$1.INVALID_INSTANCE) { + this.logger.error("The CloudInstanceDiscoveryErrorResponse error is invalid_instance."); + return null; + } + this.logger.warning(`The CloudInstanceDiscoveryErrorResponse error is ${typedResponseBody.error}`); + this.logger.warning(`The CloudInstanceDiscoveryErrorResponse error description is ${typedResponseBody.error_description}`); + this.logger.warning("Setting the value of the CloudInstanceDiscoveryMetadata (returned from the network) to []"); + metadata = []; + } else { + this.logger.error("AAD did not return a CloudInstanceDiscoveryResponse or CloudInstanceDiscoveryErrorResponse"); + return null; + } + this.logger.verbose("Attempting to find a match between the developer's authority and the CloudInstanceDiscoveryMetadata returned from the network request."); + match = getCloudDiscoveryMetadataFromNetworkResponse(metadata, this.hostnameAndPort); + } catch (error) { + if (error instanceof AuthError) { + this.logger.error(`There was a network error while attempting to get the cloud discovery instance metadata. +Error: ${error.errorCode} +Error Description: ${error.errorMessage}`); + } else { + const typedError = error; + this.logger.error(`A non-MSALJS error was thrown while attempting to get the cloud instance discovery metadata. +Error: ${typedError.name} +Error Description: ${typedError.message}`); + } + return null; + } + if (!match) { + this.logger.warning("The developer's authority was not found within the CloudInstanceDiscoveryMetadata returned from the network request."); + this.logger.verbose("Creating custom Authority for custom domain scenario."); + match = _Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort); + } + return match; + } + /** + * Helper function to determine if this host is included in the knownAuthorities config option + */ + isInKnownAuthorities() { + const matches = this.authorityOptions.knownAuthorities.filter((authority) => { + return authority && UrlString.getDomainFromUrl(authority).toLowerCase() === this.hostnameAndPort; + }); + return matches.length > 0; + } + /** + * helper function to populate the authority based on azureCloudOptions + * @param authorityString + * @param azureCloudOptions + */ + static generateAuthority(authorityString, azureCloudOptions) { + let authorityAzureCloudInstance; + if (azureCloudOptions && azureCloudOptions.azureCloudInstance !== AzureCloudInstance.None) { + const tenant = azureCloudOptions.tenant ? azureCloudOptions.tenant : Constants$1.DEFAULT_COMMON_TENANT; + authorityAzureCloudInstance = `${azureCloudOptions.azureCloudInstance}/${tenant}/`; + } + return authorityAzureCloudInstance ? authorityAzureCloudInstance : authorityString; + } + /** + * Creates cloud discovery metadata object from a given host + * @param host + */ + static createCloudDiscoveryMetadataFromHost(host) { + return { + preferred_network: host, + preferred_cache: host, + aliases: [host] + }; + } + /** + * helper function to generate environment from authority object + */ + getPreferredCache() { + if (this.managedIdentity) { + return Constants$1.DEFAULT_AUTHORITY_HOST; + } else if (this.discoveryComplete()) { + return this.metadata.preferred_cache; + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * Returns whether or not the provided host is an alias of this authority instance + * @param host + */ + isAlias(host) { + return this.metadata.aliases.indexOf(host) > -1; + } + /** + * Returns whether or not the provided host is an alias of a known Microsoft authority for purposes of endpoint discovery + * @param host + */ + isAliasOfKnownMicrosoftAuthority(host) { + return InstanceDiscoveryMetadataAliases.has(host); + } + /** + * Checks whether the provided host is that of a public cloud authority + * + * @param authority string + * @returns bool + */ + static isPublicCloudAuthority(host) { + return Constants$1.KNOWN_PUBLIC_CLOUDS.indexOf(host) >= 0; + } + /** + * Rebuild the authority string with the region + * + * @param host string + * @param region string + */ + static buildRegionalAuthorityString(host, region, queryString) { + const authorityUrlInstance = new UrlString(host); + authorityUrlInstance.validateAsUri(); + const authorityUrlParts = authorityUrlInstance.getUrlComponents(); + let hostNameAndPort = `${region}.${authorityUrlParts.HostNameAndPort}`; + if (this.isPublicCloudAuthority(authorityUrlParts.HostNameAndPort)) { + hostNameAndPort = `${region}.${Constants$1.REGIONAL_AUTH_PUBLIC_CLOUD_SUFFIX}`; + } + const url = UrlString.constructAuthorityUriFromObject({ + ...authorityUrlInstance.getUrlComponents(), + HostNameAndPort: hostNameAndPort + }).urlString; + if (queryString) + return `${url}?${queryString}`; + return url; + } + /** + * Replace the endpoints in the metadata object with their regional equivalents. + * + * @param metadata OpenIdConfigResponse + * @param azureRegion string + */ + static replaceWithRegionalInformation(metadata, azureRegion) { + const regionalMetadata = { ...metadata }; + regionalMetadata.authorization_endpoint = _Authority.buildRegionalAuthorityString(regionalMetadata.authorization_endpoint, azureRegion); + regionalMetadata.token_endpoint = _Authority.buildRegionalAuthorityString(regionalMetadata.token_endpoint, azureRegion); + if (regionalMetadata.end_session_endpoint) { + regionalMetadata.end_session_endpoint = _Authority.buildRegionalAuthorityString(regionalMetadata.end_session_endpoint, azureRegion); + } + return regionalMetadata; + } + /** + * Transform CIAM_AUTHORIY as per the below rules: + * If no path segments found and it is a CIAM authority (hostname ends with .ciamlogin.com), then transform it + * + * NOTE: The transformation path should go away once STS supports CIAM with the format: `tenantIdorDomain.ciamlogin.com` + * `ciamlogin.com` can also change in the future and we should accommodate the same + * + * @param authority + */ + static transformCIAMAuthority(authority) { + let ciamAuthority = authority; + const authorityUrl = new UrlString(authority); + const authorityUrlComponents = authorityUrl.getUrlComponents(); + if (authorityUrlComponents.PathSegments.length === 0 && authorityUrlComponents.HostNameAndPort.endsWith(Constants$1.CIAM_AUTH_URL)) { + const tenantIdOrDomain = authorityUrlComponents.HostNameAndPort.split(".")[0]; + ciamAuthority = `${ciamAuthority}${tenantIdOrDomain}${Constants$1.AAD_TENANT_DOMAIN_SUFFIX}`; + } + return ciamAuthority; + } + }; + Authority.reservedTenantDomains = /* @__PURE__ */ new Set([ + "{tenant}", + "{tenantid}", + AADAuthorityConstants.COMMON, + AADAuthorityConstants.CONSUMERS, + AADAuthorityConstants.ORGANIZATIONS + ]); + function getTenantFromAuthorityString(authority) { + const authorityUrl = new UrlString(authority); + const authorityUrlComponents = authorityUrl.getUrlComponents(); + const tenantId = authorityUrlComponents.PathSegments.slice(-1)[0]?.toLowerCase(); + switch (tenantId) { + case AADAuthorityConstants.COMMON: + case AADAuthorityConstants.ORGANIZATIONS: + case AADAuthorityConstants.CONSUMERS: + return void 0; + default: + return tenantId; + } + } + function formatAuthorityUri(authorityUri) { + return authorityUri.endsWith(Constants$1.FORWARD_SLASH) ? authorityUri : `${authorityUri}${Constants$1.FORWARD_SLASH}`; + } + function buildStaticAuthorityOptions(authOptions) { + const rawCloudDiscoveryMetadata = authOptions.cloudDiscoveryMetadata; + let cloudDiscoveryMetadata = void 0; + if (rawCloudDiscoveryMetadata) { + try { + cloudDiscoveryMetadata = JSON.parse(rawCloudDiscoveryMetadata); + } catch (e) { + throw createClientConfigurationError(invalidCloudDiscoveryMetadata); + } + } + return { + canonicalAuthority: authOptions.authority ? formatAuthorityUri(authOptions.authority) : void 0, + knownAuthorities: authOptions.knownAuthorities, + cloudDiscoveryMetadata + }; + } + async function createDiscoveredInstance(authorityUri, networkClient, cacheManager, authorityOptions, logger, correlationId, performanceClient) { + performanceClient?.addQueueMeasurement(PerformanceEvents.AuthorityFactoryCreateDiscoveredInstance, correlationId); + const authorityUriFinal = Authority.transformCIAMAuthority(formatAuthorityUri(authorityUri)); + const acquireTokenAuthority = new Authority(authorityUriFinal, networkClient, cacheManager, authorityOptions, logger, correlationId, performanceClient); + try { + await invokeAsync(acquireTokenAuthority.resolveEndpointsAsync.bind(acquireTokenAuthority), PerformanceEvents.AuthorityResolveEndpointsAsync, logger, performanceClient, correlationId)(); + return acquireTokenAuthority; + } catch (e) { + throw createClientAuthError(endpointResolutionError); + } + } + var ServerError = class _ServerError extends AuthError { + constructor(errorCode, errorMessage, subError, errorNo, status) { + super(errorCode, errorMessage, subError); + this.name = "ServerError"; + this.errorNo = errorNo; + this.status = status; + Object.setPrototypeOf(this, _ServerError.prototype); + } + }; + var ThrottlingUtils = class _ThrottlingUtils { + /** + * Prepares a RequestThumbprint to be stored as a key. + * @param thumbprint + */ + static generateThrottlingStorageKey(thumbprint) { + return `${ThrottlingConstants.THROTTLING_PREFIX}.${JSON.stringify(thumbprint)}`; + } + /** + * Performs necessary throttling checks before a network request. + * @param cacheManager + * @param thumbprint + */ + static preProcess(cacheManager, thumbprint, correlationId) { + const key = _ThrottlingUtils.generateThrottlingStorageKey(thumbprint); + const value = cacheManager.getThrottlingCache(key); + if (value) { + if (value.throttleTime < Date.now()) { + cacheManager.removeItem(key, correlationId); + return; + } + throw new ServerError(value.errorCodes?.join(" ") || Constants$1.EMPTY_STRING, value.errorMessage, value.subError); + } + } + /** + * Performs necessary throttling checks after a network request. + * @param cacheManager + * @param thumbprint + * @param response + */ + static postProcess(cacheManager, thumbprint, response, correlationId) { + if (_ThrottlingUtils.checkResponseStatus(response) || _ThrottlingUtils.checkResponseForRetryAfter(response)) { + const thumbprintValue = { + throttleTime: _ThrottlingUtils.calculateThrottleTime(parseInt(response.headers[HeaderNames.RETRY_AFTER])), + error: response.body.error, + errorCodes: response.body.error_codes, + errorMessage: response.body.error_description, + subError: response.body.suberror + }; + cacheManager.setThrottlingCache(_ThrottlingUtils.generateThrottlingStorageKey(thumbprint), thumbprintValue, correlationId); + } + } + /** + * Checks a NetworkResponse object's status codes against 429 or 5xx + * @param response + */ + static checkResponseStatus(response) { + return response.status === 429 || response.status >= 500 && response.status < 600; + } + /** + * Checks a NetworkResponse object's RetryAfter header + * @param response + */ + static checkResponseForRetryAfter(response) { + if (response.headers) { + return response.headers.hasOwnProperty(HeaderNames.RETRY_AFTER) && (response.status < 200 || response.status >= 300); + } + return false; + } + /** + * Calculates the Unix-time value for a throttle to expire given throttleTime in seconds. + * @param throttleTime + */ + static calculateThrottleTime(throttleTime) { + const time = throttleTime <= 0 ? 0 : throttleTime; + const currentSeconds = Date.now() / 1e3; + return Math.floor(Math.min(currentSeconds + (time || ThrottlingConstants.DEFAULT_THROTTLE_TIME_SECONDS), currentSeconds + ThrottlingConstants.DEFAULT_MAX_THROTTLE_TIME_SECONDS) * 1e3); + } + static removeThrottle(cacheManager, clientId, request, homeAccountIdentifier) { + const thumbprint = { + clientId, + authority: request.authority, + scopes: request.scopes, + homeAccountIdentifier, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + const key = this.generateThrottlingStorageKey(thumbprint); + cacheManager.removeItem(key, request.correlationId); + } + }; + var NetworkError = class _NetworkError extends AuthError { + constructor(error, httpStatus, responseHeaders) { + super(error.errorCode, error.errorMessage, error.subError); + Object.setPrototypeOf(this, _NetworkError.prototype); + this.name = "NetworkError"; + this.error = error; + this.httpStatus = httpStatus; + this.responseHeaders = responseHeaders; + } + }; + var BaseClient = class { + constructor(configuration, performanceClient) { + this.config = buildClientConfiguration(configuration); + this.logger = new Logger(this.config.loggerOptions, name$1, version$1); + this.cryptoUtils = this.config.cryptoInterface; + this.cacheManager = this.config.storageInterface; + this.networkClient = this.config.networkInterface; + this.serverTelemetryManager = this.config.serverTelemetryManager; + this.authority = this.config.authOptions.authority; + this.performanceClient = performanceClient; + } + /** + * Creates default headers for requests to token endpoint + */ + createTokenRequestHeaders(ccsCred) { + const headers = {}; + headers[HeaderNames.CONTENT_TYPE] = Constants$1.URL_FORM_CONTENT_TYPE; + if (!this.config.systemOptions.preventCorsPreflight && ccsCred) { + switch (ccsCred.type) { + case CcsCredentialType.HOME_ACCOUNT_ID: + try { + const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential); + headers[HeaderNames.CCS_HEADER] = `Oid:${clientInfo.uid}@${clientInfo.utid}`; + } catch (e) { + this.logger.verbose("Could not parse home account ID for CCS Header: " + e); + } + break; + case CcsCredentialType.UPN: + headers[HeaderNames.CCS_HEADER] = `UPN: ${ccsCred.credential}`; + break; + } + } + return headers; + } + /** + * Http post to token endpoint + * @param tokenEndpoint + * @param queryString + * @param headers + * @param thumbprint + */ + async executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint, correlationId, queuedEvent) { + if (queuedEvent) { + this.performanceClient?.addQueueMeasurement(queuedEvent, correlationId); + } + const response = await this.sendPostRequest(thumbprint, tokenEndpoint, { body: queryString, headers }, correlationId); + if (this.config.serverTelemetryManager && response.status < 500 && response.status !== 429) { + this.config.serverTelemetryManager.clearTelemetryCache(); + } + return response; + } + /** + * Wraps sendPostRequestAsync with necessary preflight and postflight logic + * @param thumbprint - Request thumbprint for throttling + * @param tokenEndpoint - Endpoint to make the POST to + * @param options - Body and Headers to include on the POST request + * @param correlationId - CorrelationId for telemetry + */ + async sendPostRequest(thumbprint, tokenEndpoint, options, correlationId) { + ThrottlingUtils.preProcess(this.cacheManager, thumbprint, correlationId); + let response; + try { + response = await invokeAsync(this.networkClient.sendPostRequestAsync.bind(this.networkClient), PerformanceEvents.NetworkClientSendPostRequestAsync, this.logger, this.performanceClient, correlationId)(tokenEndpoint, options); + const responseHeaders = response.headers || {}; + this.performanceClient?.addFields({ + refreshTokenSize: response.body.refresh_token?.length || 0, + httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "", + requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] || "" + }, correlationId); + } catch (e) { + if (e instanceof NetworkError) { + const responseHeaders = e.responseHeaders; + if (responseHeaders) { + this.performanceClient?.addFields({ + httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "", + requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] || "", + contentTypeHeader: responseHeaders[HeaderNames.CONTENT_TYPE] || void 0, + contentLengthHeader: responseHeaders[HeaderNames.CONTENT_LENGTH] || void 0, + httpStatus: e.httpStatus + }, correlationId); + } + throw e.error; + } + if (e instanceof AuthError) { + throw e; + } else { + throw createClientAuthError(networkError); + } + } + ThrottlingUtils.postProcess(this.cacheManager, thumbprint, response, correlationId); + return response; + } + /** + * Updates the authority object of the client. Endpoint discovery must be completed. + * @param updatedAuthority + */ + async updateAuthority(cloudInstanceHostname, correlationId) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.UpdateTokenEndpointAuthority, correlationId); + const cloudInstanceAuthorityUri = `https://${cloudInstanceHostname}/${this.authority.tenant}/`; + const cloudInstanceAuthority = await createDiscoveredInstance(cloudInstanceAuthorityUri, this.networkClient, this.cacheManager, this.authority.options, this.logger, correlationId, this.performanceClient); + this.authority = cloudInstanceAuthority; + } + /** + * Creates query string for the /token request + * @param request + */ + createTokenQueryParameters(request) { + const parameterBuilder = new RequestParameterBuilder(request.correlationId, this.performanceClient); + if (request.embeddedClientId) { + parameterBuilder.addBrokerParameters({ + brokerClientId: this.config.authOptions.clientId, + brokerRedirectUri: this.config.authOptions.redirectUri + }); + } + if (request.tokenQueryParameters) { + parameterBuilder.addExtraQueryParameters(request.tokenQueryParameters); + } + parameterBuilder.addCorrelationId(request.correlationId); + return parameterBuilder.createQueryString(); + } + }; + var noTokensFound = "no_tokens_found"; + var nativeAccountUnavailable = "native_account_unavailable"; + var refreshTokenExpired = "refresh_token_expired"; + var interactionRequired = "interaction_required"; + var consentRequired = "consent_required"; + var loginRequired = "login_required"; + var badToken = "bad_token"; + var InteractionRequiredAuthErrorCodes = /* @__PURE__ */ Object.freeze({ + __proto__: null, + badToken, + consentRequired, + interactionRequired, + loginRequired, + nativeAccountUnavailable, + noTokensFound, + refreshTokenExpired + }); + var InteractionRequiredServerErrorMessage = [ + interactionRequired, + consentRequired, + loginRequired, + badToken + ]; + var InteractionRequiredAuthSubErrorMessage = [ + "message_only", + "additional_action", + "basic_action", + "user_password_expired", + "consent_required", + "bad_token" + ]; + var InteractionRequiredAuthErrorMessages = { + [noTokensFound]: "No refresh token found in the cache. Please sign-in.", + [nativeAccountUnavailable]: "The requested account is not available in the native broker. It may have been deleted or logged out. Please sign-in again using an interactive API.", + [refreshTokenExpired]: "Refresh token has expired.", + [badToken]: "Identity provider returned bad_token due to an expired or invalid refresh token. Please invoke an interactive API to resolve." + }; + var InteractionRequiredAuthErrorMessage = { + noTokensFoundError: { + code: noTokensFound, + desc: InteractionRequiredAuthErrorMessages[noTokensFound] + }, + native_account_unavailable: { + code: nativeAccountUnavailable, + desc: InteractionRequiredAuthErrorMessages[nativeAccountUnavailable] + }, + bad_token: { + code: badToken, + desc: InteractionRequiredAuthErrorMessages[badToken] + } + }; + var InteractionRequiredAuthError = class _InteractionRequiredAuthError extends AuthError { + constructor(errorCode, errorMessage, subError, timestamp, traceId, correlationId, claims, errorNo) { + super(errorCode, errorMessage, subError); + Object.setPrototypeOf(this, _InteractionRequiredAuthError.prototype); + this.timestamp = timestamp || Constants$1.EMPTY_STRING; + this.traceId = traceId || Constants$1.EMPTY_STRING; + this.correlationId = correlationId || Constants$1.EMPTY_STRING; + this.claims = claims || Constants$1.EMPTY_STRING; + this.name = "InteractionRequiredAuthError"; + this.errorNo = errorNo; + } + }; + function isInteractionRequiredError(errorCode, errorString, subError) { + const isInteractionRequiredErrorCode = !!errorCode && InteractionRequiredServerErrorMessage.indexOf(errorCode) > -1; + const isInteractionRequiredSubError = !!subError && InteractionRequiredAuthSubErrorMessage.indexOf(subError) > -1; + const isInteractionRequiredErrorDesc = !!errorString && InteractionRequiredServerErrorMessage.some((irErrorCode) => { + return errorString.indexOf(irErrorCode) > -1; + }); + return isInteractionRequiredErrorCode || isInteractionRequiredErrorDesc || isInteractionRequiredSubError; + } + function createInteractionRequiredAuthError(errorCode) { + return new InteractionRequiredAuthError(errorCode, InteractionRequiredAuthErrorMessages[errorCode]); + } + var ProtocolUtils = class _ProtocolUtils { + /** + * Appends user state with random guid, or returns random guid. + * @param userState + * @param randomGuid + */ + static setRequestState(cryptoObj, userState, meta) { + const libraryState = _ProtocolUtils.generateLibraryState(cryptoObj, meta); + return userState ? `${libraryState}${Constants$1.RESOURCE_DELIM}${userState}` : libraryState; + } + /** + * Generates the state value used by the common library. + * @param randomGuid + * @param cryptoObj + */ + static generateLibraryState(cryptoObj, meta) { + if (!cryptoObj) { + throw createClientAuthError(noCryptoObject); + } + const stateObj = { + id: cryptoObj.createNewGuid() + }; + if (meta) { + stateObj.meta = meta; + } + const stateString = JSON.stringify(stateObj); + return cryptoObj.base64Encode(stateString); + } + /** + * Parses the state into the RequestStateObject, which contains the LibraryState info and the state passed by the user. + * @param state + * @param cryptoObj + */ + static parseRequestState(cryptoObj, state) { + if (!cryptoObj) { + throw createClientAuthError(noCryptoObject); + } + if (!state) { + throw createClientAuthError(invalidState); + } + try { + const splitState = state.split(Constants$1.RESOURCE_DELIM); + const libraryState = splitState[0]; + const userState = splitState.length > 1 ? splitState.slice(1).join(Constants$1.RESOURCE_DELIM) : Constants$1.EMPTY_STRING; + const libraryStateString = cryptoObj.base64Decode(libraryState); + const libraryStateObj = JSON.parse(libraryStateString); + return { + userRequestState: userState || Constants$1.EMPTY_STRING, + libraryState: libraryStateObj + }; + } catch (e) { + throw createClientAuthError(invalidState); + } + } + }; + var KeyLocation = { + SW: "sw" + }; + var PopTokenGenerator = class { + constructor(cryptoUtils, performanceClient) { + this.cryptoUtils = cryptoUtils; + this.performanceClient = performanceClient; + } + /** + * Generates the req_cnf validated at the RP in the POP protocol for SHR parameters + * and returns an object containing the keyid, the full req_cnf string and the req_cnf string hash + * @param request + * @returns + */ + async generateCnf(request, logger) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.PopTokenGenerateCnf, request.correlationId); + const reqCnf = await invokeAsync(this.generateKid.bind(this), PerformanceEvents.PopTokenGenerateCnf, logger, this.performanceClient, request.correlationId)(request); + const reqCnfString = this.cryptoUtils.base64UrlEncode(JSON.stringify(reqCnf)); + return { + kid: reqCnf.kid, + reqCnfString + }; + } + /** + * Generates key_id for a SHR token request + * @param request + * @returns + */ + async generateKid(request) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.PopTokenGenerateKid, request.correlationId); + const kidThumbprint = await this.cryptoUtils.getPublicKeyThumbprint(request); + return { + kid: kidThumbprint, + xms_ksl: KeyLocation.SW + }; + } + /** + * Signs the POP access_token with the local generated key-pair + * @param accessToken + * @param request + * @returns + */ + async signPopToken(accessToken, keyId, request) { + return this.signPayload(accessToken, keyId, request); + } + /** + * Utility function to generate the signed JWT for an access_token + * @param payload + * @param kid + * @param request + * @param claims + * @returns + */ + async signPayload(payload, keyId, request, claims) { + const { resourceRequestMethod, resourceRequestUri, shrClaims, shrNonce, shrOptions } = request; + const resourceUrlString = resourceRequestUri ? new UrlString(resourceRequestUri) : void 0; + const resourceUrlComponents = resourceUrlString?.getUrlComponents(); + return this.cryptoUtils.signJwt({ + at: payload, + ts: nowSeconds(), + m: resourceRequestMethod?.toUpperCase(), + u: resourceUrlComponents?.HostNameAndPort, + nonce: shrNonce || this.cryptoUtils.createNewGuid(), + p: resourceUrlComponents?.AbsolutePath, + q: resourceUrlComponents?.QueryString ? [[], resourceUrlComponents.QueryString] : void 0, + client_claims: shrClaims || void 0, + ...claims + }, keyId, shrOptions, request.correlationId); + } + }; + var TokenCacheContext = class { + constructor(tokenCache, hasChanged) { + this.cache = tokenCache; + this.hasChanged = hasChanged; + } + /** + * boolean which indicates the changes in cache + */ + get cacheHasChanged() { + return this.hasChanged; + } + /** + * function to retrieve the token cache + */ + get tokenCache() { + return this.cache; + } + }; + function parseServerErrorNo(serverResponse) { + const errorCodePrefix = "code="; + const errorCodePrefixIndex = serverResponse.error_uri?.lastIndexOf(errorCodePrefix); + return errorCodePrefixIndex && errorCodePrefixIndex >= 0 ? serverResponse.error_uri?.substring(errorCodePrefixIndex + errorCodePrefix.length) : void 0; + } + var ResponseHandler = class _ResponseHandler { + constructor(clientId, cacheStorage, cryptoObj, logger, serializableCache, persistencePlugin, performanceClient) { + this.clientId = clientId; + this.cacheStorage = cacheStorage; + this.cryptoObj = cryptoObj; + this.logger = logger; + this.serializableCache = serializableCache; + this.persistencePlugin = persistencePlugin; + this.performanceClient = performanceClient; + } + /** + * Function which validates server authorization code response. + * @param serverResponseHash + * @param requestState + * @param cryptoObj + */ + validateServerAuthorizationCodeResponse(serverResponse, requestState) { + if (!serverResponse.state || !requestState) { + throw serverResponse.state ? createClientAuthError(stateNotFound, "Cached State") : createClientAuthError(stateNotFound, "Server State"); + } + let decodedServerResponseState; + let decodedRequestState; + try { + decodedServerResponseState = decodeURIComponent(serverResponse.state); + } catch (e) { + throw createClientAuthError(invalidState, serverResponse.state); + } + try { + decodedRequestState = decodeURIComponent(requestState); + } catch (e) { + throw createClientAuthError(invalidState, serverResponse.state); + } + if (decodedServerResponseState !== decodedRequestState) { + throw createClientAuthError(stateMismatch); + } + if (serverResponse.error || serverResponse.error_description || serverResponse.suberror) { + const serverErrorNo = parseServerErrorNo(serverResponse); + if (isInteractionRequiredError(serverResponse.error, serverResponse.error_description, serverResponse.suberror)) { + throw new InteractionRequiredAuthError(serverResponse.error || "", serverResponse.error_description, serverResponse.suberror, serverResponse.timestamp || "", serverResponse.trace_id || "", serverResponse.correlation_id || "", serverResponse.claims || "", serverErrorNo); + } + throw new ServerError(serverResponse.error || "", serverResponse.error_description, serverResponse.suberror, serverErrorNo); + } + } + /** + * Function which validates server authorization token response. + * @param serverResponse + * @param refreshAccessToken + */ + validateTokenResponse(serverResponse, refreshAccessToken) { + if (serverResponse.error || serverResponse.error_description || serverResponse.suberror) { + const errString = `Error(s): ${serverResponse.error_codes || Constants$1.NOT_AVAILABLE} - Timestamp: ${serverResponse.timestamp || Constants$1.NOT_AVAILABLE} - Description: ${serverResponse.error_description || Constants$1.NOT_AVAILABLE} - Correlation ID: ${serverResponse.correlation_id || Constants$1.NOT_AVAILABLE} - Trace ID: ${serverResponse.trace_id || Constants$1.NOT_AVAILABLE}`; + const serverErrorNo = serverResponse.error_codes?.length ? serverResponse.error_codes[0] : void 0; + const serverError = new ServerError(serverResponse.error, errString, serverResponse.suberror, serverErrorNo, serverResponse.status); + if (refreshAccessToken && serverResponse.status && serverResponse.status >= HttpStatus.SERVER_ERROR_RANGE_START && serverResponse.status <= HttpStatus.SERVER_ERROR_RANGE_END) { + this.logger.warning(`executeTokenRequest:validateTokenResponse - AAD is currently unavailable and the access token is unable to be refreshed. +${serverError}`); + return; + } else if (refreshAccessToken && serverResponse.status && serverResponse.status >= HttpStatus.CLIENT_ERROR_RANGE_START && serverResponse.status <= HttpStatus.CLIENT_ERROR_RANGE_END) { + this.logger.warning(`executeTokenRequest:validateTokenResponse - AAD is currently available but is unable to refresh the access token. +${serverError}`); + return; + } + if (isInteractionRequiredError(serverResponse.error, serverResponse.error_description, serverResponse.suberror)) { + throw new InteractionRequiredAuthError(serverResponse.error, serverResponse.error_description, serverResponse.suberror, serverResponse.timestamp || Constants$1.EMPTY_STRING, serverResponse.trace_id || Constants$1.EMPTY_STRING, serverResponse.correlation_id || Constants$1.EMPTY_STRING, serverResponse.claims || Constants$1.EMPTY_STRING, serverErrorNo); + } + throw serverError; + } + } + /** + * Returns a constructed token response based on given string. Also manages the cache updates and cleanups. + * @param serverTokenResponse + * @param authority + */ + async handleServerTokenResponse(serverTokenResponse, authority, reqTimestamp, request, authCodePayload, userAssertionHash, handlingRefreshTokenResponse, forceCacheRefreshTokenResponse, serverRequestId) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.HandleServerTokenResponse, serverTokenResponse.correlation_id); + let idTokenClaims; + if (serverTokenResponse.id_token) { + idTokenClaims = extractTokenClaims(serverTokenResponse.id_token || Constants$1.EMPTY_STRING, this.cryptoObj.base64Decode); + if (authCodePayload && authCodePayload.nonce) { + if (idTokenClaims.nonce !== authCodePayload.nonce) { + throw createClientAuthError(nonceMismatch); + } + } + if (request.maxAge || request.maxAge === 0) { + const authTime = idTokenClaims.auth_time; + if (!authTime) { + throw createClientAuthError(authTimeNotFound); + } + checkMaxAge(authTime, request.maxAge); + } + } + this.homeAccountIdentifier = AccountEntity.generateHomeAccountId(serverTokenResponse.client_info || Constants$1.EMPTY_STRING, authority.authorityType, this.logger, this.cryptoObj, idTokenClaims); + let requestStateObj; + if (!!authCodePayload && !!authCodePayload.state) { + requestStateObj = ProtocolUtils.parseRequestState(this.cryptoObj, authCodePayload.state); + } + serverTokenResponse.key_id = serverTokenResponse.key_id || request.sshKid || void 0; + const cacheRecord = this.generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenClaims, userAssertionHash, authCodePayload); + let cacheContext; + try { + if (this.persistencePlugin && this.serializableCache) { + this.logger.verbose("Persistence enabled, calling beforeCacheAccess"); + cacheContext = new TokenCacheContext(this.serializableCache, true); + await this.persistencePlugin.beforeCacheAccess(cacheContext); + } + if (handlingRefreshTokenResponse && !forceCacheRefreshTokenResponse && cacheRecord.account) { + const key = cacheRecord.account.generateAccountKey(); + const account = this.cacheStorage.getAccount(key, request.correlationId, this.logger); + if (!account) { + this.logger.warning("Account used to refresh tokens not in persistence, refreshed tokens will not be stored in the cache"); + return await _ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenClaims, requestStateObj, void 0, serverRequestId); + } + } + await this.cacheStorage.saveCacheRecord(cacheRecord, request.correlationId, request.storeInCache); + } finally { + if (this.persistencePlugin && this.serializableCache && cacheContext) { + this.logger.verbose("Persistence enabled, calling afterCacheAccess"); + await this.persistencePlugin.afterCacheAccess(cacheContext); + } + } + return _ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenClaims, requestStateObj, serverTokenResponse, serverRequestId); + } + /** + * Generates CacheRecord + * @param serverTokenResponse + * @param idTokenObj + * @param authority + */ + generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenClaims, userAssertionHash, authCodePayload) { + const env = authority.getPreferredCache(); + if (!env) { + throw createClientAuthError(invalidCacheEnvironment); + } + const claimsTenantId = getTenantIdFromIdTokenClaims(idTokenClaims); + let cachedIdToken; + let cachedAccount; + if (serverTokenResponse.id_token && !!idTokenClaims) { + cachedIdToken = createIdTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.id_token, this.clientId, claimsTenantId || ""); + cachedAccount = buildAccountToCache( + this.cacheStorage, + authority, + this.homeAccountIdentifier, + this.cryptoObj.base64Decode, + request.correlationId, + idTokenClaims, + serverTokenResponse.client_info, + env, + claimsTenantId, + authCodePayload, + void 0, + // nativeAccountId + this.logger + ); + } + let cachedAccessToken = null; + if (serverTokenResponse.access_token) { + const responseScopes = serverTokenResponse.scope ? ScopeSet.fromString(serverTokenResponse.scope) : new ScopeSet(request.scopes || []); + const expiresIn = (typeof serverTokenResponse.expires_in === "string" ? parseInt(serverTokenResponse.expires_in, 10) : serverTokenResponse.expires_in) || 0; + const extExpiresIn = (typeof serverTokenResponse.ext_expires_in === "string" ? parseInt(serverTokenResponse.ext_expires_in, 10) : serverTokenResponse.ext_expires_in) || 0; + const refreshIn = (typeof serverTokenResponse.refresh_in === "string" ? parseInt(serverTokenResponse.refresh_in, 10) : serverTokenResponse.refresh_in) || void 0; + const tokenExpirationSeconds = reqTimestamp + expiresIn; + const extendedTokenExpirationSeconds = tokenExpirationSeconds + extExpiresIn; + const refreshOnSeconds = refreshIn && refreshIn > 0 ? reqTimestamp + refreshIn : void 0; + cachedAccessToken = createAccessTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.access_token, this.clientId, claimsTenantId || authority.tenant || "", responseScopes.printScopes(), tokenExpirationSeconds, extendedTokenExpirationSeconds, this.cryptoObj.base64Decode, refreshOnSeconds, serverTokenResponse.token_type, userAssertionHash, serverTokenResponse.key_id, request.claims, request.requestedClaimsHash); + } + let cachedRefreshToken = null; + if (serverTokenResponse.refresh_token) { + let rtExpiresOn; + if (serverTokenResponse.refresh_token_expires_in) { + const rtExpiresIn = typeof serverTokenResponse.refresh_token_expires_in === "string" ? parseInt(serverTokenResponse.refresh_token_expires_in, 10) : serverTokenResponse.refresh_token_expires_in; + rtExpiresOn = reqTimestamp + rtExpiresIn; + } + cachedRefreshToken = createRefreshTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.refresh_token, this.clientId, serverTokenResponse.foci, userAssertionHash, rtExpiresOn); + } + let cachedAppMetadata = null; + if (serverTokenResponse.foci) { + cachedAppMetadata = { + clientId: this.clientId, + environment: env, + familyId: serverTokenResponse.foci + }; + } + return { + account: cachedAccount, + idToken: cachedIdToken, + accessToken: cachedAccessToken, + refreshToken: cachedRefreshToken, + appMetadata: cachedAppMetadata + }; + } + /** + * Creates an @AuthenticationResult from @CacheRecord , @IdToken , and a boolean that states whether or not the result is from cache. + * + * Optionally takes a state string that is set as-is in the response. + * + * @param cacheRecord + * @param idTokenObj + * @param fromTokenCache + * @param stateString + */ + static async generateAuthenticationResult(cryptoObj, authority, cacheRecord, fromTokenCache, request, idTokenClaims, requestState, serverTokenResponse, requestId) { + let accessToken = Constants$1.EMPTY_STRING; + let responseScopes = []; + let expiresOn = null; + let extExpiresOn; + let refreshOn; + let familyId = Constants$1.EMPTY_STRING; + if (cacheRecord.accessToken) { + if (cacheRecord.accessToken.tokenType === AuthenticationScheme.POP && !request.popKid) { + const popTokenGenerator = new PopTokenGenerator(cryptoObj); + const { secret, keyId } = cacheRecord.accessToken; + if (!keyId) { + throw createClientAuthError(keyIdMissing); + } + accessToken = await popTokenGenerator.signPopToken(secret, keyId, request); + } else { + accessToken = cacheRecord.accessToken.secret; + } + responseScopes = ScopeSet.fromString(cacheRecord.accessToken.target).asArray(); + expiresOn = new Date(Number(cacheRecord.accessToken.expiresOn) * 1e3); + extExpiresOn = new Date(Number(cacheRecord.accessToken.extendedExpiresOn) * 1e3); + if (cacheRecord.accessToken.refreshOn) { + refreshOn = new Date(Number(cacheRecord.accessToken.refreshOn) * 1e3); + } + } + if (cacheRecord.appMetadata) { + familyId = cacheRecord.appMetadata.familyId === THE_FAMILY_ID ? THE_FAMILY_ID : ""; + } + const uid = idTokenClaims?.oid || idTokenClaims?.sub || ""; + const tid = idTokenClaims?.tid || ""; + if (serverTokenResponse?.spa_accountid && !!cacheRecord.account) { + cacheRecord.account.nativeAccountId = serverTokenResponse?.spa_accountid; + } + const accountInfo = cacheRecord.account ? updateAccountTenantProfileData( + cacheRecord.account.getAccountInfo(), + void 0, + // tenantProfile optional + idTokenClaims, + cacheRecord.idToken?.secret + ) : null; + return { + authority: authority.canonicalAuthority, + uniqueId: uid, + tenantId: tid, + scopes: responseScopes, + account: accountInfo, + idToken: cacheRecord?.idToken?.secret || "", + idTokenClaims: idTokenClaims || {}, + accessToken, + fromCache: fromTokenCache, + expiresOn, + extExpiresOn, + refreshOn, + correlationId: request.correlationId, + requestId: requestId || Constants$1.EMPTY_STRING, + familyId, + tokenType: cacheRecord.accessToken?.tokenType || Constants$1.EMPTY_STRING, + state: requestState ? requestState.userRequestState : Constants$1.EMPTY_STRING, + cloudGraphHostName: cacheRecord.account?.cloudGraphHostName || Constants$1.EMPTY_STRING, + msGraphHost: cacheRecord.account?.msGraphHost || Constants$1.EMPTY_STRING, + code: serverTokenResponse?.spa_code, + fromNativeBroker: false + }; + } + }; + function buildAccountToCache(cacheStorage, authority, homeAccountId, base64Decode, correlationId, idTokenClaims, clientInfo, environment, claimsTenantId, authCodePayload, nativeAccountId, logger) { + logger?.verbose("setCachedAccount called"); + const accountKeys = cacheStorage.getAccountKeys(); + const baseAccountKey = accountKeys.find((accountKey) => { + return accountKey.startsWith(homeAccountId); + }); + let cachedAccount = null; + if (baseAccountKey) { + cachedAccount = cacheStorage.getAccount(baseAccountKey, correlationId, logger); + } + const baseAccount = cachedAccount || AccountEntity.createAccount({ + homeAccountId, + idTokenClaims, + clientInfo, + environment, + cloudGraphHostName: authCodePayload?.cloud_graph_host_name, + msGraphHost: authCodePayload?.msgraph_host, + nativeAccountId + }, authority, base64Decode); + const tenantProfiles = baseAccount.tenantProfiles || []; + const tenantId = claimsTenantId || baseAccount.realm; + if (tenantId && !tenantProfiles.find((tenantProfile) => { + return tenantProfile.tenantId === tenantId; + })) { + const newTenantProfile = buildTenantProfile(homeAccountId, baseAccount.localAccountId, tenantId, idTokenClaims); + tenantProfiles.push(newTenantProfile); + } + baseAccount.tenantProfiles = tenantProfiles; + return baseAccount; + } + async function getClientAssertion(clientAssertion, clientId, tokenEndpoint) { + if (typeof clientAssertion === "string") { + return clientAssertion; + } else { + const config = { + clientId, + tokenEndpoint + }; + return clientAssertion(config); + } + } + var AuthorizationCodeClient = class extends BaseClient { + constructor(configuration, performanceClient) { + super(configuration, performanceClient); + this.includeRedirectUri = true; + this.oidcDefaultScopes = this.config.authOptions.authority.options.OIDCOptions?.defaultScopes; + } + /** + * Creates the URL of the authorization request letting the user input credentials and consent to the + * application. The URL target the /authorize endpoint of the authority configured in the + * application object. + * + * Once the user inputs their credentials and consents, the authority will send a response to the redirect URI + * sent in the request and should contain an authorization code, which can then be used to acquire tokens via + * acquireToken(AuthorizationCodeRequest) + * @param request + */ + async getAuthCodeUrl(request) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.GetAuthCodeUrl, request.correlationId); + const queryString = await invokeAsync(this.createAuthCodeUrlQueryString.bind(this), PerformanceEvents.AuthClientCreateQueryString, this.logger, this.performanceClient, request.correlationId)(request); + return UrlString.appendQueryString(this.authority.authorizationEndpoint, queryString); + } + /** + * API to acquire a token in exchange of 'authorization_code` acquired by the user in the first leg of the + * authorization_code_grant + * @param request + */ + async acquireToken(request, authCodePayload) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientAcquireToken, request.correlationId); + if (!request.code) { + throw createClientAuthError(requestCannotBeMade); + } + const reqTimestamp = nowSeconds(); + const response = await invokeAsync(this.executeTokenRequest.bind(this), PerformanceEvents.AuthClientExecuteTokenRequest, this.logger, this.performanceClient, request.correlationId)(this.authority, request); + const requestId = response.headers?.[HeaderNames.X_MS_REQUEST_ID]; + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin, this.performanceClient); + responseHandler.validateTokenResponse(response.body); + return invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), PerformanceEvents.HandleServerTokenResponse, this.logger, this.performanceClient, request.correlationId)(response.body, this.authority, reqTimestamp, request, authCodePayload, void 0, void 0, void 0, requestId); + } + /** + * Handles the hash fragment response from public client code request. Returns a code response used by + * the client to exchange for a token in acquireToken. + * @param hashFragment + */ + handleFragmentResponse(serverParams, cachedState) { + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, null, null); + responseHandler.validateServerAuthorizationCodeResponse(serverParams, cachedState); + if (!serverParams.code) { + throw createClientAuthError(authorizationCodeMissingFromServerResponse); + } + return serverParams; + } + /** + * Used to log out the current user, and redirect the user to the postLogoutRedirectUri. + * Default behaviour is to redirect the user to `window.location.href`. + * @param authorityUri + */ + getLogoutUri(logoutRequest) { + if (!logoutRequest) { + throw createClientConfigurationError(logoutRequestEmpty); + } + const queryString = this.createLogoutUrlQueryString(logoutRequest); + return UrlString.appendQueryString(this.authority.endSessionEndpoint, queryString); + } + /** + * Executes POST request to token endpoint + * @param authority + * @param request + */ + async executeTokenRequest(authority, request) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId); + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await invokeAsync(this.createTokenRequestBody.bind(this), PerformanceEvents.AuthClientCreateTokenRequestBody, this.logger, this.performanceClient, request.correlationId)(request); + let ccsCredential = void 0; + if (request.clientInfo) { + try { + const clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils.base64Decode); + ccsCredential = { + credential: `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`, + type: CcsCredentialType.HOME_ACCOUNT_ID + }; + } catch (e) { + this.logger.verbose("Could not parse client info for CCS Header: " + e); + } + } + const headers = this.createTokenRequestHeaders(ccsCredential || request.ccsCredential); + const thumbprint = { + clientId: request.tokenBodyParameters?.clientId || this.config.authOptions.clientId, + authority: authority.canonicalAuthority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + return invokeAsync(this.executePostToTokenEndpoint.bind(this), PerformanceEvents.AuthorizationCodeClientExecutePostToTokenEndpoint, this.logger, this.performanceClient, request.correlationId)(endpoint, requestBody, headers, thumbprint, request.correlationId, PerformanceEvents.AuthorizationCodeClientExecutePostToTokenEndpoint); + } + /** + * Generates a map for all the params to be sent to the service + * @param request + */ + async createTokenRequestBody(request) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientCreateTokenRequestBody, request.correlationId); + const parameterBuilder = new RequestParameterBuilder(request.correlationId, this.performanceClient); + parameterBuilder.addClientId(request.embeddedClientId || request.tokenBodyParameters?.[CLIENT_ID] || this.config.authOptions.clientId); + if (!this.includeRedirectUri) { + RequestValidator.validateRedirectUri(request.redirectUri); + } else { + parameterBuilder.addRedirectUri(request.redirectUri); + } + parameterBuilder.addScopes(request.scopes, true, this.oidcDefaultScopes); + parameterBuilder.addAuthorizationCode(request.code); + parameterBuilder.addLibraryInfo(this.config.libraryInfo); + parameterBuilder.addApplicationTelemetry(this.config.telemetry.application); + parameterBuilder.addThrottling(); + if (this.serverTelemetryManager && !isOidcProtocolMode(this.config)) { + parameterBuilder.addServerTelemetry(this.serverTelemetryManager); + } + if (request.codeVerifier) { + parameterBuilder.addCodeVerifier(request.codeVerifier); + } + if (this.config.clientCredentials.clientSecret) { + parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret); + } + if (this.config.clientCredentials.clientAssertion) { + const clientAssertion = this.config.clientCredentials.clientAssertion; + parameterBuilder.addClientAssertion(await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + parameterBuilder.addClientAssertionType(clientAssertion.assertionType); + } + parameterBuilder.addGrantType(GrantType.AUTHORIZATION_CODE_GRANT); + parameterBuilder.addClientInfo(); + if (request.authenticationScheme === AuthenticationScheme.POP) { + const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils, this.performanceClient); + let reqCnfData; + if (!request.popKid) { + const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(request, this.logger); + reqCnfData = generatedReqCnfData.reqCnfString; + } else { + reqCnfData = this.cryptoUtils.encodeKid(request.popKid); + } + parameterBuilder.addPopToken(reqCnfData); + } else if (request.authenticationScheme === AuthenticationScheme.SSH) { + if (request.sshJwk) { + parameterBuilder.addSshJwk(request.sshJwk); + } else { + throw createClientConfigurationError(missingSshJwk); + } + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities); + } + let ccsCred = void 0; + if (request.clientInfo) { + try { + const clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils.base64Decode); + ccsCred = { + credential: `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`, + type: CcsCredentialType.HOME_ACCOUNT_ID + }; + } catch (e) { + this.logger.verbose("Could not parse client info for CCS Header: " + e); + } + } else { + ccsCred = request.ccsCredential; + } + if (this.config.systemOptions.preventCorsPreflight && ccsCred) { + switch (ccsCred.type) { + case CcsCredentialType.HOME_ACCOUNT_ID: + try { + const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential); + parameterBuilder.addCcsOid(clientInfo); + } catch (e) { + this.logger.verbose("Could not parse home account ID for CCS Header: " + e); + } + break; + case CcsCredentialType.UPN: + parameterBuilder.addCcsUpn(ccsCred.credential); + break; + } + } + if (request.embeddedClientId) { + parameterBuilder.addBrokerParameters({ + brokerClientId: this.config.authOptions.clientId, + brokerRedirectUri: this.config.authOptions.redirectUri + }); + } + if (request.tokenBodyParameters) { + parameterBuilder.addExtraQueryParameters(request.tokenBodyParameters); + } + if (request.enableSpaAuthorizationCode && (!request.tokenBodyParameters || !request.tokenBodyParameters[RETURN_SPA_CODE])) { + parameterBuilder.addExtraQueryParameters({ + [RETURN_SPA_CODE]: "1" + }); + } + return parameterBuilder.createQueryString(); + } + /** + * This API validates the `AuthorizationCodeUrlRequest` and creates a URL + * @param request + */ + async createAuthCodeUrlQueryString(request) { + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientCreateQueryString, correlationId); + const parameterBuilder = new RequestParameterBuilder(correlationId, this.performanceClient); + parameterBuilder.addClientId(request.embeddedClientId || request.extraQueryParameters?.[CLIENT_ID] || this.config.authOptions.clientId); + const requestScopes = [ + ...request.scopes || [], + ...request.extraScopesToConsent || [] + ]; + parameterBuilder.addScopes(requestScopes, true, this.oidcDefaultScopes); + parameterBuilder.addRedirectUri(request.redirectUri); + parameterBuilder.addCorrelationId(correlationId); + parameterBuilder.addResponseMode(request.responseMode); + parameterBuilder.addResponseTypeCode(); + parameterBuilder.addLibraryInfo(this.config.libraryInfo); + if (!isOidcProtocolMode(this.config)) { + parameterBuilder.addApplicationTelemetry(this.config.telemetry.application); + } + parameterBuilder.addClientInfo(); + if (request.codeChallenge && request.codeChallengeMethod) { + parameterBuilder.addCodeChallengeParams(request.codeChallenge, request.codeChallengeMethod); + } + if (request.prompt) { + parameterBuilder.addPrompt(request.prompt); + } + if (request.domainHint) { + parameterBuilder.addDomainHint(request.domainHint); + } + if (request.prompt !== PromptValue.SELECT_ACCOUNT) { + if (request.sid && request.prompt === PromptValue.NONE) { + this.logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from request"); + parameterBuilder.addSid(request.sid); + } else if (request.account) { + const accountSid = this.extractAccountSid(request.account); + let accountLoginHintClaim = this.extractLoginHint(request.account); + if (accountLoginHintClaim && request.domainHint) { + this.logger.warning(`AuthorizationCodeClient.createAuthCodeUrlQueryString: "domainHint" param is set, skipping opaque "login_hint" claim. Please consider not passing domainHint`); + accountLoginHintClaim = null; + } + if (accountLoginHintClaim) { + this.logger.verbose("createAuthCodeUrlQueryString: login_hint claim present on account"); + parameterBuilder.addLoginHint(accountLoginHintClaim); + try { + const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId); + parameterBuilder.addCcsOid(clientInfo); + } catch (e) { + this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header"); + } + } else if (accountSid && request.prompt === PromptValue.NONE) { + this.logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from account"); + parameterBuilder.addSid(accountSid); + try { + const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId); + parameterBuilder.addCcsOid(clientInfo); + } catch (e) { + this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header"); + } + } else if (request.loginHint) { + this.logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from request"); + parameterBuilder.addLoginHint(request.loginHint); + parameterBuilder.addCcsUpn(request.loginHint); + } else if (request.account.username) { + this.logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from account"); + parameterBuilder.addLoginHint(request.account.username); + try { + const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId); + parameterBuilder.addCcsOid(clientInfo); + } catch (e) { + this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header"); + } + } + } else if (request.loginHint) { + this.logger.verbose("createAuthCodeUrlQueryString: No account, adding login_hint from request"); + parameterBuilder.addLoginHint(request.loginHint); + parameterBuilder.addCcsUpn(request.loginHint); + } + } else { + this.logger.verbose("createAuthCodeUrlQueryString: Prompt is select_account, ignoring account hints"); + } + if (request.nonce) { + parameterBuilder.addNonce(request.nonce); + } + if (request.state) { + parameterBuilder.addState(request.state); + } + if (request.claims || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities); + } + if (request.embeddedClientId) { + parameterBuilder.addBrokerParameters({ + brokerClientId: this.config.authOptions.clientId, + brokerRedirectUri: this.config.authOptions.redirectUri + }); + } + this.addExtraQueryParams(request, parameterBuilder); + if (request.nativeBroker) { + parameterBuilder.addNativeBroker(); + if (request.authenticationScheme === AuthenticationScheme.POP) { + const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils); + let reqCnfData; + if (!request.popKid) { + const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(request, this.logger); + reqCnfData = generatedReqCnfData.reqCnfString; + } else { + reqCnfData = this.cryptoUtils.encodeKid(request.popKid); + } + parameterBuilder.addPopToken(reqCnfData); + } + } + return parameterBuilder.createQueryString(); + } + /** + * This API validates the `EndSessionRequest` and creates a URL + * @param request + */ + createLogoutUrlQueryString(request) { + const parameterBuilder = new RequestParameterBuilder(request.correlationId, this.performanceClient); + if (request.postLogoutRedirectUri) { + parameterBuilder.addPostLogoutRedirectUri(request.postLogoutRedirectUri); + } + if (request.correlationId) { + parameterBuilder.addCorrelationId(request.correlationId); + } + if (request.idTokenHint) { + parameterBuilder.addIdTokenHint(request.idTokenHint); + } + if (request.state) { + parameterBuilder.addState(request.state); + } + if (request.logoutHint) { + parameterBuilder.addLogoutHint(request.logoutHint); + } + this.addExtraQueryParams(request, parameterBuilder); + return parameterBuilder.createQueryString(); + } + addExtraQueryParams(request, parameterBuilder) { + const hasRequestInstanceAware = request.extraQueryParameters && request.extraQueryParameters.hasOwnProperty("instance_aware"); + if (!hasRequestInstanceAware && this.config.authOptions.instanceAware) { + request.extraQueryParameters = request.extraQueryParameters || {}; + request.extraQueryParameters["instance_aware"] = "true"; + } + if (request.extraQueryParameters) { + parameterBuilder.addExtraQueryParameters(request.extraQueryParameters); + } + } + /** + * Helper to get sid from account. Returns null if idTokenClaims are not present or sid is not present. + * @param account + */ + extractAccountSid(account) { + return account.idTokenClaims?.sid || null; + } + extractLoginHint(account) { + return account.idTokenClaims?.login_hint || null; + } + }; + var DEFAULT_REFRESH_TOKEN_EXPIRATION_OFFSET_SECONDS = 300; + var RefreshTokenClient = class extends BaseClient { + constructor(configuration, performanceClient) { + super(configuration, performanceClient); + } + async acquireToken(request) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.RefreshTokenClientAcquireToken, request.correlationId); + const reqTimestamp = nowSeconds(); + const response = await invokeAsync(this.executeTokenRequest.bind(this), PerformanceEvents.RefreshTokenClientExecuteTokenRequest, this.logger, this.performanceClient, request.correlationId)(request, this.authority); + const requestId = response.headers?.[HeaderNames.X_MS_REQUEST_ID]; + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response.body); + return invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), PerformanceEvents.HandleServerTokenResponse, this.logger, this.performanceClient, request.correlationId)(response.body, this.authority, reqTimestamp, request, void 0, void 0, true, request.forceCache, requestId); + } + /** + * Gets cached refresh token and attaches to request, then calls acquireToken API + * @param request + */ + async acquireTokenByRefreshToken(request) { + if (!request) { + throw createClientConfigurationError(tokenRequestEmpty); + } + this.performanceClient?.addQueueMeasurement(PerformanceEvents.RefreshTokenClientAcquireTokenByRefreshToken, request.correlationId); + if (!request.account) { + throw createClientAuthError(noAccountInSilentRequest); + } + const isFOCI = this.cacheManager.isAppMetadataFOCI(request.account.environment); + if (isFOCI) { + try { + return await invokeAsync(this.acquireTokenWithCachedRefreshToken.bind(this), PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, this.logger, this.performanceClient, request.correlationId)(request, true); + } catch (e) { + const noFamilyRTInCache = e instanceof InteractionRequiredAuthError && e.errorCode === noTokensFound; + const clientMismatchErrorWithFamilyRT = e instanceof ServerError && e.errorCode === Errors.INVALID_GRANT_ERROR && e.subError === Errors.CLIENT_MISMATCH_ERROR; + if (noFamilyRTInCache || clientMismatchErrorWithFamilyRT) { + return invokeAsync(this.acquireTokenWithCachedRefreshToken.bind(this), PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, this.logger, this.performanceClient, request.correlationId)(request, false); + } else { + throw e; + } + } + } + return invokeAsync(this.acquireTokenWithCachedRefreshToken.bind(this), PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, this.logger, this.performanceClient, request.correlationId)(request, false); + } + /** + * makes a network call to acquire tokens by exchanging RefreshToken available in userCache; throws if refresh token is not cached + * @param request + */ + async acquireTokenWithCachedRefreshToken(request, foci) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, request.correlationId); + const refreshToken = invoke(this.cacheManager.getRefreshToken.bind(this.cacheManager), PerformanceEvents.CacheManagerGetRefreshToken, this.logger, this.performanceClient, request.correlationId)(request.account, foci, request.correlationId, void 0, this.performanceClient); + if (!refreshToken) { + throw createInteractionRequiredAuthError(noTokensFound); + } + if (refreshToken.expiresOn && isTokenExpired(refreshToken.expiresOn, request.refreshTokenExpirationOffsetSeconds || DEFAULT_REFRESH_TOKEN_EXPIRATION_OFFSET_SECONDS)) { + throw createInteractionRequiredAuthError(refreshTokenExpired); + } + const refreshTokenRequest = { + ...request, + refreshToken: refreshToken.secret, + authenticationScheme: request.authenticationScheme || AuthenticationScheme.BEARER, + ccsCredential: { + credential: request.account.homeAccountId, + type: CcsCredentialType.HOME_ACCOUNT_ID + } + }; + try { + return await invokeAsync(this.acquireToken.bind(this), PerformanceEvents.RefreshTokenClientAcquireToken, this.logger, this.performanceClient, request.correlationId)(refreshTokenRequest); + } catch (e) { + if (e instanceof InteractionRequiredAuthError && e.subError === badToken) { + this.logger.verbose("acquireTokenWithRefreshToken: bad refresh token, removing from cache"); + const badRefreshTokenKey = generateCredentialKey(refreshToken); + this.cacheManager.removeRefreshToken(badRefreshTokenKey, request.correlationId); + } + throw e; + } + } + /** + * Constructs the network message and makes a NW call to the underlying secure token service + * @param request + * @param authority + */ + async executeTokenRequest(request, authority) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.RefreshTokenClientExecuteTokenRequest, request.correlationId); + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await invokeAsync(this.createTokenRequestBody.bind(this), PerformanceEvents.RefreshTokenClientCreateTokenRequestBody, this.logger, this.performanceClient, request.correlationId)(request); + const headers = this.createTokenRequestHeaders(request.ccsCredential); + const thumbprint = { + clientId: request.tokenBodyParameters?.clientId || this.config.authOptions.clientId, + authority: authority.canonicalAuthority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + return invokeAsync(this.executePostToTokenEndpoint.bind(this), PerformanceEvents.RefreshTokenClientExecutePostToTokenEndpoint, this.logger, this.performanceClient, request.correlationId)(endpoint, requestBody, headers, thumbprint, request.correlationId, PerformanceEvents.RefreshTokenClientExecutePostToTokenEndpoint); + } + /** + * Helper function to create the token request body + * @param request + */ + async createTokenRequestBody(request) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.RefreshTokenClientCreateTokenRequestBody, request.correlationId); + const correlationId = request.correlationId; + const parameterBuilder = new RequestParameterBuilder(correlationId, this.performanceClient); + parameterBuilder.addClientId(request.embeddedClientId || request.tokenBodyParameters?.[CLIENT_ID] || this.config.authOptions.clientId); + if (request.redirectUri) { + parameterBuilder.addRedirectUri(request.redirectUri); + } + parameterBuilder.addScopes(request.scopes, true, this.config.authOptions.authority.options.OIDCOptions?.defaultScopes); + parameterBuilder.addGrantType(GrantType.REFRESH_TOKEN_GRANT); + parameterBuilder.addClientInfo(); + parameterBuilder.addLibraryInfo(this.config.libraryInfo); + parameterBuilder.addApplicationTelemetry(this.config.telemetry.application); + parameterBuilder.addThrottling(); + if (this.serverTelemetryManager && !isOidcProtocolMode(this.config)) { + parameterBuilder.addServerTelemetry(this.serverTelemetryManager); + } + parameterBuilder.addRefreshToken(request.refreshToken); + if (this.config.clientCredentials.clientSecret) { + parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret); + } + if (this.config.clientCredentials.clientAssertion) { + const clientAssertion = this.config.clientCredentials.clientAssertion; + parameterBuilder.addClientAssertion(await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + parameterBuilder.addClientAssertionType(clientAssertion.assertionType); + } + if (request.authenticationScheme === AuthenticationScheme.POP) { + const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils, this.performanceClient); + let reqCnfData; + if (!request.popKid) { + const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(request, this.logger); + reqCnfData = generatedReqCnfData.reqCnfString; + } else { + reqCnfData = this.cryptoUtils.encodeKid(request.popKid); + } + parameterBuilder.addPopToken(reqCnfData); + } else if (request.authenticationScheme === AuthenticationScheme.SSH) { + if (request.sshJwk) { + parameterBuilder.addSshJwk(request.sshJwk); + } else { + throw createClientConfigurationError(missingSshJwk); + } + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities); + } + if (this.config.systemOptions.preventCorsPreflight && request.ccsCredential) { + switch (request.ccsCredential.type) { + case CcsCredentialType.HOME_ACCOUNT_ID: + try { + const clientInfo = buildClientInfoFromHomeAccountId(request.ccsCredential.credential); + parameterBuilder.addCcsOid(clientInfo); + } catch (e) { + this.logger.verbose("Could not parse home account ID for CCS Header: " + e); + } + break; + case CcsCredentialType.UPN: + parameterBuilder.addCcsUpn(request.ccsCredential.credential); + break; + } + } + if (request.embeddedClientId) { + parameterBuilder.addBrokerParameters({ + brokerClientId: this.config.authOptions.clientId, + brokerRedirectUri: this.config.authOptions.redirectUri + }); + } + if (request.tokenBodyParameters) { + parameterBuilder.addExtraQueryParameters(request.tokenBodyParameters); + } + return parameterBuilder.createQueryString(); + } + }; + var SilentFlowClient = class extends BaseClient { + constructor(configuration, performanceClient) { + super(configuration, performanceClient); + } + /** + * Retrieves a token from cache if it is still valid, or uses the cached refresh token to renew + * the given token and returns the renewed token + * @param request + */ + async acquireToken(request) { + try { + const [authResponse, cacheOutcome] = await this.acquireCachedToken({ + ...request, + scopes: request.scopes?.length ? request.scopes : [...OIDC_DEFAULT_SCOPES] + }); + if (cacheOutcome === CacheOutcome.PROACTIVELY_REFRESHED) { + this.logger.info("SilentFlowClient:acquireCachedToken - Cached access token's refreshOn property has been exceeded'. It's not expired, but must be refreshed."); + const refreshTokenClient = new RefreshTokenClient(this.config, this.performanceClient); + refreshTokenClient.acquireTokenByRefreshToken(request).catch(() => { + }); + } + return authResponse; + } catch (e) { + if (e instanceof ClientAuthError && e.errorCode === tokenRefreshRequired) { + const refreshTokenClient = new RefreshTokenClient(this.config, this.performanceClient); + return refreshTokenClient.acquireTokenByRefreshToken(request); + } else { + throw e; + } + } + } + /** + * Retrieves token from cache or throws an error if it must be refreshed. + * @param request + */ + async acquireCachedToken(request) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.SilentFlowClientAcquireCachedToken, request.correlationId); + let lastCacheOutcome = CacheOutcome.NOT_APPLICABLE; + if (request.forceRefresh || !this.config.cacheOptions.claimsBasedCachingEnabled && !StringUtils.isEmptyObj(request.claims)) { + this.setCacheOutcome(CacheOutcome.FORCE_REFRESH_OR_CLAIMS, request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } + if (!request.account) { + throw createClientAuthError(noAccountInSilentRequest); + } + const requestTenantId = request.account.tenantId || getTenantFromAuthorityString(request.authority); + const tokenKeys = this.cacheManager.getTokenKeys(); + const cachedAccessToken = this.cacheManager.getAccessToken(request.account, request, tokenKeys, requestTenantId, this.performanceClient); + if (!cachedAccessToken) { + this.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN, request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } else if (wasClockTurnedBack(cachedAccessToken.cachedAt) || isTokenExpired(cachedAccessToken.expiresOn, this.config.systemOptions.tokenRenewalOffsetSeconds)) { + this.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED, request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } else if (cachedAccessToken.refreshOn && isTokenExpired(cachedAccessToken.refreshOn, 0)) { + lastCacheOutcome = CacheOutcome.PROACTIVELY_REFRESHED; + } + const environment = request.authority || this.authority.getPreferredCache(); + const cacheRecord = { + account: this.cacheManager.readAccountFromCache(request.account, request.correlationId), + accessToken: cachedAccessToken, + idToken: this.cacheManager.getIdToken(request.account, request.correlationId, tokenKeys, requestTenantId, this.performanceClient), + refreshToken: null, + appMetadata: this.cacheManager.readAppMetadataFromCache(environment) + }; + this.setCacheOutcome(lastCacheOutcome, request.correlationId); + if (this.config.serverTelemetryManager) { + this.config.serverTelemetryManager.incrementCacheHits(); + } + return [ + await invokeAsync(this.generateResultFromCacheRecord.bind(this), PerformanceEvents.SilentFlowClientGenerateResultFromCacheRecord, this.logger, this.performanceClient, request.correlationId)(cacheRecord, request), + lastCacheOutcome + ]; + } + setCacheOutcome(cacheOutcome, correlationId) { + this.serverTelemetryManager?.setCacheOutcome(cacheOutcome); + this.performanceClient?.addFields({ + cacheOutcome + }, correlationId); + if (cacheOutcome !== CacheOutcome.NOT_APPLICABLE) { + this.logger.info(`Token refresh is required due to cache outcome: ${cacheOutcome}`); + } + } + /** + * Helper function to build response object from the CacheRecord + * @param cacheRecord + */ + async generateResultFromCacheRecord(cacheRecord, request) { + this.performanceClient?.addQueueMeasurement(PerformanceEvents.SilentFlowClientGenerateResultFromCacheRecord, request.correlationId); + let idTokenClaims; + if (cacheRecord.idToken) { + idTokenClaims = extractTokenClaims(cacheRecord.idToken.secret, this.config.cryptoInterface.base64Decode); + } + if (request.maxAge || request.maxAge === 0) { + const authTime = idTokenClaims?.auth_time; + if (!authTime) { + throw createClientAuthError(authTimeNotFound); + } + checkMaxAge(authTime, request.maxAge); + } + return ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, cacheRecord, true, request, idTokenClaims); + } + }; + var skuGroupSeparator = ","; + var skuValueSeparator = "|"; + function makeExtraSkuString(params) { + const { skus, libraryName, libraryVersion, extensionName, extensionVersion } = params; + const skuMap = /* @__PURE__ */ new Map([ + [0, [libraryName, libraryVersion]], + [2, [extensionName, extensionVersion]] + ]); + let skuArr = []; + if (skus?.length) { + skuArr = skus.split(skuGroupSeparator); + if (skuArr.length < 4) { + return skus; + } + } else { + skuArr = Array.from({ length: 4 }, () => skuValueSeparator); + } + skuMap.forEach((value, key) => { + if (value.length === 2 && value[0]?.length && value[1]?.length) { + setSku({ + skuArr, + index: key, + skuName: value[0], + skuVersion: value[1] + }); + } + }); + return skuArr.join(skuGroupSeparator); + } + function setSku(params) { + const { skuArr, index, skuName, skuVersion } = params; + if (index >= skuArr.length) { + return; + } + skuArr[index] = [skuName, skuVersion].join(skuValueSeparator); + } + var ServerTelemetryManager = class _ServerTelemetryManager { + constructor(telemetryRequest, cacheManager) { + this.cacheOutcome = CacheOutcome.NOT_APPLICABLE; + this.cacheManager = cacheManager; + this.apiId = telemetryRequest.apiId; + this.correlationId = telemetryRequest.correlationId; + this.wrapperSKU = telemetryRequest.wrapperSKU || Constants$1.EMPTY_STRING; + this.wrapperVer = telemetryRequest.wrapperVer || Constants$1.EMPTY_STRING; + this.telemetryCacheKey = SERVER_TELEM_CONSTANTS.CACHE_KEY + Separators.CACHE_KEY_SEPARATOR + telemetryRequest.clientId; + } + /** + * API to add MSER Telemetry to request + */ + generateCurrentRequestHeaderValue() { + const request = `${this.apiId}${SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR}${this.cacheOutcome}`; + const platformFieldsArr = [this.wrapperSKU, this.wrapperVer]; + const nativeBrokerErrorCode = this.getNativeBrokerErrorCode(); + if (nativeBrokerErrorCode?.length) { + platformFieldsArr.push(`broker_error=${nativeBrokerErrorCode}`); + } + const platformFields = platformFieldsArr.join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR); + const regionDiscoveryFields = this.getRegionDiscoveryFields(); + const requestWithRegionDiscoveryFields = [ + request, + regionDiscoveryFields + ].join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR); + return [ + SERVER_TELEM_CONSTANTS.SCHEMA_VERSION, + requestWithRegionDiscoveryFields, + platformFields + ].join(SERVER_TELEM_CONSTANTS.CATEGORY_SEPARATOR); + } + /** + * API to add MSER Telemetry for the last failed request + */ + generateLastRequestHeaderValue() { + const lastRequests = this.getLastRequests(); + const maxErrors = _ServerTelemetryManager.maxErrorsToSend(lastRequests); + const failedRequests = lastRequests.failedRequests.slice(0, 2 * maxErrors).join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR); + const errors = lastRequests.errors.slice(0, maxErrors).join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR); + const errorCount = lastRequests.errors.length; + const overflow = maxErrors < errorCount ? SERVER_TELEM_CONSTANTS.OVERFLOW_TRUE : SERVER_TELEM_CONSTANTS.OVERFLOW_FALSE; + const platformFields = [errorCount, overflow].join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR); + return [ + SERVER_TELEM_CONSTANTS.SCHEMA_VERSION, + lastRequests.cacheHits, + failedRequests, + errors, + platformFields + ].join(SERVER_TELEM_CONSTANTS.CATEGORY_SEPARATOR); + } + /** + * API to cache token failures for MSER data capture + * @param error + */ + cacheFailedRequest(error) { + const lastRequests = this.getLastRequests(); + if (lastRequests.errors.length >= SERVER_TELEM_CONSTANTS.MAX_CACHED_ERRORS) { + lastRequests.failedRequests.shift(); + lastRequests.failedRequests.shift(); + lastRequests.errors.shift(); + } + lastRequests.failedRequests.push(this.apiId, this.correlationId); + if (error instanceof Error && !!error && error.toString()) { + if (error instanceof AuthError) { + if (error.subError) { + lastRequests.errors.push(error.subError); + } else if (error.errorCode) { + lastRequests.errors.push(error.errorCode); + } else { + lastRequests.errors.push(error.toString()); + } + } else { + lastRequests.errors.push(error.toString()); + } + } else { + lastRequests.errors.push(SERVER_TELEM_CONSTANTS.UNKNOWN_ERROR); + } + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId); + return; + } + /** + * Update server telemetry cache entry by incrementing cache hit counter + */ + incrementCacheHits() { + const lastRequests = this.getLastRequests(); + lastRequests.cacheHits += 1; + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId); + return lastRequests.cacheHits; + } + /** + * Get the server telemetry entity from cache or initialize a new one + */ + getLastRequests() { + const initialValue = { + failedRequests: [], + errors: [], + cacheHits: 0 + }; + const lastRequests = this.cacheManager.getServerTelemetry(this.telemetryCacheKey); + return lastRequests || initialValue; + } + /** + * Remove server telemetry cache entry + */ + clearTelemetryCache() { + const lastRequests = this.getLastRequests(); + const numErrorsFlushed = _ServerTelemetryManager.maxErrorsToSend(lastRequests); + const errorCount = lastRequests.errors.length; + if (numErrorsFlushed === errorCount) { + this.cacheManager.removeItem(this.telemetryCacheKey, this.correlationId); + } else { + const serverTelemEntity = { + failedRequests: lastRequests.failedRequests.slice(numErrorsFlushed * 2), + errors: lastRequests.errors.slice(numErrorsFlushed), + cacheHits: 0 + }; + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, serverTelemEntity, this.correlationId); + } + } + /** + * Returns the maximum number of errors that can be flushed to the server in the next network request + * @param serverTelemetryEntity + */ + static maxErrorsToSend(serverTelemetryEntity) { + let i; + let maxErrors = 0; + let dataSize = 0; + const errorCount = serverTelemetryEntity.errors.length; + for (i = 0; i < errorCount; i++) { + const apiId = serverTelemetryEntity.failedRequests[2 * i] || Constants$1.EMPTY_STRING; + const correlationId = serverTelemetryEntity.failedRequests[2 * i + 1] || Constants$1.EMPTY_STRING; + const errorCode = serverTelemetryEntity.errors[i] || Constants$1.EMPTY_STRING; + dataSize += apiId.toString().length + correlationId.toString().length + errorCode.length + 3; + if (dataSize < SERVER_TELEM_CONSTANTS.MAX_LAST_HEADER_BYTES) { + maxErrors += 1; + } else { + break; + } + } + return maxErrors; + } + /** + * Get the region discovery fields + * + * @returns string + */ + getRegionDiscoveryFields() { + const regionDiscoveryFields = []; + regionDiscoveryFields.push(this.regionUsed || Constants$1.EMPTY_STRING); + regionDiscoveryFields.push(this.regionSource || Constants$1.EMPTY_STRING); + regionDiscoveryFields.push(this.regionOutcome || Constants$1.EMPTY_STRING); + return regionDiscoveryFields.join(","); + } + /** + * Update the region discovery metadata + * + * @param regionDiscoveryMetadata + * @returns void + */ + updateRegionDiscoveryMetadata(regionDiscoveryMetadata) { + this.regionUsed = regionDiscoveryMetadata.region_used; + this.regionSource = regionDiscoveryMetadata.region_source; + this.regionOutcome = regionDiscoveryMetadata.region_outcome; + } + /** + * Set cache outcome + */ + setCacheOutcome(cacheOutcome) { + this.cacheOutcome = cacheOutcome; + } + setNativeBrokerErrorCode(errorCode) { + const lastRequests = this.getLastRequests(); + lastRequests.nativeBrokerErrorCode = errorCode; + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId); + } + getNativeBrokerErrorCode() { + return this.getLastRequests().nativeBrokerErrorCode; + } + clearNativeBrokerErrorCode() { + const lastRequests = this.getLastRequests(); + delete lastRequests.nativeBrokerErrorCode; + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId); + } + static makeExtraSkuString(params) { + return makeExtraSkuString(params); + } + }; + var Deserializer = class { + /** + * Parse the JSON blob in memory and deserialize the content + * @param cachedJson - JSON blob cache + */ + static deserializeJSONBlob(jsonFile) { + const deserializedCache = !jsonFile ? {} : JSON.parse(jsonFile); + return deserializedCache; + } + /** + * Deserializes accounts to AccountEntity objects + * @param accounts - accounts of type SerializedAccountEntity + */ + static deserializeAccounts(accounts) { + const accountObjects = {}; + if (accounts) { + Object.keys(accounts).map(function(key) { + const serializedAcc = accounts[key]; + const mappedAcc = { + homeAccountId: serializedAcc.home_account_id, + environment: serializedAcc.environment, + realm: serializedAcc.realm, + localAccountId: serializedAcc.local_account_id, + username: serializedAcc.username, + authorityType: serializedAcc.authority_type, + name: serializedAcc.name, + clientInfo: serializedAcc.client_info, + lastModificationTime: serializedAcc.last_modification_time, + lastModificationApp: serializedAcc.last_modification_app, + tenantProfiles: serializedAcc.tenantProfiles?.map((serializedTenantProfile) => { + return JSON.parse(serializedTenantProfile); + }) + }; + const account = new AccountEntity(); + CacheManager.toObject(account, mappedAcc); + accountObjects[key] = account; + }); + } + return accountObjects; + } + /** + * Deserializes id tokens to IdTokenEntity objects + * @param idTokens - credentials of type SerializedIdTokenEntity + */ + static deserializeIdTokens(idTokens) { + const idObjects = {}; + if (idTokens) { + Object.keys(idTokens).map(function(key) { + const serializedIdT = idTokens[key]; + const idToken = { + homeAccountId: serializedIdT.home_account_id, + environment: serializedIdT.environment, + credentialType: serializedIdT.credential_type, + clientId: serializedIdT.client_id, + secret: serializedIdT.secret, + realm: serializedIdT.realm + }; + idObjects[key] = idToken; + }); + } + return idObjects; + } + /** + * Deserializes access tokens to AccessTokenEntity objects + * @param accessTokens - access tokens of type SerializedAccessTokenEntity + */ + static deserializeAccessTokens(accessTokens) { + const atObjects = {}; + if (accessTokens) { + Object.keys(accessTokens).map(function(key) { + const serializedAT = accessTokens[key]; + const accessToken = { + homeAccountId: serializedAT.home_account_id, + environment: serializedAT.environment, + credentialType: serializedAT.credential_type, + clientId: serializedAT.client_id, + secret: serializedAT.secret, + realm: serializedAT.realm, + target: serializedAT.target, + cachedAt: serializedAT.cached_at, + expiresOn: serializedAT.expires_on, + extendedExpiresOn: serializedAT.extended_expires_on, + refreshOn: serializedAT.refresh_on, + keyId: serializedAT.key_id, + tokenType: serializedAT.token_type, + requestedClaims: serializedAT.requestedClaims, + requestedClaimsHash: serializedAT.requestedClaimsHash, + userAssertionHash: serializedAT.userAssertionHash + }; + atObjects[key] = accessToken; + }); + } + return atObjects; + } + /** + * Deserializes refresh tokens to RefreshTokenEntity objects + * @param refreshTokens - refresh tokens of type SerializedRefreshTokenEntity + */ + static deserializeRefreshTokens(refreshTokens) { + const rtObjects = {}; + if (refreshTokens) { + Object.keys(refreshTokens).map(function(key) { + const serializedRT = refreshTokens[key]; + const refreshToken = { + homeAccountId: serializedRT.home_account_id, + environment: serializedRT.environment, + credentialType: serializedRT.credential_type, + clientId: serializedRT.client_id, + secret: serializedRT.secret, + familyId: serializedRT.family_id, + target: serializedRT.target, + realm: serializedRT.realm + }; + rtObjects[key] = refreshToken; + }); + } + return rtObjects; + } + /** + * Deserializes appMetadata to AppMetaData objects + * @param appMetadata - app metadata of type SerializedAppMetadataEntity + */ + static deserializeAppMetadata(appMetadata) { + const appMetadataObjects = {}; + if (appMetadata) { + Object.keys(appMetadata).map(function(key) { + const serializedAmdt = appMetadata[key]; + appMetadataObjects[key] = { + clientId: serializedAmdt.client_id, + environment: serializedAmdt.environment, + familyId: serializedAmdt.family_id + }; + }); + } + return appMetadataObjects; + } + /** + * Deserialize an inMemory Cache + * @param jsonCache - JSON blob cache + */ + static deserializeAllCache(jsonCache) { + return { + accounts: jsonCache.Account ? this.deserializeAccounts(jsonCache.Account) : {}, + idTokens: jsonCache.IdToken ? this.deserializeIdTokens(jsonCache.IdToken) : {}, + accessTokens: jsonCache.AccessToken ? this.deserializeAccessTokens(jsonCache.AccessToken) : {}, + refreshTokens: jsonCache.RefreshToken ? this.deserializeRefreshTokens(jsonCache.RefreshToken) : {}, + appMetadata: jsonCache.AppMetadata ? this.deserializeAppMetadata(jsonCache.AppMetadata) : {} + }; + } + }; + var internals = /* @__PURE__ */ Object.freeze({ + __proto__: null, + Deserializer, + Serializer + }); + var AUTHORIZATION_HEADER_NAME = "Authorization"; + var METADATA_HEADER_NAME = "Metadata"; + var APP_SERVICE_SECRET_HEADER_NAME = "X-IDENTITY-HEADER"; + var SERVICE_FABRIC_SECRET_HEADER_NAME = "secret"; + var API_VERSION_QUERY_PARAMETER_NAME = "api-version"; + var RESOURCE_BODY_OR_QUERY_PARAMETER_NAME = "resource"; + var DEFAULT_MANAGED_IDENTITY_ID = "system_assigned_managed_identity"; + var MANAGED_IDENTITY_DEFAULT_TENANT = "managed_identity"; + var DEFAULT_AUTHORITY_FOR_MANAGED_IDENTITY = `https://login.microsoftonline.com/${MANAGED_IDENTITY_DEFAULT_TENANT}/`; + var ManagedIdentityEnvironmentVariableNames = { + AZURE_POD_IDENTITY_AUTHORITY_HOST: "AZURE_POD_IDENTITY_AUTHORITY_HOST", + IDENTITY_ENDPOINT: "IDENTITY_ENDPOINT", + IDENTITY_HEADER: "IDENTITY_HEADER", + IDENTITY_SERVER_THUMBPRINT: "IDENTITY_SERVER_THUMBPRINT", + IMDS_ENDPOINT: "IMDS_ENDPOINT", + MSI_ENDPOINT: "MSI_ENDPOINT" + }; + var ManagedIdentitySourceNames = { + APP_SERVICE: "AppService", + AZURE_ARC: "AzureArc", + CLOUD_SHELL: "CloudShell", + DEFAULT_TO_IMDS: "DefaultToImds", + IMDS: "Imds", + SERVICE_FABRIC: "ServiceFabric" + }; + var ManagedIdentityIdType = { + SYSTEM_ASSIGNED: "system-assigned", + USER_ASSIGNED_CLIENT_ID: "user-assigned-client-id", + USER_ASSIGNED_RESOURCE_ID: "user-assigned-resource-id", + USER_ASSIGNED_OBJECT_ID: "user-assigned-object-id" + }; + var HttpMethod = { + GET: "get", + POST: "post" + }; + var ProxyStatus = { + SUCCESS_RANGE_START: HttpStatus.SUCCESS_RANGE_START, + SUCCESS_RANGE_END: HttpStatus.SUCCESS_RANGE_END, + SERVER_ERROR: HttpStatus.SERVER_ERROR + }; + var REGION_ENVIRONMENT_VARIABLE = "REGION_NAME"; + var MSAL_FORCE_REGION = "MSAL_FORCE_REGION"; + var RANDOM_OCTET_SIZE = 32; + var Hash = { + SHA256: "sha256" + }; + var CharSet = { + CV_CHARSET: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" + }; + var Constants = { + MSAL_SKU: "msal.js.node", + JWT_BEARER_ASSERTION_TYPE: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", + AUTHORIZATION_PENDING: "authorization_pending", + HTTP_PROTOCOL: "http://", + LOCALHOST: "localhost" + }; + var ApiId = { + acquireTokenSilent: 62, + acquireTokenByUsernamePassword: 371, + acquireTokenByDeviceCode: 671, + acquireTokenByClientCredential: 771, + acquireTokenByCode: 871, + acquireTokenByRefreshToken: 872 + }; + var JwtConstants = { + RSA_256: "RS256", + PSS_256: "PS256", + X5T_256: "x5t#S256", + X5T: "x5t", + X5C: "x5c", + AUDIENCE: "aud", + EXPIRATION_TIME: "exp", + ISSUER: "iss", + SUBJECT: "sub", + NOT_BEFORE: "nbf", + JWT_ID: "jti" + }; + var LOOPBACK_SERVER_CONSTANTS = { + INTERVAL_MS: 100, + TIMEOUT_MS: 5e3 + }; + var AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES = 4096; + var MANAGED_IDENTITY_MAX_RETRIES = 3; + var MANAGED_IDENTITY_RETRY_DELAY = 1e3; + var MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON = [ + HttpStatus.NOT_FOUND, + HttpStatus.REQUEST_TIMEOUT, + HttpStatus.TOO_MANY_REQUESTS, + HttpStatus.SERVER_ERROR, + HttpStatus.SERVICE_UNAVAILABLE, + HttpStatus.GATEWAY_TIMEOUT + ]; + var NetworkUtils = class { + static getNetworkResponse(headers, body, statusCode) { + return { + headers, + body, + status: statusCode + }; + } + /* + * Utility function that converts a URL object into an ordinary options object as expected by the + * http.request and https.request APIs. + * https://github.com/nodejs/node/blob/main/lib/internal/url.js#L1090 + */ + static urlToHttpOptions(url) { + const options = { + protocol: url.protocol, + hostname: url.hostname && url.hostname.startsWith("[") ? url.hostname.slice(1, -1) : url.hostname, + hash: url.hash, + search: url.search, + pathname: url.pathname, + path: `${url.pathname || ""}${url.search || ""}`, + href: url.href + }; + if (url.port !== "") { + options.port = Number(url.port); + } + if (url.username || url.password) { + options.auth = `${decodeURIComponent(url.username)}:${decodeURIComponent(url.password)}`; + } + return options; + } + }; + var HttpClient = class { + constructor(proxyUrl, customAgentOptions) { + this.proxyUrl = proxyUrl || ""; + this.customAgentOptions = customAgentOptions || {}; + } + /** + * Http Get request + * @param url + * @param options + */ + async sendGetRequestAsync(url, options, timeout) { + if (this.proxyUrl) { + return networkRequestViaProxy(url, this.proxyUrl, HttpMethod.GET, options, this.customAgentOptions, timeout); + } else { + return networkRequestViaHttps(url, HttpMethod.GET, options, this.customAgentOptions, timeout); + } + } + /** + * Http Post request + * @param url + * @param options + */ + async sendPostRequestAsync(url, options) { + if (this.proxyUrl) { + return networkRequestViaProxy(url, this.proxyUrl, HttpMethod.POST, options, this.customAgentOptions); + } else { + return networkRequestViaHttps(url, HttpMethod.POST, options, this.customAgentOptions); + } + } + }; + var networkRequestViaProxy = (destinationUrlString, proxyUrlString, httpMethod, options, agentOptions, timeout) => { + const destinationUrl = new URL(destinationUrlString); + const proxyUrl = new URL(proxyUrlString); + const headers = options?.headers || {}; + const tunnelRequestOptions = { + host: proxyUrl.hostname, + port: proxyUrl.port, + method: "CONNECT", + path: destinationUrl.hostname, + headers + }; + if (agentOptions && Object.keys(agentOptions).length) { + tunnelRequestOptions.agent = new http.Agent(agentOptions); + } + let postRequestStringContent = ""; + if (httpMethod === HttpMethod.POST) { + const body = options?.body || ""; + postRequestStringContent = `Content-Type: application/x-www-form-urlencoded\r +Content-Length: ${body.length}\r +\r +${body}`; + } else { + if (timeout) { + tunnelRequestOptions.timeout = timeout; + } + } + const outgoingRequestString = `${httpMethod.toUpperCase()} ${destinationUrl.href} HTTP/1.1\r +Host: ${destinationUrl.host}\r +Connection: close\r +` + postRequestStringContent + "\r\n"; + return new Promise((resolve, reject) => { + const request = http.request(tunnelRequestOptions); + if (timeout) { + request.on("timeout", () => { + request.destroy(); + reject(new Error("Request time out")); + }); + } + request.end(); + request.on("connect", (response, socket) => { + const proxyStatusCode = response?.statusCode || ProxyStatus.SERVER_ERROR; + if (proxyStatusCode < ProxyStatus.SUCCESS_RANGE_START || proxyStatusCode > ProxyStatus.SUCCESS_RANGE_END) { + request.destroy(); + socket.destroy(); + reject(new Error(`Error connecting to proxy. Http status code: ${response.statusCode}. Http status message: ${response?.statusMessage || "Unknown"}`)); + } + socket.write(outgoingRequestString); + const data = []; + socket.on("data", (chunk) => { + data.push(chunk); + }); + socket.on("end", () => { + const dataString = Buffer.concat([...data]).toString(); + const dataStringArray = dataString.split("\r\n"); + const httpStatusCode = parseInt(dataStringArray[0].split(" ")[1]); + const statusMessage = dataStringArray[0].split(" ").slice(2).join(" "); + const body = dataStringArray[dataStringArray.length - 1]; + const headersArray = dataStringArray.slice(1, dataStringArray.length - 2); + const entries = /* @__PURE__ */ new Map(); + headersArray.forEach((header) => { + const headerKeyValue = header.split(new RegExp(/:\s(.*)/s)); + const headerKey = headerKeyValue[0]; + let headerValue = headerKeyValue[1]; + try { + const object = JSON.parse(headerValue); + if (object && typeof object === "object") { + headerValue = object; + } + } catch (e) { + } + entries.set(headerKey, headerValue); + }); + const headers2 = Object.fromEntries(entries); + const parsedHeaders = headers2; + const networkResponse = NetworkUtils.getNetworkResponse(parsedHeaders, parseBody(httpStatusCode, statusMessage, parsedHeaders, body), httpStatusCode); + if ((httpStatusCode < HttpStatus.SUCCESS_RANGE_START || httpStatusCode > HttpStatus.SUCCESS_RANGE_END) && // do not destroy the request for the device code flow + networkResponse.body["error"] !== Constants.AUTHORIZATION_PENDING) { + request.destroy(); + } + resolve(networkResponse); + }); + socket.on("error", (chunk) => { + request.destroy(); + socket.destroy(); + reject(new Error(chunk.toString())); + }); + }); + request.on("error", (chunk) => { + request.destroy(); + reject(new Error(chunk.toString())); + }); + }); + }; + var networkRequestViaHttps = (urlString, httpMethod, options, agentOptions, timeout) => { + const isPostRequest = httpMethod === HttpMethod.POST; + const body = options?.body || ""; + const url = new URL(urlString); + const headers = options?.headers || {}; + const customOptions = { + method: httpMethod, + headers, + ...NetworkUtils.urlToHttpOptions(url) + }; + if (agentOptions && Object.keys(agentOptions).length) { + customOptions.agent = new https.Agent(agentOptions); + } + if (isPostRequest) { + customOptions.headers = { + ...customOptions.headers, + "Content-Length": body.length + }; + } else { + if (timeout) { + customOptions.timeout = timeout; + } + } + return new Promise((resolve, reject) => { + let request; + if (customOptions.protocol === "http:") { + request = http.request(customOptions); + } else { + request = https.request(customOptions); + } + if (isPostRequest) { + request.write(body); + } + if (timeout) { + request.on("timeout", () => { + request.destroy(); + reject(new Error("Request time out")); + }); + } + request.end(); + request.on("response", (response) => { + const headers2 = response.headers; + const statusCode = response.statusCode; + const statusMessage = response.statusMessage; + const data = []; + response.on("data", (chunk) => { + data.push(chunk); + }); + response.on("end", () => { + const body2 = Buffer.concat([...data]).toString(); + const parsedHeaders = headers2; + const networkResponse = NetworkUtils.getNetworkResponse(parsedHeaders, parseBody(statusCode, statusMessage, parsedHeaders, body2), statusCode); + if ((statusCode < HttpStatus.SUCCESS_RANGE_START || statusCode > HttpStatus.SUCCESS_RANGE_END) && // do not destroy the request for the device code flow + networkResponse.body["error"] !== Constants.AUTHORIZATION_PENDING) { + request.destroy(); + } + resolve(networkResponse); + }); + }); + request.on("error", (chunk) => { + request.destroy(); + reject(new Error(chunk.toString())); + }); + }); + }; + var parseBody = (statusCode, statusMessage, headers, body) => { + let parsedBody; + try { + parsedBody = JSON.parse(body); + } catch (error) { + let errorType; + let errorDescriptionHelper; + if (statusCode >= HttpStatus.CLIENT_ERROR_RANGE_START && statusCode <= HttpStatus.CLIENT_ERROR_RANGE_END) { + errorType = "client_error"; + errorDescriptionHelper = "A client"; + } else if (statusCode >= HttpStatus.SERVER_ERROR_RANGE_START && statusCode <= HttpStatus.SERVER_ERROR_RANGE_END) { + errorType = "server_error"; + errorDescriptionHelper = "A server"; + } else { + errorType = "unknown_error"; + errorDescriptionHelper = "An unknown"; + } + parsedBody = { + error: errorType, + error_description: `${errorDescriptionHelper} error occured. +Http status code: ${statusCode} +Http status message: ${statusMessage || "Unknown"} +Headers: ${JSON.stringify(headers)}` + }; + } + return parsedBody; + }; + var invalidFileExtension = "invalid_file_extension"; + var invalidFilePath = "invalid_file_path"; + var invalidManagedIdentityIdType = "invalid_managed_identity_id_type"; + var invalidSecret = "invalid_secret"; + var missingId = "missing_client_id"; + var networkUnavailable = "network_unavailable"; + var platformNotSupported = "platform_not_supported"; + var unableToCreateAzureArc = "unable_to_create_azure_arc"; + var unableToCreateCloudShell = "unable_to_create_cloud_shell"; + var unableToCreateSource = "unable_to_create_source"; + var unableToReadSecretFile = "unable_to_read_secret_file"; + var userAssignedNotAvailableAtRuntime = "user_assigned_not_available_at_runtime"; + var wwwAuthenticateHeaderMissing = "www_authenticate_header_missing"; + var wwwAuthenticateHeaderUnsupportedFormat = "www_authenticate_header_unsupported_format"; + var MsiEnvironmentVariableUrlMalformedErrorCodes = { + [ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST]: "azure_pod_identity_authority_host_url_malformed", + [ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT]: "identity_endpoint_url_malformed", + [ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT]: "imds_endpoint_url_malformed", + [ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT]: "msi_endpoint_url_malformed" + }; + var ManagedIdentityErrorMessages = { + [invalidFileExtension]: "The file path in the WWW-Authenticate header does not contain a .key file.", + [invalidFilePath]: "The file path in the WWW-Authenticate header is not in a valid Windows or Linux Format.", + [invalidManagedIdentityIdType]: "More than one ManagedIdentityIdType was provided.", + [invalidSecret]: "The secret in the file on the file path in the WWW-Authenticate header is greater than 4096 bytes.", + [platformNotSupported]: "The platform is not supported by Azure Arc. Azure Arc only supports Windows and Linux.", + [missingId]: "A ManagedIdentityId id was not provided.", + [MsiEnvironmentVariableUrlMalformedErrorCodes.AZURE_POD_IDENTITY_AUTHORITY_HOST]: `The Managed Identity's '${ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST}' environment variable is malformed.`, + [MsiEnvironmentVariableUrlMalformedErrorCodes.IDENTITY_ENDPOINT]: `The Managed Identity's '${ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT}' environment variable is malformed.`, + [MsiEnvironmentVariableUrlMalformedErrorCodes.IMDS_ENDPOINT]: `The Managed Identity's '${ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT}' environment variable is malformed.`, + [MsiEnvironmentVariableUrlMalformedErrorCodes.MSI_ENDPOINT]: `The Managed Identity's '${ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT}' environment variable is malformed.`, + [networkUnavailable]: "Authentication unavailable. The request to the managed identity endpoint timed out.", + [unableToCreateAzureArc]: "Azure Arc Managed Identities can only be system assigned.", + [unableToCreateCloudShell]: "Cloud Shell Managed Identities can only be system assigned.", + [unableToCreateSource]: "Unable to create a Managed Identity source based on environment variables.", + [unableToReadSecretFile]: "Unable to read the secret file.", + [userAssignedNotAvailableAtRuntime]: "Service Fabric user assigned managed identity ClientId or ResourceId is not configurable at runtime.", + [wwwAuthenticateHeaderMissing]: "A 401 response was received form the Azure Arc Managed Identity, but the www-authenticate header is missing.", + [wwwAuthenticateHeaderUnsupportedFormat]: "A 401 response was received form the Azure Arc Managed Identity, but the www-authenticate header is in an unsupported format." + }; + var ManagedIdentityError = class _ManagedIdentityError extends AuthError { + constructor(errorCode) { + super(errorCode, ManagedIdentityErrorMessages[errorCode]); + this.name = "ManagedIdentityError"; + Object.setPrototypeOf(this, _ManagedIdentityError.prototype); + } + }; + function createManagedIdentityError(errorCode) { + return new ManagedIdentityError(errorCode); + } + var ManagedIdentityId = class { + get id() { + return this._id; + } + set id(value) { + this._id = value; + } + get idType() { + return this._idType; + } + set idType(value) { + this._idType = value; + } + constructor(managedIdentityIdParams) { + const userAssignedClientId = managedIdentityIdParams?.userAssignedClientId; + const userAssignedResourceId = managedIdentityIdParams?.userAssignedResourceId; + const userAssignedObjectId = managedIdentityIdParams?.userAssignedObjectId; + if (userAssignedClientId) { + if (userAssignedResourceId || userAssignedObjectId) { + throw createManagedIdentityError(invalidManagedIdentityIdType); + } + this.id = userAssignedClientId; + this.idType = ManagedIdentityIdType.USER_ASSIGNED_CLIENT_ID; + } else if (userAssignedResourceId) { + if (userAssignedClientId || userAssignedObjectId) { + throw createManagedIdentityError(invalidManagedIdentityIdType); + } + this.id = userAssignedResourceId; + this.idType = ManagedIdentityIdType.USER_ASSIGNED_RESOURCE_ID; + } else if (userAssignedObjectId) { + if (userAssignedClientId || userAssignedResourceId) { + throw createManagedIdentityError(invalidManagedIdentityIdType); + } + this.id = userAssignedObjectId; + this.idType = ManagedIdentityIdType.USER_ASSIGNED_OBJECT_ID; + } else { + this.id = DEFAULT_MANAGED_IDENTITY_ID; + this.idType = ManagedIdentityIdType.SYSTEM_ASSIGNED; + } + } + }; + var LinearRetryPolicy = class { + constructor(maxRetries, retryDelay, httpStatusCodesToRetryOn) { + this.maxRetries = maxRetries; + this.retryDelay = retryDelay; + this.httpStatusCodesToRetryOn = httpStatusCodesToRetryOn; + } + retryAfterMillisecondsToSleep(retryHeader) { + if (!retryHeader) { + return 0; + } + let millisToSleep = Math.round(parseFloat(retryHeader) * 1e3); + if (isNaN(millisToSleep)) { + millisToSleep = Math.max( + 0, + // .valueOf() is needed to subtract dates in TypeScript + new Date(retryHeader).valueOf() - (/* @__PURE__ */ new Date()).valueOf() + ); + } + return millisToSleep; + } + async pauseForRetry(httpStatusCode, currentRetry, retryAfterHeader) { + if (this.httpStatusCodesToRetryOn.includes(httpStatusCode) && currentRetry < this.maxRetries) { + const retryAfterDelay = this.retryAfterMillisecondsToSleep(retryAfterHeader); + await new Promise((resolve) => { + return setTimeout(resolve, retryAfterDelay || this.retryDelay); + }); + return true; + } + return false; + } + }; + var HttpClientWithRetries = class { + constructor(httpClientNoRetries, retryPolicy2) { + this.httpClientNoRetries = httpClientNoRetries; + this.retryPolicy = retryPolicy2; + } + async sendNetworkRequestAsyncHelper(httpMethod, url, options) { + if (httpMethod === HttpMethod.GET) { + return this.httpClientNoRetries.sendGetRequestAsync(url, options); + } else { + return this.httpClientNoRetries.sendPostRequestAsync(url, options); + } + } + async sendNetworkRequestAsync(httpMethod, url, options) { + let response = await this.sendNetworkRequestAsyncHelper(httpMethod, url, options); + let currentRetry = 0; + while (await this.retryPolicy.pauseForRetry(response.status, currentRetry, response.headers[HeaderNames.RETRY_AFTER])) { + response = await this.sendNetworkRequestAsyncHelper(httpMethod, url, options); + currentRetry++; + } + return response; + } + async sendGetRequestAsync(url, options) { + return this.sendNetworkRequestAsync(HttpMethod.GET, url, options); + } + async sendPostRequestAsync(url, options) { + return this.sendNetworkRequestAsync(HttpMethod.POST, url, options); + } + }; + var NodeAuthErrorMessage = { + invalidLoopbackAddressType: { + code: "invalid_loopback_server_address_type", + desc: "Loopback server address is not type string. This is unexpected." + }, + unableToLoadRedirectUri: { + code: "unable_to_load_redirectUrl", + desc: "Loopback server callback was invoked without a url. This is unexpected." + }, + noAuthCodeInResponse: { + code: "no_auth_code_in_response", + desc: "No auth code found in the server response. Please check your network trace to determine what happened." + }, + noLoopbackServerExists: { + code: "no_loopback_server_exists", + desc: "No loopback server exists yet." + }, + loopbackServerAlreadyExists: { + code: "loopback_server_already_exists", + desc: "Loopback server already exists. Cannot create another." + }, + loopbackServerTimeout: { + code: "loopback_server_timeout", + desc: "Timed out waiting for auth code listener to be registered." + }, + stateNotFoundError: { + code: "state_not_found", + desc: "State not found. Please verify that the request originated from msal." + }, + thumbprintMissing: { + code: "thumbprint_missing_from_client_certificate", + desc: "Client certificate does not contain a SHA-1 or SHA-256 thumbprint." + } + }; + var NodeAuthError = class _NodeAuthError extends AuthError { + constructor(errorCode, errorMessage) { + super(errorCode, errorMessage); + this.name = "NodeAuthError"; + } + /** + * Creates an error thrown if loopback server address is of type string. + */ + static createInvalidLoopbackAddressTypeError() { + return new _NodeAuthError(NodeAuthErrorMessage.invalidLoopbackAddressType.code, `${NodeAuthErrorMessage.invalidLoopbackAddressType.desc}`); + } + /** + * Creates an error thrown if the loopback server is unable to get a url. + */ + static createUnableToLoadRedirectUrlError() { + return new _NodeAuthError(NodeAuthErrorMessage.unableToLoadRedirectUri.code, `${NodeAuthErrorMessage.unableToLoadRedirectUri.desc}`); + } + /** + * Creates an error thrown if the server response does not contain an auth code. + */ + static createNoAuthCodeInResponseError() { + return new _NodeAuthError(NodeAuthErrorMessage.noAuthCodeInResponse.code, `${NodeAuthErrorMessage.noAuthCodeInResponse.desc}`); + } + /** + * Creates an error thrown if the loopback server has not been spun up yet. + */ + static createNoLoopbackServerExistsError() { + return new _NodeAuthError(NodeAuthErrorMessage.noLoopbackServerExists.code, `${NodeAuthErrorMessage.noLoopbackServerExists.desc}`); + } + /** + * Creates an error thrown if a loopback server already exists when attempting to create another one. + */ + static createLoopbackServerAlreadyExistsError() { + return new _NodeAuthError(NodeAuthErrorMessage.loopbackServerAlreadyExists.code, `${NodeAuthErrorMessage.loopbackServerAlreadyExists.desc}`); + } + /** + * Creates an error thrown if the loopback server times out registering the auth code listener. + */ + static createLoopbackServerTimeoutError() { + return new _NodeAuthError(NodeAuthErrorMessage.loopbackServerTimeout.code, `${NodeAuthErrorMessage.loopbackServerTimeout.desc}`); + } + /** + * Creates an error thrown when the state is not present. + */ + static createStateNotFoundError() { + return new _NodeAuthError(NodeAuthErrorMessage.stateNotFoundError.code, NodeAuthErrorMessage.stateNotFoundError.desc); + } + /** + * Creates an error thrown when client certificate was provided, but neither the SHA-1 or SHA-256 thumbprints were provided + */ + static createThumbprintMissingError() { + return new _NodeAuthError(NodeAuthErrorMessage.thumbprintMissing.code, NodeAuthErrorMessage.thumbprintMissing.desc); + } + }; + var DEFAULT_AUTH_OPTIONS = { + clientId: Constants$1.EMPTY_STRING, + authority: Constants$1.DEFAULT_AUTHORITY, + clientSecret: Constants$1.EMPTY_STRING, + clientAssertion: Constants$1.EMPTY_STRING, + clientCertificate: { + thumbprint: Constants$1.EMPTY_STRING, + thumbprintSha256: Constants$1.EMPTY_STRING, + privateKey: Constants$1.EMPTY_STRING, + x5c: Constants$1.EMPTY_STRING + }, + knownAuthorities: [], + cloudDiscoveryMetadata: Constants$1.EMPTY_STRING, + authorityMetadata: Constants$1.EMPTY_STRING, + clientCapabilities: [], + protocolMode: ProtocolMode.AAD, + azureCloudOptions: { + azureCloudInstance: AzureCloudInstance.None, + tenant: Constants$1.EMPTY_STRING + }, + skipAuthorityMetadataCache: false + }; + var DEFAULT_CACHE_OPTIONS = { + claimsBasedCachingEnabled: false + }; + var DEFAULT_LOGGER_OPTIONS = { + loggerCallback: () => { + }, + piiLoggingEnabled: false, + logLevel: exports2.LogLevel.Info + }; + var DEFAULT_SYSTEM_OPTIONS = { + loggerOptions: DEFAULT_LOGGER_OPTIONS, + networkClient: new HttpClient(), + proxyUrl: Constants$1.EMPTY_STRING, + customAgentOptions: {}, + disableInternalRetries: false + }; + var DEFAULT_TELEMETRY_OPTIONS = { + application: { + appName: Constants$1.EMPTY_STRING, + appVersion: Constants$1.EMPTY_STRING + } + }; + function buildAppConfiguration({ auth, broker, cache, system, telemetry }) { + const systemOptions = { + ...DEFAULT_SYSTEM_OPTIONS, + networkClient: new HttpClient(system?.proxyUrl, system?.customAgentOptions), + loggerOptions: system?.loggerOptions || DEFAULT_LOGGER_OPTIONS, + disableInternalRetries: system?.disableInternalRetries || false + }; + if (!!auth.clientCertificate && !!!auth.clientCertificate.thumbprint && !!!auth.clientCertificate.thumbprintSha256) { + throw NodeAuthError.createStateNotFoundError(); + } + return { + auth: { ...DEFAULT_AUTH_OPTIONS, ...auth }, + broker: { ...broker }, + cache: { ...DEFAULT_CACHE_OPTIONS, ...cache }, + system: { ...systemOptions, ...system }, + telemetry: { ...DEFAULT_TELEMETRY_OPTIONS, ...telemetry } + }; + } + function buildManagedIdentityConfiguration({ managedIdentityIdParams, system }) { + const managedIdentityId = new ManagedIdentityId(managedIdentityIdParams); + const loggerOptions = system?.loggerOptions || DEFAULT_LOGGER_OPTIONS; + let networkClient; + if (system?.networkClient) { + networkClient = system.networkClient; + } else { + networkClient = new HttpClient(system?.proxyUrl, system?.customAgentOptions); + } + if (!system?.disableInternalRetries) { + const linearRetryPolicy = new LinearRetryPolicy(MANAGED_IDENTITY_MAX_RETRIES, MANAGED_IDENTITY_RETRY_DELAY, MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON); + networkClient = new HttpClientWithRetries(networkClient, linearRetryPolicy); + } + return { + managedIdentityId, + system: { + loggerOptions, + networkClient + } + }; + } + var GuidGenerator = class { + /** + * + * RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or pseudo-random numbers. + * uuidv4 generates guids from cryprtographically-string random + */ + generateGuid() { + return uuid.v4(); + } + /** + * verifies if a string is GUID + * @param guid + */ + isGuid(guid) { + const regexGuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return regexGuid.test(guid); + } + }; + var EncodingUtils = class _EncodingUtils { + /** + * 'utf8': Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8. + * 'base64': Base64 encoding. + * + * @param str text + */ + static base64Encode(str, encoding) { + return Buffer.from(str, encoding).toString("base64"); + } + /** + * encode a URL + * @param str + */ + static base64EncodeUrl(str, encoding) { + return _EncodingUtils.base64Encode(str, encoding).replace(/=/g, Constants$1.EMPTY_STRING).replace(/\+/g, "-").replace(/\//g, "_"); + } + /** + * 'utf8': Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8. + * 'base64': Base64 encoding. + * + * @param base64Str Base64 encoded text + */ + static base64Decode(base64Str) { + return Buffer.from(base64Str, "base64").toString("utf8"); + } + /** + * @param base64Str Base64 encoded Url + */ + static base64DecodeUrl(base64Str) { + let str = base64Str.replace(/-/g, "+").replace(/_/g, "/"); + while (str.length % 4) { + str += "="; + } + return _EncodingUtils.base64Decode(str); + } + }; + var HashUtils = class { + /** + * generate 'SHA256' hash + * @param buffer + */ + sha256(buffer) { + return crypto12.createHash(Hash.SHA256).update(buffer).digest(); + } + }; + var PkceGenerator = class { + constructor() { + this.hashUtils = new HashUtils(); + } + /** + * generates the codeVerfier and the challenge from the codeVerfier + * reference: https://tools.ietf.org/html/rfc7636#section-4.1 and https://tools.ietf.org/html/rfc7636#section-4.2 + */ + async generatePkceCodes() { + const verifier = this.generateCodeVerifier(); + const challenge = this.generateCodeChallengeFromVerifier(verifier); + return { verifier, challenge }; + } + /** + * generates the codeVerfier; reference: https://tools.ietf.org/html/rfc7636#section-4.1 + */ + generateCodeVerifier() { + const charArr = []; + const maxNumber = 256 - 256 % CharSet.CV_CHARSET.length; + while (charArr.length <= RANDOM_OCTET_SIZE) { + const byte = crypto12.randomBytes(1)[0]; + if (byte >= maxNumber) { + continue; + } + const index = byte % CharSet.CV_CHARSET.length; + charArr.push(CharSet.CV_CHARSET[index]); + } + const verifier = charArr.join(Constants$1.EMPTY_STRING); + return EncodingUtils.base64EncodeUrl(verifier); + } + /** + * generate the challenge from the codeVerfier; reference: https://tools.ietf.org/html/rfc7636#section-4.2 + * @param codeVerifier + */ + generateCodeChallengeFromVerifier(codeVerifier) { + return EncodingUtils.base64EncodeUrl(this.hashUtils.sha256(codeVerifier).toString("base64"), "base64"); + } + }; + var CryptoProvider = class { + constructor() { + this.pkceGenerator = new PkceGenerator(); + this.guidGenerator = new GuidGenerator(); + this.hashUtils = new HashUtils(); + } + /** + * base64 URL safe encoded string + */ + base64UrlEncode() { + throw new Error("Method not implemented."); + } + /** + * Stringifies and base64Url encodes input public key + * @param inputKid - public key id + * @returns Base64Url encoded public key + */ + encodeKid() { + throw new Error("Method not implemented."); + } + /** + * Creates a new random GUID - used to populate state and nonce. + * @returns string (GUID) + */ + createNewGuid() { + return this.guidGenerator.generateGuid(); + } + /** + * Encodes input string to base64. + * @param input - string to be encoded + */ + base64Encode(input) { + return EncodingUtils.base64Encode(input); + } + /** + * Decodes input string from base64. + * @param input - string to be decoded + */ + base64Decode(input) { + return EncodingUtils.base64Decode(input); + } + /** + * Generates PKCE codes used in Authorization Code Flow. + */ + generatePkceCodes() { + return this.pkceGenerator.generatePkceCodes(); + } + /** + * Generates a keypair, stores it and returns a thumbprint - not yet implemented for node + */ + getPublicKeyThumbprint() { + throw new Error("Method not implemented."); + } + /** + * Removes cryptographic keypair from key store matching the keyId passed in + * @param kid - public key id + */ + removeTokenBindingKey() { + throw new Error("Method not implemented."); + } + /** + * Removes all cryptographic keys from Keystore + */ + clearKeystore() { + throw new Error("Method not implemented."); + } + /** + * Signs the given object as a jwt payload with private key retrieved by given kid - currently not implemented for node + */ + signJwt() { + throw new Error("Method not implemented."); + } + /** + * Returns the SHA-256 hash of an input string + */ + async hashString(plainText) { + return EncodingUtils.base64EncodeUrl(this.hashUtils.sha256(plainText).toString("base64"), "base64"); + } + }; + var NodeStorage = class extends CacheManager { + constructor(logger, clientId, cryptoImpl, staticAuthorityOptions) { + super(clientId, cryptoImpl, logger, staticAuthorityOptions); + this.cache = {}; + this.changeEmitters = []; + this.logger = logger; + } + /** + * Queue up callbacks + * @param func - a callback function for cache change indication + */ + registerChangeEmitter(func) { + this.changeEmitters.push(func); + } + /** + * Invoke the callback when cache changes + */ + emitChange() { + this.changeEmitters.forEach((func) => func.call(null)); + } + /** + * Converts cacheKVStore to InMemoryCache + * @param cache - key value store + */ + cacheToInMemoryCache(cache) { + const inMemoryCache = { + accounts: {}, + idTokens: {}, + accessTokens: {}, + refreshTokens: {}, + appMetadata: {} + }; + for (const key in cache) { + const value = cache[key]; + if (typeof value !== "object") { + continue; + } + if (value instanceof AccountEntity) { + inMemoryCache.accounts[key] = value; + } else if (isIdTokenEntity(value)) { + inMemoryCache.idTokens[key] = value; + } else if (isAccessTokenEntity(value)) { + inMemoryCache.accessTokens[key] = value; + } else if (isRefreshTokenEntity(value)) { + inMemoryCache.refreshTokens[key] = value; + } else if (isAppMetadataEntity(key, value)) { + inMemoryCache.appMetadata[key] = value; + } else { + continue; + } + } + return inMemoryCache; + } + /** + * converts inMemoryCache to CacheKVStore + * @param inMemoryCache - kvstore map for inmemory + */ + inMemoryCacheToCache(inMemoryCache) { + let cache = this.getCache(); + cache = { + ...cache, + ...inMemoryCache.accounts, + ...inMemoryCache.idTokens, + ...inMemoryCache.accessTokens, + ...inMemoryCache.refreshTokens, + ...inMemoryCache.appMetadata + }; + return cache; + } + /** + * gets the current in memory cache for the client + */ + getInMemoryCache() { + this.logger.trace("Getting in-memory cache"); + const inMemoryCache = this.cacheToInMemoryCache(this.getCache()); + return inMemoryCache; + } + /** + * sets the current in memory cache for the client + * @param inMemoryCache - key value map in memory + */ + setInMemoryCache(inMemoryCache) { + this.logger.trace("Setting in-memory cache"); + const cache = this.inMemoryCacheToCache(inMemoryCache); + this.setCache(cache); + this.emitChange(); + } + /** + * get the current cache key-value store + */ + getCache() { + this.logger.trace("Getting cache key-value store"); + return this.cache; + } + /** + * sets the current cache (key value store) + * @param cacheMap - key value map + */ + setCache(cache) { + this.logger.trace("Setting cache key value store"); + this.cache = cache; + this.emitChange(); + } + /** + * Gets cache item with given key. + * @param key - lookup key for the cache entry + */ + getItem(key) { + this.logger.tracePii(`Item key: ${key}`); + const cache = this.getCache(); + return cache[key]; + } + /** + * Gets cache item with given key-value + * @param key - lookup key for the cache entry + * @param value - value of the cache entry + */ + setItem(key, value) { + this.logger.tracePii(`Item key: ${key}`); + const cache = this.getCache(); + cache[key] = value; + this.setCache(cache); + } + getAccountKeys() { + const inMemoryCache = this.getInMemoryCache(); + const accountKeys = Object.keys(inMemoryCache.accounts); + return accountKeys; + } + getTokenKeys() { + const inMemoryCache = this.getInMemoryCache(); + const tokenKeys = { + idToken: Object.keys(inMemoryCache.idTokens), + accessToken: Object.keys(inMemoryCache.accessTokens), + refreshToken: Object.keys(inMemoryCache.refreshTokens) + }; + return tokenKeys; + } + /** + * fetch the account entity + * @param accountKey - lookup key to fetch cache type AccountEntity + */ + getAccount(accountKey) { + const accountEntity = this.getCachedAccountEntity(accountKey); + if (accountEntity && AccountEntity.isAccountEntity(accountEntity)) { + return this.updateOutdatedCachedAccount(accountKey, accountEntity, ""); + } + return null; + } + /** + * Reads account from cache, builds it into an account entity and returns it. + * @param accountKey - lookup key to fetch cache type AccountEntity + * @returns + */ + getCachedAccountEntity(accountKey) { + const cachedAccount = this.getItem(accountKey); + return cachedAccount ? Object.assign(new AccountEntity(), this.getItem(accountKey)) : null; + } + /** + * set account entity + * @param account - cache value to be set of type AccountEntity + */ + setAccount(account) { + const accountKey = account.generateAccountKey(); + this.setItem(accountKey, account); + } + /** + * fetch the idToken credential + * @param idTokenKey - lookup key to fetch cache type IdTokenEntity + */ + getIdTokenCredential(idTokenKey) { + const idToken = this.getItem(idTokenKey); + if (isIdTokenEntity(idToken)) { + return idToken; + } + return null; + } + /** + * set idToken credential + * @param idToken - cache value to be set of type IdTokenEntity + */ + setIdTokenCredential(idToken) { + const idTokenKey = generateCredentialKey(idToken); + this.setItem(idTokenKey, idToken); + } + /** + * fetch the accessToken credential + * @param accessTokenKey - lookup key to fetch cache type AccessTokenEntity + */ + getAccessTokenCredential(accessTokenKey) { + const accessToken = this.getItem(accessTokenKey); + if (isAccessTokenEntity(accessToken)) { + return accessToken; + } + return null; + } + /** + * set accessToken credential + * @param accessToken - cache value to be set of type AccessTokenEntity + */ + setAccessTokenCredential(accessToken) { + const accessTokenKey = generateCredentialKey(accessToken); + this.setItem(accessTokenKey, accessToken); + } + /** + * fetch the refreshToken credential + * @param refreshTokenKey - lookup key to fetch cache type RefreshTokenEntity + */ + getRefreshTokenCredential(refreshTokenKey) { + const refreshToken = this.getItem(refreshTokenKey); + if (isRefreshTokenEntity(refreshToken)) { + return refreshToken; + } + return null; + } + /** + * set refreshToken credential + * @param refreshToken - cache value to be set of type RefreshTokenEntity + */ + setRefreshTokenCredential(refreshToken) { + const refreshTokenKey = generateCredentialKey(refreshToken); + this.setItem(refreshTokenKey, refreshToken); + } + /** + * fetch appMetadata entity from the platform cache + * @param appMetadataKey - lookup key to fetch cache type AppMetadataEntity + */ + getAppMetadata(appMetadataKey) { + const appMetadata = this.getItem(appMetadataKey); + if (isAppMetadataEntity(appMetadataKey, appMetadata)) { + return appMetadata; + } + return null; + } + /** + * set appMetadata entity to the platform cache + * @param appMetadata - cache value to be set of type AppMetadataEntity + */ + setAppMetadata(appMetadata) { + const appMetadataKey = generateAppMetadataKey(appMetadata); + this.setItem(appMetadataKey, appMetadata); + } + /** + * fetch server telemetry entity from the platform cache + * @param serverTelemetrykey - lookup key to fetch cache type ServerTelemetryEntity + */ + getServerTelemetry(serverTelemetrykey) { + const serverTelemetryEntity = this.getItem(serverTelemetrykey); + if (serverTelemetryEntity && isServerTelemetryEntity(serverTelemetrykey, serverTelemetryEntity)) { + return serverTelemetryEntity; + } + return null; + } + /** + * set server telemetry entity to the platform cache + * @param serverTelemetryKey - lookup key to fetch cache type ServerTelemetryEntity + * @param serverTelemetry - cache value to be set of type ServerTelemetryEntity + */ + setServerTelemetry(serverTelemetryKey, serverTelemetry) { + this.setItem(serverTelemetryKey, serverTelemetry); + } + /** + * fetch authority metadata entity from the platform cache + * @param key - lookup key to fetch cache type AuthorityMetadataEntity + */ + getAuthorityMetadata(key) { + const authorityMetadataEntity = this.getItem(key); + if (authorityMetadataEntity && isAuthorityMetadataEntity(key, authorityMetadataEntity)) { + return authorityMetadataEntity; + } + return null; + } + /** + * Get all authority metadata keys + */ + getAuthorityMetadataKeys() { + return this.getKeys().filter((key) => { + return this.isAuthorityMetadata(key); + }); + } + /** + * set authority metadata entity to the platform cache + * @param key - lookup key to fetch cache type AuthorityMetadataEntity + * @param metadata - cache value to be set of type AuthorityMetadataEntity + */ + setAuthorityMetadata(key, metadata) { + this.setItem(key, metadata); + } + /** + * fetch throttling entity from the platform cache + * @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity + */ + getThrottlingCache(throttlingCacheKey) { + const throttlingCache = this.getItem(throttlingCacheKey); + if (throttlingCache && isThrottlingEntity(throttlingCacheKey, throttlingCache)) { + return throttlingCache; + } + return null; + } + /** + * set throttling entity to the platform cache + * @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity + * @param throttlingCache - cache value to be set of type ThrottlingEntity + */ + setThrottlingCache(throttlingCacheKey, throttlingCache) { + this.setItem(throttlingCacheKey, throttlingCache); + } + /** + * Removes the cache item from memory with the given key. + * @param key - lookup key to remove a cache entity + * @param inMemory - key value map of the cache + */ + removeItem(key) { + this.logger.tracePii(`Item key: ${key}`); + let result = false; + const cache = this.getCache(); + if (!!cache[key]) { + delete cache[key]; + result = true; + } + if (result) { + this.setCache(cache); + this.emitChange(); + } + return result; + } + /** + * Remove account entity from the platform cache if it's outdated + * @param accountKey - lookup key to fetch cache type AccountEntity + */ + removeOutdatedAccount(accountKey) { + this.removeItem(accountKey); + } + /** + * Checks whether key is in cache. + * @param key - look up key for a cache entity + */ + containsKey(key) { + return this.getKeys().includes(key); + } + /** + * Gets all keys in window. + */ + getKeys() { + this.logger.trace("Retrieving all cache keys"); + const cache = this.getCache(); + return [...Object.keys(cache)]; + } + /** + * Clears all cache entries created by MSAL (except tokens). + */ + clear() { + this.logger.trace("Clearing cache entries created by MSAL"); + const cacheKeys = this.getKeys(); + cacheKeys.forEach((key) => { + this.removeItem(key); + }); + this.emitChange(); + } + /** + * Initialize in memory cache from an exisiting cache vault + * @param cache - blob formatted cache (JSON) + */ + static generateInMemoryCache(cache) { + return Deserializer.deserializeAllCache(Deserializer.deserializeJSONBlob(cache)); + } + /** + * retrieves the final JSON + * @param inMemoryCache - itemised cache read from the JSON + */ + static generateJsonCache(inMemoryCache) { + return Serializer.serializeAllCache(inMemoryCache); + } + /** + * Updates a credential's cache key if the current cache key is outdated + */ + updateCredentialCacheKey(currentCacheKey, credential) { + const updatedCacheKey = generateCredentialKey(credential); + if (currentCacheKey !== updatedCacheKey) { + const cacheItem = this.getItem(currentCacheKey); + if (cacheItem) { + this.removeItem(currentCacheKey); + this.setItem(updatedCacheKey, cacheItem); + this.logger.verbose(`Updated an outdated ${credential.credentialType} cache key`); + return updatedCacheKey; + } else { + this.logger.error(`Attempted to update an outdated ${credential.credentialType} cache key but no item matching the outdated key was found in storage`); + } + } + return currentCacheKey; + } + }; + var defaultSerializedCache = { + Account: {}, + IdToken: {}, + AccessToken: {}, + RefreshToken: {}, + AppMetadata: {} + }; + var TokenCache = class { + constructor(storage, logger, cachePlugin) { + this.cacheHasChanged = false; + this.storage = storage; + this.storage.registerChangeEmitter(this.handleChangeEvent.bind(this)); + if (cachePlugin) { + this.persistence = cachePlugin; + } + this.logger = logger; + } + /** + * Set to true if cache state has changed since last time serialize or writeToPersistence was called + */ + hasChanged() { + return this.cacheHasChanged; + } + /** + * Serializes in memory cache to JSON + */ + serialize() { + this.logger.trace("Serializing in-memory cache"); + let finalState = Serializer.serializeAllCache(this.storage.getInMemoryCache()); + if (this.cacheSnapshot) { + this.logger.trace("Reading cache snapshot from disk"); + finalState = this.mergeState(JSON.parse(this.cacheSnapshot), finalState); + } else { + this.logger.trace("No cache snapshot to merge"); + } + this.cacheHasChanged = false; + return JSON.stringify(finalState); + } + /** + * Deserializes JSON to in-memory cache. JSON should be in MSAL cache schema format + * @param cache - blob formatted cache + */ + deserialize(cache) { + this.logger.trace("Deserializing JSON to in-memory cache"); + this.cacheSnapshot = cache; + if (this.cacheSnapshot) { + this.logger.trace("Reading cache snapshot from disk"); + const deserializedCache = Deserializer.deserializeAllCache(this.overlayDefaults(JSON.parse(this.cacheSnapshot))); + this.storage.setInMemoryCache(deserializedCache); + } else { + this.logger.trace("No cache snapshot to deserialize"); + } + } + /** + * Fetches the cache key-value map + */ + getKVStore() { + return this.storage.getCache(); + } + /** + * API that retrieves all accounts currently in cache to the user + */ + async getAllAccounts(correlationId = new CryptoProvider().createNewGuid()) { + this.logger.trace("getAllAccounts called"); + let cacheContext; + try { + if (this.persistence) { + cacheContext = new TokenCacheContext(this, false); + await this.persistence.beforeCacheAccess(cacheContext); + } + return this.storage.getAllAccounts(correlationId); + } finally { + if (this.persistence && cacheContext) { + await this.persistence.afterCacheAccess(cacheContext); + } + } + } + /** + * Returns the signed in account matching homeAccountId. + * (the account object is created at the time of successful login) + * or null when no matching account is found + * @param homeAccountId - unique identifier for an account (uid.utid) + */ + async getAccountByHomeId(homeAccountId) { + const allAccounts = await this.getAllAccounts(); + if (homeAccountId && allAccounts && allAccounts.length) { + return allAccounts.filter((accountObj) => accountObj.homeAccountId === homeAccountId)[0] || null; + } else { + return null; + } + } + /** + * Returns the signed in account matching localAccountId. + * (the account object is created at the time of successful login) + * or null when no matching account is found + * @param localAccountId - unique identifier of an account (sub/obj when homeAccountId cannot be populated) + */ + async getAccountByLocalId(localAccountId) { + const allAccounts = await this.getAllAccounts(); + if (localAccountId && allAccounts && allAccounts.length) { + return allAccounts.filter((accountObj) => accountObj.localAccountId === localAccountId)[0] || null; + } else { + return null; + } + } + /** + * API to remove a specific account and the relevant data from cache + * @param account - AccountInfo passed by the user + */ + async removeAccount(account, correlationId = new CryptoProvider().createNewGuid()) { + this.logger.trace("removeAccount called"); + let cacheContext; + try { + if (this.persistence) { + cacheContext = new TokenCacheContext(this, true); + await this.persistence.beforeCacheAccess(cacheContext); + } + await this.storage.removeAccount(AccountEntity.generateAccountCacheKey(account), correlationId); + } finally { + if (this.persistence && cacheContext) { + await this.persistence.afterCacheAccess(cacheContext); + } + } + } + /** + * Called when the cache has changed state. + */ + handleChangeEvent() { + this.cacheHasChanged = true; + } + /** + * Merge in memory cache with the cache snapshot. + * @param oldState - cache before changes + * @param currentState - current cache state in the library + */ + mergeState(oldState, currentState) { + this.logger.trace("Merging in-memory cache with cache snapshot"); + const stateAfterRemoval = this.mergeRemovals(oldState, currentState); + return this.mergeUpdates(stateAfterRemoval, currentState); + } + /** + * Deep update of oldState based on newState values + * @param oldState - cache before changes + * @param newState - updated cache + */ + mergeUpdates(oldState, newState) { + Object.keys(newState).forEach((newKey) => { + const newValue = newState[newKey]; + if (!oldState.hasOwnProperty(newKey)) { + if (newValue !== null) { + oldState[newKey] = newValue; + } + } else { + const newValueNotNull = newValue !== null; + const newValueIsObject = typeof newValue === "object"; + const newValueIsNotArray = !Array.isArray(newValue); + const oldStateNotUndefinedOrNull = typeof oldState[newKey] !== "undefined" && oldState[newKey] !== null; + if (newValueNotNull && newValueIsObject && newValueIsNotArray && oldStateNotUndefinedOrNull) { + this.mergeUpdates(oldState[newKey], newValue); + } else { + oldState[newKey] = newValue; + } + } + }); + return oldState; + } + /** + * Removes entities in oldState that the were removed from newState. If there are any unknown values in root of + * oldState that are not recognized, they are left untouched. + * @param oldState - cache before changes + * @param newState - updated cache + */ + mergeRemovals(oldState, newState) { + this.logger.trace("Remove updated entries in cache"); + const accounts = oldState.Account ? this.mergeRemovalsDict(oldState.Account, newState.Account) : oldState.Account; + const accessTokens = oldState.AccessToken ? this.mergeRemovalsDict(oldState.AccessToken, newState.AccessToken) : oldState.AccessToken; + const refreshTokens = oldState.RefreshToken ? this.mergeRemovalsDict(oldState.RefreshToken, newState.RefreshToken) : oldState.RefreshToken; + const idTokens = oldState.IdToken ? this.mergeRemovalsDict(oldState.IdToken, newState.IdToken) : oldState.IdToken; + const appMetadata = oldState.AppMetadata ? this.mergeRemovalsDict(oldState.AppMetadata, newState.AppMetadata) : oldState.AppMetadata; + return { + ...oldState, + Account: accounts, + AccessToken: accessTokens, + RefreshToken: refreshTokens, + IdToken: idTokens, + AppMetadata: appMetadata + }; + } + /** + * Helper to merge new cache with the old one + * @param oldState - cache before changes + * @param newState - updated cache + */ + mergeRemovalsDict(oldState, newState) { + const finalState = { ...oldState }; + Object.keys(oldState).forEach((oldKey) => { + if (!newState || !newState.hasOwnProperty(oldKey)) { + delete finalState[oldKey]; + } + }); + return finalState; + } + /** + * Helper to overlay as a part of cache merge + * @param passedInCache - cache read from the blob + */ + overlayDefaults(passedInCache) { + this.logger.trace("Overlaying input cache with the default cache"); + return { + Account: { + ...defaultSerializedCache.Account, + ...passedInCache.Account + }, + IdToken: { + ...defaultSerializedCache.IdToken, + ...passedInCache.IdToken + }, + AccessToken: { + ...defaultSerializedCache.AccessToken, + ...passedInCache.AccessToken + }, + RefreshToken: { + ...defaultSerializedCache.RefreshToken, + ...passedInCache.RefreshToken + }, + AppMetadata: { + ...defaultSerializedCache.AppMetadata, + ...passedInCache.AppMetadata + } + }; + } + }; + var ClientAssertion = class _ClientAssertion { + /** + * Initialize the ClientAssertion class from the clientAssertion passed by the user + * @param assertion - refer https://tools.ietf.org/html/rfc7521 + */ + static fromAssertion(assertion) { + const clientAssertion = new _ClientAssertion(); + clientAssertion.jwt = assertion; + return clientAssertion; + } + /** + * @deprecated Use fromCertificateWithSha256Thumbprint instead, with a SHA-256 thumprint + * Initialize the ClientAssertion class from the certificate passed by the user + * @param thumbprint - identifier of a certificate + * @param privateKey - secret key + * @param publicCertificate - electronic document provided to prove the ownership of the public key + */ + static fromCertificate(thumbprint, privateKey, publicCertificate) { + const clientAssertion = new _ClientAssertion(); + clientAssertion.privateKey = privateKey; + clientAssertion.thumbprint = thumbprint; + clientAssertion.useSha256 = false; + if (publicCertificate) { + clientAssertion.publicCertificate = this.parseCertificate(publicCertificate); + } + return clientAssertion; + } + /** + * Initialize the ClientAssertion class from the certificate passed by the user + * @param thumbprint - identifier of a certificate + * @param privateKey - secret key + * @param publicCertificate - electronic document provided to prove the ownership of the public key + */ + static fromCertificateWithSha256Thumbprint(thumbprint, privateKey, publicCertificate) { + const clientAssertion = new _ClientAssertion(); + clientAssertion.privateKey = privateKey; + clientAssertion.thumbprint = thumbprint; + clientAssertion.useSha256 = true; + if (publicCertificate) { + clientAssertion.publicCertificate = this.parseCertificate(publicCertificate); + } + return clientAssertion; + } + /** + * Update JWT for certificate based clientAssertion, if passed by the user, uses it as is + * @param cryptoProvider - library's crypto helper + * @param issuer - iss claim + * @param jwtAudience - aud claim + */ + getJwt(cryptoProvider, issuer, jwtAudience) { + if (this.privateKey && this.thumbprint) { + if (this.jwt && !this.isExpired() && issuer === this.issuer && jwtAudience === this.jwtAudience) { + return this.jwt; + } + return this.createJwt(cryptoProvider, issuer, jwtAudience); + } + if (this.jwt) { + return this.jwt; + } + throw createClientAuthError(invalidAssertion); + } + /** + * JWT format and required claims specified: https://tools.ietf.org/html/rfc7523#section-3 + */ + createJwt(cryptoProvider, issuer, jwtAudience) { + this.issuer = issuer; + this.jwtAudience = jwtAudience; + const issuedAt = nowSeconds(); + this.expirationTime = issuedAt + 600; + const algorithm = this.useSha256 ? JwtConstants.PSS_256 : JwtConstants.RSA_256; + const header = { + alg: algorithm + }; + const thumbprintHeader = this.useSha256 ? JwtConstants.X5T_256 : JwtConstants.X5T; + Object.assign(header, { + [thumbprintHeader]: EncodingUtils.base64EncodeUrl(this.thumbprint, "hex") + }); + if (this.publicCertificate) { + Object.assign(header, { + [JwtConstants.X5C]: this.publicCertificate + }); + } + const payload = { + [JwtConstants.AUDIENCE]: this.jwtAudience, + [JwtConstants.EXPIRATION_TIME]: this.expirationTime, + [JwtConstants.ISSUER]: this.issuer, + [JwtConstants.SUBJECT]: this.issuer, + [JwtConstants.NOT_BEFORE]: issuedAt, + [JwtConstants.JWT_ID]: cryptoProvider.createNewGuid() + }; + this.jwt = jwt.sign(payload, this.privateKey, { header }); + return this.jwt; + } + /** + * Utility API to check expiration + */ + isExpired() { + return this.expirationTime < nowSeconds(); + } + /** + * Extracts the raw certs from a given certificate string and returns them in an array. + * @param publicCertificate - electronic document provided to prove the ownership of the public key + */ + static parseCertificate(publicCertificate) { + const regexToFindCerts = /-----BEGIN CERTIFICATE-----\r*\n(.+?)\r*\n-----END CERTIFICATE-----/gs; + const certs = []; + let matches; + while ((matches = regexToFindCerts.exec(publicCertificate)) !== null) { + certs.push(matches[1].replace(/\r*\n/g, Constants$1.EMPTY_STRING)); + } + return certs; + } + }; + var name = "@azure/msal-node"; + var version4 = "2.16.3"; + var UsernamePasswordClient = class extends BaseClient { + constructor(configuration) { + super(configuration); + } + /** + * API to acquire a token by passing the username and password to the service in exchage of credentials + * password_grant + * @param request - CommonUsernamePasswordRequest + */ + async acquireToken(request) { + this.logger.info("in acquireToken call in username-password client"); + const reqTimestamp = nowSeconds(); + const response = await this.executeTokenRequest(this.authority, request); + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response.body); + const tokenResponse = responseHandler.handleServerTokenResponse(response.body, this.authority, reqTimestamp, request); + return tokenResponse; + } + /** + * Executes POST request to token endpoint + * @param authority - authority object + * @param request - CommonUsernamePasswordRequest provided by the developer + */ + async executeTokenRequest(authority, request) { + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await this.createTokenRequestBody(request); + const headers = this.createTokenRequestHeaders({ + credential: request.username, + type: CcsCredentialType.UPN + }); + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: authority.canonicalAuthority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + return this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId); + } + /** + * Generates a map for all the params to be sent to the service + * @param request - CommonUsernamePasswordRequest provided by the developer + */ + async createTokenRequestBody(request) { + const parameterBuilder = new RequestParameterBuilder(); + parameterBuilder.addClientId(this.config.authOptions.clientId); + parameterBuilder.addUsername(request.username); + parameterBuilder.addPassword(request.password); + parameterBuilder.addScopes(request.scopes); + parameterBuilder.addResponseTypeForTokenAndIdToken(); + parameterBuilder.addGrantType(GrantType.RESOURCE_OWNER_PASSWORD_GRANT); + parameterBuilder.addClientInfo(); + parameterBuilder.addLibraryInfo(this.config.libraryInfo); + parameterBuilder.addApplicationTelemetry(this.config.telemetry.application); + parameterBuilder.addThrottling(); + if (this.serverTelemetryManager) { + parameterBuilder.addServerTelemetry(this.serverTelemetryManager); + } + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + parameterBuilder.addCorrelationId(correlationId); + if (this.config.clientCredentials.clientSecret) { + parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret); + } + const clientAssertion = this.config.clientCredentials.clientAssertion; + if (clientAssertion) { + parameterBuilder.addClientAssertion(await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + parameterBuilder.addClientAssertionType(clientAssertion.assertionType); + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities); + } + if (this.config.systemOptions.preventCorsPreflight && request.username) { + parameterBuilder.addCcsUpn(request.username); + } + return parameterBuilder.createQueryString(); + } + }; + var ClientApplication = class { + /** + * Constructor for the ClientApplication + */ + constructor(configuration) { + this.config = buildAppConfiguration(configuration); + this.cryptoProvider = new CryptoProvider(); + this.logger = new Logger(this.config.system.loggerOptions, name, version4); + this.storage = new NodeStorage(this.logger, this.config.auth.clientId, this.cryptoProvider, buildStaticAuthorityOptions(this.config.auth)); + this.tokenCache = new TokenCache(this.storage, this.logger, this.config.cache.cachePlugin); + } + /** + * Creates the URL of the authorization request, letting the user input credentials and consent to the + * application. The URL targets the /authorize endpoint of the authority configured in the + * application object. + * + * Once the user inputs their credentials and consents, the authority will send a response to the redirect URI + * sent in the request and should contain an authorization code, which can then be used to acquire tokens via + * `acquireTokenByCode(AuthorizationCodeRequest)`. + */ + async getAuthCodeUrl(request) { + this.logger.info("getAuthCodeUrl called", request.correlationId); + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request), + responseMode: request.responseMode || ResponseMode.QUERY, + authenticationScheme: AuthenticationScheme.BEARER + }; + const authClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, validRequest.redirectUri, void 0, void 0, request.azureCloudOptions); + const authorizationCodeClient = new AuthorizationCodeClient(authClientConfig); + this.logger.verbose("Auth code client created", validRequest.correlationId); + return authorizationCodeClient.getAuthCodeUrl(validRequest); + } + /** + * Acquires a token by exchanging the Authorization Code received from the first step of OAuth2.0 + * Authorization Code flow. + * + * `getAuthCodeUrl(AuthorizationCodeUrlRequest)` can be used to create the URL for the first step of OAuth2.0 + * Authorization Code flow. Ensure that values for redirectUri and scopes in AuthorizationCodeUrlRequest and + * AuthorizationCodeRequest are the same. + */ + async acquireTokenByCode(request, authCodePayLoad) { + this.logger.info("acquireTokenByCode called"); + if (request.state && authCodePayLoad) { + this.logger.info("acquireTokenByCode - validating state"); + this.validateState(request.state, authCodePayLoad.state || ""); + authCodePayLoad = { ...authCodePayLoad, state: "" }; + } + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request), + authenticationScheme: AuthenticationScheme.BEARER + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByCode, validRequest.correlationId); + try { + const authClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, validRequest.redirectUri, serverTelemetryManager, void 0, request.azureCloudOptions); + const authorizationCodeClient = new AuthorizationCodeClient(authClientConfig); + this.logger.verbose("Auth code client created", validRequest.correlationId); + return await authorizationCodeClient.acquireToken(validRequest, authCodePayLoad); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires a token by exchanging the refresh token provided for a new set of tokens. + * + * This API is provided only for scenarios where you would like to migrate from ADAL to MSAL. Otherwise, it is + * recommended that you use `acquireTokenSilent()` for silent scenarios. When using `acquireTokenSilent()`, MSAL will + * handle the caching and refreshing of tokens automatically. + */ + async acquireTokenByRefreshToken(request) { + this.logger.info("acquireTokenByRefreshToken called", request.correlationId); + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request), + authenticationScheme: AuthenticationScheme.BEARER + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByRefreshToken, validRequest.correlationId); + try { + const refreshTokenClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, validRequest.redirectUri || "", serverTelemetryManager, void 0, request.azureCloudOptions); + const refreshTokenClient = new RefreshTokenClient(refreshTokenClientConfig); + this.logger.verbose("Refresh token client created", validRequest.correlationId); + return await refreshTokenClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires a token silently when a user specifies the account the token is requested for. + * + * This API expects the user to provide an account object and looks into the cache to retrieve the token if present. + * There is also an optional "forceRefresh" boolean the user can send to bypass the cache for access_token and id_token. + * In case the refresh_token is expired or not found, an error is thrown + * and the guidance is for the user to call any interactive token acquisition API (eg: `acquireTokenByCode()`). + */ + async acquireTokenSilent(request) { + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request), + forceRefresh: request.forceRefresh || false + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenSilent, validRequest.correlationId, validRequest.forceRefresh); + try { + const silentFlowClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, validRequest.redirectUri || "", serverTelemetryManager, void 0, request.azureCloudOptions); + const silentFlowClient = new SilentFlowClient(silentFlowClientConfig); + this.logger.verbose("Silent flow client created", validRequest.correlationId); + return await silentFlowClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires tokens with password grant by exchanging client applications username and password for credentials + * + * The latest OAuth 2.0 Security Best Current Practice disallows the password grant entirely. + * More details on this recommendation at https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13#section-3.4 + * Microsoft's documentation and recommendations are at: + * https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-authentication-flows#usernamepassword + * + * @param request - UsenamePasswordRequest + */ + async acquireTokenByUsernamePassword(request) { + this.logger.info("acquireTokenByUsernamePassword called", request.correlationId); + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request) + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByUsernamePassword, validRequest.correlationId); + try { + const usernamePasswordClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, "", serverTelemetryManager, void 0, request.azureCloudOptions); + const usernamePasswordClient = new UsernamePasswordClient(usernamePasswordClientConfig); + this.logger.verbose("Username password client created", validRequest.correlationId); + return await usernamePasswordClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Gets the token cache for the application. + */ + getTokenCache() { + this.logger.info("getTokenCache called"); + return this.tokenCache; + } + /** + * Validates OIDC state by comparing the user cached state with the state received from the server. + * + * This API is provided for scenarios where you would use OAuth2.0 state parameter to mitigate against + * CSRF attacks. + * For more information about state, visit https://datatracker.ietf.org/doc/html/rfc6819#section-3.6. + * @param state - Unique GUID generated by the user that is cached by the user and sent to the server during the first leg of the flow + * @param cachedState - This string is sent back by the server with the authorization code + */ + validateState(state, cachedState) { + if (!state) { + throw NodeAuthError.createStateNotFoundError(); + } + if (state !== cachedState) { + throw createClientAuthError(stateMismatch); + } + } + /** + * Returns the logger instance + */ + getLogger() { + return this.logger; + } + /** + * Replaces the default logger set in configurations with new Logger with new configurations + * @param logger - Logger instance + */ + setLogger(logger) { + this.logger = logger; + } + /** + * Builds the common configuration to be passed to the common component based on the platform configurarion + * @param authority - user passed authority in configuration + * @param serverTelemetryManager - initializes servertelemetry if passed + */ + async buildOauthClientConfiguration(authority, requestCorrelationId, redirectUri, serverTelemetryManager, azureRegionConfiguration, azureCloudOptions) { + this.logger.verbose("buildOauthClientConfiguration called", requestCorrelationId); + const userAzureCloudOptions = azureCloudOptions ? azureCloudOptions : this.config.auth.azureCloudOptions; + const discoveredAuthority = await this.createAuthority(authority, requestCorrelationId, azureRegionConfiguration, userAzureCloudOptions); + this.logger.info(`Building oauth client configuration with the following authority: ${discoveredAuthority.tokenEndpoint}.`, requestCorrelationId); + serverTelemetryManager?.updateRegionDiscoveryMetadata(discoveredAuthority.regionDiscoveryMetadata); + const clientConfiguration = { + authOptions: { + clientId: this.config.auth.clientId, + authority: discoveredAuthority, + clientCapabilities: this.config.auth.clientCapabilities, + redirectUri + }, + loggerOptions: { + logLevel: this.config.system.loggerOptions.logLevel, + loggerCallback: this.config.system.loggerOptions.loggerCallback, + piiLoggingEnabled: this.config.system.loggerOptions.piiLoggingEnabled, + correlationId: requestCorrelationId + }, + cacheOptions: { + claimsBasedCachingEnabled: this.config.cache.claimsBasedCachingEnabled + }, + cryptoInterface: this.cryptoProvider, + networkInterface: this.config.system.networkClient, + storageInterface: this.storage, + serverTelemetryManager, + clientCredentials: { + clientSecret: this.clientSecret, + clientAssertion: await this.getClientAssertion(discoveredAuthority) + }, + libraryInfo: { + sku: Constants.MSAL_SKU, + version: version4, + cpu: process.arch || Constants$1.EMPTY_STRING, + os: process.platform || Constants$1.EMPTY_STRING + }, + telemetry: this.config.telemetry, + persistencePlugin: this.config.cache.cachePlugin, + serializableCache: this.tokenCache + }; + return clientConfiguration; + } + async getClientAssertion(authority) { + if (this.developerProvidedClientAssertion) { + this.clientAssertion = ClientAssertion.fromAssertion(await getClientAssertion(this.developerProvidedClientAssertion, this.config.auth.clientId, authority.tokenEndpoint)); + } + return this.clientAssertion && { + assertion: this.clientAssertion.getJwt(this.cryptoProvider, this.config.auth.clientId, authority.tokenEndpoint), + assertionType: Constants.JWT_BEARER_ASSERTION_TYPE + }; + } + /** + * Generates a request with the default scopes & generates a correlationId. + * @param authRequest - BaseAuthRequest for initialization + */ + async initializeBaseRequest(authRequest) { + this.logger.verbose("initializeRequestScopes called", authRequest.correlationId); + if (authRequest.authenticationScheme && authRequest.authenticationScheme === AuthenticationScheme.POP) { + this.logger.verbose("Authentication Scheme 'pop' is not supported yet, setting Authentication Scheme to 'Bearer' for request", authRequest.correlationId); + } + authRequest.authenticationScheme = AuthenticationScheme.BEARER; + if (this.config.cache.claimsBasedCachingEnabled && authRequest.claims && // Checks for empty stringified object "{}" which doesn't qualify as requested claims + !StringUtils.isEmptyObj(authRequest.claims)) { + authRequest.requestedClaimsHash = await this.cryptoProvider.hashString(authRequest.claims); + } + return { + ...authRequest, + scopes: [ + ...authRequest && authRequest.scopes || [], + ...OIDC_DEFAULT_SCOPES + ], + correlationId: authRequest && authRequest.correlationId || this.cryptoProvider.createNewGuid(), + authority: authRequest.authority || this.config.auth.authority + }; + } + /** + * Initializes the server telemetry payload + * @param apiId - Id for a specific request + * @param correlationId - GUID + * @param forceRefresh - boolean to indicate network call + */ + initializeServerTelemetryManager(apiId, correlationId, forceRefresh) { + const telemetryPayload = { + clientId: this.config.auth.clientId, + correlationId, + apiId, + forceRefresh: forceRefresh || false + }; + return new ServerTelemetryManager(telemetryPayload, this.storage); + } + /** + * Create authority instance. If authority not passed in request, default to authority set on the application + * object. If no authority set in application object, then default to common authority. + * @param authorityString - authority from user configuration + */ + async createAuthority(authorityString, requestCorrelationId, azureRegionConfiguration, azureCloudOptions) { + this.logger.verbose("createAuthority called", requestCorrelationId); + const authorityUrl = Authority.generateAuthority(authorityString, azureCloudOptions); + const authorityOptions = { + protocolMode: this.config.auth.protocolMode, + knownAuthorities: this.config.auth.knownAuthorities, + cloudDiscoveryMetadata: this.config.auth.cloudDiscoveryMetadata, + authorityMetadata: this.config.auth.authorityMetadata, + azureRegionConfiguration, + skipAuthorityMetadataCache: this.config.auth.skipAuthorityMetadataCache + }; + return createDiscoveredInstance(authorityUrl, this.config.system.networkClient, this.storage, authorityOptions, this.logger, requestCorrelationId); + } + /** + * Clear the cache + */ + clearCache() { + this.storage.clear(); + } + }; + var LoopbackClient = class { + /** + * Spins up a loopback server which returns the server response when the localhost redirectUri is hit + * @param successTemplate + * @param errorTemplate + * @returns + */ + async listenForAuthCode(successTemplate, errorTemplate) { + if (this.server) { + throw NodeAuthError.createLoopbackServerAlreadyExistsError(); + } + return new Promise((resolve, reject) => { + this.server = http.createServer((req, res) => { + const url = req.url; + if (!url) { + res.end(errorTemplate || "Error occurred loading redirectUrl"); + reject(NodeAuthError.createUnableToLoadRedirectUrlError()); + return; + } else if (url === Constants$1.FORWARD_SLASH) { + res.end(successTemplate || "Auth code was successfully acquired. You can close this window now."); + return; + } + const redirectUri = this.getRedirectUri(); + const parsedUrl = new URL(url, redirectUri); + const authCodeResponse = getDeserializedResponse(parsedUrl.search) || {}; + if (authCodeResponse.code) { + res.writeHead(HttpStatus.REDIRECT, { + location: redirectUri + }); + res.end(); + } + if (authCodeResponse.error) { + res.end(errorTemplate || `Error occurred: ${authCodeResponse.error}`); + } + resolve(authCodeResponse); + }); + this.server.listen(0, "127.0.0.1"); + }); + } + /** + * Get the port that the loopback server is running on + * @returns + */ + getRedirectUri() { + if (!this.server || !this.server.listening) { + throw NodeAuthError.createNoLoopbackServerExistsError(); + } + const address = this.server.address(); + if (!address || typeof address === "string" || !address.port) { + this.closeServer(); + throw NodeAuthError.createInvalidLoopbackAddressTypeError(); + } + const port = address && address.port; + return `${Constants.HTTP_PROTOCOL}${Constants.LOCALHOST}:${port}`; + } + /** + * Close the loopback server + */ + closeServer() { + if (this.server) { + this.server.close(); + if (typeof this.server.closeAllConnections === "function") { + this.server.closeAllConnections(); + } + this.server.unref(); + this.server = void 0; + } + } + }; + var DeviceCodeClient = class extends BaseClient { + constructor(configuration) { + super(configuration); + } + /** + * Gets device code from device code endpoint, calls back to with device code response, and + * polls token endpoint to exchange device code for tokens + * @param request - developer provided CommonDeviceCodeRequest + */ + async acquireToken(request) { + const deviceCodeResponse = await this.getDeviceCode(request); + request.deviceCodeCallback(deviceCodeResponse); + const reqTimestamp = nowSeconds(); + const response = await this.acquireTokenWithDeviceCode(request, deviceCodeResponse); + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response); + return responseHandler.handleServerTokenResponse(response, this.authority, reqTimestamp, request); + } + /** + * Creates device code request and executes http GET + * @param request - developer provided CommonDeviceCodeRequest + */ + async getDeviceCode(request) { + const queryParametersString = this.createExtraQueryParameters(request); + const endpoint = UrlString.appendQueryString(this.authority.deviceCodeEndpoint, queryParametersString); + const queryString = this.createQueryString(request); + const headers = this.createTokenRequestHeaders(); + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: request.authority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + return this.executePostRequestToDeviceCodeEndpoint(endpoint, queryString, headers, thumbprint, request.correlationId); + } + /** + * Creates query string for the device code request + * @param request - developer provided CommonDeviceCodeRequest + */ + createExtraQueryParameters(request) { + const parameterBuilder = new RequestParameterBuilder(); + if (request.extraQueryParameters) { + parameterBuilder.addExtraQueryParameters(request.extraQueryParameters); + } + return parameterBuilder.createQueryString(); + } + /** + * Executes POST request to device code endpoint + * @param deviceCodeEndpoint - token endpoint + * @param queryString - string to be used in the body of the request + * @param headers - headers for the request + * @param thumbprint - unique request thumbprint + * @param correlationId - correlation id to be used in the request + */ + async executePostRequestToDeviceCodeEndpoint(deviceCodeEndpoint, queryString, headers, thumbprint, correlationId) { + const { body: { user_code: userCode, device_code: deviceCode, verification_uri: verificationUri, expires_in: expiresIn, interval, message } } = await this.sendPostRequest(thumbprint, deviceCodeEndpoint, { + body: queryString, + headers + }, correlationId); + return { + userCode, + deviceCode, + verificationUri, + expiresIn, + interval, + message + }; + } + /** + * Create device code endpoint query parameters and returns string + * @param request - developer provided CommonDeviceCodeRequest + */ + createQueryString(request) { + const parameterBuilder = new RequestParameterBuilder(); + parameterBuilder.addScopes(request.scopes); + parameterBuilder.addClientId(this.config.authOptions.clientId); + if (request.extraQueryParameters) { + parameterBuilder.addExtraQueryParameters(request.extraQueryParameters); + } + if (request.claims || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities); + } + return parameterBuilder.createQueryString(); + } + /** + * Breaks the polling with specific conditions + * @param deviceCodeExpirationTime - expiration time for the device code request + * @param userSpecifiedTimeout - developer provided timeout, to be compared against deviceCodeExpirationTime + * @param userSpecifiedCancelFlag - boolean indicating the developer would like to cancel the request + */ + continuePolling(deviceCodeExpirationTime, userSpecifiedTimeout, userSpecifiedCancelFlag) { + if (userSpecifiedCancelFlag) { + this.logger.error("Token request cancelled by setting DeviceCodeRequest.cancel = true"); + throw createClientAuthError(deviceCodePollingCancelled); + } else if (userSpecifiedTimeout && userSpecifiedTimeout < deviceCodeExpirationTime && nowSeconds() > userSpecifiedTimeout) { + this.logger.error(`User defined timeout for device code polling reached. The timeout was set for ${userSpecifiedTimeout}`); + throw createClientAuthError(userTimeoutReached); + } else if (nowSeconds() > deviceCodeExpirationTime) { + if (userSpecifiedTimeout) { + this.logger.verbose(`User specified timeout ignored as the device code has expired before the timeout elapsed. The user specified timeout was set for ${userSpecifiedTimeout}`); + } + this.logger.error(`Device code expired. Expiration time of device code was ${deviceCodeExpirationTime}`); + throw createClientAuthError(deviceCodeExpired); + } + return true; + } + /** + * Creates token request with device code response and polls token endpoint at interval set by the device code response + * @param request - developer provided CommonDeviceCodeRequest + * @param deviceCodeResponse - DeviceCodeResponse returned by the security token service device code endpoint + */ + async acquireTokenWithDeviceCode(request, deviceCodeResponse) { + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(this.authority.tokenEndpoint, queryParametersString); + const requestBody = this.createTokenRequestBody(request, deviceCodeResponse); + const headers = this.createTokenRequestHeaders(); + const userSpecifiedTimeout = request.timeout ? nowSeconds() + request.timeout : void 0; + const deviceCodeExpirationTime = nowSeconds() + deviceCodeResponse.expiresIn; + const pollingIntervalMilli = deviceCodeResponse.interval * 1e3; + while (this.continuePolling(deviceCodeExpirationTime, userSpecifiedTimeout, request.cancel)) { + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: request.authority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + const response = await this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId); + if (response.body && response.body.error) { + if (response.body.error === Constants$1.AUTHORIZATION_PENDING) { + this.logger.info("Authorization pending. Continue polling."); + await delay(pollingIntervalMilli); + } else { + this.logger.info("Unexpected error in polling from the server"); + throw createAuthError(postRequestFailed, response.body.error); + } + } else { + this.logger.verbose("Authorization completed successfully. Polling stopped."); + return response.body; + } + } + this.logger.error("Polling stopped for unknown reasons."); + throw createClientAuthError(deviceCodeUnknownError); + } + /** + * Creates query parameters and converts to string. + * @param request - developer provided CommonDeviceCodeRequest + * @param deviceCodeResponse - DeviceCodeResponse returned by the security token service device code endpoint + */ + createTokenRequestBody(request, deviceCodeResponse) { + const requestParameters = new RequestParameterBuilder(); + requestParameters.addScopes(request.scopes); + requestParameters.addClientId(this.config.authOptions.clientId); + requestParameters.addGrantType(GrantType.DEVICE_CODE_GRANT); + requestParameters.addDeviceCode(deviceCodeResponse.deviceCode); + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + requestParameters.addCorrelationId(correlationId); + requestParameters.addClientInfo(); + requestParameters.addLibraryInfo(this.config.libraryInfo); + requestParameters.addApplicationTelemetry(this.config.telemetry.application); + requestParameters.addThrottling(); + if (this.serverTelemetryManager) { + requestParameters.addServerTelemetry(this.serverTelemetryManager); + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + requestParameters.addClaims(request.claims, this.config.authOptions.clientCapabilities); + } + return requestParameters.createQueryString(); + } + }; + var PublicClientApplication = class extends ClientApplication { + /** + * Important attributes in the Configuration object for auth are: + * - clientID: the application ID of your application. You can obtain one by registering your application with our Application registration portal. + * - authority: the authority URL for your application. + * + * AAD authorities are of the form https://login.microsoftonline.com/\{Enter_the_Tenant_Info_Here\}. + * - If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com). + * - If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations. + * - If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common. + * - To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers. + * + * Azure B2C authorities are of the form https://\{instance\}/\{tenant\}/\{policy\}. Each policy is considered + * its own authority. You will have to set the all of the knownAuthorities at the time of the client application + * construction. + * + * ADFS authorities are of the form https://\{instance\}/adfs. + */ + constructor(configuration) { + super(configuration); + if (this.config.broker.nativeBrokerPlugin) { + if (this.config.broker.nativeBrokerPlugin.isBrokerAvailable) { + this.nativeBrokerPlugin = this.config.broker.nativeBrokerPlugin; + this.nativeBrokerPlugin.setLogger(this.config.system.loggerOptions); + } else { + this.logger.warning("NativeBroker implementation was provided but the broker is unavailable."); + } + } + this.skus = ServerTelemetryManager.makeExtraSkuString({ + libraryName: Constants.MSAL_SKU, + libraryVersion: version4 + }); + } + /** + * Acquires a token from the authority using OAuth2.0 device code flow. + * This flow is designed for devices that do not have access to a browser or have input constraints. + * The authorization server issues a DeviceCode object with a verification code, an end-user code, + * and the end-user verification URI. The DeviceCode object is provided through a callback, and the end-user should be + * instructed to use another device to navigate to the verification URI to input credentials. + * Since the client cannot receive incoming requests, it polls the authorization server repeatedly + * until the end-user completes input of credentials. + */ + async acquireTokenByDeviceCode(request) { + this.logger.info("acquireTokenByDeviceCode called", request.correlationId); + const validRequest = Object.assign(request, await this.initializeBaseRequest(request)); + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByDeviceCode, validRequest.correlationId); + try { + const deviceCodeConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, "", serverTelemetryManager, void 0, request.azureCloudOptions); + const deviceCodeClient = new DeviceCodeClient(deviceCodeConfig); + this.logger.verbose("Device code client created", validRequest.correlationId); + return await deviceCodeClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires a token interactively via the browser by requesting an authorization code then exchanging it for a token. + */ + async acquireTokenInteractive(request) { + const correlationId = request.correlationId || this.cryptoProvider.createNewGuid(); + this.logger.trace("acquireTokenInteractive called", correlationId); + const { openBrowser, successTemplate, errorTemplate, windowHandle, loopbackClient: customLoopbackClient, ...remainingProperties } = request; + if (this.nativeBrokerPlugin) { + const brokerRequest = { + ...remainingProperties, + clientId: this.config.auth.clientId, + scopes: request.scopes || OIDC_DEFAULT_SCOPES, + redirectUri: `${Constants.HTTP_PROTOCOL}${Constants.LOCALHOST}`, + authority: request.authority || this.config.auth.authority, + correlationId, + extraParameters: { + ...remainingProperties.extraQueryParameters, + ...remainingProperties.tokenQueryParameters, + [X_CLIENT_EXTRA_SKU]: this.skus + }, + accountId: remainingProperties.account?.nativeAccountId + }; + return this.nativeBrokerPlugin.acquireTokenInteractive(brokerRequest, windowHandle); + } + const { verifier, challenge } = await this.cryptoProvider.generatePkceCodes(); + const loopbackClient = customLoopbackClient || new LoopbackClient(); + let authCodeResponse = {}; + let authCodeListenerError = null; + try { + const authCodeListener = loopbackClient.listenForAuthCode(successTemplate, errorTemplate).then((response) => { + authCodeResponse = response; + }).catch((e) => { + authCodeListenerError = e; + }); + const redirectUri = await this.waitForRedirectUri(loopbackClient); + const validRequest = { + ...remainingProperties, + correlationId, + scopes: request.scopes || OIDC_DEFAULT_SCOPES, + redirectUri, + responseMode: ResponseMode.QUERY, + codeChallenge: challenge, + codeChallengeMethod: CodeChallengeMethodValues.S256 + }; + const authCodeUrl = await this.getAuthCodeUrl(validRequest); + await openBrowser(authCodeUrl); + await authCodeListener; + if (authCodeListenerError) { + throw authCodeListenerError; + } + if (authCodeResponse.error) { + throw new ServerError(authCodeResponse.error, authCodeResponse.error_description, authCodeResponse.suberror); + } else if (!authCodeResponse.code) { + throw NodeAuthError.createNoAuthCodeInResponseError(); + } + const clientInfo = authCodeResponse.client_info; + const tokenRequest = { + code: authCodeResponse.code, + codeVerifier: verifier, + clientInfo: clientInfo || Constants$1.EMPTY_STRING, + ...validRequest + }; + return await this.acquireTokenByCode(tokenRequest); + } finally { + loopbackClient.closeServer(); + } + } + /** + * Returns a token retrieved either from the cache or by exchanging the refresh token for a fresh access token. If brokering is enabled the token request will be serviced by the broker. + * @param request - developer provided SilentFlowRequest + * @returns + */ + async acquireTokenSilent(request) { + const correlationId = request.correlationId || this.cryptoProvider.createNewGuid(); + this.logger.trace("acquireTokenSilent called", correlationId); + if (this.nativeBrokerPlugin) { + const brokerRequest = { + ...request, + clientId: this.config.auth.clientId, + scopes: request.scopes || OIDC_DEFAULT_SCOPES, + redirectUri: `${Constants.HTTP_PROTOCOL}${Constants.LOCALHOST}`, + authority: request.authority || this.config.auth.authority, + correlationId, + extraParameters: { + ...request.tokenQueryParameters, + [X_CLIENT_EXTRA_SKU]: this.skus + }, + accountId: request.account.nativeAccountId, + forceRefresh: request.forceRefresh || false + }; + return this.nativeBrokerPlugin.acquireTokenSilent(brokerRequest); + } + return super.acquireTokenSilent(request); + } + /** + * Removes cache artifacts associated with the given account + * @param request - developer provided SignOutRequest + * @returns + */ + async signOut(request) { + if (this.nativeBrokerPlugin && request.account.nativeAccountId) { + const signoutRequest = { + clientId: this.config.auth.clientId, + accountId: request.account.nativeAccountId, + correlationId: request.correlationId || this.cryptoProvider.createNewGuid() + }; + await this.nativeBrokerPlugin.signOut(signoutRequest); + } + await this.getTokenCache().removeAccount(request.account, request.correlationId); + } + /** + * Returns all cached accounts for this application. If brokering is enabled this request will be serviced by the broker. + * @returns + */ + async getAllAccounts() { + if (this.nativeBrokerPlugin) { + const correlationId = this.cryptoProvider.createNewGuid(); + return this.nativeBrokerPlugin.getAllAccounts(this.config.auth.clientId, correlationId); + } + return this.getTokenCache().getAllAccounts(); + } + /** + * Attempts to retrieve the redirectUri from the loopback server. If the loopback server does not start listening for requests within the timeout this will throw. + * @param loopbackClient - developer provided custom loopback server implementation + * @returns + */ + async waitForRedirectUri(loopbackClient) { + return new Promise((resolve, reject) => { + let ticks = 0; + const id = setInterval(() => { + if (LOOPBACK_SERVER_CONSTANTS.TIMEOUT_MS / LOOPBACK_SERVER_CONSTANTS.INTERVAL_MS < ticks) { + clearInterval(id); + reject(NodeAuthError.createLoopbackServerTimeoutError()); + return; + } + try { + const r = loopbackClient.getRedirectUri(); + clearInterval(id); + resolve(r); + return; + } catch (e) { + if (e instanceof AuthError && e.errorCode === NodeAuthErrorMessage.noLoopbackServerExists.code) { + ticks++; + return; + } + clearInterval(id); + reject(e); + return; + } + }, LOOPBACK_SERVER_CONSTANTS.INTERVAL_MS); + }); + } + }; + var ClientCredentialClient = class extends BaseClient { + constructor(configuration, appTokenProvider) { + super(configuration); + this.appTokenProvider = appTokenProvider; + } + /** + * Public API to acquire a token with ClientCredential Flow for Confidential clients + * @param request - CommonClientCredentialRequest provided by the developer + */ + async acquireToken(request) { + if (request.skipCache || request.claims) { + return this.executeTokenRequest(request, this.authority); + } + const [cachedAuthenticationResult, lastCacheOutcome] = await this.getCachedAuthenticationResult(request, this.config, this.cryptoUtils, this.authority, this.cacheManager, this.serverTelemetryManager); + if (cachedAuthenticationResult) { + if (lastCacheOutcome === CacheOutcome.PROACTIVELY_REFRESHED) { + this.logger.info("ClientCredentialClient:getCachedAuthenticationResult - Cached access token's refreshOn property has been exceeded'. It's not expired, but must be refreshed."); + const refreshAccessToken = true; + await this.executeTokenRequest(request, this.authority, refreshAccessToken); + } + return cachedAuthenticationResult; + } else { + return this.executeTokenRequest(request, this.authority); + } + } + /** + * looks up cache if the tokens are cached already + */ + async getCachedAuthenticationResult(request, config, cryptoUtils, authority, cacheManager, serverTelemetryManager) { + const clientConfiguration = config; + const managedIdentityConfiguration = config; + let lastCacheOutcome = CacheOutcome.NOT_APPLICABLE; + let cacheContext; + if (clientConfiguration.serializableCache && clientConfiguration.persistencePlugin) { + cacheContext = new TokenCacheContext(clientConfiguration.serializableCache, false); + await clientConfiguration.persistencePlugin.beforeCacheAccess(cacheContext); + } + const cachedAccessToken = this.readAccessTokenFromCache(authority, managedIdentityConfiguration.managedIdentityId?.id || clientConfiguration.authOptions.clientId, new ScopeSet(request.scopes || []), cacheManager, request.correlationId); + if (clientConfiguration.serializableCache && clientConfiguration.persistencePlugin && cacheContext) { + await clientConfiguration.persistencePlugin.afterCacheAccess(cacheContext); + } + if (!cachedAccessToken) { + serverTelemetryManager?.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN); + return [null, CacheOutcome.NO_CACHED_ACCESS_TOKEN]; + } + if (isTokenExpired(cachedAccessToken.expiresOn, clientConfiguration.systemOptions?.tokenRenewalOffsetSeconds || DEFAULT_TOKEN_RENEWAL_OFFSET_SEC)) { + serverTelemetryManager?.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED); + return [null, CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED]; + } + if (cachedAccessToken.refreshOn && isTokenExpired(cachedAccessToken.refreshOn.toString(), 0)) { + lastCacheOutcome = CacheOutcome.PROACTIVELY_REFRESHED; + serverTelemetryManager?.setCacheOutcome(CacheOutcome.PROACTIVELY_REFRESHED); + } + return [ + await ResponseHandler.generateAuthenticationResult(cryptoUtils, authority, { + account: null, + idToken: null, + accessToken: cachedAccessToken, + refreshToken: null, + appMetadata: null + }, true, request), + lastCacheOutcome + ]; + } + /** + * Reads access token from the cache + */ + readAccessTokenFromCache(authority, id, scopeSet, cacheManager, correlationId) { + const accessTokenFilter = { + homeAccountId: Constants$1.EMPTY_STRING, + environment: authority.canonicalAuthorityUrlComponents.HostNameAndPort, + credentialType: CredentialType.ACCESS_TOKEN, + clientId: id, + realm: authority.tenant, + target: ScopeSet.createSearchScopes(scopeSet.asArray()) + }; + const accessTokens = cacheManager.getAccessTokensByFilter(accessTokenFilter, correlationId); + if (accessTokens.length < 1) { + return null; + } else if (accessTokens.length > 1) { + throw createClientAuthError(multipleMatchingTokens); + } + return accessTokens[0]; + } + /** + * Makes a network call to request the token from the service + * @param request - CommonClientCredentialRequest provided by the developer + * @param authority - authority object + */ + async executeTokenRequest(request, authority, refreshAccessToken) { + let serverTokenResponse; + let reqTimestamp; + if (this.appTokenProvider) { + this.logger.info("Using appTokenProvider extensibility."); + const appTokenPropviderParameters = { + correlationId: request.correlationId, + tenantId: this.config.authOptions.authority.tenant, + scopes: request.scopes, + claims: request.claims + }; + reqTimestamp = nowSeconds(); + const appTokenProviderResult = await this.appTokenProvider(appTokenPropviderParameters); + serverTokenResponse = { + access_token: appTokenProviderResult.accessToken, + expires_in: appTokenProviderResult.expiresInSeconds, + refresh_in: appTokenProviderResult.refreshInSeconds, + token_type: AuthenticationScheme.BEARER + }; + } else { + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await this.createTokenRequestBody(request); + const headers = this.createTokenRequestHeaders(); + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: request.authority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + this.logger.info("Sending token request to endpoint: " + authority.tokenEndpoint); + reqTimestamp = nowSeconds(); + const response = await this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId); + serverTokenResponse = response.body; + serverTokenResponse.status = response.status; + } + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(serverTokenResponse, refreshAccessToken); + const tokenResponse = await responseHandler.handleServerTokenResponse(serverTokenResponse, this.authority, reqTimestamp, request); + return tokenResponse; + } + /** + * generate the request to the server in the acceptable format + * @param request - CommonClientCredentialRequest provided by the developer + */ + async createTokenRequestBody(request) { + const parameterBuilder = new RequestParameterBuilder(); + parameterBuilder.addClientId(this.config.authOptions.clientId); + parameterBuilder.addScopes(request.scopes, false); + parameterBuilder.addGrantType(GrantType.CLIENT_CREDENTIALS_GRANT); + parameterBuilder.addLibraryInfo(this.config.libraryInfo); + parameterBuilder.addApplicationTelemetry(this.config.telemetry.application); + parameterBuilder.addThrottling(); + if (this.serverTelemetryManager) { + parameterBuilder.addServerTelemetry(this.serverTelemetryManager); + } + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + parameterBuilder.addCorrelationId(correlationId); + if (this.config.clientCredentials.clientSecret) { + parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret); + } + const clientAssertion = request.clientAssertion || this.config.clientCredentials.clientAssertion; + if (clientAssertion) { + parameterBuilder.addClientAssertion(await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + parameterBuilder.addClientAssertionType(clientAssertion.assertionType); + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities); + } + return parameterBuilder.createQueryString(); + } + }; + var OnBehalfOfClient = class extends BaseClient { + constructor(configuration) { + super(configuration); + } + /** + * Public API to acquire tokens with on behalf of flow + * @param request - developer provided CommonOnBehalfOfRequest + */ + async acquireToken(request) { + this.scopeSet = new ScopeSet(request.scopes || []); + this.userAssertionHash = await this.cryptoUtils.hashString(request.oboAssertion); + if (request.skipCache || request.claims) { + return this.executeTokenRequest(request, this.authority, this.userAssertionHash); + } + try { + return await this.getCachedAuthenticationResult(request); + } catch (e) { + return await this.executeTokenRequest(request, this.authority, this.userAssertionHash); + } + } + /** + * look up cache for tokens + * Find idtoken in the cache + * Find accessToken based on user assertion and account info in the cache + * Please note we are not yet supported OBO tokens refreshed with long lived RT. User will have to send a new assertion if the current access token expires + * This is to prevent security issues when the assertion changes over time, however, longlived RT helps retaining the session + * @param request - developer provided CommonOnBehalfOfRequest + */ + async getCachedAuthenticationResult(request) { + const cachedAccessToken = this.readAccessTokenFromCacheForOBO(this.config.authOptions.clientId, request); + if (!cachedAccessToken) { + this.serverTelemetryManager?.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN); + this.logger.info("SilentFlowClient:acquireCachedToken - No access token found in cache for the given properties."); + throw createClientAuthError(tokenRefreshRequired); + } else if (isTokenExpired(cachedAccessToken.expiresOn, this.config.systemOptions.tokenRenewalOffsetSeconds)) { + this.serverTelemetryManager?.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED); + this.logger.info(`OnbehalfofFlow:getCachedAuthenticationResult - Cached access token is expired or will expire within ${this.config.systemOptions.tokenRenewalOffsetSeconds} seconds.`); + throw createClientAuthError(tokenRefreshRequired); + } + const cachedIdToken = this.readIdTokenFromCacheForOBO(cachedAccessToken.homeAccountId, request.correlationId); + let idTokenClaims; + let cachedAccount = null; + if (cachedIdToken) { + idTokenClaims = extractTokenClaims(cachedIdToken.secret, EncodingUtils.base64Decode); + const localAccountId = idTokenClaims.oid || idTokenClaims.sub; + const accountInfo = { + homeAccountId: cachedIdToken.homeAccountId, + environment: cachedIdToken.environment, + tenantId: cachedIdToken.realm, + username: Constants$1.EMPTY_STRING, + localAccountId: localAccountId || Constants$1.EMPTY_STRING + }; + cachedAccount = this.cacheManager.readAccountFromCache(accountInfo, request.correlationId); + } + if (this.config.serverTelemetryManager) { + this.config.serverTelemetryManager.incrementCacheHits(); + } + return ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, { + account: cachedAccount, + accessToken: cachedAccessToken, + idToken: cachedIdToken, + refreshToken: null, + appMetadata: null + }, true, request, idTokenClaims); + } + /** + * read idtoken from cache, this is a specific implementation for OBO as the requirements differ from a generic lookup in the cacheManager + * Certain use cases of OBO flow do not expect an idToken in the cache/or from the service + * @param atHomeAccountId - account id + */ + readIdTokenFromCacheForOBO(atHomeAccountId, correlationId) { + const idTokenFilter = { + homeAccountId: atHomeAccountId, + environment: this.authority.canonicalAuthorityUrlComponents.HostNameAndPort, + credentialType: CredentialType.ID_TOKEN, + clientId: this.config.authOptions.clientId, + realm: this.authority.tenant + }; + const idTokenMap = this.cacheManager.getIdTokensByFilter(idTokenFilter, correlationId); + if (Object.values(idTokenMap).length < 1) { + return null; + } + return Object.values(idTokenMap)[0]; + } + /** + * Fetches the cached access token based on incoming assertion + * @param clientId - client id + * @param request - developer provided CommonOnBehalfOfRequest + */ + readAccessTokenFromCacheForOBO(clientId, request) { + const authScheme = request.authenticationScheme || AuthenticationScheme.BEARER; + const credentialType = authScheme.toLowerCase() !== AuthenticationScheme.BEARER.toLowerCase() ? CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME : CredentialType.ACCESS_TOKEN; + const accessTokenFilter = { + credentialType, + clientId, + target: ScopeSet.createSearchScopes(this.scopeSet.asArray()), + tokenType: authScheme, + keyId: request.sshKid, + requestedClaimsHash: request.requestedClaimsHash, + userAssertionHash: this.userAssertionHash + }; + const accessTokens = this.cacheManager.getAccessTokensByFilter(accessTokenFilter, request.correlationId); + const numAccessTokens = accessTokens.length; + if (numAccessTokens < 1) { + return null; + } else if (numAccessTokens > 1) { + throw createClientAuthError(multipleMatchingTokens); + } + return accessTokens[0]; + } + /** + * Make a network call to the server requesting credentials + * @param request - developer provided CommonOnBehalfOfRequest + * @param authority - authority object + */ + async executeTokenRequest(request, authority, userAssertionHash) { + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await this.createTokenRequestBody(request); + const headers = this.createTokenRequestHeaders(); + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: request.authority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + const reqTimestamp = nowSeconds(); + const response = await this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId); + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response.body); + const tokenResponse = await responseHandler.handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, void 0, userAssertionHash); + return tokenResponse; + } + /** + * generate a server request in accepable format + * @param request - developer provided CommonOnBehalfOfRequest + */ + async createTokenRequestBody(request) { + const parameterBuilder = new RequestParameterBuilder(); + parameterBuilder.addClientId(this.config.authOptions.clientId); + parameterBuilder.addScopes(request.scopes); + parameterBuilder.addGrantType(GrantType.JWT_BEARER); + parameterBuilder.addClientInfo(); + parameterBuilder.addLibraryInfo(this.config.libraryInfo); + parameterBuilder.addApplicationTelemetry(this.config.telemetry.application); + parameterBuilder.addThrottling(); + if (this.serverTelemetryManager) { + parameterBuilder.addServerTelemetry(this.serverTelemetryManager); + } + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + parameterBuilder.addCorrelationId(correlationId); + parameterBuilder.addRequestTokenUse(ON_BEHALF_OF); + parameterBuilder.addOboAssertion(request.oboAssertion); + if (this.config.clientCredentials.clientSecret) { + parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret); + } + const clientAssertion = this.config.clientCredentials.clientAssertion; + if (clientAssertion) { + parameterBuilder.addClientAssertion(await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + parameterBuilder.addClientAssertionType(clientAssertion.assertionType); + } + if (request.claims || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities); + } + return parameterBuilder.createQueryString(); + } + }; + var ConfidentialClientApplication = class extends ClientApplication { + /** + * Constructor for the ConfidentialClientApplication + * + * Required attributes in the Configuration object are: + * - clientID: the application ID of your application. You can obtain one by registering your application with our application registration portal + * - authority: the authority URL for your application. + * - client credential: Must set either client secret, certificate, or assertion for confidential clients. You can obtain a client secret from the application registration portal. + * + * In Azure AD, authority is a URL indicating of the form https://login.microsoftonline.com/\{Enter_the_Tenant_Info_Here\}. + * If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com). + * If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations. + * If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common. + * To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers. + * + * In Azure B2C, authority is of the form https://\{instance\}/tfp/\{tenant\}/\{policyName\}/ + * Full B2C functionality will be available in this library in future versions. + * + * @param Configuration - configuration object for the MSAL ConfidentialClientApplication instance + */ + constructor(configuration) { + super(configuration); + this.setClientCredential(); + this.appTokenProvider = void 0; + } + /** + * This extensibility point only works for the client_credential flow, i.e. acquireTokenByClientCredential and + * is meant for Azure SDK to enhance Managed Identity support. + * + * @param IAppTokenProvider - Extensibility interface, which allows the app developer to return a token from a custom source. + */ + SetAppTokenProvider(provider) { + this.appTokenProvider = provider; + } + /** + * Acquires tokens from the authority for the application (not for an end user). + */ + async acquireTokenByClientCredential(request) { + this.logger.info("acquireTokenByClientCredential called", request.correlationId); + let clientAssertion; + if (request.clientAssertion) { + clientAssertion = { + assertion: await getClientAssertion( + request.clientAssertion, + this.config.auth.clientId + // tokenEndpoint will be undefined. resourceRequestUri is omitted in ClientCredentialRequest + ), + assertionType: Constants.JWT_BEARER_ASSERTION_TYPE + }; + } + const baseRequest = await this.initializeBaseRequest(request); + const validBaseRequest = { + ...baseRequest, + scopes: baseRequest.scopes.filter((scope) => !OIDC_DEFAULT_SCOPES.includes(scope)) + }; + const validRequest = { + ...request, + ...validBaseRequest, + clientAssertion + }; + const authority = new UrlString(validRequest.authority); + const tenantId = authority.getUrlComponents().PathSegments[0]; + if (Object.values(AADAuthorityConstants).includes(tenantId)) { + throw createClientAuthError(missingTenantIdError); + } + const ENV_MSAL_FORCE_REGION = process.env[MSAL_FORCE_REGION]; + let region; + if (validRequest.azureRegion !== "DisableMsalForceRegion") { + if (!validRequest.azureRegion && ENV_MSAL_FORCE_REGION) { + region = ENV_MSAL_FORCE_REGION; + } else { + region = validRequest.azureRegion; + } + } + const azureRegionConfiguration = { + azureRegion: region, + environmentRegion: process.env[REGION_ENVIRONMENT_VARIABLE] + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByClientCredential, validRequest.correlationId, validRequest.skipCache); + try { + const clientCredentialConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, "", serverTelemetryManager, azureRegionConfiguration, request.azureCloudOptions); + const clientCredentialClient = new ClientCredentialClient(clientCredentialConfig, this.appTokenProvider); + this.logger.verbose("Client credential client created", validRequest.correlationId); + return await clientCredentialClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires tokens from the authority for the application. + * + * Used in scenarios where the current app is a middle-tier service which was called with a token + * representing an end user. The current app can use the token (oboAssertion) to request another + * token to access downstream web API, on behalf of that user. + * + * The current middle-tier app has no user interaction to obtain consent. + * See how to gain consent upfront for your middle-tier app from this article. + * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow#gaining-consent-for-the-middle-tier-application + */ + async acquireTokenOnBehalfOf(request) { + this.logger.info("acquireTokenOnBehalfOf called", request.correlationId); + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request) + }; + try { + const onBehalfOfConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, "", void 0, void 0, request.azureCloudOptions); + const oboClient = new OnBehalfOfClient(onBehalfOfConfig); + this.logger.verbose("On behalf of client created", validRequest.correlationId); + return await oboClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + throw e; + } + } + setClientCredential() { + const clientSecretNotEmpty = !!this.config.auth.clientSecret; + const clientAssertionNotEmpty = !!this.config.auth.clientAssertion; + const certificateNotEmpty = (!!this.config.auth.clientCertificate?.thumbprint || !!this.config.auth.clientCertificate?.thumbprintSha256) && !!this.config.auth.clientCertificate?.privateKey; + if (this.appTokenProvider) { + return; + } + if (clientSecretNotEmpty && clientAssertionNotEmpty || clientAssertionNotEmpty && certificateNotEmpty || clientSecretNotEmpty && certificateNotEmpty) { + throw createClientAuthError(invalidClientCredential); + } + if (this.config.auth.clientSecret) { + this.clientSecret = this.config.auth.clientSecret; + return; + } + if (this.config.auth.clientAssertion) { + this.developerProvidedClientAssertion = this.config.auth.clientAssertion; + return; + } + if (!certificateNotEmpty) { + throw createClientAuthError(invalidClientCredential); + } else { + this.clientAssertion = !!this.config.auth.clientCertificate.thumbprintSha256 ? ClientAssertion.fromCertificateWithSha256Thumbprint(this.config.auth.clientCertificate.thumbprintSha256, this.config.auth.clientCertificate.privateKey, this.config.auth.clientCertificate.x5c) : ClientAssertion.fromCertificate( + // guaranteed to be a string, due to prior error checking in this function + this.config.auth.clientCertificate.thumbprint, + this.config.auth.clientCertificate.privateKey, + this.config.auth.clientCertificate.x5c + ); + } + } + }; + var ManagedIdentityUserAssignedIdQueryParameterNames = { + MANAGED_IDENTITY_CLIENT_ID: "client_id", + MANAGED_IDENTITY_OBJECT_ID: "object_id", + MANAGED_IDENTITY_RESOURCE_ID: "mi_res_id" + }; + var BaseManagedIdentitySource = class { + constructor(logger, nodeStorage, networkClient, cryptoProvider) { + this.logger = logger; + this.nodeStorage = nodeStorage; + this.networkClient = networkClient; + this.cryptoProvider = cryptoProvider; + } + async getServerTokenResponseAsync(response, _networkClient, _networkRequest, _networkRequestOptions) { + return this.getServerTokenResponse(response); + } + getServerTokenResponse(response) { + let refreshIn, expiresIn; + if (response.body.expires_on) { + expiresIn = response.body.expires_on - nowSeconds(); + if (expiresIn > 2 * 3600) { + refreshIn = expiresIn / 2; + } + } + const serverTokenResponse = { + status: response.status, + // success + access_token: response.body.access_token, + expires_in: expiresIn, + scope: response.body.resource, + token_type: response.body.token_type, + refresh_in: refreshIn, + // error + correlation_id: response.body.correlation_id || response.body.correlationId, + error: typeof response.body.error === "string" ? response.body.error : response.body.error?.code, + error_description: response.body.message || (typeof response.body.error === "string" ? response.body.error_description : response.body.error?.message), + error_codes: response.body.error_codes, + timestamp: response.body.timestamp, + trace_id: response.body.trace_id + }; + return serverTokenResponse; + } + async acquireTokenWithManagedIdentity(managedIdentityRequest, managedIdentityId, fakeAuthority, refreshAccessToken) { + const networkRequest = this.createRequest(managedIdentityRequest.resource, managedIdentityId); + const headers = networkRequest.headers; + headers[HeaderNames.CONTENT_TYPE] = Constants$1.URL_FORM_CONTENT_TYPE; + const networkRequestOptions = { headers }; + if (Object.keys(networkRequest.bodyParameters).length) { + networkRequestOptions.body = networkRequest.computeParametersBodyString(); + } + const reqTimestamp = nowSeconds(); + let response; + try { + if (networkRequest.httpMethod === HttpMethod.POST) { + response = await this.networkClient.sendPostRequestAsync(networkRequest.computeUri(), networkRequestOptions); + } else { + response = await this.networkClient.sendGetRequestAsync(networkRequest.computeUri(), networkRequestOptions); + } + } catch (error) { + if (error instanceof AuthError) { + throw error; + } else { + throw createClientAuthError(networkError); + } + } + const responseHandler = new ResponseHandler(managedIdentityId.id, this.nodeStorage, this.cryptoProvider, this.logger, null, null); + const serverTokenResponse = await this.getServerTokenResponseAsync(response, this.networkClient, networkRequest, networkRequestOptions); + responseHandler.validateTokenResponse(serverTokenResponse, refreshAccessToken); + return responseHandler.handleServerTokenResponse(serverTokenResponse, fakeAuthority, reqTimestamp, managedIdentityRequest); + } + getManagedIdentityUserAssignedIdQueryParameterKey(managedIdentityIdType) { + switch (managedIdentityIdType) { + case ManagedIdentityIdType.USER_ASSIGNED_CLIENT_ID: + this.logger.info("[Managed Identity] Adding user assigned client id to the request."); + return ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_CLIENT_ID; + case ManagedIdentityIdType.USER_ASSIGNED_RESOURCE_ID: + this.logger.info("[Managed Identity] Adding user assigned resource id to the request."); + return ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_RESOURCE_ID; + case ManagedIdentityIdType.USER_ASSIGNED_OBJECT_ID: + this.logger.info("[Managed Identity] Adding user assigned object id to the request."); + return ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_OBJECT_ID; + default: + throw createManagedIdentityError(invalidManagedIdentityIdType); + } + } + }; + BaseManagedIdentitySource.getValidatedEnvVariableUrlString = (envVariableStringName, envVariable, sourceName, logger) => { + try { + return new UrlString(envVariable).urlString; + } catch (error) { + logger.info(`[Managed Identity] ${sourceName} managed identity is unavailable because the '${envVariableStringName}' environment variable is malformed.`); + throw createManagedIdentityError(MsiEnvironmentVariableUrlMalformedErrorCodes[envVariableStringName]); + } + }; + var ManagedIdentityRequestParameters = class { + constructor(httpMethod, endpoint) { + this.httpMethod = httpMethod; + this._baseEndpoint = endpoint; + this.headers = {}; + this.bodyParameters = {}; + this.queryParameters = {}; + } + computeUri() { + const parameterBuilder = new RequestParameterBuilder(); + if (this.queryParameters) { + parameterBuilder.addExtraQueryParameters(this.queryParameters); + } + const queryParametersString = parameterBuilder.createQueryString(); + return UrlString.appendQueryString(this._baseEndpoint, queryParametersString); + } + computeParametersBodyString() { + const parameterBuilder = new RequestParameterBuilder(); + if (this.bodyParameters) { + parameterBuilder.addExtraQueryParameters(this.bodyParameters); + } + return parameterBuilder.createQueryString(); + } + }; + var APP_SERVICE_MSI_API_VERSION = "2019-08-01"; + var AppService = class _AppService extends BaseManagedIdentitySource { + constructor(logger, nodeStorage, networkClient, cryptoProvider, identityEndpoint, identityHeader) { + super(logger, nodeStorage, networkClient, cryptoProvider); + this.identityEndpoint = identityEndpoint; + this.identityHeader = identityHeader; + } + static getEnvironmentVariables() { + const identityEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT]; + const identityHeader = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_HEADER]; + return [identityEndpoint, identityHeader]; + } + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider) { + const [identityEndpoint, identityHeader] = _AppService.getEnvironmentVariables(); + if (!identityEndpoint || !identityHeader) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.APP_SERVICE} managed identity is unavailable because one or both of the '${ManagedIdentityEnvironmentVariableNames.IDENTITY_HEADER}' and '${ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT}' environment variables are not defined.`); + return null; + } + const validatedIdentityEndpoint = _AppService.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT, identityEndpoint, ManagedIdentitySourceNames.APP_SERVICE, logger); + logger.info(`[Managed Identity] Environment variables validation passed for ${ManagedIdentitySourceNames.APP_SERVICE} managed identity. Endpoint URI: ${validatedIdentityEndpoint}. Creating ${ManagedIdentitySourceNames.APP_SERVICE} managed identity.`); + return new _AppService(logger, nodeStorage, networkClient, cryptoProvider, identityEndpoint, identityHeader); + } + createRequest(resource, managedIdentityId) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.identityEndpoint); + request.headers[APP_SERVICE_SECRET_HEADER_NAME] = this.identityHeader; + request.queryParameters[API_VERSION_QUERY_PARAMETER_NAME] = APP_SERVICE_MSI_API_VERSION; + request.queryParameters[RESOURCE_BODY_OR_QUERY_PARAMETER_NAME] = resource; + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + request.queryParameters[this.getManagedIdentityUserAssignedIdQueryParameterKey(managedIdentityId.idType)] = managedIdentityId.id; + } + return request; + } + }; + var ARC_API_VERSION = "2019-11-01"; + var DEFAULT_AZURE_ARC_IDENTITY_ENDPOINT = "http://127.0.0.1:40342/metadata/identity/oauth2/token"; + var HIMDS_EXECUTABLE_HELPER_STRING = "N/A: himds executable exists"; + var SUPPORTED_AZURE_ARC_PLATFORMS = { + win32: `${process.env["ProgramData"]}\\AzureConnectedMachineAgent\\Tokens\\`, + linux: "/var/opt/azcmagent/tokens/" + }; + var AZURE_ARC_FILE_DETECTION = { + win32: `${process.env["ProgramFiles"]}\\AzureConnectedMachineAgent\\himds.exe`, + linux: "/opt/azcmagent/bin/himds" + }; + var AzureArc = class _AzureArc extends BaseManagedIdentitySource { + constructor(logger, nodeStorage, networkClient, cryptoProvider, identityEndpoint) { + super(logger, nodeStorage, networkClient, cryptoProvider); + this.identityEndpoint = identityEndpoint; + } + static getEnvironmentVariables() { + let identityEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT]; + let imdsEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT]; + if (!identityEndpoint || !imdsEndpoint) { + const fileDetectionPath = AZURE_ARC_FILE_DETECTION[process.platform]; + try { + fs6.accessSync(fileDetectionPath, fs6.constants.F_OK | fs6.constants.R_OK); + identityEndpoint = DEFAULT_AZURE_ARC_IDENTITY_ENDPOINT; + imdsEndpoint = HIMDS_EXECUTABLE_HELPER_STRING; + } catch (err) { + } + } + return [identityEndpoint, imdsEndpoint]; + } + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, managedIdentityId) { + const [identityEndpoint, imdsEndpoint] = _AzureArc.getEnvironmentVariables(); + if (!identityEndpoint || !imdsEndpoint) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.AZURE_ARC} managed identity is unavailable through environment variables because one or both of '${ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT}' and '${ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT}' are not defined. ${ManagedIdentitySourceNames.AZURE_ARC} managed identity is also unavailable through file detection.`); + return null; + } + if (imdsEndpoint === HIMDS_EXECUTABLE_HELPER_STRING) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.AZURE_ARC} managed identity is available through file detection. Defaulting to known ${ManagedIdentitySourceNames.AZURE_ARC} endpoint: ${DEFAULT_AZURE_ARC_IDENTITY_ENDPOINT}. Creating ${ManagedIdentitySourceNames.AZURE_ARC} managed identity.`); + } else { + const validatedIdentityEndpoint = _AzureArc.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT, identityEndpoint, ManagedIdentitySourceNames.AZURE_ARC, logger); + validatedIdentityEndpoint.endsWith("/") ? validatedIdentityEndpoint.slice(0, -1) : validatedIdentityEndpoint; + _AzureArc.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT, imdsEndpoint, ManagedIdentitySourceNames.AZURE_ARC, logger); + logger.info(`[Managed Identity] Environment variables validation passed for ${ManagedIdentitySourceNames.AZURE_ARC} managed identity. Endpoint URI: ${validatedIdentityEndpoint}. Creating ${ManagedIdentitySourceNames.AZURE_ARC} managed identity.`); + } + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + throw createManagedIdentityError(unableToCreateAzureArc); + } + return new _AzureArc(logger, nodeStorage, networkClient, cryptoProvider, identityEndpoint); + } + createRequest(resource) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.identityEndpoint.replace("localhost", "127.0.0.1")); + request.headers[METADATA_HEADER_NAME] = "true"; + request.queryParameters[API_VERSION_QUERY_PARAMETER_NAME] = ARC_API_VERSION; + request.queryParameters[RESOURCE_BODY_OR_QUERY_PARAMETER_NAME] = resource; + return request; + } + async getServerTokenResponseAsync(originalResponse, networkClient, networkRequest, networkRequestOptions) { + let retryResponse; + if (originalResponse.status === HttpStatus.UNAUTHORIZED) { + const wwwAuthHeader = originalResponse.headers["www-authenticate"]; + if (!wwwAuthHeader) { + throw createManagedIdentityError(wwwAuthenticateHeaderMissing); + } + if (!wwwAuthHeader.includes("Basic realm=")) { + throw createManagedIdentityError(wwwAuthenticateHeaderUnsupportedFormat); + } + const secretFilePath = wwwAuthHeader.split("Basic realm=")[1]; + if (!SUPPORTED_AZURE_ARC_PLATFORMS.hasOwnProperty(process.platform)) { + throw createManagedIdentityError(platformNotSupported); + } + const expectedSecretFilePath = SUPPORTED_AZURE_ARC_PLATFORMS[process.platform]; + const fileName = path3.basename(secretFilePath); + if (!fileName.endsWith(".key")) { + throw createManagedIdentityError(invalidFileExtension); + } + if (expectedSecretFilePath + fileName !== secretFilePath) { + throw createManagedIdentityError(invalidFilePath); + } + let secretFileSize; + try { + secretFileSize = await fs6.statSync(secretFilePath).size; + } catch (e) { + throw createManagedIdentityError(unableToReadSecretFile); + } + if (secretFileSize > AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES) { + throw createManagedIdentityError(invalidSecret); + } + let secret; + try { + secret = fs6.readFileSync(secretFilePath, "utf-8"); + } catch (e) { + throw createManagedIdentityError(unableToReadSecretFile); + } + const authHeaderValue = `Basic ${secret}`; + this.logger.info(`[Managed Identity] Adding authorization header to the request.`); + networkRequest.headers[AUTHORIZATION_HEADER_NAME] = authHeaderValue; + try { + retryResponse = await networkClient.sendGetRequestAsync(networkRequest.computeUri(), networkRequestOptions); + } catch (error) { + if (error instanceof AuthError) { + throw error; + } else { + throw createClientAuthError(networkError); + } + } + } + return this.getServerTokenResponse(retryResponse || originalResponse); + } + }; + var CloudShell = class _CloudShell extends BaseManagedIdentitySource { + constructor(logger, nodeStorage, networkClient, cryptoProvider, msiEndpoint) { + super(logger, nodeStorage, networkClient, cryptoProvider); + this.msiEndpoint = msiEndpoint; + } + static getEnvironmentVariables() { + const msiEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT]; + return [msiEndpoint]; + } + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, managedIdentityId) { + const [msiEndpoint] = _CloudShell.getEnvironmentVariables(); + if (!msiEndpoint) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.CLOUD_SHELL} managed identity is unavailable because the '${ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT} environment variable is not defined.`); + return null; + } + const validatedMsiEndpoint = _CloudShell.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT, msiEndpoint, ManagedIdentitySourceNames.CLOUD_SHELL, logger); + logger.info(`[Managed Identity] Environment variable validation passed for ${ManagedIdentitySourceNames.CLOUD_SHELL} managed identity. Endpoint URI: ${validatedMsiEndpoint}. Creating ${ManagedIdentitySourceNames.CLOUD_SHELL} managed identity.`); + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + throw createManagedIdentityError(unableToCreateCloudShell); + } + return new _CloudShell(logger, nodeStorage, networkClient, cryptoProvider, msiEndpoint); + } + createRequest(resource) { + const request = new ManagedIdentityRequestParameters(HttpMethod.POST, this.msiEndpoint); + request.headers[METADATA_HEADER_NAME] = "true"; + request.bodyParameters[RESOURCE_BODY_OR_QUERY_PARAMETER_NAME] = resource; + return request; + } + }; + var IMDS_TOKEN_PATH = "/metadata/identity/oauth2/token"; + var DEFAULT_IMDS_ENDPOINT = `http://169.254.169.254${IMDS_TOKEN_PATH}`; + var IMDS_API_VERSION = "2018-02-01"; + var Imds = class _Imds extends BaseManagedIdentitySource { + constructor(logger, nodeStorage, networkClient, cryptoProvider, identityEndpoint) { + super(logger, nodeStorage, networkClient, cryptoProvider); + this.identityEndpoint = identityEndpoint; + } + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider) { + let validatedIdentityEndpoint; + if (process.env[ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST]) { + logger.info(`[Managed Identity] Environment variable ${ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST} for ${ManagedIdentitySourceNames.IMDS} returned endpoint: ${process.env[ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST]}`); + validatedIdentityEndpoint = _Imds.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST, `${process.env[ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST]}${IMDS_TOKEN_PATH}`, ManagedIdentitySourceNames.IMDS, logger); + } else { + logger.info(`[Managed Identity] Unable to find ${ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST} environment variable for ${ManagedIdentitySourceNames.IMDS}, using the default endpoint.`); + validatedIdentityEndpoint = DEFAULT_IMDS_ENDPOINT; + } + return new _Imds(logger, nodeStorage, networkClient, cryptoProvider, validatedIdentityEndpoint); + } + createRequest(resource, managedIdentityId) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.identityEndpoint); + request.headers[METADATA_HEADER_NAME] = "true"; + request.queryParameters[API_VERSION_QUERY_PARAMETER_NAME] = IMDS_API_VERSION; + request.queryParameters[RESOURCE_BODY_OR_QUERY_PARAMETER_NAME] = resource; + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + request.queryParameters[this.getManagedIdentityUserAssignedIdQueryParameterKey(managedIdentityId.idType)] = managedIdentityId.id; + } + return request; + } + }; + var SERVICE_FABRIC_MSI_API_VERSION = "2019-07-01-preview"; + var ServiceFabric = class _ServiceFabric extends BaseManagedIdentitySource { + constructor(logger, nodeStorage, networkClient, cryptoProvider, identityEndpoint, identityHeader) { + super(logger, nodeStorage, networkClient, cryptoProvider); + this.identityEndpoint = identityEndpoint; + this.identityHeader = identityHeader; + } + static getEnvironmentVariables() { + const identityEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT]; + const identityHeader = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_HEADER]; + const identityServerThumbprint = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_SERVER_THUMBPRINT]; + return [identityEndpoint, identityHeader, identityServerThumbprint]; + } + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, managedIdentityId) { + const [identityEndpoint, identityHeader, identityServerThumbprint] = _ServiceFabric.getEnvironmentVariables(); + if (!identityEndpoint || !identityHeader || !identityServerThumbprint) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.SERVICE_FABRIC} managed identity is unavailable because one or all of the '${ManagedIdentityEnvironmentVariableNames.IDENTITY_HEADER}', '${ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT}' or '${ManagedIdentityEnvironmentVariableNames.IDENTITY_SERVER_THUMBPRINT}' environment variables are not defined.`); + return null; + } + const validatedIdentityEndpoint = _ServiceFabric.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT, identityEndpoint, ManagedIdentitySourceNames.SERVICE_FABRIC, logger); + logger.info(`[Managed Identity] Environment variables validation passed for ${ManagedIdentitySourceNames.SERVICE_FABRIC} managed identity. Endpoint URI: ${validatedIdentityEndpoint}. Creating ${ManagedIdentitySourceNames.SERVICE_FABRIC} managed identity.`); + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + logger.warning(`[Managed Identity] ${ManagedIdentitySourceNames.SERVICE_FABRIC} user assigned managed identity is configured in the cluster, not during runtime. See also: https://learn.microsoft.com/en-us/azure/service-fabric/configure-existing-cluster-enable-managed-identity-token-service.`); + } + return new _ServiceFabric(logger, nodeStorage, networkClient, cryptoProvider, identityEndpoint, identityHeader); + } + createRequest(resource, managedIdentityId) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.identityEndpoint); + request.headers[SERVICE_FABRIC_SECRET_HEADER_NAME] = this.identityHeader; + request.queryParameters[API_VERSION_QUERY_PARAMETER_NAME] = SERVICE_FABRIC_MSI_API_VERSION; + request.queryParameters[RESOURCE_BODY_OR_QUERY_PARAMETER_NAME] = resource; + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + request.queryParameters[this.getManagedIdentityUserAssignedIdQueryParameterKey(managedIdentityId.idType)] = managedIdentityId.id; + } + return request; + } + }; + var ManagedIdentityClient = class _ManagedIdentityClient { + constructor(logger, nodeStorage, networkClient, cryptoProvider) { + this.logger = logger; + this.nodeStorage = nodeStorage; + this.networkClient = networkClient; + this.cryptoProvider = cryptoProvider; + } + async sendManagedIdentityTokenRequest(managedIdentityRequest, managedIdentityId, fakeAuthority, refreshAccessToken) { + if (!_ManagedIdentityClient.identitySource) { + _ManagedIdentityClient.identitySource = this.selectManagedIdentitySource(this.logger, this.nodeStorage, this.networkClient, this.cryptoProvider, managedIdentityId); + } + return _ManagedIdentityClient.identitySource.acquireTokenWithManagedIdentity(managedIdentityRequest, managedIdentityId, fakeAuthority, refreshAccessToken); + } + allEnvironmentVariablesAreDefined(environmentVariables) { + return Object.values(environmentVariables).every((environmentVariable) => { + return environmentVariable !== void 0; + }); + } + /** + * Determine the Managed Identity Source based on available environment variables. This API is consumed by ManagedIdentityApplication's getManagedIdentitySource. + * @returns ManagedIdentitySourceNames - The Managed Identity source's name + */ + getManagedIdentitySource() { + _ManagedIdentityClient.sourceName = this.allEnvironmentVariablesAreDefined(ServiceFabric.getEnvironmentVariables()) ? ManagedIdentitySourceNames.SERVICE_FABRIC : this.allEnvironmentVariablesAreDefined(AppService.getEnvironmentVariables()) ? ManagedIdentitySourceNames.APP_SERVICE : this.allEnvironmentVariablesAreDefined(CloudShell.getEnvironmentVariables()) ? ManagedIdentitySourceNames.CLOUD_SHELL : this.allEnvironmentVariablesAreDefined(AzureArc.getEnvironmentVariables()) ? ManagedIdentitySourceNames.AZURE_ARC : ManagedIdentitySourceNames.DEFAULT_TO_IMDS; + return _ManagedIdentityClient.sourceName; + } + /** + * Tries to create a managed identity source for all sources + * @returns the managed identity Source + */ + selectManagedIdentitySource(logger, nodeStorage, networkClient, cryptoProvider, managedIdentityId) { + const source = ServiceFabric.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, managedIdentityId) || AppService.tryCreate(logger, nodeStorage, networkClient, cryptoProvider) || CloudShell.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, managedIdentityId) || AzureArc.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, managedIdentityId) || Imds.tryCreate(logger, nodeStorage, networkClient, cryptoProvider); + if (!source) { + throw createManagedIdentityError(unableToCreateSource); + } + return source; + } + }; + var ManagedIdentityApplication = class _ManagedIdentityApplication { + constructor(configuration) { + this.config = buildManagedIdentityConfiguration(configuration || {}); + this.logger = new Logger(this.config.system.loggerOptions, name, version4); + const fakeStatusAuthorityOptions = { + canonicalAuthority: Constants$1.DEFAULT_AUTHORITY + }; + if (!_ManagedIdentityApplication.nodeStorage) { + _ManagedIdentityApplication.nodeStorage = new NodeStorage(this.logger, this.config.managedIdentityId.id, DEFAULT_CRYPTO_IMPLEMENTATION, fakeStatusAuthorityOptions); + } + this.networkClient = this.config.system.networkClient; + this.cryptoProvider = new CryptoProvider(); + const fakeAuthorityOptions = { + protocolMode: ProtocolMode.AAD, + knownAuthorities: [DEFAULT_AUTHORITY_FOR_MANAGED_IDENTITY], + cloudDiscoveryMetadata: "", + authorityMetadata: "" + }; + this.fakeAuthority = new Authority( + DEFAULT_AUTHORITY_FOR_MANAGED_IDENTITY, + this.networkClient, + _ManagedIdentityApplication.nodeStorage, + fakeAuthorityOptions, + this.logger, + this.cryptoProvider.createNewGuid(), + // correlationID + void 0, + true + ); + this.fakeClientCredentialClient = new ClientCredentialClient({ + authOptions: { + clientId: this.config.managedIdentityId.id, + authority: this.fakeAuthority + } + }); + this.managedIdentityClient = new ManagedIdentityClient(this.logger, _ManagedIdentityApplication.nodeStorage, this.networkClient, this.cryptoProvider); + } + /** + * Acquire an access token from the cache or the managed identity + * @param managedIdentityRequest - the ManagedIdentityRequestParams object passed in by the developer + * @returns the access token + */ + async acquireToken(managedIdentityRequestParams) { + if (!managedIdentityRequestParams.resource) { + throw createClientConfigurationError(urlEmptyError); + } + const managedIdentityRequest = { + forceRefresh: managedIdentityRequestParams.forceRefresh, + resource: managedIdentityRequestParams.resource.replace("/.default", ""), + scopes: [ + managedIdentityRequestParams.resource.replace("/.default", "") + ], + authority: this.fakeAuthority.canonicalAuthority, + correlationId: this.cryptoProvider.createNewGuid() + }; + if (managedIdentityRequestParams.claims || managedIdentityRequest.forceRefresh) { + return this.managedIdentityClient.sendManagedIdentityTokenRequest(managedIdentityRequest, this.config.managedIdentityId, this.fakeAuthority); + } + const [cachedAuthenticationResult, lastCacheOutcome] = await this.fakeClientCredentialClient.getCachedAuthenticationResult(managedIdentityRequest, this.config, this.cryptoProvider, this.fakeAuthority, _ManagedIdentityApplication.nodeStorage); + if (cachedAuthenticationResult) { + if (lastCacheOutcome === CacheOutcome.PROACTIVELY_REFRESHED) { + this.logger.info("ClientCredentialClient:getCachedAuthenticationResult - Cached access token's refreshOn property has been exceeded'. It's not expired, but must be refreshed."); + const refreshAccessToken = true; + await this.managedIdentityClient.sendManagedIdentityTokenRequest(managedIdentityRequest, this.config.managedIdentityId, this.fakeAuthority, refreshAccessToken); + } + return cachedAuthenticationResult; + } else { + return this.managedIdentityClient.sendManagedIdentityTokenRequest(managedIdentityRequest, this.config.managedIdentityId, this.fakeAuthority); + } + } + /** + * Determine the Managed Identity Source based on available environment variables. This API is consumed by Azure Identity SDK. + * @returns ManagedIdentitySourceNames - The Managed Identity source's name + */ + getManagedIdentitySource() { + return ManagedIdentityClient.sourceName || this.managedIdentityClient.getManagedIdentitySource(); + } + }; + var DistributedCachePlugin = class { + constructor(client, partitionManager) { + this.client = client; + this.partitionManager = partitionManager; + } + /** + * Deserializes the cache before accessing it + * @param cacheContext - TokenCacheContext + */ + async beforeCacheAccess(cacheContext) { + const partitionKey = await this.partitionManager.getKey(); + const cacheData = await this.client.get(partitionKey); + cacheContext.tokenCache.deserialize(cacheData); + } + /** + * Serializes the cache after accessing it + * @param cacheContext - TokenCacheContext + */ + async afterCacheAccess(cacheContext) { + if (cacheContext.cacheHasChanged) { + const kvStore = cacheContext.tokenCache.getKVStore(); + const accountEntities = Object.values(kvStore).filter((value) => AccountEntity.isAccountEntity(value)); + let partitionKey; + if (accountEntities.length > 0) { + const accountEntity = accountEntities[0]; + partitionKey = await this.partitionManager.extractKey(accountEntity); + } else { + partitionKey = await this.partitionManager.getKey(); + } + await this.client.set(partitionKey, cacheContext.tokenCache.serialize()); + } + } + }; + exports2.AuthError = AuthError; + exports2.AuthErrorCodes = AuthErrorCodes; + exports2.AuthErrorMessage = AuthErrorMessage; + exports2.AzureCloudInstance = AzureCloudInstance; + exports2.ClientApplication = ClientApplication; + exports2.ClientAssertion = ClientAssertion; + exports2.ClientAuthError = ClientAuthError; + exports2.ClientAuthErrorCodes = ClientAuthErrorCodes; + exports2.ClientAuthErrorMessage = ClientAuthErrorMessage; + exports2.ClientConfigurationError = ClientConfigurationError; + exports2.ClientConfigurationErrorCodes = ClientConfigurationErrorCodes; + exports2.ClientConfigurationErrorMessage = ClientConfigurationErrorMessage; + exports2.ClientCredentialClient = ClientCredentialClient; + exports2.ConfidentialClientApplication = ConfidentialClientApplication; + exports2.CryptoProvider = CryptoProvider; + exports2.DeviceCodeClient = DeviceCodeClient; + exports2.DistributedCachePlugin = DistributedCachePlugin; + exports2.InteractionRequiredAuthError = InteractionRequiredAuthError; + exports2.InteractionRequiredAuthErrorCodes = InteractionRequiredAuthErrorCodes; + exports2.InteractionRequiredAuthErrorMessage = InteractionRequiredAuthErrorMessage; + exports2.Logger = Logger; + exports2.ManagedIdentityApplication = ManagedIdentityApplication; + exports2.ManagedIdentitySourceNames = ManagedIdentitySourceNames; + exports2.NodeStorage = NodeStorage; + exports2.OnBehalfOfClient = OnBehalfOfClient; + exports2.PromptValue = PromptValue; + exports2.ProtocolMode = ProtocolMode; + exports2.PublicClientApplication = PublicClientApplication; + exports2.ResponseMode = ResponseMode; + exports2.ServerError = ServerError; + exports2.TokenCache = TokenCache; + exports2.TokenCacheContext = TokenCacheContext; + exports2.UsernamePasswordClient = UsernamePasswordClient; + exports2.internals = internals; + exports2.version = version4; + } +}); + +// node_modules/botframework-connector/lib/auth/msalAppCredentials.js +var require_msalAppCredentials = __commonJS({ + "node_modules/botframework-connector/lib/auth/msalAppCredentials.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MsalAppCredentials = void 0; + var msal_node_1 = require_msal_node(); + var appCredentials_1 = require_appCredentials(); + var MsalAppCredentials = class extends appCredentials_1.AppCredentials { + /** + * @internal + */ + constructor(maybeClientApplicationOrAppId, maybeAppIdOrAppPasswordOrCertificate, maybeAuthority, maybeScope) { + const appId = typeof maybeClientApplicationOrAppId === "string" ? maybeClientApplicationOrAppId : typeof maybeAppIdOrAppPasswordOrCertificate === "string" ? maybeAppIdOrAppPasswordOrCertificate : void 0; + super(appId, void 0, maybeScope); + if (typeof maybeClientApplicationOrAppId !== "string") { + this.clientApplication = maybeClientApplicationOrAppId; + } else { + const auth = { + authority: maybeAuthority, + clientId: appId + }; + auth.clientCertificate = typeof maybeAppIdOrAppPasswordOrCertificate !== "string" ? maybeAppIdOrAppPasswordOrCertificate : void 0; + auth.clientSecret = typeof maybeAppIdOrAppPasswordOrCertificate === "string" ? maybeAppIdOrAppPasswordOrCertificate : ""; + this.clientApplication = new msal_node_1.ConfidentialClientApplication({ auth }); + } + } + /** + * @inheritdoc + */ + refreshToken() { + return __awaiter2(this, void 0, void 0, function* () { + if (!this.clientApplication) { + throw new Error("getToken should not be called for empty credentials."); + } + const scopePostfix = "/.default"; + let scope = this.oAuthScope; + if (!scope.endsWith(scopePostfix)) { + scope = `${scope}${scopePostfix}`; + } + const token = yield this.clientApplication.acquireTokenByClientCredential({ + scopes: [scope], + skipCache: true + }); + const { accessToken } = token !== null && token !== void 0 ? token : {}; + if (typeof accessToken !== "string") { + throw new Error("Authentication: No access token received from MSAL."); + } + return { + accessToken: token.accessToken, + expiresOn: token.expiresOn + }; + }); + } + }; + exports2.MsalAppCredentials = MsalAppCredentials; + MsalAppCredentials.Empty = new MsalAppCredentials(); + } +}); + +// node_modules/botframework-connector/lib/auth/certificateAppCredentials.js +var require_certificateAppCredentials = __commonJS({ + "node_modules/botframework-connector/lib/auth/certificateAppCredentials.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CertificateAppCredentials = void 0; + var msal_node_1 = require_msal_node(); + var appCredentials_1 = require_appCredentials(); + var msalAppCredentials_1 = require_msalAppCredentials(); + var CertificateAppCredentials = class extends appCredentials_1.AppCredentials { + /** + * Initializes a new instance of the [CertificateAppCredentials](xref:botframework-connector.CertificateAppCredentials) class. + * + * @param appId Microsoft application Id related to the certificate. + * @param certificateThumbprint A hex encoded thumbprint of the certificate. + * @param certificatePrivateKey A PEM encoded certificate private key. + * @param channelAuthTenant Tenant ID of the Azure AD tenant where the bot is created. + * - Required for SingleTenant app types. + * - Optional for MultiTenant app types. **Note**: '_botframework.com_' is the default tenant when no value is provided. + * + * More information: https://learn.microsoft.com/en-us/security/zero-trust/develop/identity-supported-account-types. + * @param oAuthScope Optional. The scope for the token. + * @param x5c Optional. Enables application developers to achieve easy certificates roll-over in Azure AD: + * set this parameter to send the public certificate (BEGIN CERTIFICATE) to Azure AD, so that Azure AD can use it to validate the subject name based on a trusted issuer policy. + */ + constructor(appId, certificateThumbprint, certificatePrivateKey, channelAuthTenant, oAuthScope, x5c) { + super(appId, channelAuthTenant, oAuthScope); + this.certificateThumbprint = certificateThumbprint; + this.certificatePrivateKey = certificatePrivateKey; + this.x5c = x5c; + } + /** + * @inheritdoc + */ + getToken(forceRefresh = false) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + (_a = this.credentials) !== null && _a !== void 0 ? _a : this.credentials = new msalAppCredentials_1.MsalAppCredentials(this.createClientApplication(), this.appId, this.oAuthEndpoint, this.oAuthScope); + return this.credentials.getToken(forceRefresh); + }); + } + /** + * @inheritdoc + */ + refreshToken() { + throw new Error("Method not implemented."); + } + createClientApplication() { + return new msal_node_1.ConfidentialClientApplication({ + auth: { + clientId: this.appId, + authority: this.oAuthEndpoint, + clientCertificate: { + thumbprint: this.certificateThumbprint, + privateKey: this.certificatePrivateKey, + x5c: this.x5c + } + } + }); + } + }; + exports2.CertificateAppCredentials = CertificateAppCredentials; + } +}); + +// node_modules/botframework-connector/lib/auth/serviceClientCredentialsFactory.js +var require_serviceClientCredentialsFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/serviceClientCredentialsFactory.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ServiceClientCredentialsFactory = void 0; + var ServiceClientCredentialsFactory = class { + }; + exports2.ServiceClientCredentialsFactory = ServiceClientCredentialsFactory; + } +}); + +// node_modules/openssl-wrapper/lib/index.js +var require_lib8 = __commonJS({ + "node_modules/openssl-wrapper/lib/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { + value: true + }); + exports2.exec = void 0; + exports2.default = exec; + var _child_process = require("child_process"); + var isFunction = function isFunction2(maybeFunction) { + return typeof maybeFunction === "function"; + }; + var expectedStderrForAction = { + "cms.verify": /^verification successful/i, + "genrsa": /^generating/i, + "pkcs12": /^mac verified ok/i, + "req.new": /^generating/i, + "req.verify": /^verify ok/i, + "rsa": /^writing rsa key/i, + "smime.verify": /^verification successful/i, + "x509.req": /^signature ok/i + }; + function exec(action, maybeBuffer, maybeOptions, maybeCallback) { + var buffer = maybeBuffer; + var options = maybeOptions; + var callback = maybeCallback; + if (!Buffer.isBuffer(buffer)) { + callback = options; + options = buffer; + buffer = false; + } + if (isFunction(options)) { + callback = options; + options = {}; + } + var params = action.split(".").map(function(value, key) { + return !key ? value : "-" + value; + }); + var lastParams = []; + Object.keys(options).forEach(function(key) { + if (options[key] === false) { + lastParams.push(key); + } else if (options[key] === true) { + params.push("-" + key); + } else { + if (Array.isArray(options[key])) { + options[key].forEach(function(value) { + params.push("-" + key, value); + }); + } else { + params.push("-" + key, options[key]); + } + } + }); + params = params.concat(lastParams); + var openssl = (0, _child_process.spawn)("openssl", params); + var outResult = []; + var outLength = 0; + var errResult = []; + var errLength = 0; + openssl.stdout.on("data", function(data) { + outLength += data.length; + outResult.push(data); + }); + openssl.stderr.on("data", function(data) { + errLength += data.length; + errResult.push(data); + }); + openssl.on("close", function(code) { + var stdout = Buffer.concat(outResult, outLength); + var stderr = Buffer.concat(errResult, errLength).toString("utf8"); + var expectedStderr = expectedStderrForAction[action]; + var err = null; + if (code || stderr && expectedStderr && !stderr.match(expectedStderr)) { + err = new Error(stderr); + err.code = code; + } + if (isFunction(callback)) { + callback.apply(null, [err, stdout]); + } + }); + if (buffer) { + openssl.stdin.write(buffer); + } + openssl.stdin.end(); + return openssl; + } + exports2.exec = exec; + } +}); + +// node_modules/botframework-connector/lib/auth/certificateServiceClientCredentialsFactory.js +var require_certificateServiceClientCredentialsFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/certificateServiceClientCredentialsFactory.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CertificateServiceClientCredentialsFactory = void 0; + var serviceClientCredentialsFactory_1 = require_serviceClientCredentialsFactory(); + var assert_1 = require("assert"); + var certificateAppCredentials_1 = require_certificateAppCredentials(); + var util_1 = require("util"); + var opensslWrapper = __importStar2(require_lib8()); + var openssl = (0, util_1.promisify)(opensslWrapper.default); + var CertificateServiceClientCredentialsFactory = class extends serviceClientCredentialsFactory_1.ServiceClientCredentialsFactory { + /** + * @internal + */ + constructor(appId, certificateThumbprintOrx5c, certificatePrivateKey, tenantId, x5c) { + super(); + (0, assert_1.ok)(appId === null || appId === void 0 ? void 0 : appId.trim(), "CertificateServiceClientCredentialsFactory.constructor(): missing appId."); + (0, assert_1.ok)(certificatePrivateKey === null || certificatePrivateKey === void 0 ? void 0 : certificatePrivateKey.trim(), "CertificateServiceClientCredentialsFactory.constructor(): missing certificatePrivateKey."); + if (certificateThumbprintOrx5c === null || certificateThumbprintOrx5c === void 0 ? void 0 : certificateThumbprintOrx5c.includes("-----BEGIN CERTIFICATE-----")) { + this.x5c = certificateThumbprintOrx5c; + } else { + (0, assert_1.ok)(certificateThumbprintOrx5c === null || certificateThumbprintOrx5c === void 0 ? void 0 : certificateThumbprintOrx5c.trim(), "CertificateServiceClientCredentialsFactory.constructor(): missing certificateThumbprint or x5c value."); + this.certificateThumbprint = certificateThumbprintOrx5c; + this.x5c = x5c; + } + this.appId = appId; + this.certificatePrivateKey = certificatePrivateKey; + this.tenantId = tenantId; + } + /** + * @inheritdoc + */ + isValidAppId(appId) { + return __awaiter2(this, void 0, void 0, function* () { + return appId === this.appId; + }); + } + /** + * @param cert Value with the certificate content. + * @returns The thumbprint value calculated from the cert content. + */ + getThumbprint(cert) { + return __awaiter2(this, void 0, void 0, function* () { + const fingerprintResponse = yield openssl("x509", Buffer.from(cert), { fingerprint: true, noout: true }); + return Buffer.from(fingerprintResponse).toString().replace(/^.*Fingerprint=/, "").replace(/:/g, "").trim(); + }); + } + /** + * @inheritdoc + */ + isAuthenticationDisabled() { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * @inheritdoc + */ + createCredentials(appId, audience) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + (0, assert_1.ok)(yield this.isValidAppId(appId), "CertificateServiceClientCredentialsFactory.createCredentials(): Invalid Managed ID."); + return new certificateAppCredentials_1.CertificateAppCredentials(this.appId, (_a = this.certificateThumbprint) !== null && _a !== void 0 ? _a : yield this.getThumbprint(this.x5c), this.certificatePrivateKey, this.tenantId, audience, this.x5c); + }); + } + }; + exports2.CertificateServiceClientCredentialsFactory = CertificateServiceClientCredentialsFactory; + } +}); + +// node_modules/botframework-connector/lib/auth/federatedAppCredentials.js +var require_federatedAppCredentials = __commonJS({ + "node_modules/botframework-connector/lib/auth/federatedAppCredentials.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.FederatedAppCredentials = void 0; + var msal_node_1 = require_msal_node(); + var assert_1 = require("assert"); + var appCredentials_1 = require_appCredentials(); + var msalAppCredentials_1 = require_msalAppCredentials(); + var FederatedAppCredentials = class extends appCredentials_1.AppCredentials { + /** + * Initializes a new instance of the [FederatedAppCredentials](xref:botframework-connector.FederatedAppCredentials) class. + * + * @param {string} appId App ID for the Application. + * @param {string} clientId Client ID for the managed identity assigned to the bot. + * @param {string} channelAuthTenant Tenant ID of the Azure AD tenant where the bot is created. + * - **Required** for SingleTenant app types. + * - **Optional** for MultiTenant app types. **Note**: '_botframework.com_' is the default tenant when no value is provided. + * + * More information: https://learn.microsoft.com/en-us/security/zero-trust/develop/identity-supported-account-types. + * @param {string} oAuthScope **Optional**. The scope for the token. + * @param {string} clientAudience **Optional**. The Audience used in the Client's Federated Credential. **Default** (_api://AzureADTokenExchange_). + */ + constructor(appId, clientId, channelAuthTenant, oAuthScope, clientAudience) { + super(appId, channelAuthTenant, oAuthScope); + (0, assert_1.ok)(appId === null || appId === void 0 ? void 0 : appId.trim(), "FederatedAppCredentials.constructor(): missing appId."); + this.clientAudience = clientAudience !== null && clientAudience !== void 0 ? clientAudience : "api://AzureADTokenExchange"; + this.managedIdentityClientAssertion = new msal_node_1.ManagedIdentityApplication({ + managedIdentityIdParams: { userAssignedClientId: clientId } + }); + } + /** + * @inheritdoc + */ + getToken(forceRefresh = false) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + (_a = this.credentials) !== null && _a !== void 0 ? _a : this.credentials = new msalAppCredentials_1.MsalAppCredentials(this.createClientApplication(yield this.fetchExternalToken(forceRefresh)), this.oAuthEndpoint, this.oAuthEndpoint, this.oAuthScope); + return this.credentials.getToken(forceRefresh); + }); + } + /** + * @inheritdoc + */ + refreshToken() { + throw new Error("Method not implemented."); + } + createClientApplication(clientAssertion) { + return new msal_node_1.ConfidentialClientApplication({ + auth: { + clientId: this.appId, + authority: this.oAuthEndpoint, + clientAssertion + } + }); + } + fetchExternalToken(forceRefresh = false) { + return __awaiter2(this, void 0, void 0, function* () { + const response = yield this.managedIdentityClientAssertion.acquireToken({ + resource: this.clientAudience, + forceRefresh + }); + return response.accessToken; + }); + } + }; + exports2.FederatedAppCredentials = FederatedAppCredentials; + } +}); + +// node_modules/botframework-connector/lib/auth/federatedServiceClientCredentialsFactory.js +var require_federatedServiceClientCredentialsFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/federatedServiceClientCredentialsFactory.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.FederatedServiceClientCredentialsFactory = void 0; + var assert_1 = require("assert"); + var serviceClientCredentialsFactory_1 = require_serviceClientCredentialsFactory(); + var federatedAppCredentials_1 = require_federatedAppCredentials(); + var FederatedServiceClientCredentialsFactory = class extends serviceClientCredentialsFactory_1.ServiceClientCredentialsFactory { + /** + * Initializes a new instance of the [FederatedServiceClientCredentialsFactory](xref:botframework-connector.FederatedServiceClientCredentialsFactory) class. + * + * @param {string} appId App ID for the Application. + * @param {string} clientId Client ID for the managed identity assigned to the bot. + * @param {string} tenantId Tenant ID of the Azure AD tenant where the bot is created. + * - **Required** for SingleTenant app types. + * - **Optional** for MultiTenant app types. **Note**: '_botframework.com_' is the default tenant when no value is provided. + * + * More information: https://learn.microsoft.com/en-us/security/zero-trust/develop/identity-supported-account-types. + * @param {string} clientAudience **Optional**. The Audience used in the Client's Federated Credential. **Default** (_api://AzureADTokenExchange_). + */ + constructor(appId, clientId, tenantId, clientAudience) { + super(); + this.appId = appId; + this.clientId = clientId; + this.tenantId = tenantId; + this.clientAudience = clientAudience; + (0, assert_1.ok)(appId === null || appId === void 0 ? void 0 : appId.trim(), "FederatedServiceClientCredentialsFactory.constructor(): missing appId."); + (0, assert_1.ok)(clientId === null || clientId === void 0 ? void 0 : clientId.trim(), "FederatedServiceClientCredentialsFactory.constructor(): missing clientId."); + } + /** + * @inheritdoc + */ + isValidAppId(appId = "") { + return __awaiter2(this, void 0, void 0, function* () { + return appId === this.appId; + }); + } + /** + * @inheritdoc + */ + isAuthenticationDisabled() { + return __awaiter2(this, void 0, void 0, function* () { + return; + }); + } + /** + * @inheritdoc + */ + createCredentials(appId, audience) { + return __awaiter2(this, void 0, void 0, function* () { + (0, assert_1.ok)(yield this.isValidAppId(appId), "FederatedServiceClientCredentialsFactory.createCredentials(): Invalid App ID."); + return new federatedAppCredentials_1.FederatedAppCredentials(this.appId, this.clientId, this.tenantId, audience, this.clientAudience); + }); + } + }; + exports2.FederatedServiceClientCredentialsFactory = FederatedServiceClientCredentialsFactory; + } +}); + +// node_modules/@azure/identity/dist/commonjs/constants.js +var require_constants4 = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/constants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DEFAULT_TOKEN_CACHE_NAME = exports2.CACHE_NON_CAE_SUFFIX = exports2.CACHE_CAE_SUFFIX = exports2.ALL_TENANTS = exports2.DefaultAuthority = exports2.DefaultAuthorityHost = exports2.AzureAuthorityHosts = exports2.DefaultTenantId = exports2.DeveloperSignOnClientId = exports2.SDK_VERSION = void 0; + exports2.SDK_VERSION = `4.13.1`; + exports2.DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46"; + exports2.DefaultTenantId = "common"; + var AzureAuthorityHosts; + (function(AzureAuthorityHosts2) { + AzureAuthorityHosts2["AzureChina"] = "https://login.chinacloudapi.cn"; + AzureAuthorityHosts2["AzureGermany"] = "https://login.microsoftonline.de"; + AzureAuthorityHosts2["AzureGovernment"] = "https://login.microsoftonline.us"; + AzureAuthorityHosts2["AzurePublicCloud"] = "https://login.microsoftonline.com"; + })(AzureAuthorityHosts || (exports2.AzureAuthorityHosts = AzureAuthorityHosts = {})); + exports2.DefaultAuthorityHost = AzureAuthorityHosts.AzurePublicCloud; + exports2.DefaultAuthority = "login.microsoftonline.com"; + exports2.ALL_TENANTS = ["*"]; + exports2.CACHE_CAE_SUFFIX = "cae"; + exports2.CACHE_NON_CAE_SUFFIX = "nocae"; + exports2.DEFAULT_TOKEN_CACHE_NAME = "msal.cache"; + } +}); + +// node_modules/@azure/identity/dist/commonjs/msal/nodeFlows/msalPlugins.js +var require_msalPlugins = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/msal/nodeFlows/msalPlugins.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.msalPlugins = exports2.msalNodeFlowVSCodeCredentialControl = exports2.msalNodeFlowNativeBrokerControl = exports2.vsCodeBrokerInfo = exports2.vsCodeAuthRecordPath = exports2.nativeBrokerInfo = exports2.msalNodeFlowCacheControl = exports2.persistenceProvider = void 0; + exports2.hasNativeBroker = hasNativeBroker; + exports2.hasVSCodePlugin = hasVSCodePlugin; + var constants_js_1 = require_constants4(); + exports2.persistenceProvider = void 0; + exports2.msalNodeFlowCacheControl = { + setPersistence(pluginProvider) { + exports2.persistenceProvider = pluginProvider; + } + }; + exports2.nativeBrokerInfo = void 0; + exports2.vsCodeAuthRecordPath = void 0; + exports2.vsCodeBrokerInfo = void 0; + function hasNativeBroker() { + return exports2.nativeBrokerInfo !== void 0; + } + function hasVSCodePlugin() { + return exports2.vsCodeAuthRecordPath !== void 0 && exports2.vsCodeBrokerInfo !== void 0; + } + exports2.msalNodeFlowNativeBrokerControl = { + setNativeBroker(broker) { + exports2.nativeBrokerInfo = { + broker + }; + } + }; + exports2.msalNodeFlowVSCodeCredentialControl = { + setVSCodeAuthRecordPath(path3) { + exports2.vsCodeAuthRecordPath = path3; + }, + setVSCodeBroker(broker) { + exports2.vsCodeBrokerInfo = { + broker + }; + } + }; + function generatePluginConfiguration(options) { + const config = { + cache: {}, + broker: { + ...options.brokerOptions, + isEnabled: options.brokerOptions?.enabled ?? false, + enableMsaPassthrough: options.brokerOptions?.legacyEnableMsaPassthrough ?? false + } + }; + if (options.tokenCachePersistenceOptions?.enabled) { + if (exports2.persistenceProvider === void 0) { + throw new Error([ + "Persistent token caching was requested, but no persistence provider was configured.", + "You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)", + "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling", + "`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`." + ].join(" ")); + } + const cacheBaseName = options.tokenCachePersistenceOptions.name || constants_js_1.DEFAULT_TOKEN_CACHE_NAME; + config.cache.cachePlugin = (0, exports2.persistenceProvider)({ + name: `${cacheBaseName}.${constants_js_1.CACHE_NON_CAE_SUFFIX}`, + ...options.tokenCachePersistenceOptions + }); + config.cache.cachePluginCae = (0, exports2.persistenceProvider)({ + name: `${cacheBaseName}.${constants_js_1.CACHE_CAE_SUFFIX}`, + ...options.tokenCachePersistenceOptions + }); + } + if (options.brokerOptions?.enabled) { + config.broker.nativeBrokerPlugin = getBrokerPlugin(options.isVSCodeCredential || false); + } + return config; + } + var brokerErrorTemplates = { + missing: (credentialName, packageName, pluginVar) => [ + `${credentialName} was requested, but no plugin was configured or no authentication record was found.`, + `You must install the ${packageName} plugin package (npm install --save ${packageName})`, + "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling", + `useIdentityPlugin(${pluginVar}) before using enableBroker.` + ].join(" "), + unavailable: (credentialName, packageName) => [ + `${credentialName} was requested, and the plugin is configured, but the broker is unavailable.`, + `Ensure the ${credentialName} plugin is properly installed and configured.`, + "Check for missing native dependencies and ensure the package is properly installed.", + `See the README for prerequisites on installing and using ${packageName}.` + ].join(" ") + }; + var brokerConfig = { + vsCode: { + credentialName: "Visual Studio Code Credential", + packageName: "@azure/identity-vscode", + pluginVar: "vsCodePlugin", + get brokerInfo() { + return exports2.vsCodeBrokerInfo; + } + }, + native: { + credentialName: "Broker for WAM", + packageName: "@azure/identity-broker", + pluginVar: "nativeBrokerPlugin", + get brokerInfo() { + return exports2.nativeBrokerInfo; + } + } + }; + function getBrokerPlugin(isVSCodePlugin) { + const { credentialName, packageName, pluginVar, brokerInfo } = brokerConfig[isVSCodePlugin ? "vsCode" : "native"]; + if (brokerInfo === void 0) { + throw new Error(brokerErrorTemplates.missing(credentialName, packageName, pluginVar)); + } + if (brokerInfo.broker.isBrokerAvailable === false) { + throw new Error(brokerErrorTemplates.unavailable(credentialName, packageName)); + } + return brokerInfo.broker; + } + exports2.msalPlugins = { + generatePluginConfiguration + }; + } +}); + +// node_modules/@azure/identity/dist/commonjs/plugins/consumer.js +var require_consumer = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/plugins/consumer.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.useIdentityPlugin = useIdentityPlugin; + var msalPlugins_js_1 = require_msalPlugins(); + var pluginContext = { + cachePluginControl: msalPlugins_js_1.msalNodeFlowCacheControl, + nativeBrokerPluginControl: msalPlugins_js_1.msalNodeFlowNativeBrokerControl, + vsCodeCredentialControl: msalPlugins_js_1.msalNodeFlowVSCodeCredentialControl + }; + function useIdentityPlugin(plugin) { + plugin(pluginContext); + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/errors.js +var require_errors2 = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/errors.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AuthenticationRequiredError = exports2.AggregateAuthenticationError = exports2.AggregateAuthenticationErrorName = exports2.AuthenticationError = exports2.AuthenticationErrorName = exports2.CredentialUnavailableError = exports2.CredentialUnavailableErrorName = void 0; + function isErrorResponse(errorResponse) { + return errorResponse && typeof errorResponse.error === "string" && typeof errorResponse.error_description === "string"; + } + exports2.CredentialUnavailableErrorName = "CredentialUnavailableError"; + var CredentialUnavailableError = class extends Error { + constructor(message, options) { + super(message, options); + this.name = exports2.CredentialUnavailableErrorName; + } + }; + exports2.CredentialUnavailableError = CredentialUnavailableError; + exports2.AuthenticationErrorName = "AuthenticationError"; + var AuthenticationError = class extends Error { + /** + * The HTTP status code returned from the authentication request. + */ + statusCode; + /** + * The error response details. + */ + errorResponse; + constructor(statusCode, errorBody, options) { + let errorResponse = { + error: "unknown", + errorDescription: "An unknown error occurred and no additional details are available." + }; + if (isErrorResponse(errorBody)) { + errorResponse = convertOAuthErrorResponseToErrorResponse(errorBody); + } else if (typeof errorBody === "string") { + try { + const oauthErrorResponse = JSON.parse(errorBody); + errorResponse = convertOAuthErrorResponseToErrorResponse(oauthErrorResponse); + } catch (e) { + if (statusCode === 400) { + errorResponse = { + error: "invalid_request", + errorDescription: `The service indicated that the request was invalid. + +${errorBody}` + }; + } else { + errorResponse = { + error: "unknown_error", + errorDescription: `An unknown error has occurred. Response body: + +${errorBody}` + }; + } + } + } else { + errorResponse = { + error: "unknown_error", + errorDescription: "An unknown error occurred and no additional details are available." + }; + } + super(`${errorResponse.error} Status code: ${statusCode} +More details: +${errorResponse.errorDescription},`, options); + this.statusCode = statusCode; + this.errorResponse = errorResponse; + this.name = exports2.AuthenticationErrorName; + } + }; + exports2.AuthenticationError = AuthenticationError; + exports2.AggregateAuthenticationErrorName = "AggregateAuthenticationError"; + var AggregateAuthenticationError = class extends Error { + /** + * The array of error objects that were thrown while trying to authenticate + * with the credentials in a {@link ChainedTokenCredential}. + */ + errors; + constructor(errors, errorMessage) { + const errorDetail = errors.join("\n"); + super(`${errorMessage} +${errorDetail}`); + this.errors = errors; + this.name = exports2.AggregateAuthenticationErrorName; + } + }; + exports2.AggregateAuthenticationError = AggregateAuthenticationError; + function convertOAuthErrorResponseToErrorResponse(errorBody) { + return { + error: errorBody.error, + errorDescription: errorBody.error_description, + correlationId: errorBody.correlation_id, + errorCodes: errorBody.error_codes, + timestamp: errorBody.timestamp, + traceId: errorBody.trace_id + }; + } + var AuthenticationRequiredError = class extends Error { + /** + * The list of scopes for which the token will have access. + */ + scopes; + /** + * The options passed to the getToken request. + */ + getTokenOptions; + constructor(options) { + super(options.message, options.cause ? { cause: options.cause } : void 0); + this.scopes = options.scopes; + this.getTokenOptions = options.getTokenOptions; + this.name = "AuthenticationRequiredError"; + } + }; + exports2.AuthenticationRequiredError = AuthenticationRequiredError; + } +}); + +// node_modules/@azure/identity/dist/commonjs/util/logging.js +var require_logging = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/util/logging.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.logger = void 0; + exports2.processEnvVars = processEnvVars; + exports2.logEnvVars = logEnvVars; + exports2.formatSuccess = formatSuccess; + exports2.formatError = formatError; + exports2.credentialLoggerInstance = credentialLoggerInstance; + exports2.credentialLogger = credentialLogger; + var logger_1 = require_commonjs2(); + exports2.logger = (0, logger_1.createClientLogger)("identity"); + function processEnvVars(supportedEnvVars) { + return supportedEnvVars.reduce((acc, envVariable) => { + if (process.env[envVariable]) { + acc.assigned.push(envVariable); + } else { + acc.missing.push(envVariable); + } + return acc; + }, { missing: [], assigned: [] }); + } + function logEnvVars(credentialName, supportedEnvVars) { + const { assigned } = processEnvVars(supportedEnvVars); + exports2.logger.info(`${credentialName} => Found the following environment variables: ${assigned.join(", ")}`); + } + function formatSuccess(scope) { + return `SUCCESS. Scopes: ${Array.isArray(scope) ? scope.join(", ") : scope}.`; + } + function formatError(scope, error) { + let message = "ERROR."; + if (scope?.length) { + message += ` Scopes: ${Array.isArray(scope) ? scope.join(", ") : scope}.`; + } + return `${message} Error message: ${typeof error === "string" ? error : error.message}.`; + } + function credentialLoggerInstance(title, parent, log = exports2.logger) { + const fullTitle = parent ? `${parent.fullTitle} ${title}` : title; + function info(message) { + log.info(`${fullTitle} =>`, message); + } + function warning(message) { + log.warning(`${fullTitle} =>`, message); + } + function verbose(message) { + log.verbose(`${fullTitle} =>`, message); + } + function error(message) { + log.error(`${fullTitle} =>`, message); + } + return { + title, + fullTitle, + info, + warning, + verbose, + error + }; + } + function credentialLogger(title, log = exports2.logger) { + const credLogger = credentialLoggerInstance(title, void 0, log); + return { + ...credLogger, + parent: log, + getToken: credentialLoggerInstance("=> getToken()", credLogger, log) + }; + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/util/tracing.js +var require_tracing = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/util/tracing.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.tracingClient = void 0; + var constants_js_1 = require_constants4(); + var core_tracing_1 = require_commonjs5(); + exports2.tracingClient = (0, core_tracing_1.createTracingClient)({ + namespace: "Microsoft.AAD", + packageName: "@azure/identity", + packageVersion: constants_js_1.SDK_VERSION + }); + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/chainedTokenCredential.js +var require_chainedTokenCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/chainedTokenCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ChainedTokenCredential = exports2.logger = void 0; + var errors_js_1 = require_errors2(); + var logging_js_1 = require_logging(); + var tracing_js_1 = require_tracing(); + exports2.logger = (0, logging_js_1.credentialLogger)("ChainedTokenCredential"); + var ChainedTokenCredential = class { + _sources = []; + /** + * Creates an instance of ChainedTokenCredential using the given credentials. + * + * @param sources - `TokenCredential` implementations to be tried in order. + * + * Example usage: + * ```ts snippet:chained_token_credential_example + * import { ClientSecretCredential, ChainedTokenCredential } from "@azure/identity"; + * + * const tenantId = ""; + * const clientId = ""; + * const clientSecret = ""; + * const anotherClientId = ""; + * const anotherSecret = ""; + * + * const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret); + * const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret); + * + * const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential); + * ``` + */ + constructor(...sources) { + this._sources = sources; + } + /** + * Returns the first access token returned by one of the chained + * `TokenCredential` implementations. Throws an {@link AggregateAuthenticationError} + * when one or more credentials throws an {@link AuthenticationError} and + * no credentials have returned an access token. + * + * This method is called automatically by Azure SDK client libraries. You may call this method + * directly, but you must also handle token caching and token refreshing. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * `TokenCredential` implementation might make. + */ + async getToken(scopes, options = {}) { + const { token } = await this.getTokenInternal(scopes, options); + return token; + } + async getTokenInternal(scopes, options = {}) { + let token = null; + let successfulCredential; + const errors = []; + return tracing_js_1.tracingClient.withSpan("ChainedTokenCredential.getToken", options, async (updatedOptions) => { + for (let i = 0; i < this._sources.length && token === null; i++) { + try { + token = await this._sources[i].getToken(scopes, updatedOptions); + successfulCredential = this._sources[i]; + } catch (err) { + if (err.name === "CredentialUnavailableError" || err.name === "AuthenticationRequiredError") { + errors.push(err); + } else { + exports2.logger.getToken.info((0, logging_js_1.formatError)(scopes, err)); + throw err; + } + } + } + if (!token && errors.length > 0) { + const err = new errors_js_1.AggregateAuthenticationError(errors, "ChainedTokenCredential authentication failed."); + exports2.logger.getToken.info((0, logging_js_1.formatError)(scopes, err)); + throw err; + } + exports2.logger.getToken.info(`Result for ${successfulCredential.constructor.name}: ${(0, logging_js_1.formatSuccess)(scopes)}`); + if (token === null) { + throw new errors_js_1.CredentialUnavailableError("Failed to retrieve a valid token"); + } + return { token, successfulCredential }; + }); + } + }; + exports2.ChainedTokenCredential = ChainedTokenCredential; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/rng.js +function rng3() { + if (poolPtr3 > rnds8Pool3.length - 16) { + import_crypto4.default.randomFillSync(rnds8Pool3); + poolPtr3 = 0; + } + return rnds8Pool3.slice(poolPtr3, poolPtr3 += 16); +} +var import_crypto4, rnds8Pool3, poolPtr3; +var init_rng3 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/rng.js"() { + import_crypto4 = __toESM(require("crypto")); + rnds8Pool3 = new Uint8Array(256); + poolPtr3 = rnds8Pool3.length; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/regex.js +var regex_default3; +var init_regex3 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/regex.js"() { + regex_default3 = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/validate.js +function validate3(uuid) { + return typeof uuid === "string" && regex_default3.test(uuid); +} +var validate_default3; +var init_validate3 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/validate.js"() { + init_regex3(); + validate_default3 = validate3; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/stringify.js +function stringify3(arr, offset = 0) { + const uuid = (byteToHex3[arr[offset + 0]] + byteToHex3[arr[offset + 1]] + byteToHex3[arr[offset + 2]] + byteToHex3[arr[offset + 3]] + "-" + byteToHex3[arr[offset + 4]] + byteToHex3[arr[offset + 5]] + "-" + byteToHex3[arr[offset + 6]] + byteToHex3[arr[offset + 7]] + "-" + byteToHex3[arr[offset + 8]] + byteToHex3[arr[offset + 9]] + "-" + byteToHex3[arr[offset + 10]] + byteToHex3[arr[offset + 11]] + byteToHex3[arr[offset + 12]] + byteToHex3[arr[offset + 13]] + byteToHex3[arr[offset + 14]] + byteToHex3[arr[offset + 15]]).toLowerCase(); + if (!validate_default3(uuid)) { + throw TypeError("Stringified UUID is invalid"); + } + return uuid; +} +var byteToHex3, stringify_default3; +var init_stringify3 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/stringify.js"() { + init_validate3(); + byteToHex3 = []; + for (let i = 0; i < 256; ++i) { + byteToHex3.push((i + 256).toString(16).substr(1)); + } + stringify_default3 = stringify3; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v1.js +function v13(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId3; + let clockseq = options.clockseq !== void 0 ? options.clockseq : _clockseq3; + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || rng3)(); + if (node == null) { + node = _nodeId3 = [seedBytes[0] | 1, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + if (clockseq == null) { + clockseq = _clockseq3 = (seedBytes[6] << 8 | seedBytes[7]) & 16383; + } + } + let msecs = options.msecs !== void 0 ? options.msecs : Date.now(); + let nsecs = options.nsecs !== void 0 ? options.nsecs : _lastNSecs3 + 1; + const dt = msecs - _lastMSecs3 + (nsecs - _lastNSecs3) / 1e4; + if (dt < 0 && options.clockseq === void 0) { + clockseq = clockseq + 1 & 16383; + } + if ((dt < 0 || msecs > _lastMSecs3) && options.nsecs === void 0) { + nsecs = 0; + } + if (nsecs >= 1e4) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + _lastMSecs3 = msecs; + _lastNSecs3 = nsecs; + _clockseq3 = clockseq; + msecs += 122192928e5; + const tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296; + b[i++] = tl >>> 24 & 255; + b[i++] = tl >>> 16 & 255; + b[i++] = tl >>> 8 & 255; + b[i++] = tl & 255; + const tmh = msecs / 4294967296 * 1e4 & 268435455; + b[i++] = tmh >>> 8 & 255; + b[i++] = tmh & 255; + b[i++] = tmh >>> 24 & 15 | 16; + b[i++] = tmh >>> 16 & 255; + b[i++] = clockseq >>> 8 | 128; + b[i++] = clockseq & 255; + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + return buf || stringify_default3(b); +} +var _nodeId3, _clockseq3, _lastMSecs3, _lastNSecs3, v1_default3; +var init_v13 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v1.js"() { + init_rng3(); + init_stringify3(); + _lastMSecs3 = 0; + _lastNSecs3 = 0; + v1_default3 = v13; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/parse.js +function parse3(uuid) { + if (!validate_default3(uuid)) { + throw TypeError("Invalid UUID"); + } + let v; + const arr = new Uint8Array(16); + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 255; + arr[2] = v >>> 8 & 255; + arr[3] = v & 255; + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 255; + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 255; + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 255; + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255; + arr[11] = v / 4294967296 & 255; + arr[12] = v >>> 24 & 255; + arr[13] = v >>> 16 & 255; + arr[14] = v >>> 8 & 255; + arr[15] = v & 255; + return arr; +} +var parse_default3; +var init_parse3 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/parse.js"() { + init_validate3(); + parse_default3 = parse3; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v35.js +function stringToBytes3(str) { + str = unescape(encodeURIComponent(str)); + const bytes = []; + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + return bytes; +} +function v35_default2(name, version4, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === "string") { + value = stringToBytes3(value); + } + if (typeof namespace === "string") { + namespace = parse_default3(namespace); + } + if (namespace.length !== 16) { + throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)"); + } + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 15 | version4; + bytes[8] = bytes[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + return buf; + } + return stringify_default3(bytes); + } + try { + generateUUID.name = name; + } catch (err) { + } + generateUUID.DNS = DNS3; + generateUUID.URL = URL4; + return generateUUID; +} +var DNS3, URL4; +var init_v353 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v35.js"() { + init_stringify3(); + init_parse3(); + DNS3 = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; + URL4 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/md5.js +function md53(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return import_crypto5.default.createHash("md5").update(bytes).digest(); +} +var import_crypto5, md5_default3; +var init_md53 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/md5.js"() { + import_crypto5 = __toESM(require("crypto")); + md5_default3 = md53; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v3.js +var v33, v3_default3; +var init_v33 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v3.js"() { + init_v353(); + init_md53(); + v33 = v35_default2("v3", 48, md5_default3); + v3_default3 = v33; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v4.js +function v43(options, buf, offset) { + options = options || {}; + const rnds = options.random || (options.rng || rng3)(); + rnds[6] = rnds[6] & 15 | 64; + rnds[8] = rnds[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + return buf; + } + return stringify_default3(rnds); +} +var v4_default3; +var init_v43 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v4.js"() { + init_rng3(); + init_stringify3(); + v4_default3 = v43; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/sha1.js +function sha13(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return import_crypto6.default.createHash("sha1").update(bytes).digest(); +} +var import_crypto6, sha1_default3; +var init_sha13 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/sha1.js"() { + import_crypto6 = __toESM(require("crypto")); + sha1_default3 = sha13; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v5.js +var v53, v5_default3; +var init_v53 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/v5.js"() { + init_v353(); + init_sha13(); + v53 = v35_default2("v5", 80, sha1_default3); + v5_default3 = v53; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/nil.js +var nil_default3; +var init_nil3 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/nil.js"() { + nil_default3 = "00000000-0000-0000-0000-000000000000"; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/version.js +function version3(uuid) { + if (!validate_default3(uuid)) { + throw TypeError("Invalid UUID"); + } + return parseInt(uuid.substr(14, 1), 16); +} +var version_default3; +var init_version3 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/version.js"() { + init_validate3(); + version_default3 = version3; + } +}); + +// node_modules/@azure/identity/node_modules/uuid/dist/esm-node/index.js +var esm_node_exports3 = {}; +__export(esm_node_exports3, { + NIL: () => nil_default3, + parse: () => parse_default3, + stringify: () => stringify_default3, + v1: () => v1_default3, + v3: () => v3_default3, + v4: () => v4_default3, + v5: () => v5_default3, + validate: () => validate_default3, + version: () => version_default3 +}); +var init_esm_node3 = __esm({ + "node_modules/@azure/identity/node_modules/uuid/dist/esm-node/index.js"() { + init_v13(); + init_v33(); + init_v43(); + init_v53(); + init_nil3(); + init_version3(); + init_validate3(); + init_stringify3(); + init_parse3(); + } +}); + +// node_modules/@azure/identity/node_modules/@azure/msal-node/lib/msal-node.cjs +var require_msal_node2 = __commonJS({ + "node_modules/@azure/identity/node_modules/@azure/msal-node/lib/msal-node.cjs"(exports2) { + "use strict"; + var uuid = (init_esm_node3(), __toCommonJS(esm_node_exports3)); + var crypto12 = require("crypto"); + var jwt = require_jsonwebtoken(); + var http = require("http"); + var fs6 = require("fs"); + var path3 = require("path"); + var Serializer = class { + /** + * serialize the JSON blob + * @param data - JSON blob cache + */ + static serializeJSONBlob(data) { + return JSON.stringify(data); + } + /** + * Serialize Accounts + * @param accCache - cache of accounts + */ + static serializeAccounts(accCache) { + const accounts = {}; + Object.keys(accCache).map(function(key) { + const accountEntity = accCache[key]; + accounts[key] = { + home_account_id: accountEntity.homeAccountId, + environment: accountEntity.environment, + realm: accountEntity.realm, + local_account_id: accountEntity.localAccountId, + username: accountEntity.username, + authority_type: accountEntity.authorityType, + name: accountEntity.name, + client_info: accountEntity.clientInfo, + last_modification_time: accountEntity.lastModificationTime, + last_modification_app: accountEntity.lastModificationApp, + tenantProfiles: accountEntity.tenantProfiles?.map((tenantProfile) => { + return JSON.stringify(tenantProfile); + }) + }; + }); + return accounts; + } + /** + * Serialize IdTokens + * @param idTCache - cache of ID tokens + */ + static serializeIdTokens(idTCache) { + const idTokens = {}; + Object.keys(idTCache).map(function(key) { + const idTEntity = idTCache[key]; + idTokens[key] = { + home_account_id: idTEntity.homeAccountId, + environment: idTEntity.environment, + credential_type: idTEntity.credentialType, + client_id: idTEntity.clientId, + secret: idTEntity.secret, + realm: idTEntity.realm + }; + }); + return idTokens; + } + /** + * Serializes AccessTokens + * @param atCache - cache of access tokens + */ + static serializeAccessTokens(atCache) { + const accessTokens = {}; + Object.keys(atCache).map(function(key) { + const atEntity = atCache[key]; + accessTokens[key] = { + home_account_id: atEntity.homeAccountId, + environment: atEntity.environment, + credential_type: atEntity.credentialType, + client_id: atEntity.clientId, + secret: atEntity.secret, + realm: atEntity.realm, + target: atEntity.target, + cached_at: atEntity.cachedAt, + expires_on: atEntity.expiresOn, + extended_expires_on: atEntity.extendedExpiresOn, + refresh_on: atEntity.refreshOn, + key_id: atEntity.keyId, + token_type: atEntity.tokenType, + userAssertionHash: atEntity.userAssertionHash, + resource: atEntity.resource + }; + }); + return accessTokens; + } + /** + * Serialize refreshTokens + * @param rtCache - cache of refresh tokens + */ + static serializeRefreshTokens(rtCache) { + const refreshTokens = {}; + Object.keys(rtCache).map(function(key) { + const rtEntity = rtCache[key]; + refreshTokens[key] = { + home_account_id: rtEntity.homeAccountId, + environment: rtEntity.environment, + credential_type: rtEntity.credentialType, + client_id: rtEntity.clientId, + secret: rtEntity.secret, + family_id: rtEntity.familyId, + target: rtEntity.target, + realm: rtEntity.realm + }; + }); + return refreshTokens; + } + /** + * Serialize amdtCache + * @param amdtCache - cache of app metadata + */ + static serializeAppMetadata(amdtCache) { + const appMetadata = {}; + Object.keys(amdtCache).map(function(key) { + const amdtEntity = amdtCache[key]; + appMetadata[key] = { + client_id: amdtEntity.clientId, + environment: amdtEntity.environment, + family_id: amdtEntity.familyId + }; + }); + return appMetadata; + } + /** + * Serialize the cache + * @param inMemCache - itemised cache read from the JSON + */ + static serializeAllCache(inMemCache) { + return { + Account: this.serializeAccounts(inMemCache.accounts), + IdToken: this.serializeIdTokens(inMemCache.idTokens), + AccessToken: this.serializeAccessTokens(inMemCache.accessTokens), + RefreshToken: this.serializeRefreshTokens(inMemCache.refreshTokens), + AppMetadata: this.serializeAppMetadata(inMemCache.appMetadata) + }; + } + }; + var SKU = "msal.js.common"; + var DEFAULT_AUTHORITY = "https://login.microsoftonline.com/common/"; + var DEFAULT_AUTHORITY_HOST = "login.microsoftonline.com"; + var DEFAULT_COMMON_TENANT = "common"; + var ADFS = "adfs"; + var DSTS = "dstsv2"; + var AAD_INSTANCE_DISCOVERY_ENDPT = `${DEFAULT_AUTHORITY}discovery/instance?api-version=1.1&authorization_endpoint=`; + var CIAM_AUTH_URL = ".ciamlogin.com"; + var AAD_TENANT_DOMAIN_SUFFIX = ".onmicrosoft.com"; + var RESOURCE_DELIM = "|"; + var OPENID_SCOPE = "openid"; + var PROFILE_SCOPE = "profile"; + var OFFLINE_ACCESS_SCOPE = "offline_access"; + var EMAIL_SCOPE = "email"; + var URL_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded;charset=utf-8"; + var AUTHORIZATION_PENDING = "authorization_pending"; + var NOT_APPLICABLE = "N/A"; + var NOT_AVAILABLE = "Not Available"; + var FORWARD_SLASH = "/"; + var IMDS_ENDPOINT = "http://169.254.169.254/metadata/instance/compute/location"; + var IMDS_VERSION = "2020-06-01"; + var IMDS_TIMEOUT = 2e3; + var AZURE_REGION_AUTO_DISCOVER_FLAG = "TryAutoDetect"; + var REGIONAL_AUTH_PUBLIC_CLOUD_SUFFIX = "login.microsoft.com"; + var KNOWN_PUBLIC_CLOUDS = [ + "login.microsoftonline.com", + "login.windows.net", + "login.microsoft.com", + "sts.windows.net" + ]; + var INVALID_INSTANCE = "invalid_instance"; + var HTTP_SUCCESS = 200; + var HTTP_REDIRECT = 302; + var HTTP_CLIENT_ERROR_RANGE_START = 400; + var HTTP_BAD_REQUEST = 400; + var HTTP_UNAUTHORIZED = 401; + var HTTP_NOT_FOUND = 404; + var HTTP_REQUEST_TIMEOUT = 408; + var HTTP_GONE = 410; + var HTTP_TOO_MANY_REQUESTS = 429; + var HTTP_CLIENT_ERROR_RANGE_END = 499; + var HTTP_SERVER_ERROR = 500; + var HTTP_SERVER_ERROR_RANGE_START = 500; + var HTTP_SERVICE_UNAVAILABLE = 503; + var HTTP_GATEWAY_TIMEOUT = 504; + var HTTP_SERVER_ERROR_RANGE_END = 599; + var OIDC_DEFAULT_SCOPES = [ + OPENID_SCOPE, + PROFILE_SCOPE, + OFFLINE_ACCESS_SCOPE + ]; + var OIDC_SCOPES = [...OIDC_DEFAULT_SCOPES, EMAIL_SCOPE]; + var HeaderNames = { + CONTENT_TYPE: "Content-Type", + CONTENT_LENGTH: "Content-Length", + RETRY_AFTER: "Retry-After", + CCS_HEADER: "X-AnchorMailbox", + WWWAuthenticate: "WWW-Authenticate", + AuthenticationInfo: "Authentication-Info", + X_MS_REQUEST_ID: "x-ms-request-id", + X_MS_HTTP_VERSION: "x-ms-httpver" + }; + var AADAuthority = { + COMMON: "common", + ORGANIZATIONS: "organizations", + CONSUMERS: "consumers" + }; + var ClaimsRequestKeys = { + ACCESS_TOKEN: "access_token", + XMS_CC: "xms_cc" + }; + var PromptValue$1 = { + LOGIN: "login", + SELECT_ACCOUNT: "select_account", + CONSENT: "consent", + NONE: "none", + CREATE: "create", + NO_SESSION: "no_session" + }; + var CodeChallengeMethodValues = { + S256: "S256" + }; + var OAuthResponseType = { + CODE: "code", + IDTOKEN_TOKEN: "id_token token" + }; + var ResponseMode$1 = { + QUERY: "query", + FRAGMENT: "fragment", + FORM_POST: "form_post" + }; + var GrantType = { + AUTHORIZATION_CODE_GRANT: "authorization_code", + CLIENT_CREDENTIALS_GRANT: "client_credentials", + RESOURCE_OWNER_PASSWORD_GRANT: "password", + REFRESH_TOKEN_GRANT: "refresh_token", + DEVICE_CODE_GRANT: "device_code", + JWT_BEARER: "urn:ietf:params:oauth:grant-type:jwt-bearer" + }; + var CACHE_ACCOUNT_TYPE_MSSTS = "MSSTS"; + var CACHE_ACCOUNT_TYPE_ADFS = "ADFS"; + var CACHE_ACCOUNT_TYPE_GENERIC = "Generic"; + var CACHE_KEY_SEPARATOR = "-"; + var CLIENT_INFO_SEPARATOR = "."; + var CredentialType = { + ID_TOKEN: "IdToken", + ACCESS_TOKEN: "AccessToken", + ACCESS_TOKEN_WITH_AUTH_SCHEME: "AccessToken_With_AuthScheme", + REFRESH_TOKEN: "RefreshToken" + }; + var APP_METADATA = "appmetadata"; + var CLIENT_INFO = "client_info"; + var THE_FAMILY_ID = "1"; + var AUTHORITY_METADATA_CACHE_KEY = "authority-metadata"; + var AUTHORITY_METADATA_REFRESH_TIME_SECONDS = 3600 * 24; + var AuthorityMetadataSource = { + CONFIG: "config", + CACHE: "cache", + NETWORK: "network", + HARDCODED_VALUES: "hardcoded_values" + }; + var SERVER_TELEM_SCHEMA_VERSION = 5; + var SERVER_TELEM_MAX_LAST_HEADER_BYTES = 330; + var SERVER_TELEM_MAX_CACHED_ERRORS = 50; + var SERVER_TELEM_CACHE_KEY = "server-telemetry"; + var SERVER_TELEM_CATEGORY_SEPARATOR = "|"; + var SERVER_TELEM_VALUE_SEPARATOR = ","; + var SERVER_TELEM_OVERFLOW_TRUE = "1"; + var SERVER_TELEM_OVERFLOW_FALSE = "0"; + var SERVER_TELEM_UNKNOWN_ERROR = "unknown_error"; + var AuthenticationScheme = { + BEARER: "Bearer", + POP: "pop", + SSH: "ssh-cert" + }; + var DEFAULT_THROTTLE_TIME_SECONDS = 60; + var DEFAULT_MAX_THROTTLE_TIME_SECONDS = 3600; + var THROTTLING_PREFIX = "throttling"; + var X_MS_LIB_CAPABILITY_VALUE = "retry-after, h429"; + var INVALID_GRANT_ERROR = "invalid_grant"; + var CLIENT_MISMATCH_ERROR = "client_mismatch"; + var PasswordGrantConstants = { + username: "username", + password: "password" + }; + var RegionDiscoverySources = { + FAILED_AUTO_DETECTION: "1", + INTERNAL_CACHE: "2", + ENVIRONMENT_VARIABLE: "3", + IMDS: "4" + }; + var RegionDiscoveryOutcomes = { + CONFIGURED_NO_AUTO_DETECTION: "2", + AUTO_DETECTION_REQUESTED_SUCCESSFUL: "4", + AUTO_DETECTION_REQUESTED_FAILED: "5" + }; + var CacheOutcome = { + // When a token is found in the cache or the cache is not supposed to be hit when making the request + NOT_APPLICABLE: "0", + // When the token request goes to the identity provider because force_refresh was set to true. Also occurs if claims were requested + FORCE_REFRESH_OR_CLAIMS: "1", + // When the token request goes to the identity provider because no cached access token exists + NO_CACHED_ACCESS_TOKEN: "2", + // When the token request goes to the identity provider because cached access token expired + CACHED_ACCESS_TOKEN_EXPIRED: "3", + // When the token request goes to the identity provider because refresh_in was used and the existing token needs to be refreshed + PROACTIVELY_REFRESHED: "4" + }; + var DEFAULT_TOKEN_RENEWAL_OFFSET_SEC = 300; + var EncodingTypes = { + BASE64: "base64", + HEX: "hex", + UTF8: "utf-8" + }; + var CLIENT_ID = "client_id"; + var REDIRECT_URI = "redirect_uri"; + var RESPONSE_TYPE = "response_type"; + var RESPONSE_MODE = "response_mode"; + var GRANT_TYPE = "grant_type"; + var CLAIMS = "claims"; + var SCOPE = "scope"; + var REFRESH_TOKEN = "refresh_token"; + var STATE = "state"; + var NONCE = "nonce"; + var PROMPT = "prompt"; + var CODE = "code"; + var CODE_CHALLENGE = "code_challenge"; + var CODE_CHALLENGE_METHOD = "code_challenge_method"; + var CODE_VERIFIER = "code_verifier"; + var CLIENT_REQUEST_ID = "client-request-id"; + var X_CLIENT_SKU = "x-client-SKU"; + var X_CLIENT_VER = "x-client-VER"; + var X_CLIENT_OS = "x-client-OS"; + var X_CLIENT_CPU = "x-client-CPU"; + var X_CLIENT_CURR_TELEM = "x-client-current-telemetry"; + var X_CLIENT_LAST_TELEM = "x-client-last-telemetry"; + var X_MS_LIB_CAPABILITY = "x-ms-lib-capability"; + var X_APP_NAME = "x-app-name"; + var X_APP_VER = "x-app-ver"; + var POST_LOGOUT_URI = "post_logout_redirect_uri"; + var ID_TOKEN_HINT = "id_token_hint"; + var DEVICE_CODE = "device_code"; + var CLIENT_SECRET = "client_secret"; + var CLIENT_ASSERTION = "client_assertion"; + var CLIENT_ASSERTION_TYPE = "client_assertion_type"; + var TOKEN_TYPE = "token_type"; + var REQ_CNF = "req_cnf"; + var OBO_ASSERTION = "assertion"; + var REQUESTED_TOKEN_USE = "requested_token_use"; + var ON_BEHALF_OF = "on_behalf_of"; + var RETURN_SPA_CODE = "return_spa_code"; + var LOGOUT_HINT = "logout_hint"; + var SID = "sid"; + var LOGIN_HINT = "login_hint"; + var DOMAIN_HINT = "domain_hint"; + var X_CLIENT_EXTRA_SKU = "x-client-xtra-sku"; + var BROKER_CLIENT_ID = "brk_client_id"; + var BROKER_REDIRECT_URI = "brk_redirect_uri"; + var INSTANCE_AWARE = "instance_aware"; + var RESOURCE = "resource"; + var CLI_DATA = "clidata"; + function getDefaultErrorMessage(code) { + return `See https://aka.ms/msal.js.errors#${code} for details`; + } + var AuthError = class _AuthError extends Error { + constructor(errorCode, errorMessage, suberror) { + const message = errorMessage || (errorCode ? getDefaultErrorMessage(errorCode) : ""); + const errorString = message ? `${errorCode}: ${message}` : errorCode; + super(errorString); + Object.setPrototypeOf(this, _AuthError.prototype); + this.errorCode = errorCode || ""; + this.errorMessage = message || ""; + this.subError = suberror || ""; + this.name = "AuthError"; + } + setCorrelationId(correlationId) { + this.correlationId = correlationId; + } + }; + function createAuthError(code, additionalMessage) { + return new AuthError(code, additionalMessage || getDefaultErrorMessage(code)); + } + var ClientConfigurationError = class _ClientConfigurationError extends AuthError { + constructor(errorCode) { + super(errorCode); + this.name = "ClientConfigurationError"; + Object.setPrototypeOf(this, _ClientConfigurationError.prototype); + } + }; + function createClientConfigurationError(errorCode) { + return new ClientConfigurationError(errorCode); + } + var StringUtils = class { + /** + * Check if stringified object is empty + * @param strObj + */ + static isEmptyObj(strObj) { + if (strObj) { + try { + const obj = JSON.parse(strObj); + return Object.keys(obj).length === 0; + } catch (e) { + } + } + return true; + } + static startsWith(str, search) { + return str.indexOf(search) === 0; + } + static endsWith(str, search) { + return str.length >= search.length && str.lastIndexOf(search) === str.length - search.length; + } + /** + * Parses string into an object. + * + * @param query + */ + static queryStringToObject(query) { + const obj = {}; + const params = query.split("&"); + const decode = (s) => decodeURIComponent(s.replace(/\+/g, " ")); + params.forEach((pair) => { + if (pair.trim()) { + const [key, value] = pair.split(/=(.+)/g, 2); + if (key && value) { + obj[decode(key)] = decode(value); + } + } + }); + return obj; + } + /** + * Trims entries in an array. + * + * @param arr + */ + static trimArrayEntries(arr) { + return arr.map((entry) => entry.trim()); + } + /** + * Removes empty strings from array + * @param arr + */ + static removeEmptyStringsFromArray(arr) { + return arr.filter((entry) => { + return !!entry; + }); + } + /** + * Attempts to parse a string into JSON + * @param str + */ + static jsonParseHelper(str) { + try { + return JSON.parse(str); + } catch (e) { + return null; + } + } + }; + var ClientAuthError = class _ClientAuthError extends AuthError { + constructor(errorCode, additionalMessage) { + super(errorCode, additionalMessage); + this.name = "ClientAuthError"; + Object.setPrototypeOf(this, _ClientAuthError.prototype); + } + }; + function createClientAuthError(errorCode, additionalMessage) { + return new ClientAuthError(errorCode, additionalMessage); + } + var redirectUriEmpty = "redirect_uri_empty"; + var claimsRequestParsingError = "claims_request_parsing_error"; + var authorityUriInsecure = "authority_uri_insecure"; + var urlParseError = "url_parse_error"; + var urlEmptyError = "empty_url_error"; + var emptyInputScopesError = "empty_input_scopes_error"; + var invalidClaims = "invalid_claims"; + var tokenRequestEmpty = "token_request_empty"; + var logoutRequestEmpty = "logout_request_empty"; + var invalidCodeChallengeMethod = "invalid_code_challenge_method"; + var pkceParamsMissing = "pkce_params_missing"; + var invalidCloudDiscoveryMetadata = "invalid_cloud_discovery_metadata"; + var invalidAuthorityMetadata = "invalid_authority_metadata"; + var untrustedAuthority = "untrusted_authority"; + var missingSshJwk = "missing_ssh_jwk"; + var missingSshKid = "missing_ssh_kid"; + var missingNonceAuthenticationHeader = "missing_nonce_authentication_header"; + var invalidAuthenticationHeader = "invalid_authentication_header"; + var cannotSetOIDCOptions = "cannot_set_OIDCOptions"; + var cannotAllowPlatformBroker = "cannot_allow_platform_broker"; + var authorityMismatch = "authority_mismatch"; + var invalidRequestMethodForEAR = "invalid_request_method_for_EAR"; + var ClientConfigurationErrorCodes = /* @__PURE__ */ Object.freeze({ + __proto__: null, + authorityMismatch, + authorityUriInsecure, + cannotAllowPlatformBroker, + cannotSetOIDCOptions, + claimsRequestParsingError, + emptyInputScopesError, + invalidAuthenticationHeader, + invalidAuthorityMetadata, + invalidClaims, + invalidCloudDiscoveryMetadata, + invalidCodeChallengeMethod, + invalidRequestMethodForEAR, + logoutRequestEmpty, + missingNonceAuthenticationHeader, + missingSshJwk, + missingSshKid, + pkceParamsMissing, + redirectUriEmpty, + tokenRequestEmpty, + untrustedAuthority, + urlEmptyError, + urlParseError + }); + var clientInfoDecodingError = "client_info_decoding_error"; + var clientInfoEmptyError = "client_info_empty_error"; + var tokenParsingError = "token_parsing_error"; + var nullOrEmptyToken = "null_or_empty_token"; + var endpointResolutionError = "endpoints_resolution_error"; + var networkError = "network_error"; + var openIdConfigError = "openid_config_error"; + var hashNotDeserialized = "hash_not_deserialized"; + var invalidState = "invalid_state"; + var stateMismatch = "state_mismatch"; + var stateNotFound = "state_not_found"; + var nonceMismatch = "nonce_mismatch"; + var authTimeNotFound = "auth_time_not_found"; + var maxAgeTranspired = "max_age_transpired"; + var multipleMatchingTokens = "multiple_matching_tokens"; + var multipleMatchingAppMetadata = "multiple_matching_appMetadata"; + var requestCannotBeMade = "request_cannot_be_made"; + var cannotRemoveEmptyScope = "cannot_remove_empty_scope"; + var cannotAppendScopeSet = "cannot_append_scopeset"; + var emptyInputScopeSet = "empty_input_scopeset"; + var noAccountInSilentRequest = "no_account_in_silent_request"; + var invalidCacheRecord = "invalid_cache_record"; + var invalidCacheEnvironment = "invalid_cache_environment"; + var noAccountFound = "no_account_found"; + var noCryptoObject = "no_crypto_object"; + var unexpectedCredentialType = "unexpected_credential_type"; + var tokenRefreshRequired = "token_refresh_required"; + var tokenClaimsCnfRequiredForSignedJwt = "token_claims_cnf_required_for_signedjwt"; + var authorizationCodeMissingFromServerResponse = "authorization_code_missing_from_server_response"; + var bindingKeyNotRemoved = "binding_key_not_removed"; + var endSessionEndpointNotSupported = "end_session_endpoint_not_supported"; + var keyIdMissing = "key_id_missing"; + var noNetworkConnectivity = "no_network_connectivity"; + var userCanceled = "user_canceled"; + var methodNotImplemented = "method_not_implemented"; + var nestedAppAuthBridgeDisabled = "nested_app_auth_bridge_disabled"; + var platformBrokerError = "platform_broker_error"; + var resourceParameterRequired = "resource_parameter_required"; + var misplacedResourceParam = "misplaced_resource_parameter"; + var ClientAuthErrorCodes = /* @__PURE__ */ Object.freeze({ + __proto__: null, + authTimeNotFound, + authorizationCodeMissingFromServerResponse, + bindingKeyNotRemoved, + cannotAppendScopeSet, + cannotRemoveEmptyScope, + clientInfoDecodingError, + clientInfoEmptyError, + emptyInputScopeSet, + endSessionEndpointNotSupported, + endpointResolutionError, + hashNotDeserialized, + invalidCacheEnvironment, + invalidCacheRecord, + invalidState, + keyIdMissing, + maxAgeTranspired, + methodNotImplemented, + misplacedResourceParam, + multipleMatchingAppMetadata, + multipleMatchingTokens, + nestedAppAuthBridgeDisabled, + networkError, + noAccountFound, + noAccountInSilentRequest, + noCryptoObject, + noNetworkConnectivity, + nonceMismatch, + nullOrEmptyToken, + openIdConfigError, + platformBrokerError, + requestCannotBeMade, + resourceParameterRequired, + stateMismatch, + stateNotFound, + tokenClaimsCnfRequiredForSignedJwt, + tokenParsingError, + tokenRefreshRequired, + unexpectedCredentialType, + userCanceled + }); + var ScopeSet = class _ScopeSet { + constructor(inputScopes) { + const scopeArr = inputScopes ? StringUtils.trimArrayEntries([...inputScopes]) : []; + const filteredInput = scopeArr ? StringUtils.removeEmptyStringsFromArray(scopeArr) : []; + if (!filteredInput || !filteredInput.length) { + throw createClientConfigurationError(emptyInputScopesError); + } + this.scopes = /* @__PURE__ */ new Set(); + filteredInput.forEach((scope) => this.scopes.add(scope)); + } + /** + * Factory method to create ScopeSet from space-delimited string + * @param inputScopeString + * @param appClientId + * @param scopesRequired + */ + static fromString(inputScopeString) { + const scopeString = inputScopeString || ""; + const inputScopes = scopeString.split(" "); + return new _ScopeSet(inputScopes); + } + /** + * Creates the set of scopes to search for in cache lookups + * @param inputScopeString + * @returns + */ + static createSearchScopes(inputScopeString) { + const scopesToUse = inputScopeString && inputScopeString.length > 0 ? inputScopeString : [...OIDC_DEFAULT_SCOPES]; + const scopeSet = new _ScopeSet(scopesToUse); + if (!scopeSet.containsOnlyOIDCScopes()) { + scopeSet.removeOIDCScopes(); + } else { + scopeSet.removeScope(OFFLINE_ACCESS_SCOPE); + } + return scopeSet; + } + /** + * Check if a given scope is present in this set of scopes. + * @param scope + */ + containsScope(scope) { + const lowerCaseScopes = this.printScopesLowerCase().split(" "); + const lowerCaseScopesSet = new _ScopeSet(lowerCaseScopes); + return scope ? lowerCaseScopesSet.scopes.has(scope.toLowerCase()) : false; + } + /** + * Check if a set of scopes is present in this set of scopes. + * @param scopeSet + */ + containsScopeSet(scopeSet) { + if (!scopeSet || scopeSet.scopes.size <= 0) { + return false; + } + return this.scopes.size >= scopeSet.scopes.size && scopeSet.asArray().every((scope) => this.containsScope(scope)); + } + /** + * Check if set of scopes contains only the defaults + */ + containsOnlyOIDCScopes() { + let defaultScopeCount = 0; + OIDC_SCOPES.forEach((defaultScope) => { + if (this.containsScope(defaultScope)) { + defaultScopeCount += 1; + } + }); + return this.scopes.size === defaultScopeCount; + } + /** + * Appends single scope if passed + * @param newScope + */ + appendScope(newScope) { + if (newScope) { + this.scopes.add(newScope.trim()); + } + } + /** + * Appends multiple scopes if passed + * @param newScopes + */ + appendScopes(newScopes) { + try { + newScopes.forEach((newScope) => this.appendScope(newScope)); + } catch (e) { + throw createClientAuthError(cannotAppendScopeSet); + } + } + /** + * Removes element from set of scopes. + * @param scope + */ + removeScope(scope) { + if (!scope) { + throw createClientAuthError(cannotRemoveEmptyScope); + } + this.scopes.delete(scope.trim()); + } + /** + * Removes default scopes from set of scopes + * Primarily used to prevent cache misses if the default scopes are not returned from the server + */ + removeOIDCScopes() { + OIDC_SCOPES.forEach((defaultScope) => { + this.scopes.delete(defaultScope); + }); + } + /** + * Combines an array of scopes with the current set of scopes. + * @param otherScopes + */ + unionScopeSets(otherScopes) { + if (!otherScopes) { + throw createClientAuthError(emptyInputScopeSet); + } + const unionScopes = /* @__PURE__ */ new Set(); + otherScopes.scopes.forEach((scope) => unionScopes.add(scope.toLowerCase())); + this.scopes.forEach((scope) => unionScopes.add(scope.toLowerCase())); + return unionScopes; + } + /** + * Check if scopes intersect between this set and another. + * @param otherScopes + */ + intersectingScopeSets(otherScopes) { + if (!otherScopes) { + throw createClientAuthError(emptyInputScopeSet); + } + if (!otherScopes.containsOnlyOIDCScopes()) { + otherScopes.removeOIDCScopes(); + } + const unionScopes = this.unionScopeSets(otherScopes); + const sizeOtherScopes = otherScopes.getScopeCount(); + const sizeThisScopes = this.getScopeCount(); + const sizeUnionScopes = unionScopes.size; + return sizeUnionScopes < sizeThisScopes + sizeOtherScopes; + } + /** + * Returns size of set of scopes. + */ + getScopeCount() { + return this.scopes.size; + } + /** + * Returns the scopes as an array of string values + */ + asArray() { + const array = []; + this.scopes.forEach((val) => array.push(val)); + return array; + } + /** + * Prints scopes into a space-delimited string + */ + printScopes() { + if (this.scopes) { + const scopeArr = this.asArray(); + return scopeArr.join(" "); + } + return ""; + } + /** + * Prints scopes into a space-delimited lower-case string (used for caching) + */ + printScopesLowerCase() { + return this.printScopes().toLowerCase(); + } + }; + function instrumentBrokerParams(parameters, correlationId, performanceClient) { + if (!correlationId) { + return; + } + const clientId = parameters.get(CLIENT_ID); + if (clientId && parameters.has(BROKER_CLIENT_ID)) { + performanceClient?.addFields({ + embeddedClientId: clientId, + embeddedRedirectUri: parameters.get(REDIRECT_URI) + }, correlationId); + } + } + function addResponseType(parameters, responseType) { + parameters.set(RESPONSE_TYPE, responseType); + } + function addResponseMode(parameters, responseMode) { + parameters.set(RESPONSE_MODE, responseMode ? responseMode : ResponseMode$1.QUERY); + } + function addScopes(parameters, scopes, addOidcScopes = true, defaultScopes = OIDC_DEFAULT_SCOPES) { + if (addOidcScopes && !defaultScopes.includes("openid") && !scopes.includes("openid")) { + defaultScopes.push("openid"); + } + const requestScopes = addOidcScopes ? [...scopes || [], ...defaultScopes] : scopes || []; + const scopeSet = new ScopeSet(requestScopes); + parameters.set(SCOPE, scopeSet.printScopes()); + } + function addClientId(parameters, clientId) { + parameters.set(CLIENT_ID, clientId); + } + function addRedirectUri(parameters, redirectUri) { + parameters.set(REDIRECT_URI, redirectUri); + } + function addPostLogoutRedirectUri(parameters, redirectUri) { + parameters.set(POST_LOGOUT_URI, redirectUri); + } + function addIdTokenHint(parameters, idTokenHint) { + parameters.set(ID_TOKEN_HINT, idTokenHint); + } + function addDomainHint(parameters, domainHint) { + parameters.set(DOMAIN_HINT, domainHint); + } + function addLoginHint(parameters, loginHint) { + parameters.set(LOGIN_HINT, loginHint); + } + function addCcsUpn(parameters, loginHint) { + parameters.set(HeaderNames.CCS_HEADER, `UPN:${loginHint}`); + } + function addCcsOid(parameters, clientInfo) { + parameters.set(HeaderNames.CCS_HEADER, `Oid:${clientInfo.uid}@${clientInfo.utid}`); + } + function addSid(parameters, sid) { + parameters.set(SID, sid); + } + function addClaims(parameters, claims, clientCapabilities) { + const mergedClaims = addClientCapabilitiesToClaims(claims, clientCapabilities); + try { + JSON.parse(mergedClaims); + } catch (e) { + throw createClientConfigurationError(invalidClaims); + } + parameters.set(CLAIMS, mergedClaims); + } + function addCorrelationId(parameters, correlationId) { + parameters.set(CLIENT_REQUEST_ID, correlationId); + } + function addLibraryInfo(parameters, libraryInfo) { + parameters.set(X_CLIENT_SKU, libraryInfo.sku); + parameters.set(X_CLIENT_VER, libraryInfo.version); + if (libraryInfo.os) { + parameters.set(X_CLIENT_OS, libraryInfo.os); + } + if (libraryInfo.cpu) { + parameters.set(X_CLIENT_CPU, libraryInfo.cpu); + } + } + function addApplicationTelemetry(parameters, appTelemetry) { + if (appTelemetry?.appName) { + parameters.set(X_APP_NAME, appTelemetry.appName); + } + if (appTelemetry?.appVersion) { + parameters.set(X_APP_VER, appTelemetry.appVersion); + } + } + function addPrompt(parameters, prompt) { + parameters.set(PROMPT, prompt); + } + function addState(parameters, state) { + if (state) { + parameters.set(STATE, state); + } + } + function addNonce(parameters, nonce) { + parameters.set(NONCE, nonce); + } + function addCodeChallengeParams(parameters, codeChallenge, codeChallengeMethod) { + if (codeChallenge && codeChallengeMethod) { + parameters.set(CODE_CHALLENGE, codeChallenge); + parameters.set(CODE_CHALLENGE_METHOD, codeChallengeMethod); + } else { + throw createClientConfigurationError(pkceParamsMissing); + } + } + function addAuthorizationCode(parameters, code) { + parameters.set(CODE, code); + } + function addDeviceCode(parameters, code) { + parameters.set(DEVICE_CODE, code); + } + function addRefreshToken(parameters, refreshToken) { + parameters.set(REFRESH_TOKEN, refreshToken); + } + function addCodeVerifier(parameters, codeVerifier) { + parameters.set(CODE_VERIFIER, codeVerifier); + } + function addClientSecret(parameters, clientSecret) { + parameters.set(CLIENT_SECRET, clientSecret); + } + function addClientAssertion(parameters, clientAssertion) { + if (clientAssertion) { + parameters.set(CLIENT_ASSERTION, clientAssertion); + } + } + function addClientAssertionType(parameters, clientAssertionType) { + if (clientAssertionType) { + parameters.set(CLIENT_ASSERTION_TYPE, clientAssertionType); + } + } + function addOboAssertion(parameters, oboAssertion) { + parameters.set(OBO_ASSERTION, oboAssertion); + } + function addRequestTokenUse(parameters, tokenUse) { + parameters.set(REQUESTED_TOKEN_USE, tokenUse); + } + function addGrantType(parameters, grantType) { + parameters.set(GRANT_TYPE, grantType); + } + function addClientInfo(parameters) { + parameters.set(CLIENT_INFO, "1"); + } + function addCliData(parameters) { + parameters.set(CLI_DATA, "1"); + } + function addInstanceAware(parameters) { + if (!parameters.has(INSTANCE_AWARE)) { + parameters.set(INSTANCE_AWARE, "true"); + } + } + function addExtraParameters(parameters, extraParams) { + Object.entries(extraParams).forEach(([key, value]) => { + if (!parameters.has(key) && value) { + parameters.set(key, value); + } + }); + } + function addClientCapabilitiesToClaims(claims, clientCapabilities) { + let mergedClaims; + if (!claims) { + mergedClaims = {}; + } else { + try { + mergedClaims = JSON.parse(claims); + } catch (e) { + throw createClientConfigurationError(invalidClaims); + } + } + if (clientCapabilities && clientCapabilities.length > 0) { + if (!mergedClaims.hasOwnProperty(ClaimsRequestKeys.ACCESS_TOKEN)) { + mergedClaims[ClaimsRequestKeys.ACCESS_TOKEN] = {}; + } + mergedClaims[ClaimsRequestKeys.ACCESS_TOKEN][ClaimsRequestKeys.XMS_CC] = { + values: clientCapabilities + }; + } + return JSON.stringify(mergedClaims); + } + function addUsername(parameters, username) { + parameters.set(PasswordGrantConstants.username, username); + } + function addPassword(parameters, password) { + parameters.set(PasswordGrantConstants.password, password); + } + function addPopToken(parameters, cnfString) { + if (cnfString) { + parameters.set(TOKEN_TYPE, AuthenticationScheme.POP); + parameters.set(REQ_CNF, cnfString); + } + } + function addSshJwk(parameters, sshJwkString) { + if (sshJwkString) { + parameters.set(TOKEN_TYPE, AuthenticationScheme.SSH); + parameters.set(REQ_CNF, sshJwkString); + } + } + function addServerTelemetry(parameters, serverTelemetryManager) { + parameters.set(X_CLIENT_CURR_TELEM, serverTelemetryManager.generateCurrentRequestHeaderValue()); + parameters.set(X_CLIENT_LAST_TELEM, serverTelemetryManager.generateLastRequestHeaderValue()); + } + function addThrottling(parameters) { + parameters.set(X_MS_LIB_CAPABILITY, X_MS_LIB_CAPABILITY_VALUE); + } + function addLogoutHint(parameters, logoutHint) { + parameters.set(LOGOUT_HINT, logoutHint); + } + function addBrokerParameters(parameters, brokerClientId, brokerRedirectUri) { + if (!parameters.has(BROKER_CLIENT_ID)) { + parameters.set(BROKER_CLIENT_ID, brokerClientId); + } + if (!parameters.has(BROKER_REDIRECT_URI)) { + parameters.set(BROKER_REDIRECT_URI, brokerRedirectUri); + } + } + function addResource(parameters, resource) { + if (resource) { + parameters.set(RESOURCE, resource); + } + } + function stripLeadingHashOrQuery(responseString) { + if (responseString.startsWith("#/")) { + return responseString.substring(2); + } else if (responseString.startsWith("#") || responseString.startsWith("?")) { + return responseString.substring(1); + } + return responseString; + } + function getDeserializedResponse(responseString) { + if (!responseString || responseString.indexOf("=") < 0) { + return null; + } + try { + const normalizedResponse = stripLeadingHashOrQuery(responseString); + const deserializedHash = Object.fromEntries(new URLSearchParams(normalizedResponse)); + if (deserializedHash.code || deserializedHash.ear_jwe || deserializedHash.error || deserializedHash.error_description || deserializedHash.state) { + return deserializedHash; + } + } catch (e) { + throw createClientAuthError(hashNotDeserialized); + } + return null; + } + function mapToQueryString(parameters) { + const queryParameterArray = new Array(); + parameters.forEach((value, key) => { + queryParameterArray.push(`${key}=${encodeURIComponent(value)}`); + }); + return queryParameterArray.join("&"); + } + var DEFAULT_CRYPTO_IMPLEMENTATION = { + createNewGuid: () => { + throw createClientAuthError(methodNotImplemented); + }, + base64Decode: () => { + throw createClientAuthError(methodNotImplemented); + }, + base64Encode: () => { + throw createClientAuthError(methodNotImplemented); + }, + base64UrlEncode: () => { + throw createClientAuthError(methodNotImplemented); + }, + encodeKid: () => { + throw createClientAuthError(methodNotImplemented); + }, + async getPublicKeyThumbprint() { + throw createClientAuthError(methodNotImplemented); + }, + async removeTokenBindingKey() { + throw createClientAuthError(methodNotImplemented); + }, + async clearKeystore() { + throw createClientAuthError(methodNotImplemented); + }, + async signJwt() { + throw createClientAuthError(methodNotImplemented); + }, + async hashString() { + throw createClientAuthError(methodNotImplemented); + } + }; + exports2.LogLevel = void 0; + (function(LogLevel) { + LogLevel[LogLevel["Error"] = 0] = "Error"; + LogLevel[LogLevel["Warning"] = 1] = "Warning"; + LogLevel[LogLevel["Info"] = 2] = "Info"; + LogLevel[LogLevel["Verbose"] = 3] = "Verbose"; + LogLevel[LogLevel["Trace"] = 4] = "Trace"; + })(exports2.LogLevel || (exports2.LogLevel = {})); + var CACHE_CAPACITY = 50; + var MAX_LOGS_PER_CORRELATION = 500; + var correlationCache = /* @__PURE__ */ new Map(); + function markAsRecentlyUsed(correlationId, data) { + correlationCache.delete(correlationId); + correlationCache.set(correlationId, data); + } + function addLogToCache(correlationId, loggedMessage) { + const currentTime = Date.now(); + let data = correlationCache.get(correlationId); + if (data) { + markAsRecentlyUsed(correlationId, data); + } else { + data = { logs: [], firstEventTime: currentTime }; + correlationCache.set(correlationId, data); + if (correlationCache.size > CACHE_CAPACITY) { + const firstKey = correlationCache.keys().next().value; + if (firstKey) { + correlationCache.delete(firstKey); + } + } + } + data.logs.push({ + ...loggedMessage, + milliseconds: currentTime - data.firstEventTime + }); + if (data.logs.length > MAX_LOGS_PER_CORRELATION) { + data.logs.shift(); + } + } + function isHashedString(str) { + if (str.length !== 6) { + return false; + } + for (let i = 0; i < str.length; i++) { + const char = str[i]; + const isAlphaNumeric = char >= "a" && char <= "z" || char >= "A" && char <= "Z" || char >= "0" && char <= "9"; + if (!isAlphaNumeric) { + return false; + } + } + return true; + } + var Logger = class _Logger { + constructor(loggerOptions, packageName, packageVersion) { + this.level = exports2.LogLevel.Info; + const defaultLoggerCallback = () => { + return; + }; + const setLoggerOptions = loggerOptions || _Logger.createDefaultLoggerOptions(); + this.localCallback = setLoggerOptions.loggerCallback || defaultLoggerCallback; + this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false; + this.level = typeof setLoggerOptions.logLevel === "number" ? setLoggerOptions.logLevel : exports2.LogLevel.Info; + this.packageName = packageName || ""; + this.packageVersion = packageVersion || ""; + } + static createDefaultLoggerOptions() { + return { + loggerCallback: () => { + }, + piiLoggingEnabled: false, + logLevel: exports2.LogLevel.Info + }; + } + /** + * Create new Logger with existing configurations. + */ + clone(packageName, packageVersion) { + return new _Logger({ + loggerCallback: this.localCallback, + piiLoggingEnabled: this.piiLoggingEnabled, + logLevel: this.level + }, packageName, packageVersion); + } + /** + * Log message with required options. + */ + logMessage(logMessage, options) { + const correlationId = options.correlationId; + const isHashedInput = isHashedString(logMessage); + if (isHashedInput) { + const loggedMessage = { + hash: logMessage, + level: options.logLevel, + containsPii: options.containsPii || false, + milliseconds: 0 + // Will be calculated in addLogToCache + }; + addLogToCache(correlationId, loggedMessage); + } + if (options.logLevel > this.level || !this.piiLoggingEnabled && options.containsPii) { + return; + } + const timestamp = (/* @__PURE__ */ new Date()).toUTCString(); + const logHeader = `[${timestamp}] : [${correlationId}]`; + const log = `${logHeader} : ${this.packageName}@${this.packageVersion} : ${exports2.LogLevel[options.logLevel]} - ${logMessage}`; + this.executeCallback(options.logLevel, log, options.containsPii || false); + } + /** + * Execute callback with message. + */ + executeCallback(level, message, containsPii) { + if (this.localCallback) { + this.localCallback(level, message, containsPii); + } + } + /** + * Logs error messages. + */ + error(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Error, + containsPii: false, + correlationId + }); + } + /** + * Logs error messages with PII. + */ + errorPii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Error, + containsPii: true, + correlationId + }); + } + /** + * Logs warning messages. + */ + warning(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Warning, + containsPii: false, + correlationId + }); + } + /** + * Logs warning messages with PII. + */ + warningPii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Warning, + containsPii: true, + correlationId + }); + } + /** + * Logs info messages. + */ + info(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Info, + containsPii: false, + correlationId + }); + } + /** + * Logs info messages with PII. + */ + infoPii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Info, + containsPii: true, + correlationId + }); + } + /** + * Logs verbose messages. + */ + verbose(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Verbose, + containsPii: false, + correlationId + }); + } + /** + * Logs verbose messages with PII. + */ + verbosePii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Verbose, + containsPii: true, + correlationId + }); + } + /** + * Logs trace messages. + */ + trace(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Trace, + containsPii: false, + correlationId + }); + } + /** + * Logs trace messages with PII. + */ + tracePii(message, correlationId) { + this.logMessage(message, { + logLevel: exports2.LogLevel.Trace, + containsPii: true, + correlationId + }); + } + /** + * Returns whether PII Logging is enabled or not. + */ + isPiiLoggingEnabled() { + return this.piiLoggingEnabled || false; + } + }; + var name$1 = "@azure/msal-common"; + var version$1 = "16.4.1"; + var AzureCloudInstance = { + // AzureCloudInstance is not specified. + None: "none", + // Microsoft Azure public cloud + AzurePublic: "https://login.microsoftonline.com", + // Microsoft PPE + AzurePpe: "https://login.windows-ppe.net", + // Microsoft Chinese national/regional cloud + AzureChina: "https://login.chinacloudapi.cn", + // Microsoft German national/regional cloud ("Black Forest") + AzureGermany: "https://login.microsoftonline.de", + // US Government cloud + AzureUsGovernment: "https://login.microsoftonline.us" + }; + function tenantIdMatchesHomeTenant(tenantId, homeAccountId) { + return !!tenantId && !!homeAccountId && tenantId === homeAccountId.split(".")[1]; + } + function buildTenantProfile(homeAccountId, localAccountId, tenantId, idTokenClaims) { + if (idTokenClaims) { + const { oid, sub, tid, name: name2, tfp, acr, preferred_username, upn, login_hint } = idTokenClaims; + const tenantId2 = tid || tfp || acr || ""; + return { + tenantId: tenantId2, + localAccountId: oid || sub || "", + name: name2, + username: preferred_username || upn || "", + loginHint: login_hint, + isHomeTenant: tenantIdMatchesHomeTenant(tenantId2, homeAccountId) + }; + } else { + return { + tenantId, + localAccountId, + username: "", + isHomeTenant: tenantIdMatchesHomeTenant(tenantId, homeAccountId) + }; + } + } + function updateAccountTenantProfileData(baseAccountInfo, tenantProfile, idTokenClaims, idTokenSecret) { + let updatedAccountInfo = baseAccountInfo; + if (tenantProfile) { + const { isHomeTenant, ...tenantProfileOverride } = tenantProfile; + updatedAccountInfo = { ...baseAccountInfo, ...tenantProfileOverride }; + } + if (idTokenClaims) { + const { isHomeTenant, ...claimsSourcedTenantProfile } = buildTenantProfile(baseAccountInfo.homeAccountId, baseAccountInfo.localAccountId, baseAccountInfo.tenantId, idTokenClaims); + updatedAccountInfo = { + ...updatedAccountInfo, + ...claimsSourcedTenantProfile, + idTokenClaims, + idToken: idTokenSecret + }; + return updatedAccountInfo; + } + return updatedAccountInfo; + } + function extractTokenClaims(encodedToken, base64Decode) { + const jswPayload = getJWSPayload(encodedToken); + try { + const base64Decoded = base64Decode(jswPayload); + return JSON.parse(base64Decoded); + } catch (err) { + throw createClientAuthError(tokenParsingError); + } + } + function isKmsi(idTokenClaims) { + if (!idTokenClaims.signin_state) { + return false; + } + const kmsiClaims = ["kmsi", "dvc_dmjd"]; + return idTokenClaims.signin_state.some((value) => kmsiClaims.includes(value.trim().toLowerCase())); + } + function getJWSPayload(authToken) { + if (!authToken) { + throw createClientAuthError(nullOrEmptyToken); + } + const tokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/; + const matches = tokenPartsRegex.exec(authToken); + if (!matches || matches.length < 4) { + throw createClientAuthError(tokenParsingError); + } + return matches[2]; + } + function checkMaxAge(authTime, maxAge) { + const fiveMinuteSkew = 3e5; + if (maxAge === 0 || Date.now() - fiveMinuteSkew > authTime + maxAge) { + throw createClientAuthError(maxAgeTranspired); + } + } + var UrlString = class _UrlString { + get urlString() { + return this._urlString; + } + constructor(url) { + this._urlString = url; + if (!this._urlString) { + throw createClientConfigurationError(urlEmptyError); + } + if (!url.includes("#")) { + this._urlString = _UrlString.canonicalizeUri(url); + } + } + /** + * Ensure urls are lower case and end with a / character. + * @param url + */ + static canonicalizeUri(url) { + if (url) { + let lowerCaseUrl = url.toLowerCase(); + if (StringUtils.endsWith(lowerCaseUrl, "?")) { + lowerCaseUrl = lowerCaseUrl.slice(0, -1); + } else if (StringUtils.endsWith(lowerCaseUrl, "?/")) { + lowerCaseUrl = lowerCaseUrl.slice(0, -2); + } + if (!StringUtils.endsWith(lowerCaseUrl, "/")) { + lowerCaseUrl += "/"; + } + return lowerCaseUrl; + } + return url; + } + /** + * Throws if urlString passed is not a valid authority URI string. + */ + validateAsUri() { + let components; + try { + components = this.getUrlComponents(); + } catch (e) { + throw createClientConfigurationError(urlParseError); + } + if (!components.HostNameAndPort || !components.PathSegments) { + throw createClientConfigurationError(urlParseError); + } + if (!components.Protocol || components.Protocol.toLowerCase() !== "https:") { + throw createClientConfigurationError(authorityUriInsecure); + } + } + /** + * Given a url and a query string return the url with provided query string appended + * @param url + * @param queryString + */ + static appendQueryString(url, queryString) { + if (!queryString) { + return url; + } + return url.indexOf("?") < 0 ? `${url}?${queryString}` : `${url}&${queryString}`; + } + /** + * Returns a url with the hash removed + * @param url + */ + static removeHashFromUrl(url) { + return _UrlString.canonicalizeUri(url.split("#")[0]); + } + /** + * Given a url like https://a:b/common/d?e=f#g, and a tenantId, returns https://a:b/tenantId/d + * @param href The url + * @param tenantId The tenant id to replace + */ + replaceTenantPath(tenantId) { + const urlObject = this.getUrlComponents(); + const pathArray = urlObject.PathSegments; + if (tenantId && pathArray.length !== 0 && (pathArray[0] === AADAuthority.COMMON || pathArray[0] === AADAuthority.ORGANIZATIONS)) { + pathArray[0] = tenantId; + } + return _UrlString.constructAuthorityUriFromObject(urlObject); + } + /** + * Parses out the components from a url string. + * @returns An object with the various components. Please cache this value insted of calling this multiple times on the same url. + */ + getUrlComponents() { + const regEx = RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"); + const match = this.urlString.match(regEx); + if (!match) { + throw createClientConfigurationError(urlParseError); + } + const urlComponents = { + Protocol: match[1], + HostNameAndPort: match[4], + AbsolutePath: match[5], + QueryString: match[7] + }; + let pathSegments = urlComponents.AbsolutePath.split("/"); + pathSegments = pathSegments.filter((val) => val && val.length > 0); + urlComponents.PathSegments = pathSegments; + if (urlComponents.QueryString && urlComponents.QueryString.endsWith("/")) { + urlComponents.QueryString = urlComponents.QueryString.substring(0, urlComponents.QueryString.length - 1); + } + return urlComponents; + } + static getDomainFromUrl(url) { + const regEx = RegExp("^([^:/?#]+://)?([^/?#]*)"); + const match = url.match(regEx); + if (!match) { + throw createClientConfigurationError(urlParseError); + } + return match[2]; + } + static getAbsoluteUrl(relativeUrl, baseUrl) { + if (relativeUrl[0] === FORWARD_SLASH) { + const url = new _UrlString(baseUrl); + const baseComponents = url.getUrlComponents(); + return baseComponents.Protocol + "//" + baseComponents.HostNameAndPort + relativeUrl; + } + return relativeUrl; + } + static constructAuthorityUriFromObject(urlObject) { + return new _UrlString(urlObject.Protocol + "//" + urlObject.HostNameAndPort + "/" + urlObject.PathSegments.join("/")); + } + }; + var endpointHosts = [ + { host: "login.microsoftonline.com" }, + { + host: "login.chinacloudapi.cn", + issuerHost: "login.partner.microsoftonline.cn" + // Issuer differs + }, + { host: "login.microsoftonline.us" }, + { host: "login.sovcloud-identity.fr" }, + { host: "login.sovcloud-identity.de" }, + { host: "login.sovcloud-identity.sg" } + ]; + function buildOpenIdConfig(host, issuerHost) { + return { + token_endpoint: `https://${host}/{tenantid}/oauth2/v2.0/token`, + jwks_uri: `https://${host}/{tenantid}/discovery/v2.0/keys`, + issuer: `https://${issuerHost}/{tenantid}/v2.0`, + authorization_endpoint: `https://${host}/{tenantid}/oauth2/v2.0/authorize`, + end_session_endpoint: `https://${host}/{tenantid}/oauth2/v2.0/logout` + }; + } + var dynamicEndpointMetadata = endpointHosts.reduce((acc, { host, issuerHost }) => { + acc[host] = buildOpenIdConfig(host, issuerHost || host); + return acc; + }, {}); + var rawMetdataJSON = { + endpointMetadata: dynamicEndpointMetadata, + instanceDiscoveryMetadata: { + metadata: [ + { + preferred_network: "login.microsoftonline.com", + preferred_cache: "login.windows.net", + aliases: [ + "login.microsoftonline.com", + "login.windows.net", + "login.microsoft.com", + "sts.windows.net" + ] + }, + { + preferred_network: "login.partner.microsoftonline.cn", + preferred_cache: "login.partner.microsoftonline.cn", + aliases: [ + "login.partner.microsoftonline.cn", + "login.chinacloudapi.cn" + ] + }, + { + preferred_network: "login.microsoftonline.de", + preferred_cache: "login.microsoftonline.de", + aliases: ["login.microsoftonline.de"] + }, + { + preferred_network: "login.microsoftonline.us", + preferred_cache: "login.microsoftonline.us", + aliases: [ + "login.microsoftonline.us", + "login.usgovcloudapi.net" + ] + }, + { + preferred_network: "login-us.microsoftonline.com", + preferred_cache: "login-us.microsoftonline.com", + aliases: ["login-us.microsoftonline.com"] + }, + { + preferred_network: "login.sovcloud-identity.fr", + preferred_cache: "login.sovcloud-identity.fr", + aliases: ["login.sovcloud-identity.fr"] + }, + { + preferred_network: "login.sovcloud-identity.de", + preferred_cache: "login.sovcloud-identity.de", + aliases: ["login.sovcloud-identity.de"] + }, + { + preferred_network: "login.sovcloud-identity.sg", + preferred_cache: "login.sovcloud-identity.sg", + aliases: ["login.sovcloud-identity.sg"] + } + ] + } + }; + var EndpointMetadata = rawMetdataJSON.endpointMetadata; + var InstanceDiscoveryMetadata = rawMetdataJSON.instanceDiscoveryMetadata; + var InstanceDiscoveryMetadataAliases = /* @__PURE__ */ new Set(); + InstanceDiscoveryMetadata.metadata.forEach((metadataEntry) => { + metadataEntry.aliases.forEach((alias) => { + InstanceDiscoveryMetadataAliases.add(alias); + }); + }); + function getAliasesFromStaticSources(staticAuthorityOptions, logger, correlationId) { + let staticAliases; + const canonicalAuthority = staticAuthorityOptions.canonicalAuthority; + if (canonicalAuthority) { + const authorityHost = new UrlString(canonicalAuthority).getUrlComponents().HostNameAndPort; + staticAliases = getAliasesFromMetadata(logger, correlationId, authorityHost, staticAuthorityOptions.cloudDiscoveryMetadata?.metadata, AuthorityMetadataSource.CONFIG) || getAliasesFromMetadata(logger, correlationId, authorityHost, InstanceDiscoveryMetadata.metadata, AuthorityMetadataSource.HARDCODED_VALUES) || staticAuthorityOptions.knownAuthorities; + } + return staticAliases || []; + } + function getAliasesFromMetadata(logger, correlationId, authorityHost, cloudDiscoveryMetadata, source) { + logger.trace(`getAliasesFromMetadata called with source: '${source}'`, correlationId); + if (authorityHost && cloudDiscoveryMetadata) { + const metadata = getCloudDiscoveryMetadataFromNetworkResponse(cloudDiscoveryMetadata, authorityHost); + if (metadata) { + logger.trace(`getAliasesFromMetadata: found cloud discovery metadata in '${source}', returning aliases`, correlationId); + return metadata.aliases; + } else { + logger.trace(`getAliasesFromMetadata: did not find cloud discovery metadata in '${source}'`, correlationId); + } + } + return null; + } + function getCloudDiscoveryMetadataFromHardcodedValues(authorityHost) { + const metadata = getCloudDiscoveryMetadataFromNetworkResponse(InstanceDiscoveryMetadata.metadata, authorityHost); + return metadata; + } + function getCloudDiscoveryMetadataFromNetworkResponse(response, authorityHost) { + for (let i = 0; i < response.length; i++) { + const metadata = response[i]; + if (metadata.aliases.includes(authorityHost)) { + return metadata; + } + } + return null; + } + var cacheQuotaExceeded = "cache_quota_exceeded"; + var cacheErrorUnknown = "cache_error_unknown"; + var CacheError = class _CacheError extends Error { + constructor(errorCode, errorMessage) { + const message = errorMessage || getDefaultErrorMessage(errorCode); + super(message); + Object.setPrototypeOf(this, _CacheError.prototype); + this.name = "CacheError"; + this.errorCode = errorCode; + this.errorMessage = message; + } + }; + function createCacheError(e) { + if (!(e instanceof Error)) { + return new CacheError(cacheErrorUnknown); + } + if (e.name === "QuotaExceededError" || e.name === "NS_ERROR_DOM_QUOTA_REACHED" || e.message.includes("exceeded the quota")) { + return new CacheError(cacheQuotaExceeded); + } else { + return new CacheError(e.name, e.message); + } + } + function buildClientInfo(rawClientInfo, base64Decode) { + if (!rawClientInfo) { + throw createClientAuthError(clientInfoEmptyError); + } + try { + const decodedClientInfo = base64Decode(rawClientInfo); + return JSON.parse(decodedClientInfo); + } catch (e) { + throw createClientAuthError(clientInfoDecodingError); + } + } + function buildClientInfoFromHomeAccountId(homeAccountId) { + if (!homeAccountId) { + throw createClientAuthError(clientInfoDecodingError); + } + const clientInfoParts = homeAccountId.split(CLIENT_INFO_SEPARATOR, 2); + return { + uid: clientInfoParts[0], + utid: clientInfoParts.length < 2 ? "" : clientInfoParts[1] + }; + } + var AuthorityType = { + Default: 0, + Adfs: 1, + Dsts: 2, + Ciam: 3 + }; + function getTenantIdFromIdTokenClaims(idTokenClaims) { + if (idTokenClaims) { + const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr; + return tenantId || null; + } + return null; + } + var ProtocolMode = { + /** + * Auth Code + PKCE with Entra ID (formerly AAD) specific optimizations and features + */ + AAD: "AAD", + /** + * Auth Code + PKCE without Entra ID specific optimizations and features. For use only with non-Microsoft owned authorities. + * Support is limited for this mode. + */ + OIDC: "OIDC", + /** + * Encrypted Authorize Response (EAR) with Entra ID specific optimizations and features + */ + EAR: "EAR" + }; + function getAccountInfo(accountEntity) { + const tenantProfiles = accountEntity.tenantProfiles || []; + if (tenantProfiles.length === 0 && accountEntity.realm && accountEntity.localAccountId) { + tenantProfiles.push(buildTenantProfile(accountEntity.homeAccountId, accountEntity.localAccountId, accountEntity.realm)); + } + return { + homeAccountId: accountEntity.homeAccountId, + environment: accountEntity.environment, + tenantId: accountEntity.realm, + username: accountEntity.username, + localAccountId: accountEntity.localAccountId, + loginHint: accountEntity.loginHint, + name: accountEntity.name, + nativeAccountId: accountEntity.nativeAccountId, + authorityType: accountEntity.authorityType, + // Deserialize tenant profiles array into a Map + tenantProfiles: new Map(tenantProfiles.map((tenantProfile) => { + return [tenantProfile.tenantId, tenantProfile]; + })), + dataBoundary: accountEntity.dataBoundary + }; + } + function createAccountEntity(accountDetails, authority, base64Decode) { + let authorityType; + if (authority.authorityType === AuthorityType.Adfs) { + authorityType = CACHE_ACCOUNT_TYPE_ADFS; + } else if (authority.protocolMode === ProtocolMode.OIDC) { + authorityType = CACHE_ACCOUNT_TYPE_GENERIC; + } else { + authorityType = CACHE_ACCOUNT_TYPE_MSSTS; + } + let clientInfo; + let dataBoundary; + if (accountDetails.clientInfo && base64Decode) { + clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode); + if (clientInfo.xms_tdbr) { + dataBoundary = clientInfo.xms_tdbr === "EU" ? "EU" : "None"; + } + } + const env = accountDetails.environment || authority && authority.getPreferredCache(); + if (!env) { + throw createClientAuthError(invalidCacheEnvironment); + } + const preferredUsername = accountDetails.idTokenClaims?.preferred_username || accountDetails.idTokenClaims?.upn; + const email = accountDetails.idTokenClaims?.emails ? accountDetails.idTokenClaims.emails[0] : null; + const username = preferredUsername || email || ""; + const loginHint = accountDetails.idTokenClaims?.login_hint; + const realm = clientInfo?.utid || getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) || ""; + const localAccountId = clientInfo?.uid || accountDetails.idTokenClaims?.oid || accountDetails.idTokenClaims?.sub || ""; + let tenantProfiles; + if (accountDetails.tenantProfiles) { + tenantProfiles = accountDetails.tenantProfiles; + } else { + const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, localAccountId, realm, accountDetails.idTokenClaims); + tenantProfiles = [tenantProfile]; + } + return { + homeAccountId: accountDetails.homeAccountId, + environment: env, + realm, + localAccountId, + username, + authorityType, + loginHint, + clientInfo: accountDetails.clientInfo, + name: accountDetails.idTokenClaims?.name || "", + lastModificationTime: void 0, + lastModificationApp: void 0, + cloudGraphHostName: accountDetails.cloudGraphHostName, + msGraphHost: accountDetails.msGraphHost, + nativeAccountId: accountDetails.nativeAccountId, + tenantProfiles, + dataBoundary + }; + } + function generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, correlationId, idTokenClaims) { + if (!(authType === AuthorityType.Adfs || authType === AuthorityType.Dsts)) { + if (serverClientInfo) { + try { + const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode); + if (clientInfo.uid && clientInfo.utid) { + return `${clientInfo.uid}.${clientInfo.utid}`; + } + } catch (e) { + } + } + logger.warning("No client info in response", correlationId); + } + return idTokenClaims?.sub || ""; + } + function isAccountEntity(entity) { + if (!entity) { + return false; + } + return entity.hasOwnProperty("homeAccountId") && entity.hasOwnProperty("environment") && entity.hasOwnProperty("realm") && entity.hasOwnProperty("localAccountId") && entity.hasOwnProperty("username") && entity.hasOwnProperty("authorityType"); + } + var CacheManager = class { + constructor(clientId, cryptoImpl, logger, performanceClient, staticAuthorityOptions) { + this.clientId = clientId; + this.cryptoImpl = cryptoImpl; + this.commonLogger = logger.clone(name$1, version$1); + this.staticAuthorityOptions = staticAuthorityOptions; + this.performanceClient = performanceClient; + } + /** + * Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned. + * @param accountFilter - (Optional) filter to narrow down the accounts returned + * @returns Array of AccountInfo objects in cache + */ + getAllAccounts(accountFilter = {}, correlationId) { + return this.buildTenantProfiles(this.getAccountsFilteredBy(accountFilter, correlationId), correlationId, accountFilter); + } + /** + * Gets first tenanted AccountInfo object found based on provided filters + */ + getAccountInfoFilteredBy(accountFilter, correlationId) { + if (Object.keys(accountFilter).length === 0 || Object.values(accountFilter).every((value) => value === null || value === void 0 || value === "")) { + this.commonLogger.warning("getAccountInfoFilteredBy: Account filter is empty or invalid, returning null", correlationId); + return null; + } + const allAccounts = this.getAllAccounts(accountFilter, correlationId); + if (allAccounts.length > 1) { + const sortedAccounts = allAccounts.sort((account) => { + return account.idTokenClaims ? -1 : 1; + }); + return sortedAccounts[0]; + } else if (allAccounts.length === 1) { + return allAccounts[0]; + } else { + return null; + } + } + /** + * Returns a single matching + * @param accountFilter + * @returns + */ + getBaseAccountInfo(accountFilter, correlationId) { + const accountEntities = this.getAccountsFilteredBy(accountFilter, correlationId); + if (accountEntities.length > 0) { + return getAccountInfo(accountEntities[0]); + } else { + return null; + } + } + /** + * Matches filtered account entities with cached ID tokens that match the tenant profile-specific account filters + * and builds the account info objects from the matching ID token's claims + * @param cachedAccounts + * @param accountFilter + * @returns Array of AccountInfo objects that match account and tenant profile filters + */ + buildTenantProfiles(cachedAccounts, correlationId, accountFilter) { + return cachedAccounts.flatMap((accountEntity) => { + return this.getTenantProfilesFromAccountEntity(accountEntity, correlationId, accountFilter?.tenantId, accountFilter); + }); + } + getTenantedAccountInfoByFilter(accountInfo, tokenKeys, tenantProfile, correlationId, tenantProfileFilter) { + let tenantedAccountInfo = null; + let idTokenClaims; + if (tenantProfileFilter) { + if (!this.tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter)) { + return null; + } + } + const idToken = this.getIdToken(accountInfo, correlationId, tokenKeys, tenantProfile.tenantId); + if (idToken) { + idTokenClaims = extractTokenClaims(idToken.secret, this.cryptoImpl.base64Decode); + if (!this.idTokenClaimsMatchTenantProfileFilter(idTokenClaims, tenantProfileFilter)) { + return null; + } + } + tenantedAccountInfo = updateAccountTenantProfileData(accountInfo, tenantProfile, idTokenClaims, idToken?.secret); + return tenantedAccountInfo; + } + getTenantProfilesFromAccountEntity(accountEntity, correlationId, targetTenantId, tenantProfileFilter) { + const accountInfo = getAccountInfo(accountEntity); + let searchTenantProfiles = accountInfo.tenantProfiles || /* @__PURE__ */ new Map(); + const tokenKeys = this.getTokenKeys(); + if (targetTenantId) { + const tenantProfile = searchTenantProfiles.get(targetTenantId); + if (tenantProfile) { + searchTenantProfiles = /* @__PURE__ */ new Map([ + [targetTenantId, tenantProfile] + ]); + } else { + return []; + } + } + const matchingTenantProfiles = []; + searchTenantProfiles.forEach((tenantProfile) => { + const tenantedAccountInfo = this.getTenantedAccountInfoByFilter(accountInfo, tokenKeys, tenantProfile, correlationId, tenantProfileFilter); + if (tenantedAccountInfo) { + matchingTenantProfiles.push(tenantedAccountInfo); + } + }); + return matchingTenantProfiles; + } + tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter) { + if (!!tenantProfileFilter.localAccountId && !this.matchLocalAccountIdFromTenantProfile(tenantProfile, tenantProfileFilter.localAccountId)) { + return false; + } + if (!!tenantProfileFilter.name && !(tenantProfile.name === tenantProfileFilter.name)) { + return false; + } + if (tenantProfileFilter.isHomeTenant !== void 0 && !(tenantProfile.isHomeTenant === tenantProfileFilter.isHomeTenant)) { + return false; + } + return true; + } + idTokenClaimsMatchTenantProfileFilter(idTokenClaims, tenantProfileFilter) { + if (tenantProfileFilter) { + if (!!tenantProfileFilter.localAccountId && !this.matchLocalAccountIdFromTokenClaims(idTokenClaims, tenantProfileFilter.localAccountId)) { + return false; + } + if (!!tenantProfileFilter.loginHint && !this.matchLoginHintFromTokenClaims(idTokenClaims, tenantProfileFilter.loginHint)) { + return false; + } + if (!!tenantProfileFilter.username && !this.matchUsername(idTokenClaims.preferred_username, tenantProfileFilter.username)) { + return false; + } + if (!!tenantProfileFilter.name && !this.matchName(idTokenClaims, tenantProfileFilter.name)) { + return false; + } + if (!!tenantProfileFilter.sid && !this.matchSid(idTokenClaims, tenantProfileFilter.sid)) { + return false; + } + } + return true; + } + /** + * saves a cache record + * @param cacheRecord {CacheRecord} + * @param storeInCache {?StoreInCache} + * @param correlationId {?string} correlation id + */ + async saveCacheRecord(cacheRecord, correlationId, kmsi, apiId, storeInCache) { + if (!cacheRecord) { + throw createClientAuthError(invalidCacheRecord); + } + try { + if (!!cacheRecord.account) { + await this.setAccount(cacheRecord.account, correlationId, kmsi, apiId); + } + if (!!cacheRecord.idToken && storeInCache?.idToken !== false) { + await this.setIdTokenCredential(cacheRecord.idToken, correlationId, kmsi); + } + if (!!cacheRecord.accessToken && storeInCache?.accessToken !== false) { + await this.saveAccessToken(cacheRecord.accessToken, correlationId, kmsi); + } + if (!!cacheRecord.refreshToken && storeInCache?.refreshToken !== false) { + await this.setRefreshTokenCredential(cacheRecord.refreshToken, correlationId, kmsi); + } + if (!!cacheRecord.appMetadata) { + this.setAppMetadata(cacheRecord.appMetadata, correlationId); + } + } catch (e) { + this.commonLogger?.error(`CacheManager.saveCacheRecord: failed`, correlationId); + if (e instanceof AuthError) { + throw e; + } else { + throw createCacheError(e); + } + } + } + /** + * saves access token credential + * @param credential + */ + async saveAccessToken(credential, correlationId, kmsi) { + const accessTokenFilter = { + clientId: credential.clientId, + credentialType: credential.credentialType, + environment: credential.environment, + homeAccountId: credential.homeAccountId, + realm: credential.realm, + tokenType: credential.tokenType + }; + const tokenKeys = this.getTokenKeys(); + const currentScopes = ScopeSet.fromString(credential.target); + tokenKeys.accessToken.forEach((key) => { + if (!this.accessTokenKeyMatchesFilter(key, accessTokenFilter, false)) { + return; + } + const tokenEntity = this.getAccessTokenCredential(key, correlationId); + if (tokenEntity && this.credentialMatchesFilter(tokenEntity, accessTokenFilter, correlationId)) { + const tokenScopeSet = ScopeSet.fromString(tokenEntity.target); + if (tokenScopeSet.intersectingScopeSets(currentScopes)) { + this.removeAccessToken(key, correlationId); + } + } + }); + await this.setAccessTokenCredential(credential, correlationId, kmsi); + } + /** + * Retrieve account entities matching all provided tenant-agnostic filters; if no filter is set, get all account entities in the cache + * Not checking for casing as keys are all generated in lower case, remember to convert to lower case if object properties are compared + * @param accountFilter - An object containing Account properties to filter by + */ + getAccountsFilteredBy(accountFilter, correlationId) { + const allAccountKeys = this.getAccountKeys(); + const matchingAccounts = []; + allAccountKeys.forEach((cacheKey) => { + const entity = this.getAccount(cacheKey, correlationId); + if (!entity) { + return; + } + if (!!accountFilter.homeAccountId && !this.matchHomeAccountId(entity, accountFilter.homeAccountId)) { + return; + } + if (!!accountFilter.username && !this.matchUsername(entity.username, accountFilter.username)) { + return; + } + if (!!accountFilter.environment && !this.matchEnvironment(entity, accountFilter.environment, correlationId)) { + return; + } + if (!!accountFilter.realm && !this.matchRealm(entity, accountFilter.realm)) { + return; + } + if (!!accountFilter.nativeAccountId && !this.matchNativeAccountId(entity, accountFilter.nativeAccountId)) { + return; + } + if (!!accountFilter.authorityType && !this.matchAuthorityType(entity, accountFilter.authorityType)) { + return; + } + const tenantProfileFilter = { + localAccountId: accountFilter?.localAccountId, + name: accountFilter?.name + }; + const matchingTenantProfiles = entity.tenantProfiles?.filter((tenantProfile) => { + return this.tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter); + }); + if (matchingTenantProfiles && matchingTenantProfiles.length === 0) { + return; + } + matchingAccounts.push(entity); + }); + return matchingAccounts; + } + /** + * Returns whether or not the given credential entity matches the filter + * @param entity + * @param filter + * @param correlationId + * @returns + */ + credentialMatchesFilter(entity, filter, correlationId) { + if (!!filter.clientId && !this.matchClientId(entity, filter.clientId)) { + return false; + } + if (!!filter.userAssertionHash && !this.matchUserAssertionHash(entity, filter.userAssertionHash)) { + return false; + } + if (typeof filter.homeAccountId === "string" && !this.matchHomeAccountId(entity, filter.homeAccountId)) { + return false; + } + if (!!filter.environment && !this.matchEnvironment(entity, filter.environment, correlationId)) { + return false; + } + if (!!filter.realm && !this.matchRealm(entity, filter.realm)) { + return false; + } + if (!!filter.credentialType && !this.matchCredentialType(entity, filter.credentialType)) { + return false; + } + if (!!filter.familyId && !this.matchFamilyId(entity, filter.familyId)) { + return false; + } + if (!!filter.target && !this.matchTarget(entity, filter.target)) { + return false; + } + if (entity.credentialType === CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME) { + if (!!filter.tokenType && !this.matchTokenType(entity, filter.tokenType)) { + return false; + } + if (filter.tokenType === AuthenticationScheme.SSH) { + if (filter.keyId && !this.matchKeyId(entity, filter.keyId)) { + return false; + } + } + } + return true; + } + /** + * retrieve appMetadata matching all provided filters; if no filter is set, get all appMetadata + * @param filter + * @param correlationId + */ + getAppMetadataFilteredBy(filter, correlationId) { + const allCacheKeys = this.getKeys(); + const matchingAppMetadata = {}; + allCacheKeys.forEach((cacheKey) => { + if (!this.isAppMetadata(cacheKey)) { + return; + } + const entity = this.getAppMetadata(cacheKey, correlationId); + if (!entity) { + return; + } + if (!!filter.environment && !this.matchEnvironment(entity, filter.environment, correlationId)) { + return; + } + if (!!filter.clientId && !this.matchClientId(entity, filter.clientId)) { + return; + } + matchingAppMetadata[cacheKey] = entity; + }); + return matchingAppMetadata; + } + /** + * retrieve authorityMetadata that contains a matching alias + * @param host + * @param correlationId + */ + getAuthorityMetadataByAlias(host, correlationId) { + const allCacheKeys = this.getAuthorityMetadataKeys(); + let matchedEntity = null; + allCacheKeys.forEach((cacheKey) => { + if (!this.isAuthorityMetadata(cacheKey) || cacheKey.indexOf(this.clientId) === -1) { + return; + } + const entity = this.getAuthorityMetadata(cacheKey, correlationId); + if (!entity) { + return; + } + if (entity.aliases.indexOf(host) === -1) { + return; + } + matchedEntity = entity; + }); + return matchedEntity; + } + /** + * Removes all accounts and related tokens from cache. + */ + removeAllAccounts(correlationId) { + const accounts = this.getAllAccounts({}, correlationId); + accounts.forEach((account) => { + this.removeAccount(account, correlationId); + }); + } + /** + * Removes the account and related tokens for a given account key + * @param account + */ + removeAccount(account, correlationId) { + this.removeAccountContext(account, correlationId); + const accountKeys = this.getAccountKeys(); + const keyFilter = (key) => { + return key.includes(account.homeAccountId) && key.includes(account.environment); + }; + accountKeys.filter(keyFilter).forEach((key) => { + this.removeItem(key, correlationId); + this.performanceClient.incrementFields({ accountsRemoved: 1 }, correlationId); + }); + } + /** + * Removes credentials associated with the provided account + * @param account + */ + removeAccountContext(account, correlationId) { + const allTokenKeys = this.getTokenKeys(); + const keyFilter = (key) => { + return key.includes(account.homeAccountId) && key.includes(account.environment); + }; + allTokenKeys.idToken.filter(keyFilter).forEach((key) => { + this.removeIdToken(key, correlationId); + }); + allTokenKeys.accessToken.filter(keyFilter).forEach((key) => { + this.removeAccessToken(key, correlationId); + }); + allTokenKeys.refreshToken.filter(keyFilter).forEach((key) => { + this.removeRefreshToken(key, correlationId); + }); + } + /** + * returns a boolean if the given credential is removed + * @param key + * @param correlationId + */ + removeAccessToken(key, correlationId) { + const credential = this.getAccessTokenCredential(key, correlationId); + if (!credential) { + return; + } + this.removeItem(key, correlationId); + this.performanceClient.incrementFields({ accessTokensRemoved: 1 }, correlationId); + if (credential.credentialType.toLowerCase() === CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) { + if (credential.tokenType === AuthenticationScheme.POP) { + const accessTokenWithAuthSchemeEntity = credential; + const kid = accessTokenWithAuthSchemeEntity.keyId; + if (kid) { + void this.cryptoImpl.removeTokenBindingKey(kid, correlationId).catch(() => { + this.commonLogger.error(`Failed to remove token binding key '${kid}'`, correlationId); + this.performanceClient?.incrementFields({ removeTokenBindingKeyFailure: 1 }, correlationId); + }); + } + } + } + } + /** + * Removes all app metadata objects from cache. + */ + removeAppMetadata(correlationId) { + const allCacheKeys = this.getKeys(); + allCacheKeys.forEach((cacheKey) => { + if (this.isAppMetadata(cacheKey)) { + this.removeItem(cacheKey, correlationId); + } + }); + return true; + } + /** + * Retrieve IdTokenEntity from cache + * @param account {AccountInfo} + * @param tokenKeys {?TokenKeys} + * @param targetRealm {?string} + * @param performanceClient {?IPerformanceClient} + * @param correlationId {?string} + */ + getIdToken(account, correlationId, tokenKeys, targetRealm) { + this.commonLogger.trace("CacheManager - getIdToken called", correlationId); + const idTokenFilter = { + homeAccountId: account.homeAccountId, + environment: account.environment, + credentialType: CredentialType.ID_TOKEN, + clientId: this.clientId, + realm: targetRealm + }; + const idTokenMap = this.getIdTokensByFilter(idTokenFilter, correlationId, tokenKeys); + const numIdTokens = idTokenMap.size; + if (numIdTokens < 1) { + this.commonLogger.info("CacheManager:getIdToken - No token found", correlationId); + return null; + } else if (numIdTokens > 1) { + let tokensToBeRemoved = idTokenMap; + if (!targetRealm) { + const homeIdTokenMap = /* @__PURE__ */ new Map(); + idTokenMap.forEach((idToken, key) => { + if (idToken.realm === account.tenantId) { + homeIdTokenMap.set(key, idToken); + } + }); + const numHomeIdTokens = homeIdTokenMap.size; + if (numHomeIdTokens < 1) { + this.commonLogger.info("CacheManager:getIdToken - Multiple ID tokens found for account but none match account entity tenant id, returning first result", correlationId); + return idTokenMap.values().next().value; + } else if (numHomeIdTokens === 1) { + this.commonLogger.info("CacheManager:getIdToken - Multiple ID tokens found for account, defaulting to home tenant profile", correlationId); + return homeIdTokenMap.values().next().value; + } else { + tokensToBeRemoved = homeIdTokenMap; + } + } + this.commonLogger.info("CacheManager:getIdToken - Multiple matching ID tokens found, clearing them", correlationId); + tokensToBeRemoved.forEach((idToken, key) => { + this.removeIdToken(key, correlationId); + }); + this.performanceClient.addFields({ multiMatchedID: idTokenMap.size }, correlationId); + return null; + } + this.commonLogger.info("CacheManager:getIdToken - Returning ID token", correlationId); + return idTokenMap.values().next().value; + } + /** + * Gets all idTokens matching the given filter + * @param filter + * @returns + */ + getIdTokensByFilter(filter, correlationId, tokenKeys) { + const idTokenKeys = tokenKeys && tokenKeys.idToken || this.getTokenKeys().idToken; + const idTokens = /* @__PURE__ */ new Map(); + idTokenKeys.forEach((key) => { + if (!this.idTokenKeyMatchesFilter(key, { + clientId: this.clientId, + ...filter + })) { + return; + } + const idToken = this.getIdTokenCredential(key, correlationId); + if (idToken && this.credentialMatchesFilter(idToken, filter, correlationId)) { + idTokens.set(key, idToken); + } + }); + return idTokens; + } + /** + * Validate the cache key against filter before retrieving and parsing cache value + * @param key + * @param filter + * @returns + */ + idTokenKeyMatchesFilter(inputKey, filter) { + const key = inputKey.toLowerCase(); + if (filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) { + return false; + } + if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) { + return false; + } + return true; + } + /** + * Removes idToken from the cache + * @param key + */ + removeIdToken(key, correlationId) { + this.removeItem(key, correlationId); + } + /** + * Removes refresh token from the cache + * @param key + */ + removeRefreshToken(key, correlationId) { + this.removeItem(key, correlationId); + } + /** + * Retrieve AccessTokenEntity from cache + * @param account {AccountInfo} + * @param request {BaseAuthRequest} + * @param tokenKeys {?TokenKeys} + * @param performanceClient {?IPerformanceClient} + */ + getAccessToken(account, request, tokenKeys, targetRealm) { + const correlationId = request.correlationId; + this.commonLogger.trace("CacheManager - getAccessToken called", correlationId); + const scopes = ScopeSet.createSearchScopes(request.scopes); + const authScheme = request.authenticationScheme || AuthenticationScheme.BEARER; + const credentialType = authScheme.toLowerCase() !== AuthenticationScheme.BEARER.toLowerCase() ? CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME : CredentialType.ACCESS_TOKEN; + const accessTokenFilter = { + homeAccountId: account.homeAccountId, + environment: account.environment, + credentialType, + clientId: this.clientId, + realm: targetRealm || account.tenantId, + target: scopes, + tokenType: authScheme, + keyId: request.sshKid + }; + const accessTokenKeys = tokenKeys && tokenKeys.accessToken || this.getTokenKeys().accessToken; + const accessTokens = []; + accessTokenKeys.forEach((key) => { + if (this.accessTokenKeyMatchesFilter(key, accessTokenFilter, true)) { + const accessToken = this.getAccessTokenCredential(key, correlationId); + if (accessToken && this.credentialMatchesFilter(accessToken, accessTokenFilter, correlationId)) { + accessTokens.push(accessToken); + } + } + }); + const numAccessTokens = accessTokens.length; + if (numAccessTokens < 1) { + this.commonLogger.info("CacheManager:getAccessToken - No token found", correlationId); + return null; + } else if (numAccessTokens > 1) { + this.commonLogger.info("CacheManager:getAccessToken - Multiple access tokens found, clearing them", correlationId); + accessTokens.forEach((accessToken) => { + this.removeAccessToken(this.generateCredentialKey(accessToken), correlationId); + }); + this.performanceClient.addFields({ multiMatchedAT: accessTokens.length }, correlationId); + return null; + } + this.commonLogger.info("CacheManager:getAccessToken - Returning access token", correlationId); + return accessTokens[0]; + } + /** + * Validate the cache key against filter before retrieving and parsing cache value + * @param key + * @param filter + * @param keyMustContainAllScopes + * @returns + */ + accessTokenKeyMatchesFilter(inputKey, filter, keyMustContainAllScopes) { + const key = inputKey.toLowerCase(); + if (filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) { + return false; + } + if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) { + return false; + } + if (filter.realm && key.indexOf(filter.realm.toLowerCase()) === -1) { + return false; + } + if (filter.target) { + const scopes = filter.target.asArray(); + for (let i = 0; i < scopes.length; i++) { + if (keyMustContainAllScopes && !key.includes(scopes[i].toLowerCase())) { + return false; + } else if (!keyMustContainAllScopes && key.includes(scopes[i].toLowerCase())) { + return true; + } + } + } + return true; + } + /** + * Gets all access tokens matching the filter + * @param filter + * @returns + */ + getAccessTokensByFilter(filter, correlationId) { + const tokenKeys = this.getTokenKeys(); + const accessTokens = []; + tokenKeys.accessToken.forEach((key) => { + if (!this.accessTokenKeyMatchesFilter(key, filter, true)) { + return; + } + const accessToken = this.getAccessTokenCredential(key, correlationId); + if (accessToken && this.credentialMatchesFilter(accessToken, filter, correlationId)) { + accessTokens.push(accessToken); + } + }); + return accessTokens; + } + /** + * Helper to retrieve the appropriate refresh token from cache + * @param account {AccountInfo} + * @param familyRT {boolean} + * @param tokenKeys {?TokenKeys} + * @param performanceClient {?IPerformanceClient} + * @param correlationId {?string} + */ + getRefreshToken(account, familyRT, correlationId, tokenKeys) { + this.commonLogger.trace("CacheManager - getRefreshToken called", correlationId); + const id = familyRT ? THE_FAMILY_ID : void 0; + const refreshTokenFilter = { + homeAccountId: account.homeAccountId, + environment: account.environment, + credentialType: CredentialType.REFRESH_TOKEN, + clientId: this.clientId, + familyId: id + }; + const refreshTokenKeys = tokenKeys && tokenKeys.refreshToken || this.getTokenKeys().refreshToken; + const refreshTokens = []; + refreshTokenKeys.forEach((key) => { + if (this.refreshTokenKeyMatchesFilter(key, refreshTokenFilter)) { + const refreshToken = this.getRefreshTokenCredential(key, correlationId); + if (refreshToken && this.credentialMatchesFilter(refreshToken, refreshTokenFilter, correlationId)) { + refreshTokens.push(refreshToken); + } + } + }); + const numRefreshTokens = refreshTokens.length; + if (numRefreshTokens < 1) { + this.commonLogger.info("CacheManager:getRefreshToken - No refresh token found.", correlationId); + return null; + } + if (numRefreshTokens > 1) { + this.performanceClient.addFields({ multiMatchedRT: numRefreshTokens }, correlationId); + } + this.commonLogger.info("CacheManager:getRefreshToken - returning refresh token", correlationId); + return refreshTokens[0]; + } + /** + * Validate the cache key against filter before retrieving and parsing cache value + * @param key + * @param filter + */ + refreshTokenKeyMatchesFilter(inputKey, filter) { + const key = inputKey.toLowerCase(); + if (filter.familyId && key.indexOf(filter.familyId.toLowerCase()) === -1) { + return false; + } + if (!filter.familyId && filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) { + return false; + } + if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) { + return false; + } + return true; + } + /** + * Retrieve AppMetadataEntity from cache + */ + readAppMetadataFromCache(environment, correlationId) { + const appMetadataFilter = { + environment, + clientId: this.clientId + }; + const appMetadata = this.getAppMetadataFilteredBy(appMetadataFilter, correlationId); + const appMetadataEntries = Object.keys(appMetadata).map((key) => appMetadata[key]); + const numAppMetadata = appMetadataEntries.length; + if (numAppMetadata < 1) { + return null; + } else if (numAppMetadata > 1) { + throw createClientAuthError(multipleMatchingAppMetadata); + } + return appMetadataEntries[0]; + } + /** + * Return the family_id value associated with FOCI + * @param environment + * @param clientId + */ + isAppMetadataFOCI(environment, correlationId) { + const appMetadata = this.readAppMetadataFromCache(environment, correlationId); + return !!(appMetadata && appMetadata.familyId === THE_FAMILY_ID); + } + /** + * helper to match account ids + * @param value + * @param homeAccountId + */ + matchHomeAccountId(entity, homeAccountId) { + return !!(typeof entity.homeAccountId === "string" && homeAccountId === entity.homeAccountId); + } + /** + * helper to match account ids + * @param entity + * @param localAccountId + * @returns + */ + matchLocalAccountIdFromTokenClaims(tokenClaims, localAccountId) { + const idTokenLocalAccountId = tokenClaims.oid || tokenClaims.sub; + return localAccountId === idTokenLocalAccountId; + } + matchLocalAccountIdFromTenantProfile(tenantProfile, localAccountId) { + return tenantProfile.localAccountId === localAccountId; + } + /** + * helper to match names + * @param entity + * @param name + * @returns true if the downcased name properties are present and match in the filter and the entity + */ + matchName(claims, name2) { + return !!(name2.toLowerCase() === claims.name?.toLowerCase()); + } + /** + * helper to match usernames + * @param entity + * @param username + * @returns + */ + matchUsername(cachedUsername, filterUsername) { + return !!(cachedUsername && typeof cachedUsername === "string" && filterUsername?.toLowerCase() === cachedUsername.toLowerCase()); + } + /** + * helper to match assertion + * @param value + * @param oboAssertion + */ + matchUserAssertionHash(entity, userAssertionHash) { + return !!(entity.userAssertionHash && userAssertionHash === entity.userAssertionHash); + } + /** + * helper to match environment + * @param value + * @param environment + */ + matchEnvironment(entity, environment, correlationId) { + if (this.staticAuthorityOptions) { + const staticAliases = getAliasesFromStaticSources(this.staticAuthorityOptions, this.commonLogger, correlationId); + if (staticAliases.includes(environment) && staticAliases.includes(entity.environment)) { + return true; + } + } + const cloudMetadata = this.getAuthorityMetadataByAlias(environment, correlationId); + if (cloudMetadata && cloudMetadata.aliases.indexOf(entity.environment) > -1) { + return true; + } + return false; + } + /** + * helper to match credential type + * @param entity + * @param credentialType + */ + matchCredentialType(entity, credentialType) { + return entity.credentialType && credentialType.toLowerCase() === entity.credentialType.toLowerCase(); + } + /** + * helper to match client ids + * @param entity + * @param clientId + */ + matchClientId(entity, clientId) { + return !!(entity.clientId && clientId === entity.clientId); + } + /** + * helper to match family ids + * @param entity + * @param familyId + */ + matchFamilyId(entity, familyId) { + return !!(entity.familyId && familyId === entity.familyId); + } + /** + * helper to match realm + * @param entity + * @param realm + */ + matchRealm(entity, realm) { + return !!(entity.realm?.toLowerCase() === realm.toLowerCase()); + } + /** + * helper to match nativeAccountId + * @param entity + * @param nativeAccountId + * @returns boolean indicating the match result + */ + matchNativeAccountId(entity, nativeAccountId) { + return !!(entity.nativeAccountId && nativeAccountId === entity.nativeAccountId); + } + /** + * helper to match loginHint which can be either: + * 1. login_hint ID token claim + * 2. username in cached account object + * 3. upn in ID token claims + * @param entity + * @param loginHint + * @returns + */ + matchLoginHintFromTokenClaims(tokenClaims, loginHint) { + if (tokenClaims.login_hint === loginHint) { + return true; + } + if (tokenClaims.preferred_username === loginHint) { + return true; + } + if (tokenClaims.upn === loginHint) { + return true; + } + return false; + } + /** + * Helper to match sid + * @param entity + * @param sid + * @returns true if the sid claim is present and matches the filter + */ + matchSid(idTokenClaims, sid) { + return idTokenClaims.sid === sid; + } + matchAuthorityType(entity, authorityType) { + return !!(entity.authorityType && authorityType.toLowerCase() === entity.authorityType.toLowerCase()); + } + /** + * Returns true if the target scopes are a subset of the current entity's scopes, false otherwise. + * @param entity + * @param target + */ + matchTarget(entity, target) { + const isNotAccessTokenCredential = entity.credentialType !== CredentialType.ACCESS_TOKEN && entity.credentialType !== CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME; + if (isNotAccessTokenCredential || !entity.target) { + return false; + } + const entityScopeSet = ScopeSet.fromString(entity.target); + return entityScopeSet.containsScopeSet(target); + } + /** + * Returns true if the credential's tokenType or Authentication Scheme matches the one in the request, false otherwise + * @param entity + * @param tokenType + */ + matchTokenType(entity, tokenType) { + return !!(entity.tokenType && entity.tokenType === tokenType); + } + /** + * Returns true if the credential's keyId matches the one in the request, false otherwise + * @param entity + * @param keyId + */ + matchKeyId(entity, keyId) { + return !!(entity.keyId && entity.keyId === keyId); + } + /** + * returns if a given cache entity is of the type appmetadata + * @param key + */ + isAppMetadata(key) { + return key.indexOf(APP_METADATA) !== -1; + } + /** + * returns if a given cache entity is of the type authoritymetadata + * @param key + */ + isAuthorityMetadata(key) { + return key.indexOf(AUTHORITY_METADATA_CACHE_KEY) !== -1; + } + /** + * returns cache key used for cloud instance metadata + */ + generateAuthorityMetadataCacheKey(authority) { + return `${AUTHORITY_METADATA_CACHE_KEY}-${this.clientId}-${authority}`; + } + /** + * Helper to convert serialized data to object + * @param obj + * @param json + */ + static toObject(obj, json) { + for (const propertyName in json) { + obj[propertyName] = json[propertyName]; + } + return obj; + } + }; + var DefaultStorageClass = class extends CacheManager { + async setAccount() { + throw createClientAuthError(methodNotImplemented); + } + getAccount() { + throw createClientAuthError(methodNotImplemented); + } + async setIdTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + getIdTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + async setAccessTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + getAccessTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + async setRefreshTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + getRefreshTokenCredential() { + throw createClientAuthError(methodNotImplemented); + } + setAppMetadata() { + throw createClientAuthError(methodNotImplemented); + } + getAppMetadata() { + throw createClientAuthError(methodNotImplemented); + } + setServerTelemetry() { + throw createClientAuthError(methodNotImplemented); + } + getServerTelemetry() { + throw createClientAuthError(methodNotImplemented); + } + setAuthorityMetadata() { + throw createClientAuthError(methodNotImplemented); + } + getAuthorityMetadata() { + throw createClientAuthError(methodNotImplemented); + } + getAuthorityMetadataKeys() { + throw createClientAuthError(methodNotImplemented); + } + setThrottlingCache() { + throw createClientAuthError(methodNotImplemented); + } + getThrottlingCache() { + throw createClientAuthError(methodNotImplemented); + } + removeItem() { + throw createClientAuthError(methodNotImplemented); + } + getKeys() { + throw createClientAuthError(methodNotImplemented); + } + getAccountKeys() { + throw createClientAuthError(methodNotImplemented); + } + getTokenKeys() { + throw createClientAuthError(methodNotImplemented); + } + generateCredentialKey() { + throw createClientAuthError(methodNotImplemented); + } + generateAccountKey() { + throw createClientAuthError(methodNotImplemented); + } + }; + var PerformanceEventStatus = { + InProgress: 1 + }; + var StubPerformanceClient = class { + generateId() { + return "callback-id"; + } + startMeasurement(measureName, correlationId) { + return { + end: () => null, + discard: () => { + }, + add: () => { + }, + increment: () => { + }, + event: { + eventId: this.generateId(), + status: PerformanceEventStatus.InProgress, + authority: "", + libraryName: "", + libraryVersion: "", + clientId: "", + name: measureName, + startTimeMs: Date.now(), + correlationId: correlationId || "" + } + }; + } + endMeasurement() { + return null; + } + discardMeasurements() { + return; + } + removePerformanceCallback() { + return true; + } + addPerformanceCallback() { + return ""; + } + emitEvents() { + return; + } + addFields() { + return; + } + incrementFields() { + return; + } + cacheEventByCorrelationId() { + return; + } + }; + var DEFAULT_SYSTEM_OPTIONS$1 = { + tokenRenewalOffsetSeconds: DEFAULT_TOKEN_RENEWAL_OFFSET_SEC, + preventCorsPreflight: false + }; + var DEFAULT_LOGGER_IMPLEMENTATION = { + loggerCallback: () => { + }, + piiLoggingEnabled: false, + logLevel: exports2.LogLevel.Info, + correlationId: "" + }; + var DEFAULT_NETWORK_IMPLEMENTATION = { + async sendGetRequestAsync() { + throw createClientAuthError(methodNotImplemented); + }, + async sendPostRequestAsync() { + throw createClientAuthError(methodNotImplemented); + } + }; + var DEFAULT_LIBRARY_INFO = { + sku: SKU, + version: version$1, + cpu: "", + os: "" + }; + var DEFAULT_CLIENT_CREDENTIALS = { + clientSecret: "", + clientAssertion: void 0 + }; + var DEFAULT_AZURE_CLOUD_OPTIONS = { + azureCloudInstance: AzureCloudInstance.None, + tenant: `${DEFAULT_COMMON_TENANT}` + }; + var DEFAULT_TELEMETRY_OPTIONS$1 = { + application: { + appName: "", + appVersion: "" + } + }; + function buildClientConfiguration({ authOptions: userAuthOptions, systemOptions: userSystemOptions, loggerOptions: userLoggerOption, storageInterface: storageImplementation, networkInterface: networkImplementation, cryptoInterface: cryptoImplementation, clientCredentials, libraryInfo, telemetry, serverTelemetryManager, persistencePlugin, serializableCache }) { + const loggerOptions = { + ...DEFAULT_LOGGER_IMPLEMENTATION, + ...userLoggerOption + }; + return { + authOptions: buildAuthOptions(userAuthOptions), + systemOptions: { ...DEFAULT_SYSTEM_OPTIONS$1, ...userSystemOptions }, + loggerOptions, + storageInterface: storageImplementation || new DefaultStorageClass(userAuthOptions.clientId, DEFAULT_CRYPTO_IMPLEMENTATION, new Logger(loggerOptions), new StubPerformanceClient()), + networkInterface: networkImplementation || DEFAULT_NETWORK_IMPLEMENTATION, + cryptoInterface: cryptoImplementation || DEFAULT_CRYPTO_IMPLEMENTATION, + clientCredentials: clientCredentials || DEFAULT_CLIENT_CREDENTIALS, + libraryInfo: { ...DEFAULT_LIBRARY_INFO, ...libraryInfo }, + telemetry: { ...DEFAULT_TELEMETRY_OPTIONS$1, ...telemetry }, + serverTelemetryManager: serverTelemetryManager || null, + persistencePlugin: persistencePlugin || null, + serializableCache: serializableCache || null + }; + } + function buildAuthOptions(authOptions) { + return { + clientCapabilities: [], + azureCloudOptions: DEFAULT_AZURE_CLOUD_OPTIONS, + instanceAware: false, + isMcp: false, + ...authOptions + }; + } + function isOidcProtocolMode(config) { + return config.authOptions.authority.options.protocolMode === ProtocolMode.OIDC; + } + var TokenCacheContext = class { + constructor(tokenCache, hasChanged) { + this.cache = tokenCache; + this.hasChanged = hasChanged; + } + /** + * boolean which indicates the changes in cache + */ + get cacheHasChanged() { + return this.hasChanged; + } + /** + * function to retrieve the token cache + */ + get tokenCache() { + return this.cache; + } + }; + function nowSeconds() { + return Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3); + } + function toDateFromSeconds(seconds) { + if (seconds) { + return new Date(Number(seconds) * 1e3); + } + return /* @__PURE__ */ new Date(); + } + function isTokenExpired(expiresOn, offset) { + const expirationSec = Number(expiresOn) || 0; + const offsetCurrentTimeSec = nowSeconds() + offset; + return offsetCurrentTimeSec > expirationSec; + } + function wasClockTurnedBack(cachedAt) { + const cachedAtSec = Number(cachedAt); + return cachedAtSec > nowSeconds(); + } + function delay(t, value) { + return new Promise((resolve) => setTimeout(() => resolve(value), t)); + } + function createIdTokenEntity(homeAccountId, environment, idToken, clientId, tenantId) { + const idTokenEntity = { + credentialType: CredentialType.ID_TOKEN, + homeAccountId, + environment, + clientId, + secret: idToken, + realm: tenantId, + lastUpdatedAt: Date.now().toString() + // Set the last updated time to now + }; + return idTokenEntity; + } + function createAccessTokenEntity(homeAccountId, environment, accessToken, clientId, tenantId, scopes, expiresOn, extExpiresOn, base64Decode, refreshOn, tokenType, userAssertionHash, keyId) { + const atEntity = { + homeAccountId, + credentialType: CredentialType.ACCESS_TOKEN, + secret: accessToken, + cachedAt: nowSeconds().toString(), + expiresOn: expiresOn.toString(), + extendedExpiresOn: extExpiresOn.toString(), + environment, + clientId, + realm: tenantId, + target: scopes, + tokenType: tokenType || AuthenticationScheme.BEARER, + lastUpdatedAt: Date.now().toString() + // Set the last updated time to now + }; + if (userAssertionHash) { + atEntity.userAssertionHash = userAssertionHash; + } + if (refreshOn) { + atEntity.refreshOn = refreshOn.toString(); + } + if (atEntity.tokenType?.toLowerCase() !== AuthenticationScheme.BEARER.toLowerCase()) { + atEntity.credentialType = CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME; + switch (atEntity.tokenType) { + case AuthenticationScheme.POP: + const tokenClaims = extractTokenClaims(accessToken, base64Decode); + if (!tokenClaims?.cnf?.kid) { + throw createClientAuthError(tokenClaimsCnfRequiredForSignedJwt); + } + atEntity.keyId = tokenClaims.cnf.kid; + break; + case AuthenticationScheme.SSH: + atEntity.keyId = keyId; + } + } + return atEntity; + } + function createRefreshTokenEntity(homeAccountId, environment, refreshToken, clientId, familyId, userAssertionHash, expiresOn) { + const rtEntity = { + credentialType: CredentialType.REFRESH_TOKEN, + homeAccountId, + environment, + clientId, + secret: refreshToken, + lastUpdatedAt: Date.now().toString() + }; + if (userAssertionHash) { + rtEntity.userAssertionHash = userAssertionHash; + } + if (familyId) { + rtEntity.familyId = familyId; + } + if (expiresOn) { + rtEntity.expiresOn = expiresOn.toString(); + } + return rtEntity; + } + function isCredentialEntity(entity) { + return entity.hasOwnProperty("homeAccountId") && entity.hasOwnProperty("environment") && entity.hasOwnProperty("credentialType") && entity.hasOwnProperty("clientId") && entity.hasOwnProperty("secret"); + } + function isAccessTokenEntity(entity) { + if (!entity) { + return false; + } + return isCredentialEntity(entity) && entity.hasOwnProperty("realm") && entity.hasOwnProperty("target") && (entity["credentialType"] === CredentialType.ACCESS_TOKEN || entity["credentialType"] === CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME); + } + function isIdTokenEntity(entity) { + if (!entity) { + return false; + } + return isCredentialEntity(entity) && entity.hasOwnProperty("realm") && entity["credentialType"] === CredentialType.ID_TOKEN; + } + function isRefreshTokenEntity(entity) { + if (!entity) { + return false; + } + return isCredentialEntity(entity) && entity["credentialType"] === CredentialType.REFRESH_TOKEN; + } + function isServerTelemetryEntity(key, entity) { + const validateKey = key.indexOf(SERVER_TELEM_CACHE_KEY) === 0; + let validateEntity = true; + if (entity) { + validateEntity = entity.hasOwnProperty("failedRequests") && entity.hasOwnProperty("errors") && entity.hasOwnProperty("cacheHits"); + } + return validateKey && validateEntity; + } + function isThrottlingEntity(key, entity) { + let validateKey = false; + if (key) { + validateKey = key.indexOf(THROTTLING_PREFIX) === 0; + } + let validateEntity = true; + if (entity) { + validateEntity = entity.hasOwnProperty("throttleTime"); + } + return validateKey && validateEntity; + } + function generateAppMetadataKey({ environment, clientId }) { + const appMetaDataKeyArray = [ + APP_METADATA, + environment, + clientId + ]; + return appMetaDataKeyArray.join(CACHE_KEY_SEPARATOR).toLowerCase(); + } + function isAppMetadataEntity(key, entity) { + if (!entity) { + return false; + } + return key.indexOf(APP_METADATA) === 0 && entity.hasOwnProperty("clientId") && entity.hasOwnProperty("environment"); + } + function isAuthorityMetadataEntity(key, entity) { + if (!entity) { + return false; + } + return key.indexOf(AUTHORITY_METADATA_CACHE_KEY) === 0 && entity.hasOwnProperty("aliases") && entity.hasOwnProperty("preferred_cache") && entity.hasOwnProperty("preferred_network") && entity.hasOwnProperty("canonical_authority") && entity.hasOwnProperty("authorization_endpoint") && entity.hasOwnProperty("token_endpoint") && entity.hasOwnProperty("issuer") && entity.hasOwnProperty("aliasesFromNetwork") && entity.hasOwnProperty("endpointsFromNetwork") && entity.hasOwnProperty("expiresAt") && entity.hasOwnProperty("jwks_uri"); + } + function generateAuthorityMetadataExpiresAt() { + return nowSeconds() + AUTHORITY_METADATA_REFRESH_TIME_SECONDS; + } + function updateAuthorityEndpointMetadata(authorityMetadata, updatedValues, fromNetwork) { + authorityMetadata.authorization_endpoint = updatedValues.authorization_endpoint; + authorityMetadata.token_endpoint = updatedValues.token_endpoint; + authorityMetadata.end_session_endpoint = updatedValues.end_session_endpoint; + authorityMetadata.issuer = updatedValues.issuer; + authorityMetadata.endpointsFromNetwork = fromNetwork; + authorityMetadata.jwks_uri = updatedValues.jwks_uri; + } + function updateCloudDiscoveryMetadata(authorityMetadata, updatedValues, fromNetwork) { + authorityMetadata.aliases = updatedValues.aliases; + authorityMetadata.preferred_cache = updatedValues.preferred_cache; + authorityMetadata.preferred_network = updatedValues.preferred_network; + authorityMetadata.aliasesFromNetwork = fromNetwork; + } + function isAuthorityMetadataExpired(metadata) { + return metadata.expiresAt <= nowSeconds(); + } + var NetworkClientSendPostRequestAsync = "networkClientSendPostRequestAsync"; + var RefreshTokenClientExecutePostToTokenEndpoint = "refreshTokenClientExecutePostToTokenEndpoint"; + var AuthorizationCodeClientExecutePostToTokenEndpoint = "authorizationCodeClientExecutePostToTokenEndpoint"; + var RefreshTokenClientExecuteTokenRequest = "refreshTokenClientExecuteTokenRequest"; + var RefreshTokenClientAcquireToken = "refreshTokenClientAcquireToken"; + var RefreshTokenClientAcquireTokenWithCachedRefreshToken = "refreshTokenClientAcquireTokenWithCachedRefreshToken"; + var RefreshTokenClientCreateTokenRequestBody = "refreshTokenClientCreateTokenRequestBody"; + var SilentFlowClientGenerateResultFromCacheRecord = "silentFlowClientGenerateResultFromCacheRecord"; + var AuthClientExecuteTokenRequest = "authClientExecuteTokenRequest"; + var AuthClientCreateTokenRequestBody = "authClientCreateTokenRequestBody"; + var UpdateTokenEndpointAuthority = "updateTokenEndpointAuthority"; + var PopTokenGenerateCnf = "popTokenGenerateCnf"; + var HandleServerTokenResponse = "handleServerTokenResponse"; + var AuthorityResolveEndpointsAsync = "authorityResolveEndpointsAsync"; + var AuthorityGetCloudDiscoveryMetadataFromNetwork = "authorityGetCloudDiscoveryMetadataFromNetwork"; + var AuthorityUpdateCloudDiscoveryMetadata = "authorityUpdateCloudDiscoveryMetadata"; + var AuthorityGetEndpointMetadataFromNetwork = "authorityGetEndpointMetadataFromNetwork"; + var AuthorityUpdateEndpointMetadata = "authorityUpdateEndpointMetadata"; + var AuthorityUpdateMetadataWithRegionalInformation = "authorityUpdateMetadataWithRegionalInformation"; + var RegionDiscoveryDetectRegion = "regionDiscoveryDetectRegion"; + var RegionDiscoveryGetRegionFromIMDS = "regionDiscoveryGetRegionFromIMDS"; + var RegionDiscoveryGetCurrentVersion = "regionDiscoveryGetCurrentVersion"; + var CacheManagerGetRefreshToken = "cacheManagerGetRefreshToken"; + var invoke = (callback, eventName, logger, telemetryClient, correlationId) => { + return (...args) => { + logger.trace(`Executing function '${eventName}'`, correlationId); + const inProgressEvent = telemetryClient.startMeasurement(eventName, correlationId); + if (correlationId) { + telemetryClient.incrementFields({ [`ext.${eventName}CallCount`]: 1 }, correlationId); + } + try { + const result = callback(...args); + inProgressEvent.end({ + success: true + }); + logger.trace(`Returning result from '${eventName}'`, correlationId); + return result; + } catch (e) { + logger.trace(`Error occurred in '${eventName}'`, correlationId); + try { + logger.trace(JSON.stringify(e), correlationId); + } catch (e2) { + logger.trace("Unable to print error message.", correlationId); + } + inProgressEvent.end({ + success: false + }, e); + throw e; + } + }; + }; + var invokeAsync = (callback, eventName, logger, telemetryClient, correlationId) => { + return (...args) => { + logger.trace(`Executing function '${eventName}'`, correlationId); + const inProgressEvent = telemetryClient.startMeasurement(eventName, correlationId); + if (correlationId) { + telemetryClient.incrementFields({ [`ext.${eventName}CallCount`]: 1 }, correlationId); + } + return callback(...args).then((response) => { + logger.trace(`Returning result from '${eventName}'`, correlationId); + inProgressEvent.end({ + success: true + }); + return response; + }).catch((e) => { + logger.trace(`Error occurred in '${eventName}'`, correlationId); + try { + logger.trace(JSON.stringify(e), correlationId); + } catch (e2) { + logger.trace("Unable to print error message.", correlationId); + } + inProgressEvent.end({ + success: false + }, e); + throw e; + }); + }; + }; + var KeyLocation = { + SW: "sw" + }; + var PopTokenGenerator = class { + constructor(cryptoUtils, performanceClient) { + this.cryptoUtils = cryptoUtils; + this.performanceClient = performanceClient; + } + /** + * Generates the req_cnf validated at the RP in the POP protocol for SHR parameters + * and returns an object containing the keyid, the full req_cnf string and the req_cnf string hash + * @param request + * @returns + */ + async generateCnf(request, logger) { + const reqCnf = await invokeAsync(this.generateKid.bind(this), PopTokenGenerateCnf, logger, this.performanceClient, request.correlationId)(request); + const reqCnfString = this.cryptoUtils.base64UrlEncode(JSON.stringify(reqCnf)); + return { + kid: reqCnf.kid, + reqCnfString + }; + } + /** + * Generates key_id for a SHR token request + * @param request + * @returns + */ + async generateKid(request) { + const kidThumbprint = await this.cryptoUtils.getPublicKeyThumbprint(request); + return { + kid: kidThumbprint, + xms_ksl: KeyLocation.SW + }; + } + /** + * Signs the POP access_token with the local generated key-pair + * @param accessToken + * @param request + * @returns + */ + async signPopToken(accessToken, keyId, request) { + return this.signPayload(accessToken, keyId, request); + } + /** + * Utility function to generate the signed JWT for an access_token + * @param payload + * @param kid + * @param request + * @param claims + * @returns + */ + async signPayload(payload, keyId, request, claims) { + const { resourceRequestMethod, resourceRequestUri, shrClaims, shrNonce, shrOptions } = request; + const resourceUrlString = resourceRequestUri ? new UrlString(resourceRequestUri) : void 0; + const resourceUrlComponents = resourceUrlString?.getUrlComponents(); + return this.cryptoUtils.signJwt({ + at: payload, + ts: nowSeconds(), + m: resourceRequestMethod?.toUpperCase(), + u: resourceUrlComponents?.HostNameAndPort, + nonce: shrNonce || this.cryptoUtils.createNewGuid(), + p: resourceUrlComponents?.AbsolutePath, + q: resourceUrlComponents?.QueryString ? [[], resourceUrlComponents.QueryString] : void 0, + client_claims: shrClaims || void 0, + ...claims + }, keyId, shrOptions, request.correlationId); + } + }; + var noTokensFound = "no_tokens_found"; + var nativeAccountUnavailable = "native_account_unavailable"; + var refreshTokenExpired = "refresh_token_expired"; + var uxNotAllowed = "ux_not_allowed"; + var interactionRequired = "interaction_required"; + var consentRequired = "consent_required"; + var loginRequired = "login_required"; + var badToken = "bad_token"; + var interruptedUser = "interrupted_user"; + var InteractionRequiredAuthErrorCodes = /* @__PURE__ */ Object.freeze({ + __proto__: null, + badToken, + consentRequired, + interactionRequired, + interruptedUser, + loginRequired, + nativeAccountUnavailable, + noTokensFound, + refreshTokenExpired, + uxNotAllowed + }); + var InteractionRequiredServerErrorMessage = [ + interactionRequired, + consentRequired, + loginRequired, + badToken, + uxNotAllowed, + interruptedUser + ]; + var InteractionRequiredAuthSubErrorMessage = [ + "message_only", + "additional_action", + "basic_action", + "user_password_expired", + "consent_required", + "bad_token", + "ux_not_allowed", + "interrupted_user" + ]; + var InteractionRequiredAuthError = class _InteractionRequiredAuthError extends AuthError { + constructor(errorCode, errorMessage, subError, timestamp, traceId, correlationId, claims, errorNo) { + super(errorCode, errorMessage, subError); + Object.setPrototypeOf(this, _InteractionRequiredAuthError.prototype); + this.timestamp = timestamp || ""; + this.traceId = traceId || ""; + this.correlationId = correlationId || ""; + this.claims = claims || ""; + this.name = "InteractionRequiredAuthError"; + this.errorNo = errorNo; + } + }; + function isInteractionRequiredError(errorCode, errorString, subError) { + const isInteractionRequiredErrorCode = !!errorCode && InteractionRequiredServerErrorMessage.indexOf(errorCode) > -1; + const isInteractionRequiredSubError = !!subError && InteractionRequiredAuthSubErrorMessage.indexOf(subError) > -1; + const isInteractionRequiredErrorDesc = !!errorString && InteractionRequiredServerErrorMessage.some((irErrorCode) => { + return errorString.indexOf(irErrorCode) > -1; + }); + return isInteractionRequiredErrorCode || isInteractionRequiredErrorDesc || isInteractionRequiredSubError; + } + function createInteractionRequiredAuthError(errorCode, errorMessage) { + return new InteractionRequiredAuthError(errorCode, errorMessage); + } + var ServerError = class _ServerError extends AuthError { + constructor(errorCode, errorMessage, subError, errorNo, status) { + super(errorCode, errorMessage, subError); + this.name = "ServerError"; + this.errorNo = errorNo; + this.status = status; + Object.setPrototypeOf(this, _ServerError.prototype); + } + }; + function parseRequestState(base64Decode, state) { + if (!base64Decode) { + throw createClientAuthError(noCryptoObject); + } + if (!state) { + throw createClientAuthError(invalidState); + } + try { + const splitState = state.split(RESOURCE_DELIM); + const libraryState = splitState[0]; + const userState = splitState.length > 1 ? splitState.slice(1).join(RESOURCE_DELIM) : ""; + const libraryStateString = base64Decode(libraryState); + const libraryStateObj = JSON.parse(libraryStateString); + return { + userRequestState: userState || "", + libraryState: libraryStateObj + }; + } catch (e) { + throw createClientAuthError(invalidState); + } + } + var ResponseHandler = class _ResponseHandler { + constructor(clientId, cacheStorage, cryptoObj, logger, performanceClient, serializableCache, persistencePlugin) { + this.clientId = clientId; + this.cacheStorage = cacheStorage; + this.cryptoObj = cryptoObj; + this.logger = logger; + this.performanceClient = performanceClient; + this.serializableCache = serializableCache; + this.persistencePlugin = persistencePlugin; + } + /** + * Function which validates server authorization token response. + * @param serverResponse + * @param correlationId + * @param refreshAccessToken + */ + validateTokenResponse(serverResponse, correlationId, refreshAccessToken) { + if (serverResponse.error || serverResponse.error_description || serverResponse.suberror) { + const errString = `Error(s): ${serverResponse.error_codes || NOT_AVAILABLE} - Timestamp: ${serverResponse.timestamp || NOT_AVAILABLE} - Description: ${serverResponse.error_description || NOT_AVAILABLE} - Correlation ID: ${serverResponse.correlation_id || NOT_AVAILABLE} - Trace ID: ${serverResponse.trace_id || NOT_AVAILABLE}`; + const serverErrorNo = serverResponse.error_codes?.length ? serverResponse.error_codes[0] : void 0; + const serverError = new ServerError(serverResponse.error, errString, serverResponse.suberror, serverErrorNo, serverResponse.status); + if (refreshAccessToken && serverResponse.status && serverResponse.status >= HTTP_SERVER_ERROR_RANGE_START && serverResponse.status <= HTTP_SERVER_ERROR_RANGE_END) { + this.logger.warning(`executeTokenRequest:validateTokenResponse - AAD is currently unavailable and the access token is unable to be refreshed. +${serverError}`, correlationId); + return; + } else if (refreshAccessToken && serverResponse.status && serverResponse.status >= HTTP_CLIENT_ERROR_RANGE_START && serverResponse.status <= HTTP_CLIENT_ERROR_RANGE_END) { + this.logger.warning(`executeTokenRequest:validateTokenResponse - AAD is currently available but is unable to refresh the access token. +${serverError}`, correlationId); + return; + } + if (isInteractionRequiredError(serverResponse.error, serverResponse.error_description, serverResponse.suberror)) { + throw new InteractionRequiredAuthError(serverResponse.error, serverResponse.error_description, serverResponse.suberror, serverResponse.timestamp || "", serverResponse.trace_id || "", serverResponse.correlation_id || "", serverResponse.claims || "", serverErrorNo); + } + throw serverError; + } + } + /** + * Returns a constructed token response based on given string. Also manages the cache updates and cleanups. + * @param serverTokenResponse + * @param authority + */ + async handleServerTokenResponse(serverTokenResponse, authority, reqTimestamp, request, apiId, authCodePayload, userAssertionHash, handlingRefreshTokenResponse, forceCacheRefreshTokenResponse, serverRequestId) { + let idTokenClaims; + if (serverTokenResponse.id_token) { + idTokenClaims = extractTokenClaims(serverTokenResponse.id_token || "", this.cryptoObj.base64Decode); + if (authCodePayload && authCodePayload.nonce) { + if (idTokenClaims.nonce !== authCodePayload.nonce) { + throw createClientAuthError(nonceMismatch); + } + } + if (request.maxAge || request.maxAge === 0) { + const authTime = idTokenClaims.auth_time; + if (!authTime) { + throw createClientAuthError(authTimeNotFound); + } + checkMaxAge(authTime, request.maxAge); + } + } + this.homeAccountIdentifier = generateHomeAccountId(serverTokenResponse.client_info || "", authority.authorityType, this.logger, this.cryptoObj, request.correlationId, idTokenClaims); + let requestStateObj; + if (!!authCodePayload && !!authCodePayload.state) { + requestStateObj = parseRequestState(this.cryptoObj.base64Decode, authCodePayload.state); + } + serverTokenResponse.key_id = serverTokenResponse.key_id || request.sshKid || void 0; + const cacheRecord = this.generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenClaims, userAssertionHash, authCodePayload); + let cacheContext; + try { + if (this.persistencePlugin && this.serializableCache) { + this.logger.verbose("Persistence enabled, calling beforeCacheAccess", request.correlationId); + cacheContext = new TokenCacheContext(this.serializableCache, true); + await this.persistencePlugin.beforeCacheAccess(cacheContext); + } + if (handlingRefreshTokenResponse && !forceCacheRefreshTokenResponse && cacheRecord.account) { + const cachedAccounts = this.cacheStorage.getAllAccounts({ + homeAccountId: cacheRecord.account.homeAccountId, + environment: cacheRecord.account.environment + }, request.correlationId); + if (cachedAccounts.length < 1) { + this.logger.warning("Account used to refresh tokens not in persistence, refreshed tokens will not be stored in the cache", request.correlationId); + this.performanceClient?.addFields({ + acntLoggedOut: true + }, request.correlationId); + return await _ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, this.performanceClient, idTokenClaims, requestStateObj, void 0, serverRequestId); + } + } + await this.cacheStorage.saveCacheRecord(cacheRecord, request.correlationId, isKmsi(idTokenClaims || {}), apiId, request.storeInCache); + } finally { + if (this.persistencePlugin && this.serializableCache && cacheContext) { + this.logger.verbose("Persistence enabled, calling afterCacheAccess", request.correlationId); + await this.persistencePlugin.afterCacheAccess(cacheContext); + } + } + return _ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, this.performanceClient, idTokenClaims, requestStateObj, serverTokenResponse, serverRequestId); + } + /** + * Generates CacheRecord + * @param serverTokenResponse + * @param idTokenObj + * @param authority + */ + generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenClaims, userAssertionHash, authCodePayload) { + const env = authority.getPreferredCache(); + if (!env) { + throw createClientAuthError(invalidCacheEnvironment); + } + const claimsTenantId = getTenantIdFromIdTokenClaims(idTokenClaims); + let cachedIdToken; + let cachedAccount; + if (serverTokenResponse.id_token && !!idTokenClaims) { + cachedIdToken = createIdTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.id_token, this.clientId, claimsTenantId || ""); + cachedAccount = buildAccountToCache( + this.cacheStorage, + authority, + this.homeAccountIdentifier, + this.cryptoObj.base64Decode, + request.correlationId, + idTokenClaims, + serverTokenResponse.client_info, + env, + claimsTenantId, + authCodePayload, + void 0, + // nativeAccountId + this.logger, + this.performanceClient + ); + } + let cachedAccessToken = null; + if (serverTokenResponse.access_token) { + const responseScopes = serverTokenResponse.scope ? ScopeSet.fromString(serverTokenResponse.scope) : new ScopeSet(request.scopes || []); + const expiresIn = (typeof serverTokenResponse.expires_in === "string" ? parseInt(serverTokenResponse.expires_in, 10) : serverTokenResponse.expires_in) || 0; + const extExpiresIn = (typeof serverTokenResponse.ext_expires_in === "string" ? parseInt(serverTokenResponse.ext_expires_in, 10) : serverTokenResponse.ext_expires_in) || 0; + const refreshIn = (typeof serverTokenResponse.refresh_in === "string" ? parseInt(serverTokenResponse.refresh_in, 10) : serverTokenResponse.refresh_in) || void 0; + const tokenExpirationSeconds = reqTimestamp + expiresIn; + const extendedTokenExpirationSeconds = tokenExpirationSeconds + extExpiresIn; + const refreshOnSeconds = refreshIn && refreshIn > 0 ? reqTimestamp + refreshIn : void 0; + cachedAccessToken = createAccessTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.access_token, this.clientId, claimsTenantId || authority.tenant || "", responseScopes.printScopes(), tokenExpirationSeconds, extendedTokenExpirationSeconds, this.cryptoObj.base64Decode, refreshOnSeconds, serverTokenResponse.token_type, userAssertionHash, serverTokenResponse.key_id); + const resource = request.resource || null; + if (resource) { + cachedAccessToken.resource = resource; + } + } + let cachedRefreshToken = null; + if (serverTokenResponse.refresh_token) { + let rtExpiresOn; + if (serverTokenResponse.refresh_token_expires_in) { + const rtExpiresIn = typeof serverTokenResponse.refresh_token_expires_in === "string" ? parseInt(serverTokenResponse.refresh_token_expires_in, 10) : serverTokenResponse.refresh_token_expires_in; + rtExpiresOn = reqTimestamp + rtExpiresIn; + this.performanceClient?.addFields({ ntwkRtExpiresOnSeconds: rtExpiresOn }, request.correlationId); + } + cachedRefreshToken = createRefreshTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.refresh_token, this.clientId, serverTokenResponse.foci, userAssertionHash, rtExpiresOn); + } + let cachedAppMetadata = null; + if (serverTokenResponse.foci) { + cachedAppMetadata = { + clientId: this.clientId, + environment: env, + familyId: serverTokenResponse.foci + }; + } + return { + account: cachedAccount, + idToken: cachedIdToken, + accessToken: cachedAccessToken, + refreshToken: cachedRefreshToken, + appMetadata: cachedAppMetadata + }; + } + /** + * Creates an @AuthenticationResult from @CacheRecord , @IdToken , and a boolean that states whether or not the result is from cache. + * + * Optionally takes a state string that is set as-is in the response. + * + * @param cacheRecord + * @param idTokenObj + * @param fromTokenCache + * @param stateString + */ + static async generateAuthenticationResult(cryptoObj, authority, cacheRecord, fromTokenCache, request, performanceClient, idTokenClaims, requestState, serverTokenResponse, requestId) { + let accessToken = ""; + let responseScopes = []; + let expiresOn = null; + let extExpiresOn; + let refreshOn; + let familyId = ""; + if (cacheRecord.accessToken) { + if (cacheRecord.accessToken.tokenType === AuthenticationScheme.POP && !request.popKid) { + const popTokenGenerator = new PopTokenGenerator(cryptoObj, performanceClient); + const { secret, keyId } = cacheRecord.accessToken; + if (!keyId) { + throw createClientAuthError(keyIdMissing); + } + accessToken = await popTokenGenerator.signPopToken(secret, keyId, request); + } else { + accessToken = cacheRecord.accessToken.secret; + } + responseScopes = ScopeSet.fromString(cacheRecord.accessToken.target).asArray(); + expiresOn = toDateFromSeconds(cacheRecord.accessToken.expiresOn); + extExpiresOn = toDateFromSeconds(cacheRecord.accessToken.extendedExpiresOn); + if (cacheRecord.accessToken.refreshOn) { + refreshOn = toDateFromSeconds(cacheRecord.accessToken.refreshOn); + } + } + if (cacheRecord.appMetadata) { + familyId = cacheRecord.appMetadata.familyId === THE_FAMILY_ID ? THE_FAMILY_ID : ""; + } + const uid = idTokenClaims?.oid || idTokenClaims?.sub || ""; + const tid = idTokenClaims?.tid || ""; + if (serverTokenResponse?.spa_accountid && !!cacheRecord.account) { + cacheRecord.account.nativeAccountId = serverTokenResponse?.spa_accountid; + } + const accountInfo = cacheRecord.account ? updateAccountTenantProfileData( + getAccountInfo(cacheRecord.account), + void 0, + // tenantProfile optional + idTokenClaims, + cacheRecord.idToken?.secret + ) : null; + return { + authority: authority.canonicalAuthority, + uniqueId: uid, + tenantId: tid, + scopes: responseScopes, + account: accountInfo, + idToken: cacheRecord?.idToken?.secret || "", + idTokenClaims: idTokenClaims || {}, + accessToken, + fromCache: fromTokenCache, + expiresOn, + extExpiresOn, + refreshOn, + correlationId: request.correlationId, + requestId: requestId || "", + familyId, + tokenType: cacheRecord.accessToken?.tokenType || "", + state: requestState ? requestState.userRequestState : "", + cloudGraphHostName: cacheRecord.account?.cloudGraphHostName || "", + msGraphHost: cacheRecord.account?.msGraphHost || "", + code: serverTokenResponse?.spa_code, + fromPlatformBroker: false + }; + } + }; + function buildAccountToCache(cacheStorage, authority, homeAccountId, base64Decode, correlationId, idTokenClaims, clientInfo, environment, claimsTenantId, authCodePayload, nativeAccountId, logger, performanceClient) { + logger?.verbose("setCachedAccount called", correlationId); + const accountEnvironment = environment || authority.getPreferredCache(); + const matchedAccounts = cacheStorage.getAccountsFilteredBy({ homeAccountId, environment: accountEnvironment }, correlationId); + performanceClient?.addFields({ cacheMatchedAccounts: matchedAccounts.length }, correlationId); + if (matchedAccounts.length > 1) { + logger?.warning("Multiple base accounts matched homeAccountId. Ignoring cached account and creating a new base account.", correlationId); + } + const cachedAccount = matchedAccounts.length === 1 ? matchedAccounts[0] : null; + const baseAccount = cachedAccount || createAccountEntity({ + homeAccountId, + idTokenClaims, + clientInfo, + environment, + cloudGraphHostName: authCodePayload?.cloud_graph_host_name, + msGraphHost: authCodePayload?.msgraph_host, + nativeAccountId + }, authority, base64Decode); + const tenantProfiles = baseAccount.tenantProfiles || []; + const tenantId = claimsTenantId || baseAccount.realm; + if (tenantId && !tenantProfiles.find((tenantProfile) => { + return tenantProfile.tenantId === tenantId; + })) { + const newTenantProfile = buildTenantProfile(homeAccountId, baseAccount.localAccountId, tenantId, idTokenClaims); + tenantProfiles.push(newTenantProfile); + } + baseAccount.tenantProfiles = tenantProfiles; + return baseAccount; + } + var CcsCredentialType = { + HOME_ACCOUNT_ID: "home_account_id", + UPN: "UPN" + }; + async function getClientAssertion(clientAssertion, clientId, tokenEndpoint) { + if (typeof clientAssertion === "string") { + return clientAssertion; + } else { + const config = { + clientId, + tokenEndpoint + }; + return clientAssertion(config); + } + } + function getRequestThumbprint(clientId, request, homeAccountId) { + return { + clientId, + authority: request.authority, + scopes: request.scopes, + homeAccountIdentifier: homeAccountId, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid, + embeddedClientId: request.embeddedClientId || request.extraParameters?.clientId + }; + } + var ThrottlingUtils = class _ThrottlingUtils { + /** + * Prepares a RequestThumbprint to be stored as a key. + * @param thumbprint + */ + static generateThrottlingStorageKey(thumbprint) { + return `${THROTTLING_PREFIX}.${JSON.stringify(thumbprint)}`; + } + /** + * Performs necessary throttling checks before a network request. + * @param cacheManager + * @param thumbprint + */ + static preProcess(cacheManager, thumbprint, correlationId) { + const key = _ThrottlingUtils.generateThrottlingStorageKey(thumbprint); + const value = cacheManager.getThrottlingCache(key, correlationId); + if (value) { + if (value.throttleTime < Date.now()) { + cacheManager.removeItem(key, correlationId); + return; + } + throw new ServerError(value.errorCodes?.join(" ") || "", value.errorMessage, value.subError); + } + } + /** + * Performs necessary throttling checks after a network request. + * @param cacheManager + * @param thumbprint + * @param response + */ + static postProcess(cacheManager, thumbprint, response, correlationId) { + if (_ThrottlingUtils.checkResponseStatus(response) || _ThrottlingUtils.checkResponseForRetryAfter(response)) { + const thumbprintValue = { + throttleTime: _ThrottlingUtils.calculateThrottleTime(parseInt(response.headers[HeaderNames.RETRY_AFTER])), + error: response.body.error, + errorCodes: response.body.error_codes, + errorMessage: response.body.error_description, + subError: response.body.suberror + }; + cacheManager.setThrottlingCache(_ThrottlingUtils.generateThrottlingStorageKey(thumbprint), thumbprintValue, correlationId); + } + } + /** + * Checks a NetworkResponse object's status codes against 429 or 5xx + * @param response + */ + static checkResponseStatus(response) { + return response.status === 429 || response.status >= 500 && response.status < 600; + } + /** + * Checks a NetworkResponse object's RetryAfter header + * @param response + */ + static checkResponseForRetryAfter(response) { + if (response.headers) { + return response.headers.hasOwnProperty(HeaderNames.RETRY_AFTER) && (response.status < 200 || response.status >= 300); + } + return false; + } + /** + * Calculates the Unix-time value for a throttle to expire given throttleTime in seconds. + * @param throttleTime + */ + static calculateThrottleTime(throttleTime) { + const time = throttleTime <= 0 ? 0 : throttleTime; + const currentSeconds = Date.now() / 1e3; + return Math.floor(Math.min(currentSeconds + (time || DEFAULT_THROTTLE_TIME_SECONDS), currentSeconds + DEFAULT_MAX_THROTTLE_TIME_SECONDS) * 1e3); + } + static removeThrottle(cacheManager, clientId, request, homeAccountIdentifier) { + const thumbprint = getRequestThumbprint(clientId, request, homeAccountIdentifier); + const key = this.generateThrottlingStorageKey(thumbprint); + cacheManager.removeItem(key, request.correlationId); + } + }; + var NetworkError = class _NetworkError extends AuthError { + constructor(error, httpStatus, responseHeaders) { + super(error.errorCode, error.errorMessage, error.subError); + Object.setPrototypeOf(this, _NetworkError.prototype); + this.name = "NetworkError"; + this.error = error; + this.httpStatus = httpStatus; + this.responseHeaders = responseHeaders; + } + }; + function createNetworkError(error, httpStatus, responseHeaders, additionalError) { + error.errorMessage = `${error.errorMessage}, additionalErrorInfo: error.name:${additionalError?.name}, error.message:${additionalError?.message}`; + return new NetworkError(error, httpStatus, responseHeaders); + } + function createTokenRequestHeaders(logger, preventCorsPreflight, ccsCred) { + const headers = {}; + headers[HeaderNames.CONTENT_TYPE] = URL_FORM_CONTENT_TYPE; + if (!preventCorsPreflight && ccsCred) { + switch (ccsCred.type) { + case CcsCredentialType.HOME_ACCOUNT_ID: + try { + const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential); + headers[HeaderNames.CCS_HEADER] = `Oid:${clientInfo.uid}@${clientInfo.utid}`; + } catch (e) { + logger.verbose(`Could not parse home account ID for CCS Header: '${e}'`, ""); + } + break; + case CcsCredentialType.UPN: + headers[HeaderNames.CCS_HEADER] = `UPN: ${ccsCred.credential}`; + break; + } + } + return headers; + } + function createTokenQueryParameters(request, clientId, redirectUri, performanceClient) { + const parameters = /* @__PURE__ */ new Map(); + if (request.embeddedClientId) { + addBrokerParameters(parameters, clientId, redirectUri); + } + if (request.extraQueryParameters) { + addExtraParameters(parameters, request.extraQueryParameters); + } + addCorrelationId(parameters, request.correlationId); + instrumentBrokerParams(parameters, request.correlationId, performanceClient); + return mapToQueryString(parameters); + } + async function executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint, correlationId, cacheManager, networkClient, logger, performanceClient, serverTelemetryManager) { + const response = await sendPostRequest(thumbprint, tokenEndpoint, { body: queryString, headers }, correlationId, cacheManager, networkClient, logger, performanceClient); + if (serverTelemetryManager && response.status < 500 && response.status !== 429) { + serverTelemetryManager.clearTelemetryCache(); + } + return response; + } + async function sendPostRequest(thumbprint, tokenEndpoint, options, correlationId, cacheManager, networkClient, logger, performanceClient) { + ThrottlingUtils.preProcess(cacheManager, thumbprint, correlationId); + let response; + try { + response = await invokeAsync(networkClient.sendPostRequestAsync.bind(networkClient), NetworkClientSendPostRequestAsync, logger, performanceClient, correlationId)(tokenEndpoint, options); + const responseHeaders = response.headers || {}; + performanceClient?.addFields({ + refreshTokenSize: response.body.refresh_token?.length || 0, + httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "", + requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] || "" + }, correlationId); + } catch (e) { + if (e instanceof NetworkError) { + const responseHeaders = e.responseHeaders; + if (responseHeaders) { + performanceClient?.addFields({ + httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "", + requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] || "", + contentTypeHeader: responseHeaders[HeaderNames.CONTENT_TYPE] || void 0, + contentLengthHeader: responseHeaders[HeaderNames.CONTENT_LENGTH] || void 0, + httpStatus: e.httpStatus + }, correlationId); + } + throw e.error; + } + if (e instanceof AuthError) { + throw e; + } else { + throw createClientAuthError(networkError); + } + } + ThrottlingUtils.postProcess(cacheManager, thumbprint, response, correlationId); + return response; + } + function isOpenIdConfigResponse(response) { + return response.hasOwnProperty("authorization_endpoint") && response.hasOwnProperty("token_endpoint") && response.hasOwnProperty("issuer") && response.hasOwnProperty("jwks_uri"); + } + function isCloudInstanceDiscoveryResponse(response) { + return response.hasOwnProperty("tenant_discovery_endpoint") && response.hasOwnProperty("metadata"); + } + function isCloudInstanceDiscoveryErrorResponse(response) { + return response.hasOwnProperty("error") && response.hasOwnProperty("error_description"); + } + var RegionDiscovery = class _RegionDiscovery { + constructor(networkInterface, logger, performanceClient, correlationId) { + this.networkInterface = networkInterface; + this.logger = logger; + this.performanceClient = performanceClient; + this.correlationId = correlationId; + } + /** + * Detect the region from the application's environment. + * + * @returns Promise + */ + async detectRegion(environmentRegion, regionDiscoveryMetadata) { + let autodetectedRegionName = environmentRegion; + if (!autodetectedRegionName) { + const options = _RegionDiscovery.IMDS_OPTIONS; + try { + const localIMDSVersionResponse = await invokeAsync(this.getRegionFromIMDS.bind(this), RegionDiscoveryGetRegionFromIMDS, this.logger, this.performanceClient, this.correlationId)(IMDS_VERSION, options); + if (localIMDSVersionResponse.status === HTTP_SUCCESS) { + autodetectedRegionName = localIMDSVersionResponse.body; + regionDiscoveryMetadata.region_source = RegionDiscoverySources.IMDS; + } + if (localIMDSVersionResponse.status === HTTP_BAD_REQUEST) { + const currentIMDSVersion = await invokeAsync(this.getCurrentVersion.bind(this), RegionDiscoveryGetCurrentVersion, this.logger, this.performanceClient, this.correlationId)(options); + if (!currentIMDSVersion) { + regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION; + return null; + } + const currentIMDSVersionResponse = await invokeAsync(this.getRegionFromIMDS.bind(this), RegionDiscoveryGetRegionFromIMDS, this.logger, this.performanceClient, this.correlationId)(currentIMDSVersion, options); + if (currentIMDSVersionResponse.status === HTTP_SUCCESS) { + autodetectedRegionName = currentIMDSVersionResponse.body; + regionDiscoveryMetadata.region_source = RegionDiscoverySources.IMDS; + } + } + } catch (e) { + regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION; + return null; + } + } else { + regionDiscoveryMetadata.region_source = RegionDiscoverySources.ENVIRONMENT_VARIABLE; + } + if (!autodetectedRegionName) { + regionDiscoveryMetadata.region_source = RegionDiscoverySources.FAILED_AUTO_DETECTION; + } + return autodetectedRegionName || null; + } + /** + * Make the call to the IMDS endpoint + * + * @param imdsEndpointUrl + * @returns Promise> + */ + async getRegionFromIMDS(version5, options) { + return this.networkInterface.sendGetRequestAsync(`${IMDS_ENDPOINT}?api-version=${version5}&format=text`, options, IMDS_TIMEOUT); + } + /** + * Get the most recent version of the IMDS endpoint available + * + * @returns Promise + */ + async getCurrentVersion(options) { + try { + const response = await this.networkInterface.sendGetRequestAsync(`${IMDS_ENDPOINT}?format=json`, options); + if (response.status === HTTP_BAD_REQUEST && response.body && response.body["newest-versions"] && response.body["newest-versions"].length > 0) { + return response.body["newest-versions"][0]; + } + return null; + } catch (e) { + return null; + } + } + }; + RegionDiscovery.IMDS_OPTIONS = { + headers: { + Metadata: "true" + } + }; + var Authority = class _Authority { + constructor(authority, networkInterface, cacheManager, authorityOptions, logger, correlationId, performanceClient, managedIdentity) { + this.canonicalAuthority = authority; + this._canonicalAuthority.validateAsUri(); + this.networkInterface = networkInterface; + this.cacheManager = cacheManager; + this.authorityOptions = authorityOptions; + this.regionDiscoveryMetadata = { + region_used: void 0, + region_source: void 0, + region_outcome: void 0 + }; + this.logger = logger; + this.performanceClient = performanceClient; + this.correlationId = correlationId; + this.managedIdentity = managedIdentity || false; + this.regionDiscovery = new RegionDiscovery(networkInterface, this.logger, this.performanceClient, this.correlationId); + } + /** + * Get {@link AuthorityType} + * @param authorityUri {@link IUri} + * @private + */ + getAuthorityType(authorityUri) { + if (authorityUri.HostNameAndPort.endsWith(CIAM_AUTH_URL)) { + return AuthorityType.Ciam; + } + const pathSegments = authorityUri.PathSegments; + if (pathSegments.length) { + switch (pathSegments[0].toLowerCase()) { + case ADFS: + return AuthorityType.Adfs; + case DSTS: + return AuthorityType.Dsts; + } + } + return AuthorityType.Default; + } + // See above for AuthorityType + get authorityType() { + return this.getAuthorityType(this.canonicalAuthorityUrlComponents); + } + /** + * ProtocolMode enum representing the way endpoints are constructed. + */ + get protocolMode() { + return this.authorityOptions.protocolMode; + } + /** + * Returns authorityOptions which can be used to reinstantiate a new authority instance + */ + get options() { + return this.authorityOptions; + } + /** + * A URL that is the authority set by the developer + */ + get canonicalAuthority() { + return this._canonicalAuthority.urlString; + } + /** + * Sets canonical authority. + */ + set canonicalAuthority(url) { + this._canonicalAuthority = new UrlString(url); + this._canonicalAuthority.validateAsUri(); + this._canonicalAuthorityUrlComponents = null; + } + /** + * Get authority components. + */ + get canonicalAuthorityUrlComponents() { + if (!this._canonicalAuthorityUrlComponents) { + this._canonicalAuthorityUrlComponents = this._canonicalAuthority.getUrlComponents(); + } + return this._canonicalAuthorityUrlComponents; + } + /** + * Get hostname and port i.e. login.microsoftonline.com + */ + get hostnameAndPort() { + return this.canonicalAuthorityUrlComponents.HostNameAndPort.toLowerCase(); + } + /** + * Get tenant for authority. + */ + get tenant() { + return this.canonicalAuthorityUrlComponents.PathSegments[0]; + } + /** + * OAuth /authorize endpoint for requests + */ + get authorizationEndpoint() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.authorization_endpoint); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * OAuth /token endpoint for requests + */ + get tokenEndpoint() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.token_endpoint); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + get deviceCodeEndpoint() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.token_endpoint.replace("/token", "/devicecode")); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * OAuth logout endpoint for requests + */ + get endSessionEndpoint() { + if (this.discoveryComplete()) { + if (!this.metadata.end_session_endpoint) { + throw createClientAuthError(endSessionEndpointNotSupported); + } + return this.replacePath(this.metadata.end_session_endpoint); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * OAuth issuer for requests + */ + get selfSignedJwtAudience() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.issuer); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * Jwks_uri for token signing keys + */ + get jwksUri() { + if (this.discoveryComplete()) { + return this.replacePath(this.metadata.jwks_uri); + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * Returns a flag indicating that tenant name can be replaced in authority {@link IUri} + * @param authorityUri {@link IUri} + * @private + */ + canReplaceTenant(authorityUri) { + return authorityUri.PathSegments.length === 1 && !_Authority.reservedTenantDomains.has(authorityUri.PathSegments[0]) && this.getAuthorityType(authorityUri) === AuthorityType.Default && this.protocolMode !== ProtocolMode.OIDC; + } + /** + * Replaces tenant in url path with current tenant. Defaults to common. + * @param urlString + */ + replaceTenant(urlString) { + return urlString.replace(/{tenant}|{tenantid}/g, this.tenant); + } + /** + * Replaces path such as tenant or policy with the current tenant or policy. + * @param urlString + */ + replacePath(urlString) { + let endpoint = urlString; + const cachedAuthorityUrl = new UrlString(this.metadata.canonical_authority); + const cachedAuthorityUrlComponents = cachedAuthorityUrl.getUrlComponents(); + const cachedAuthorityParts = cachedAuthorityUrlComponents.PathSegments; + const currentAuthorityParts = this.canonicalAuthorityUrlComponents.PathSegments; + currentAuthorityParts.forEach((currentPart, index) => { + let cachedPart = cachedAuthorityParts[index]; + if (index === 0 && this.canReplaceTenant(cachedAuthorityUrlComponents)) { + const tenantId = new UrlString(this.metadata.authorization_endpoint).getUrlComponents().PathSegments[0]; + if (cachedPart !== tenantId) { + this.logger.verbose(`Replacing tenant domain name '${cachedPart}' with id '${tenantId}'`, this.correlationId); + cachedPart = tenantId; + } + } + if (currentPart !== cachedPart) { + endpoint = endpoint.replace(`/${cachedPart}/`, `/${currentPart}/`); + } + }); + return this.replaceTenant(endpoint); + } + /** + * The default open id configuration endpoint for any canonical authority. + */ + get defaultOpenIdConfigurationEndpoint() { + const canonicalAuthorityHost = this.hostnameAndPort; + if (this.canonicalAuthority.endsWith("v2.0/") || this.authorityType === AuthorityType.Adfs || this.protocolMode === ProtocolMode.OIDC && !this.isAliasOfKnownMicrosoftAuthority(canonicalAuthorityHost)) { + return `${this.canonicalAuthority}.well-known/openid-configuration`; + } + return `${this.canonicalAuthority}v2.0/.well-known/openid-configuration`; + } + /** + * Boolean that returns whether or not tenant discovery has been completed. + */ + discoveryComplete() { + return !!this.metadata; + } + /** + * Perform endpoint discovery to discover aliases, preferred_cache, preferred_network + * and the /authorize, /token and logout endpoints. + */ + async resolveEndpointsAsync() { + const metadataEntity = this.getCurrentMetadataEntity(); + const cloudDiscoverySource = await invokeAsync(this.updateCloudDiscoveryMetadata.bind(this), AuthorityUpdateCloudDiscoveryMetadata, this.logger, this.performanceClient, this.correlationId)(metadataEntity); + this.canonicalAuthority = this.canonicalAuthority.replace(this.hostnameAndPort, metadataEntity.preferred_network); + const endpointSource = await invokeAsync(this.updateEndpointMetadata.bind(this), AuthorityUpdateEndpointMetadata, this.logger, this.performanceClient, this.correlationId)(metadataEntity); + this.updateCachedMetadata(metadataEntity, cloudDiscoverySource, { + source: endpointSource + }); + this.performanceClient?.addFields({ + cloudDiscoverySource, + authorityEndpointSource: endpointSource + }, this.correlationId); + } + /** + * Returns metadata entity from cache if it exists, otherwiser returns a new metadata entity built + * from the configured canonical authority + * @returns + */ + getCurrentMetadataEntity() { + let metadataEntity = this.cacheManager.getAuthorityMetadataByAlias(this.hostnameAndPort, this.correlationId); + if (!metadataEntity) { + metadataEntity = { + aliases: [], + preferred_cache: this.hostnameAndPort, + preferred_network: this.hostnameAndPort, + canonical_authority: this.canonicalAuthority, + authorization_endpoint: "", + token_endpoint: "", + end_session_endpoint: "", + issuer: "", + aliasesFromNetwork: false, + endpointsFromNetwork: false, + expiresAt: generateAuthorityMetadataExpiresAt(), + jwks_uri: "" + }; + } + return metadataEntity; + } + /** + * Updates cached metadata based on metadata source and sets the instance's metadata + * property to the same value + * @param metadataEntity + * @param cloudDiscoverySource + * @param endpointMetadataResult + */ + updateCachedMetadata(metadataEntity, cloudDiscoverySource, endpointMetadataResult) { + if (cloudDiscoverySource !== AuthorityMetadataSource.CACHE && endpointMetadataResult?.source !== AuthorityMetadataSource.CACHE) { + metadataEntity.expiresAt = generateAuthorityMetadataExpiresAt(); + metadataEntity.canonical_authority = this.canonicalAuthority; + } + const cacheKey = this.cacheManager.generateAuthorityMetadataCacheKey(metadataEntity.preferred_cache, this.correlationId); + this.cacheManager.setAuthorityMetadata(cacheKey, metadataEntity, this.correlationId); + this.metadata = metadataEntity; + } + /** + * Update AuthorityMetadataEntity with new endpoints and return where the information came from + * @param metadataEntity + */ + async updateEndpointMetadata(metadataEntity) { + const localMetadata = this.updateEndpointMetadataFromLocalSources(metadataEntity); + if (localMetadata) { + if (localMetadata.source === AuthorityMetadataSource.HARDCODED_VALUES) { + if (this.authorityOptions.azureRegionConfiguration?.azureRegion) { + if (localMetadata.metadata) { + const hardcodedMetadata = await invokeAsync(this.updateMetadataWithRegionalInformation.bind(this), AuthorityUpdateMetadataWithRegionalInformation, this.logger, this.performanceClient, this.correlationId)(localMetadata.metadata); + updateAuthorityEndpointMetadata(metadataEntity, hardcodedMetadata, false); + metadataEntity.canonical_authority = this.canonicalAuthority; + } + } + } + return localMetadata.source; + } + let metadata = await invokeAsync(this.getEndpointMetadataFromNetwork.bind(this), AuthorityGetEndpointMetadataFromNetwork, this.logger, this.performanceClient, this.correlationId)(); + if (metadata) { + if (this.authorityOptions.azureRegionConfiguration?.azureRegion) { + metadata = await invokeAsync(this.updateMetadataWithRegionalInformation.bind(this), AuthorityUpdateMetadataWithRegionalInformation, this.logger, this.performanceClient, this.correlationId)(metadata); + } + updateAuthorityEndpointMetadata(metadataEntity, metadata, true); + return AuthorityMetadataSource.NETWORK; + } else { + throw createClientAuthError(openIdConfigError, this.defaultOpenIdConfigurationEndpoint); + } + } + /** + * Updates endpoint metadata from local sources and returns where the information was retrieved from and the metadata config + * response if the source is hardcoded metadata + * @param metadataEntity + * @returns + */ + updateEndpointMetadataFromLocalSources(metadataEntity) { + this.logger.verbose("Attempting to get endpoint metadata from authority configuration", this.correlationId); + const configMetadata = this.getEndpointMetadataFromConfig(); + if (configMetadata) { + this.logger.verbose("Found endpoint metadata in authority configuration", this.correlationId); + updateAuthorityEndpointMetadata(metadataEntity, configMetadata, false); + return { + source: AuthorityMetadataSource.CONFIG + }; + } + this.logger.verbose("Did not find endpoint metadata in the config... Attempting to get endpoint metadata from the hardcoded values.", this.correlationId); + const hardcodedMetadata = this.getEndpointMetadataFromHardcodedValues(); + if (hardcodedMetadata) { + updateAuthorityEndpointMetadata(metadataEntity, hardcodedMetadata, false); + return { + source: AuthorityMetadataSource.HARDCODED_VALUES, + metadata: hardcodedMetadata + }; + } else { + this.logger.verbose("Did not find endpoint metadata in hardcoded values... Attempting to get endpoint metadata from the network metadata cache.", this.correlationId); + } + const metadataEntityExpired = isAuthorityMetadataExpired(metadataEntity); + if (this.isAuthoritySameType(metadataEntity) && metadataEntity.endpointsFromNetwork && !metadataEntityExpired) { + this.logger.verbose("Found endpoint metadata in the cache.", ""); + return { source: AuthorityMetadataSource.CACHE }; + } else if (metadataEntityExpired) { + this.logger.verbose("The metadata entity is expired.", ""); + } + return null; + } + /** + * Compares the number of url components after the domain to determine if the cached + * authority metadata can be used for the requested authority. Protects against same domain different + * authority such as login.microsoftonline.com/tenant and login.microsoftonline.com/tfp/tenant/policy + * @param metadataEntity + */ + isAuthoritySameType(metadataEntity) { + const cachedAuthorityUrl = new UrlString(metadataEntity.canonical_authority); + const cachedParts = cachedAuthorityUrl.getUrlComponents().PathSegments; + return cachedParts.length === this.canonicalAuthorityUrlComponents.PathSegments.length; + } + /** + * Parse authorityMetadata config option + */ + getEndpointMetadataFromConfig() { + if (this.authorityOptions.authorityMetadata) { + try { + return JSON.parse(this.authorityOptions.authorityMetadata); + } catch (e) { + throw createClientConfigurationError(invalidAuthorityMetadata); + } + } + return null; + } + /** + * Gets OAuth endpoints from the given OpenID configuration endpoint. + * + * @param hasHardcodedMetadata boolean + */ + async getEndpointMetadataFromNetwork() { + const options = {}; + const openIdConfigurationEndpoint = this.defaultOpenIdConfigurationEndpoint; + this.logger.verbose(`Authority.getEndpointMetadataFromNetwork: attempting to retrieve OAuth endpoints from '${openIdConfigurationEndpoint}'`, this.correlationId); + try { + const response = await this.networkInterface.sendGetRequestAsync(openIdConfigurationEndpoint, options); + const isValidResponse = isOpenIdConfigResponse(response.body); + if (isValidResponse) { + return response.body; + } else { + this.logger.verbose(`Authority.getEndpointMetadataFromNetwork: could not parse response as OpenID configuration`, this.correlationId); + return null; + } + } catch (e) { + this.logger.verbose(`Authority.getEndpointMetadataFromNetwork: '${e}'`, this.correlationId); + return null; + } + } + /** + * Get OAuth endpoints for common authorities. + */ + getEndpointMetadataFromHardcodedValues() { + if (this.hostnameAndPort in EndpointMetadata) { + return EndpointMetadata[this.hostnameAndPort]; + } + return null; + } + /** + * Update the retrieved metadata with regional information. + * User selected Azure region will be used if configured. + */ + async updateMetadataWithRegionalInformation(metadata) { + const userConfiguredAzureRegion = this.authorityOptions.azureRegionConfiguration?.azureRegion; + if (userConfiguredAzureRegion) { + if (userConfiguredAzureRegion !== AZURE_REGION_AUTO_DISCOVER_FLAG) { + this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.CONFIGURED_NO_AUTO_DETECTION; + this.regionDiscoveryMetadata.region_used = userConfiguredAzureRegion; + return _Authority.replaceWithRegionalInformation(metadata, userConfiguredAzureRegion); + } + const autodetectedRegionName = await invokeAsync(this.regionDiscovery.detectRegion.bind(this.regionDiscovery), RegionDiscoveryDetectRegion, this.logger, this.performanceClient, this.correlationId)(this.authorityOptions.azureRegionConfiguration?.environmentRegion, this.regionDiscoveryMetadata); + if (autodetectedRegionName) { + this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.AUTO_DETECTION_REQUESTED_SUCCESSFUL; + this.regionDiscoveryMetadata.region_used = autodetectedRegionName; + return _Authority.replaceWithRegionalInformation(metadata, autodetectedRegionName); + } + this.regionDiscoveryMetadata.region_outcome = RegionDiscoveryOutcomes.AUTO_DETECTION_REQUESTED_FAILED; + } + return metadata; + } + /** + * Updates the AuthorityMetadataEntity with new aliases, preferred_network and preferred_cache + * and returns where the information was retrieved from + * @param metadataEntity + * @returns AuthorityMetadataSource + */ + async updateCloudDiscoveryMetadata(metadataEntity) { + const localMetadataSource = this.updateCloudDiscoveryMetadataFromLocalSources(metadataEntity); + if (localMetadataSource) { + return localMetadataSource; + } + const metadata = await invokeAsync(this.getCloudDiscoveryMetadataFromNetwork.bind(this), AuthorityGetCloudDiscoveryMetadataFromNetwork, this.logger, this.performanceClient, this.correlationId)(); + if (metadata) { + updateCloudDiscoveryMetadata(metadataEntity, metadata, true); + return AuthorityMetadataSource.NETWORK; + } + throw createClientConfigurationError(untrustedAuthority); + } + updateCloudDiscoveryMetadataFromLocalSources(metadataEntity) { + this.logger.verbose("Attempting to get cloud discovery metadata from authority configuration", this.correlationId); + this.logger.verbosePii(`Known Authorities: '${this.authorityOptions.knownAuthorities || NOT_APPLICABLE}'`, this.correlationId); + this.logger.verbosePii(`Authority Metadata: '${this.authorityOptions.authorityMetadata || NOT_APPLICABLE}'`, this.correlationId); + this.logger.verbosePii(`Canonical Authority: '${metadataEntity.canonical_authority || NOT_APPLICABLE}'`, this.correlationId); + const metadata = this.getCloudDiscoveryMetadataFromConfig(); + if (metadata) { + this.logger.verbose("Found cloud discovery metadata in authority configuration", this.correlationId); + updateCloudDiscoveryMetadata(metadataEntity, metadata, false); + return AuthorityMetadataSource.CONFIG; + } + this.logger.verbose("Did not find cloud discovery metadata in the config... Attempting to get cloud discovery metadata from the hardcoded values.", this.correlationId); + const hardcodedMetadata = getCloudDiscoveryMetadataFromHardcodedValues(this.hostnameAndPort); + if (hardcodedMetadata) { + this.logger.verbose("Found cloud discovery metadata from hardcoded values.", this.correlationId); + updateCloudDiscoveryMetadata(metadataEntity, hardcodedMetadata, false); + return AuthorityMetadataSource.HARDCODED_VALUES; + } + this.logger.verbose("Did not find cloud discovery metadata in hardcoded values... Attempting to get cloud discovery metadata from the network metadata cache.", this.correlationId); + const metadataEntityExpired = isAuthorityMetadataExpired(metadataEntity); + if (this.isAuthoritySameType(metadataEntity) && metadataEntity.aliasesFromNetwork && !metadataEntityExpired) { + this.logger.verbose("Found cloud discovery metadata in the cache.", ""); + return AuthorityMetadataSource.CACHE; + } else if (metadataEntityExpired) { + this.logger.verbose("The metadata entity is expired.", ""); + } + return null; + } + /** + * Parse cloudDiscoveryMetadata config or check knownAuthorities + */ + getCloudDiscoveryMetadataFromConfig() { + if (this.authorityType === AuthorityType.Ciam) { + this.logger.verbose("CIAM authorities do not support cloud discovery metadata, generate the aliases from authority host.", this.correlationId); + return _Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort); + } + if (this.authorityOptions.cloudDiscoveryMetadata) { + this.logger.verbose("The cloud discovery metadata has been provided as a network response, in the config.", this.correlationId); + try { + this.logger.verbose("Attempting to parse the cloud discovery metadata.", this.correlationId); + const parsedResponse = JSON.parse(this.authorityOptions.cloudDiscoveryMetadata); + const metadata = getCloudDiscoveryMetadataFromNetworkResponse(parsedResponse.metadata, this.hostnameAndPort); + this.logger.verbose("Parsed the cloud discovery metadata.", ""); + if (metadata) { + this.logger.verbose("There is returnable metadata attached to the parsed cloud discovery metadata.", this.correlationId); + return metadata; + } else { + this.logger.verbose("There is no metadata attached to the parsed cloud discovery metadata.", this.correlationId); + } + } catch (e) { + this.logger.verbose("Unable to parse the cloud discovery metadata. Throwing Invalid Cloud Discovery Metadata Error.", this.correlationId); + throw createClientConfigurationError(invalidCloudDiscoveryMetadata); + } + } + if (this.isInKnownAuthorities()) { + this.logger.verbose("The host is included in knownAuthorities. Creating new cloud discovery metadata from the host.", this.correlationId); + return _Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort); + } + return null; + } + /** + * Called to get metadata from network if CloudDiscoveryMetadata was not populated by config + * + * @param hasHardcodedMetadata boolean + */ + async getCloudDiscoveryMetadataFromNetwork() { + const instanceDiscoveryEndpoint = `${AAD_INSTANCE_DISCOVERY_ENDPT}${this.canonicalAuthority}oauth2/v2.0/authorize`; + const options = {}; + let match = null; + try { + const response = await this.networkInterface.sendGetRequestAsync(instanceDiscoveryEndpoint, options); + let typedResponseBody; + let metadata; + if (isCloudInstanceDiscoveryResponse(response.body)) { + typedResponseBody = response.body; + metadata = typedResponseBody.metadata; + this.logger.verbosePii(`tenant_discovery_endpoint is: '${typedResponseBody.tenant_discovery_endpoint}'`, this.correlationId); + } else if (isCloudInstanceDiscoveryErrorResponse(response.body)) { + this.logger.warning(`A CloudInstanceDiscoveryErrorResponse was returned. The cloud instance discovery network request's status code is: '${response.status}'`, this.correlationId); + typedResponseBody = response.body; + if (typedResponseBody.error === INVALID_INSTANCE) { + this.logger.error("The CloudInstanceDiscoveryErrorResponse error is invalid_instance.", this.correlationId); + return null; + } + this.logger.warning(`The CloudInstanceDiscoveryErrorResponse error is '${typedResponseBody.error}'`, this.correlationId); + this.logger.warning(`The CloudInstanceDiscoveryErrorResponse error description is '${typedResponseBody.error_description}'`, this.correlationId); + this.logger.warning("Setting the value of the CloudInstanceDiscoveryMetadata (returned from the network, correlationId) to []", this.correlationId); + metadata = []; + } else { + this.logger.error("AAD did not return a CloudInstanceDiscoveryResponse or CloudInstanceDiscoveryErrorResponse", this.correlationId); + return null; + } + this.logger.verbose("Attempting to find a match between the developer's authority and the CloudInstanceDiscoveryMetadata returned from the network request.", this.correlationId); + match = getCloudDiscoveryMetadataFromNetworkResponse(metadata, this.hostnameAndPort); + } catch (error) { + if (error instanceof AuthError) { + this.logger.error(`There was a network error while attempting to get the cloud discovery instance metadata. +Error: '${error.errorCode}' +Error Description: '${error.errorMessage}'`, this.correlationId); + } else { + const typedError = error; + this.logger.error(`A non-MSALJS error was thrown while attempting to get the cloud instance discovery metadata. +Error: '${typedError.name}' +Error Description: '${typedError.message}'`, this.correlationId); + } + return null; + } + if (!match) { + this.logger.warning("The developer's authority was not found within the CloudInstanceDiscoveryMetadata returned from the network request.", this.correlationId); + this.logger.verbose("Creating custom Authority for custom domain scenario.", this.correlationId); + match = _Authority.createCloudDiscoveryMetadataFromHost(this.hostnameAndPort); + } + return match; + } + /** + * Helper function to determine if this host is included in the knownAuthorities config option + */ + isInKnownAuthorities() { + const matches = this.authorityOptions.knownAuthorities.filter((authority) => { + return authority && UrlString.getDomainFromUrl(authority).toLowerCase() === this.hostnameAndPort; + }); + return matches.length > 0; + } + /** + * helper function to populate the authority based on azureCloudOptions + * @param authorityString + * @param azureCloudOptions + */ + static generateAuthority(authorityString, azureCloudOptions) { + let authorityAzureCloudInstance; + if (azureCloudOptions && azureCloudOptions.azureCloudInstance !== AzureCloudInstance.None) { + const tenant = azureCloudOptions.tenant ? azureCloudOptions.tenant : DEFAULT_COMMON_TENANT; + authorityAzureCloudInstance = `${azureCloudOptions.azureCloudInstance}/${tenant}/`; + } + return authorityAzureCloudInstance ? authorityAzureCloudInstance : authorityString; + } + /** + * Creates cloud discovery metadata object from a given host + * @param host + */ + static createCloudDiscoveryMetadataFromHost(host) { + return { + preferred_network: host, + preferred_cache: host, + aliases: [host] + }; + } + /** + * helper function to generate environment from authority object + */ + getPreferredCache() { + if (this.managedIdentity) { + return DEFAULT_AUTHORITY_HOST; + } else if (this.discoveryComplete()) { + return this.metadata.preferred_cache; + } else { + throw createClientAuthError(endpointResolutionError); + } + } + /** + * Returns whether or not the provided host is an alias of this authority instance + * @param host + */ + isAlias(host) { + return this.metadata.aliases.indexOf(host) > -1; + } + /** + * Returns whether or not the provided host is an alias of a known Microsoft authority for purposes of endpoint discovery + * @param host + */ + isAliasOfKnownMicrosoftAuthority(host) { + return InstanceDiscoveryMetadataAliases.has(host); + } + /** + * Checks whether the provided host is that of a public cloud authority + * + * @param authority string + * @returns bool + */ + static isPublicCloudAuthority(host) { + return KNOWN_PUBLIC_CLOUDS.indexOf(host) >= 0; + } + /** + * Rebuild the authority string with the region + * + * @param host string + * @param region string + */ + static buildRegionalAuthorityString(host, region, queryString) { + const authorityUrlInstance = new UrlString(host); + authorityUrlInstance.validateAsUri(); + const authorityUrlParts = authorityUrlInstance.getUrlComponents(); + let hostNameAndPort = `${region}.${authorityUrlParts.HostNameAndPort}`; + if (this.isPublicCloudAuthority(authorityUrlParts.HostNameAndPort)) { + hostNameAndPort = `${region}.${REGIONAL_AUTH_PUBLIC_CLOUD_SUFFIX}`; + } + const url = UrlString.constructAuthorityUriFromObject({ + ...authorityUrlInstance.getUrlComponents(), + HostNameAndPort: hostNameAndPort + }).urlString; + if (queryString) + return `${url}?${queryString}`; + return url; + } + /** + * Replace the endpoints in the metadata object with their regional equivalents. + * + * @param metadata OpenIdConfigResponse + * @param azureRegion string + */ + static replaceWithRegionalInformation(metadata, azureRegion) { + const regionalMetadata = { ...metadata }; + regionalMetadata.authorization_endpoint = _Authority.buildRegionalAuthorityString(regionalMetadata.authorization_endpoint, azureRegion); + regionalMetadata.token_endpoint = _Authority.buildRegionalAuthorityString(regionalMetadata.token_endpoint, azureRegion); + if (regionalMetadata.end_session_endpoint) { + regionalMetadata.end_session_endpoint = _Authority.buildRegionalAuthorityString(regionalMetadata.end_session_endpoint, azureRegion); + } + return regionalMetadata; + } + /** + * Transform CIAM_AUTHORIY as per the below rules: + * If no path segments found and it is a CIAM authority (hostname ends with .ciamlogin.com), then transform it + * + * NOTE: The transformation path should go away once STS supports CIAM with the format: `tenantIdorDomain.ciamlogin.com` + * `ciamlogin.com` can also change in the future and we should accommodate the same + * + * @param authority + */ + static transformCIAMAuthority(authority) { + let ciamAuthority = authority; + const authorityUrl = new UrlString(authority); + const authorityUrlComponents = authorityUrl.getUrlComponents(); + if (authorityUrlComponents.PathSegments.length === 0 && authorityUrlComponents.HostNameAndPort.endsWith(CIAM_AUTH_URL)) { + const tenantIdOrDomain = authorityUrlComponents.HostNameAndPort.split(".")[0]; + ciamAuthority = `${ciamAuthority}${tenantIdOrDomain}${AAD_TENANT_DOMAIN_SUFFIX}`; + } + return ciamAuthority; + } + }; + Authority.reservedTenantDomains = /* @__PURE__ */ new Set([ + "{tenant}", + "{tenantid}", + AADAuthority.COMMON, + AADAuthority.CONSUMERS, + AADAuthority.ORGANIZATIONS + ]); + function getTenantFromAuthorityString(authority) { + const authorityUrl = new UrlString(authority); + const authorityUrlComponents = authorityUrl.getUrlComponents(); + const tenantId = authorityUrlComponents.PathSegments.slice(-1)[0]?.toLowerCase(); + switch (tenantId) { + case AADAuthority.COMMON: + case AADAuthority.ORGANIZATIONS: + case AADAuthority.CONSUMERS: + return void 0; + default: + return tenantId; + } + } + function formatAuthorityUri(authorityUri) { + return authorityUri.endsWith(FORWARD_SLASH) ? authorityUri : `${authorityUri}${FORWARD_SLASH}`; + } + function buildStaticAuthorityOptions(authOptions) { + const rawCloudDiscoveryMetadata = authOptions.cloudDiscoveryMetadata; + let cloudDiscoveryMetadata = void 0; + if (rawCloudDiscoveryMetadata) { + try { + cloudDiscoveryMetadata = JSON.parse(rawCloudDiscoveryMetadata); + } catch (e) { + throw createClientConfigurationError(invalidCloudDiscoveryMetadata); + } + } + return { + canonicalAuthority: authOptions.authority ? formatAuthorityUri(authOptions.authority) : void 0, + knownAuthorities: authOptions.knownAuthorities, + cloudDiscoveryMetadata + }; + } + async function createDiscoveredInstance(authorityUri, networkClient, cacheManager, authorityOptions, logger, correlationId, performanceClient) { + const authorityUriFinal = Authority.transformCIAMAuthority(formatAuthorityUri(authorityUri)); + const acquireTokenAuthority = new Authority(authorityUriFinal, networkClient, cacheManager, authorityOptions, logger, correlationId, performanceClient); + try { + await invokeAsync(acquireTokenAuthority.resolveEndpointsAsync.bind(acquireTokenAuthority), AuthorityResolveEndpointsAsync, logger, performanceClient, correlationId)(); + return acquireTokenAuthority; + } catch (e) { + throw createClientAuthError(endpointResolutionError); + } + } + var AuthorizationCodeClient = class { + constructor(configuration, performanceClient) { + this.includeRedirectUri = true; + this.config = buildClientConfiguration(configuration); + this.logger = new Logger(this.config.loggerOptions, name$1, version$1); + this.cryptoUtils = this.config.cryptoInterface; + this.cacheManager = this.config.storageInterface; + this.networkClient = this.config.networkInterface; + this.serverTelemetryManager = this.config.serverTelemetryManager; + this.authority = this.config.authOptions.authority; + this.performanceClient = performanceClient; + this.oidcDefaultScopes = this.config.authOptions.authority.options.OIDCOptions?.defaultScopes; + } + /** + * API to acquire a token in exchange of 'authorization_code` acquired by the user in the first leg of the + * authorization_code_grant + * @param request + */ + async acquireToken(request, apiId, authCodePayload) { + if (!request.code) { + throw createClientAuthError(requestCannotBeMade); + } + if (authCodePayload && authCodePayload.cloud_instance_host_name) { + await invokeAsync(this.updateTokenEndpointAuthority.bind(this), UpdateTokenEndpointAuthority, this.logger, this.performanceClient, request.correlationId)(authCodePayload.cloud_instance_host_name, request.correlationId); + } + const reqTimestamp = nowSeconds(); + const response = await invokeAsync(this.executeTokenRequest.bind(this), AuthClientExecuteTokenRequest, this.logger, this.performanceClient, request.correlationId)(this.authority, request, this.serverTelemetryManager); + const requestId = response.headers?.[HeaderNames.X_MS_REQUEST_ID]; + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.performanceClient, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response.body, request.correlationId); + return invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), HandleServerTokenResponse, this.logger, this.performanceClient, request.correlationId)(response.body, this.authority, reqTimestamp, request, apiId, authCodePayload, void 0, void 0, void 0, requestId); + } + /** + * Used to log out the current user, and redirect the user to the postLogoutRedirectUri. + * Default behaviour is to redirect the user to `window.location.href`. + * @param authorityUri + */ + getLogoutUri(logoutRequest) { + if (!logoutRequest) { + throw createClientConfigurationError(logoutRequestEmpty); + } + const queryString = this.createLogoutUrlQueryString(logoutRequest); + return UrlString.appendQueryString(this.authority.endSessionEndpoint, queryString); + } + /** + * Executes POST request to token endpoint + * @param authority + * @param request + */ + async executeTokenRequest(authority, request, serverTelemetryManager) { + const queryParametersString = createTokenQueryParameters(request, this.config.authOptions.clientId, this.config.authOptions.redirectUri, this.performanceClient); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await invokeAsync(this.createTokenRequestBody.bind(this), AuthClientCreateTokenRequestBody, this.logger, this.performanceClient, request.correlationId)(request); + let ccsCredential = void 0; + if (request.clientInfo) { + try { + const clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils.base64Decode); + ccsCredential = { + credential: `${clientInfo.uid}${CLIENT_INFO_SEPARATOR}${clientInfo.utid}`, + type: CcsCredentialType.HOME_ACCOUNT_ID + }; + } catch (e) { + this.logger.verbose(`Could not parse client info for CCS Header: '${e}'`, request.correlationId); + } + } + const headers = createTokenRequestHeaders(this.logger, this.config.systemOptions.preventCorsPreflight, ccsCredential || request.ccsCredential); + const thumbprint = getRequestThumbprint(this.config.authOptions.clientId, request); + return invokeAsync(executePostToTokenEndpoint, AuthorizationCodeClientExecutePostToTokenEndpoint, this.logger, this.performanceClient, request.correlationId)(endpoint, requestBody, headers, thumbprint, request.correlationId, this.cacheManager, this.networkClient, this.logger, this.performanceClient, serverTelemetryManager); + } + /** + * Generates a map for all the params to be sent to the service + * @param request + */ + async createTokenRequestBody(request) { + const parameters = /* @__PURE__ */ new Map(); + addClientId(parameters, request.embeddedClientId || request.extraParameters?.[CLIENT_ID] || this.config.authOptions.clientId); + if (!this.includeRedirectUri) { + if (!request.redirectUri) { + throw createClientConfigurationError(redirectUriEmpty); + } + } else { + addRedirectUri(parameters, request.redirectUri); + } + addScopes(parameters, request.scopes, true, this.oidcDefaultScopes); + addResource(parameters, request.resource); + addAuthorizationCode(parameters, request.code); + addLibraryInfo(parameters, this.config.libraryInfo); + addApplicationTelemetry(parameters, this.config.telemetry.application); + addThrottling(parameters); + if (this.serverTelemetryManager && !isOidcProtocolMode(this.config)) { + addServerTelemetry(parameters, this.serverTelemetryManager); + } + if (request.codeVerifier) { + addCodeVerifier(parameters, request.codeVerifier); + } + if (this.config.clientCredentials.clientSecret) { + addClientSecret(parameters, this.config.clientCredentials.clientSecret); + } + if (this.config.clientCredentials.clientAssertion) { + const clientAssertion = this.config.clientCredentials.clientAssertion; + addClientAssertion(parameters, await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + addClientAssertionType(parameters, clientAssertion.assertionType); + } + addGrantType(parameters, GrantType.AUTHORIZATION_CODE_GRANT); + addClientInfo(parameters); + if (request.authenticationScheme === AuthenticationScheme.POP) { + const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils, this.performanceClient); + let reqCnfData; + if (!request.popKid) { + const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(request, this.logger); + reqCnfData = generatedReqCnfData.reqCnfString; + } else { + reqCnfData = this.cryptoUtils.encodeKid(request.popKid); + } + addPopToken(parameters, reqCnfData); + } else if (request.authenticationScheme === AuthenticationScheme.SSH) { + if (request.sshJwk) { + addSshJwk(parameters, request.sshJwk); + } else { + throw createClientConfigurationError(missingSshJwk); + } + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + addClaims(parameters, request.claims, this.config.authOptions.clientCapabilities); + } + let ccsCred = void 0; + if (request.clientInfo) { + try { + const clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils.base64Decode); + ccsCred = { + credential: `${clientInfo.uid}${CLIENT_INFO_SEPARATOR}${clientInfo.utid}`, + type: CcsCredentialType.HOME_ACCOUNT_ID + }; + } catch (e) { + this.logger.verbose(`Could not parse client info for CCS Header: '${e}'`, request.correlationId); + } + } else { + ccsCred = request.ccsCredential; + } + if (this.config.systemOptions.preventCorsPreflight && ccsCred) { + switch (ccsCred.type) { + case CcsCredentialType.HOME_ACCOUNT_ID: + try { + const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential); + addCcsOid(parameters, clientInfo); + } catch (e) { + this.logger.verbose(`Could not parse home account ID for CCS Header: '${e}'`, request.correlationId); + } + break; + case CcsCredentialType.UPN: + addCcsUpn(parameters, ccsCred.credential); + break; + } + } + if (request.embeddedClientId) { + addBrokerParameters(parameters, this.config.authOptions.clientId, this.config.authOptions.redirectUri); + } + if (request.extraParameters) { + addExtraParameters(parameters, request.extraParameters); + } + if (request.enableSpaAuthorizationCode && (!request.extraParameters || !request.extraParameters[RETURN_SPA_CODE])) { + addExtraParameters(parameters, { + [RETURN_SPA_CODE]: "1" + }); + } + instrumentBrokerParams(parameters, request.correlationId, this.performanceClient); + return mapToQueryString(parameters); + } + /** + * This API validates the `EndSessionRequest` and creates a URL + * @param request + */ + createLogoutUrlQueryString(request) { + const parameters = /* @__PURE__ */ new Map(); + if (request.postLogoutRedirectUri) { + addPostLogoutRedirectUri(parameters, request.postLogoutRedirectUri); + } + if (request.correlationId) { + addCorrelationId(parameters, request.correlationId); + } + if (request.idTokenHint) { + addIdTokenHint(parameters, request.idTokenHint); + } + if (request.state) { + addState(parameters, request.state); + } + if (request.logoutHint) { + addLogoutHint(parameters, request.logoutHint); + } + if (request.extraQueryParameters) { + addExtraParameters(parameters, request.extraQueryParameters); + } + if (this.config.authOptions.instanceAware) { + addInstanceAware(parameters); + } + return mapToQueryString(parameters); + } + /** + * Updates the authority to the cloud instance provided in the authorization response + * @param cloudInstanceHostName - cloud instance host name from authorization code payload + * @param correlationId - request correlation id + */ + async updateTokenEndpointAuthority(cloudInstanceHostName, correlationId) { + const cloudInstanceAuthorityUri = `https://${cloudInstanceHostName}/${this.authority.tenant}/`; + const cloudInstanceAuthority = await createDiscoveredInstance(cloudInstanceAuthorityUri, this.networkClient, this.cacheManager, this.authority.options, this.logger, correlationId, this.performanceClient); + this.authority = cloudInstanceAuthority; + } + }; + var DEFAULT_REFRESH_TOKEN_EXPIRATION_OFFSET_SECONDS = 300; + var RefreshTokenClient = class { + constructor(configuration, performanceClient) { + this.config = buildClientConfiguration(configuration); + this.logger = new Logger(this.config.loggerOptions, name$1, version$1); + this.cryptoUtils = this.config.cryptoInterface; + this.cacheManager = this.config.storageInterface; + this.networkClient = this.config.networkInterface; + this.serverTelemetryManager = this.config.serverTelemetryManager; + this.authority = this.config.authOptions.authority; + this.performanceClient = performanceClient; + } + async acquireToken(request, apiId) { + const reqTimestamp = nowSeconds(); + const response = await invokeAsync(this.executeTokenRequest.bind(this), RefreshTokenClientExecuteTokenRequest, this.logger, this.performanceClient, request.correlationId)(request, this.authority); + const requestId = response.headers?.[HeaderNames.X_MS_REQUEST_ID]; + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.performanceClient, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response.body, request.correlationId); + return invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), HandleServerTokenResponse, this.logger, this.performanceClient, request.correlationId)(response.body, this.authority, reqTimestamp, request, apiId, void 0, void 0, true, request.forceCache, requestId); + } + /** + * Gets cached refresh token and attaches to request, then calls acquireToken API + * @param request + */ + async acquireTokenByRefreshToken(request, apiId) { + if (!request) { + throw createClientConfigurationError(tokenRequestEmpty); + } + if (!request.account) { + throw createClientAuthError(noAccountInSilentRequest); + } + const isFOCI = this.cacheManager.isAppMetadataFOCI(request.account.environment, request.correlationId); + if (isFOCI) { + try { + return await invokeAsync(this.acquireTokenWithCachedRefreshToken.bind(this), RefreshTokenClientAcquireTokenWithCachedRefreshToken, this.logger, this.performanceClient, request.correlationId)(request, true, apiId); + } catch (e) { + const noFamilyRTInCache = e instanceof InteractionRequiredAuthError && e.errorCode === noTokensFound; + const clientMismatchErrorWithFamilyRT = e instanceof ServerError && e.errorCode === INVALID_GRANT_ERROR && e.subError === CLIENT_MISMATCH_ERROR; + if (noFamilyRTInCache || clientMismatchErrorWithFamilyRT) { + return invokeAsync(this.acquireTokenWithCachedRefreshToken.bind(this), RefreshTokenClientAcquireTokenWithCachedRefreshToken, this.logger, this.performanceClient, request.correlationId)(request, false, apiId); + } else { + throw e; + } + } + } + return invokeAsync(this.acquireTokenWithCachedRefreshToken.bind(this), RefreshTokenClientAcquireTokenWithCachedRefreshToken, this.logger, this.performanceClient, request.correlationId)(request, false, apiId); + } + /** + * makes a network call to acquire tokens by exchanging RefreshToken available in userCache; throws if refresh token is not cached + * @param request + */ + async acquireTokenWithCachedRefreshToken(request, foci, apiId) { + const refreshToken = invoke(this.cacheManager.getRefreshToken.bind(this.cacheManager), CacheManagerGetRefreshToken, this.logger, this.performanceClient, request.correlationId)(request.account, foci, request.correlationId, void 0); + if (!refreshToken) { + throw createInteractionRequiredAuthError(noTokensFound); + } + if (refreshToken.expiresOn) { + const offset = request.refreshTokenExpirationOffsetSeconds || DEFAULT_REFRESH_TOKEN_EXPIRATION_OFFSET_SECONDS; + this.performanceClient?.addFields({ + cacheRtExpiresOnSeconds: Number(refreshToken.expiresOn), + rtOffsetSeconds: offset + }, request.correlationId); + if (isTokenExpired(refreshToken.expiresOn, offset)) { + throw createInteractionRequiredAuthError(refreshTokenExpired); + } + } + const refreshTokenRequest = { + ...request, + refreshToken: refreshToken.secret, + authenticationScheme: request.authenticationScheme || AuthenticationScheme.BEARER, + ccsCredential: { + credential: request.account.homeAccountId, + type: CcsCredentialType.HOME_ACCOUNT_ID + } + }; + try { + return await invokeAsync(this.acquireToken.bind(this), RefreshTokenClientAcquireToken, this.logger, this.performanceClient, request.correlationId)(refreshTokenRequest, apiId); + } catch (e) { + if (e instanceof InteractionRequiredAuthError) { + if (e.subError === badToken) { + this.logger.verbose("acquireTokenWithRefreshToken: bad refresh token, removing from cache", request.correlationId); + const badRefreshTokenKey = this.cacheManager.generateCredentialKey(refreshToken); + this.cacheManager.removeRefreshToken(badRefreshTokenKey, request.correlationId); + } + } + throw e; + } + } + /** + * Constructs the network message and makes a NW call to the underlying secure token service + * @param request + * @param authority + */ + async executeTokenRequest(request, authority) { + const queryParametersString = createTokenQueryParameters(request, this.config.authOptions.clientId, this.config.authOptions.redirectUri, this.performanceClient); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await invokeAsync(this.createTokenRequestBody.bind(this), RefreshTokenClientCreateTokenRequestBody, this.logger, this.performanceClient, request.correlationId)(request); + const headers = createTokenRequestHeaders(this.logger, this.config.systemOptions.preventCorsPreflight, request.ccsCredential); + const thumbprint = getRequestThumbprint(this.config.authOptions.clientId, request); + return invokeAsync(executePostToTokenEndpoint, RefreshTokenClientExecutePostToTokenEndpoint, this.logger, this.performanceClient, request.correlationId)(endpoint, requestBody, headers, thumbprint, request.correlationId, this.cacheManager, this.networkClient, this.logger, this.performanceClient, this.serverTelemetryManager); + } + /** + * Helper function to create the token request body + * @param request + */ + async createTokenRequestBody(request) { + const parameters = /* @__PURE__ */ new Map(); + addClientId(parameters, request.embeddedClientId || request.extraParameters?.[CLIENT_ID] || this.config.authOptions.clientId); + if (request.redirectUri) { + addRedirectUri(parameters, request.redirectUri); + } + addScopes(parameters, request.scopes, true, this.config.authOptions.authority.options.OIDCOptions?.defaultScopes); + addGrantType(parameters, GrantType.REFRESH_TOKEN_GRANT); + addClientInfo(parameters); + addLibraryInfo(parameters, this.config.libraryInfo); + addApplicationTelemetry(parameters, this.config.telemetry.application); + addThrottling(parameters); + if (this.serverTelemetryManager && !isOidcProtocolMode(this.config)) { + addServerTelemetry(parameters, this.serverTelemetryManager); + } + addRefreshToken(parameters, request.refreshToken); + if (this.config.clientCredentials.clientSecret) { + addClientSecret(parameters, this.config.clientCredentials.clientSecret); + } + if (this.config.clientCredentials.clientAssertion) { + const clientAssertion = this.config.clientCredentials.clientAssertion; + addClientAssertion(parameters, await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + addClientAssertionType(parameters, clientAssertion.assertionType); + } + if (request.authenticationScheme === AuthenticationScheme.POP) { + const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils, this.performanceClient); + let reqCnfData; + if (!request.popKid) { + const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(request, this.logger); + reqCnfData = generatedReqCnfData.reqCnfString; + } else { + reqCnfData = this.cryptoUtils.encodeKid(request.popKid); + } + addPopToken(parameters, reqCnfData); + } else if (request.authenticationScheme === AuthenticationScheme.SSH) { + if (request.sshJwk) { + addSshJwk(parameters, request.sshJwk); + } else { + throw createClientConfigurationError(missingSshJwk); + } + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + addClaims(parameters, request.claims, this.config.authOptions.clientCapabilities); + } + if (this.config.systemOptions.preventCorsPreflight && request.ccsCredential) { + switch (request.ccsCredential.type) { + case CcsCredentialType.HOME_ACCOUNT_ID: + try { + const clientInfo = buildClientInfoFromHomeAccountId(request.ccsCredential.credential); + addCcsOid(parameters, clientInfo); + } catch (e) { + this.logger.verbose(`Could not parse home account ID for CCS Header: '${e}'`, request.correlationId); + } + break; + case CcsCredentialType.UPN: + addCcsUpn(parameters, request.ccsCredential.credential); + break; + } + } + if (request.embeddedClientId) { + addBrokerParameters(parameters, this.config.authOptions.clientId, this.config.authOptions.redirectUri); + } + if (request.extraParameters) { + addExtraParameters(parameters, { + ...request.extraParameters + }); + } + instrumentBrokerParams(parameters, request.correlationId, this.performanceClient); + return mapToQueryString(parameters); + } + }; + var SilentFlowClient = class { + constructor(configuration, performanceClient) { + this.config = buildClientConfiguration(configuration); + this.logger = new Logger(this.config.loggerOptions, name$1, version$1); + this.cryptoUtils = this.config.cryptoInterface; + this.cacheManager = this.config.storageInterface; + this.networkClient = this.config.networkInterface; + this.serverTelemetryManager = this.config.serverTelemetryManager; + this.authority = this.config.authOptions.authority; + this.performanceClient = performanceClient; + } + /** + * Retrieves token from cache or throws an error if it must be refreshed. + * @param request + */ + async acquireCachedToken(request) { + let lastCacheOutcome = CacheOutcome.NOT_APPLICABLE; + if (request.forceRefresh || !StringUtils.isEmptyObj(request.claims)) { + this.setCacheOutcome(CacheOutcome.FORCE_REFRESH_OR_CLAIMS, request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } + if (!request.account) { + throw createClientAuthError(noAccountInSilentRequest); + } + const requestTenantId = request.account.tenantId || getTenantFromAuthorityString(request.authority); + const tokenKeys = this.cacheManager.getTokenKeys(); + const cachedAccessToken = this.cacheManager.getAccessToken(request.account, request, tokenKeys, requestTenantId); + if (!cachedAccessToken) { + this.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN, request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } else if (wasClockTurnedBack(cachedAccessToken.cachedAt) || isTokenExpired(cachedAccessToken.expiresOn, this.config.systemOptions.tokenRenewalOffsetSeconds)) { + this.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED, request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } else if (request.resource) { + if (cachedAccessToken.resource !== request.resource) { + this.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN, request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } + } else if (cachedAccessToken.refreshOn && isTokenExpired(cachedAccessToken.refreshOn, 0)) { + lastCacheOutcome = CacheOutcome.PROACTIVELY_REFRESHED; + } + const environment = request.authority || this.authority.getPreferredCache(); + const cacheRecord = { + account: this.cacheManager.getAccount(this.cacheManager.generateAccountKey(request.account), request.correlationId), + accessToken: cachedAccessToken, + idToken: this.cacheManager.getIdToken(request.account, request.correlationId, tokenKeys, requestTenantId), + refreshToken: null, + appMetadata: this.cacheManager.readAppMetadataFromCache(environment, request.correlationId) + }; + this.setCacheOutcome(lastCacheOutcome, request.correlationId); + if (this.config.serverTelemetryManager) { + this.config.serverTelemetryManager.incrementCacheHits(); + } + return [ + await invokeAsync(this.generateResultFromCacheRecord.bind(this), SilentFlowClientGenerateResultFromCacheRecord, this.logger, this.performanceClient, request.correlationId)(cacheRecord, request), + lastCacheOutcome + ]; + } + setCacheOutcome(cacheOutcome, correlationId) { + this.serverTelemetryManager?.setCacheOutcome(cacheOutcome); + this.performanceClient?.addFields({ + cacheOutcome + }, correlationId); + if (cacheOutcome !== CacheOutcome.NOT_APPLICABLE) { + this.logger.info(`Token refresh is required due to cache outcome: '${cacheOutcome}'`, correlationId); + } + } + /** + * Helper function to build response object from the CacheRecord + * @param cacheRecord + */ + async generateResultFromCacheRecord(cacheRecord, request) { + let idTokenClaims; + if (cacheRecord.idToken) { + idTokenClaims = extractTokenClaims(cacheRecord.idToken.secret, this.config.cryptoInterface.base64Decode); + } + if (request.maxAge || request.maxAge === 0) { + const authTime = idTokenClaims?.auth_time; + if (!authTime) { + throw createClientAuthError(authTimeNotFound); + } + checkMaxAge(authTime, request.maxAge); + } + return ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, cacheRecord, true, request, this.performanceClient, idTokenClaims); + } + }; + function getStandardAuthorizeRequestParameters(authOptions, request, logger, performanceClient) { + const correlationId = request.correlationId; + const parameters = /* @__PURE__ */ new Map(); + addClientId(parameters, request.embeddedClientId || request.extraQueryParameters?.[CLIENT_ID] || authOptions.clientId); + const requestScopes = [ + ...request.scopes || [], + ...request.extraScopesToConsent || [] + ]; + addScopes(parameters, requestScopes, true, authOptions.authority.options.OIDCOptions?.defaultScopes); + addResource(parameters, request.resource); + addRedirectUri(parameters, request.redirectUri); + addCorrelationId(parameters, correlationId); + addResponseMode(parameters, request.responseMode); + addClientInfo(parameters); + addCliData(parameters); + if (request.prompt) { + addPrompt(parameters, request.prompt); + } + if (request.domainHint) { + addDomainHint(parameters, request.domainHint); + } + if (request.prompt !== PromptValue$1.SELECT_ACCOUNT) { + if (request.sid && request.prompt === PromptValue$1.NONE) { + logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from request", request.correlationId); + addSid(parameters, request.sid); + } else if (request.account) { + const accountSid = extractAccountSid(request.account); + let accountLoginHintClaim = extractLoginHint(request.account); + if (accountLoginHintClaim && request.domainHint) { + logger.warning(`AuthorizationCodeClient.createAuthCodeUrlQueryString: "domainHint" param is set, skipping opaque "login_hint" claim. Please consider not passing domainHint`, request.correlationId); + accountLoginHintClaim = null; + } + if (accountLoginHintClaim) { + logger.verbose("createAuthCodeUrlQueryString: login_hint claim present on account", request.correlationId); + addLoginHint(parameters, accountLoginHintClaim); + try { + const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId); + addCcsOid(parameters, clientInfo); + } catch (e) { + logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header", request.correlationId); + } + } else if (accountSid && request.prompt === PromptValue$1.NONE) { + logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from account", request.correlationId); + addSid(parameters, accountSid); + try { + const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId); + addCcsOid(parameters, clientInfo); + } catch (e) { + logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header", request.correlationId); + } + } else if (request.loginHint) { + logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from request", request.correlationId); + addLoginHint(parameters, request.loginHint); + addCcsUpn(parameters, request.loginHint); + } else if (request.account.username) { + logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from account", request.correlationId); + addLoginHint(parameters, request.account.username); + try { + const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId); + addCcsOid(parameters, clientInfo); + } catch (e) { + logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header", request.correlationId); + } + } + } else if (request.loginHint) { + logger.verbose("createAuthCodeUrlQueryString: No account, adding login_hint from request", request.correlationId); + addLoginHint(parameters, request.loginHint); + addCcsUpn(parameters, request.loginHint); + } + } else { + logger.verbose("createAuthCodeUrlQueryString: Prompt is select_account, ignoring account hints", request.correlationId); + } + if (request.nonce) { + addNonce(parameters, request.nonce); + } + if (request.state) { + addState(parameters, request.state); + } + if (request.claims || authOptions.clientCapabilities && authOptions.clientCapabilities.length > 0) { + addClaims(parameters, request.claims, authOptions.clientCapabilities); + } + if (request.embeddedClientId) { + addBrokerParameters(parameters, authOptions.clientId, authOptions.redirectUri); + } + if (authOptions.instanceAware && (!request.extraQueryParameters || !Object.keys(request.extraQueryParameters).includes(INSTANCE_AWARE))) { + addInstanceAware(parameters); + } + return parameters; + } + function getAuthorizeUrl(authority, requestParameters) { + const queryString = mapToQueryString(requestParameters); + return UrlString.appendQueryString(authority.authorizationEndpoint, queryString); + } + function extractAccountSid(account) { + return account.idTokenClaims?.sid || null; + } + function extractLoginHint(account) { + return account.loginHint || account.idTokenClaims?.login_hint || null; + } + function enforceResourceParameter(isMcp, request) { + if (!isMcp) { + return; + } + if (request.resource && (containsResourceParam(request.extraParameters) || containsResourceParam(request.extraQueryParameters))) { + throw createClientAuthError(misplacedResourceParam); + } + if (!request.resource) { + throw createClientAuthError(resourceParameterRequired); + } + } + function containsResourceParam(params) { + if (!params) { + return false; + } + return Object.prototype.hasOwnProperty.call(params, "resource"); + } + var unexpectedError = "unexpected_error"; + var postRequestFailed = "post_request_failed"; + var AuthErrorCodes = /* @__PURE__ */ Object.freeze({ + __proto__: null, + postRequestFailed, + unexpectedError + }); + var skuGroupSeparator = ","; + var skuValueSeparator = "|"; + function makeExtraSkuString(params) { + const { skus, libraryName, libraryVersion, extensionName, extensionVersion } = params; + const skuMap = /* @__PURE__ */ new Map([ + [0, [libraryName, libraryVersion]], + [2, [extensionName, extensionVersion]] + ]); + let skuArr = []; + if (skus?.length) { + skuArr = skus.split(skuGroupSeparator); + if (skuArr.length < 4) { + return skus; + } + } else { + skuArr = Array.from({ length: 4 }, () => skuValueSeparator); + } + skuMap.forEach((value, key) => { + if (value.length === 2 && value[0]?.length && value[1]?.length) { + setSku({ + skuArr, + index: key, + skuName: value[0], + skuVersion: value[1] + }); + } + }); + return skuArr.join(skuGroupSeparator); + } + function setSku(params) { + const { skuArr, index, skuName, skuVersion } = params; + if (index >= skuArr.length) { + return; + } + skuArr[index] = [skuName, skuVersion].join(skuValueSeparator); + } + var ServerTelemetryManager = class _ServerTelemetryManager { + constructor(telemetryRequest, cacheManager) { + this.cacheOutcome = CacheOutcome.NOT_APPLICABLE; + this.cacheManager = cacheManager; + this.apiId = telemetryRequest.apiId; + this.correlationId = telemetryRequest.correlationId; + this.wrapperSKU = telemetryRequest.wrapperSKU || ""; + this.wrapperVer = telemetryRequest.wrapperVer || ""; + this.telemetryCacheKey = SERVER_TELEM_CACHE_KEY + CACHE_KEY_SEPARATOR + telemetryRequest.clientId; + } + /** + * API to add MSER Telemetry to request + */ + generateCurrentRequestHeaderValue() { + const request = `${this.apiId}${SERVER_TELEM_VALUE_SEPARATOR}${this.cacheOutcome}`; + const platformFieldsArr = [this.wrapperSKU, this.wrapperVer]; + const nativeBrokerErrorCode = this.getNativeBrokerErrorCode(); + if (nativeBrokerErrorCode?.length) { + platformFieldsArr.push(`broker_error=${nativeBrokerErrorCode}`); + } + const platformFields = platformFieldsArr.join(SERVER_TELEM_VALUE_SEPARATOR); + const regionDiscoveryFields = this.getRegionDiscoveryFields(); + const requestWithRegionDiscoveryFields = [ + request, + regionDiscoveryFields + ].join(SERVER_TELEM_VALUE_SEPARATOR); + return [ + SERVER_TELEM_SCHEMA_VERSION, + requestWithRegionDiscoveryFields, + platformFields + ].join(SERVER_TELEM_CATEGORY_SEPARATOR); + } + /** + * API to add MSER Telemetry for the last failed request + */ + generateLastRequestHeaderValue() { + const lastRequests = this.getLastRequests(); + const maxErrors = _ServerTelemetryManager.maxErrorsToSend(lastRequests); + const failedRequests = lastRequests.failedRequests.slice(0, 2 * maxErrors).join(SERVER_TELEM_VALUE_SEPARATOR); + const errors = lastRequests.errors.slice(0, maxErrors).join(SERVER_TELEM_VALUE_SEPARATOR); + const errorCount = lastRequests.errors.length; + const overflow = maxErrors < errorCount ? SERVER_TELEM_OVERFLOW_TRUE : SERVER_TELEM_OVERFLOW_FALSE; + const platformFields = [errorCount, overflow].join(SERVER_TELEM_VALUE_SEPARATOR); + return [ + SERVER_TELEM_SCHEMA_VERSION, + lastRequests.cacheHits, + failedRequests, + errors, + platformFields + ].join(SERVER_TELEM_CATEGORY_SEPARATOR); + } + /** + * API to cache token failures for MSER data capture + * @param error + */ + cacheFailedRequest(error) { + const lastRequests = this.getLastRequests(); + if (lastRequests.errors.length >= SERVER_TELEM_MAX_CACHED_ERRORS) { + lastRequests.failedRequests.shift(); + lastRequests.failedRequests.shift(); + lastRequests.errors.shift(); + } + lastRequests.failedRequests.push(this.apiId, this.correlationId); + if (error instanceof Error && !!error && error.toString()) { + if (error instanceof AuthError) { + if (error.subError) { + lastRequests.errors.push(error.subError); + } else if (error.errorCode) { + lastRequests.errors.push(error.errorCode); + } else { + lastRequests.errors.push(error.toString()); + } + } else { + lastRequests.errors.push(error.toString()); + } + } else { + lastRequests.errors.push(SERVER_TELEM_UNKNOWN_ERROR); + } + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId); + return; + } + /** + * Update server telemetry cache entry by incrementing cache hit counter + */ + incrementCacheHits() { + const lastRequests = this.getLastRequests(); + lastRequests.cacheHits += 1; + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId); + return lastRequests.cacheHits; + } + /** + * Get the server telemetry entity from cache or initialize a new one + */ + getLastRequests() { + const initialValue = { + failedRequests: [], + errors: [], + cacheHits: 0 + }; + const lastRequests = this.cacheManager.getServerTelemetry(this.telemetryCacheKey, this.correlationId); + return lastRequests || initialValue; + } + /** + * Remove server telemetry cache entry + */ + clearTelemetryCache() { + const lastRequests = this.getLastRequests(); + const numErrorsFlushed = _ServerTelemetryManager.maxErrorsToSend(lastRequests); + const errorCount = lastRequests.errors.length; + if (numErrorsFlushed === errorCount) { + this.cacheManager.removeItem(this.telemetryCacheKey, this.correlationId); + } else { + const serverTelemEntity = { + failedRequests: lastRequests.failedRequests.slice(numErrorsFlushed * 2), + errors: lastRequests.errors.slice(numErrorsFlushed), + cacheHits: 0 + }; + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, serverTelemEntity, this.correlationId); + } + } + /** + * Returns the maximum number of errors that can be flushed to the server in the next network request + * @param serverTelemetryEntity + */ + static maxErrorsToSend(serverTelemetryEntity) { + let i; + let maxErrors = 0; + let dataSize = 0; + const errorCount = serverTelemetryEntity.errors.length; + for (i = 0; i < errorCount; i++) { + const apiId = serverTelemetryEntity.failedRequests[2 * i] || ""; + const correlationId = serverTelemetryEntity.failedRequests[2 * i + 1] || ""; + const errorCode = serverTelemetryEntity.errors[i] || ""; + dataSize += apiId.toString().length + correlationId.toString().length + errorCode.length + 3; + if (dataSize < SERVER_TELEM_MAX_LAST_HEADER_BYTES) { + maxErrors += 1; + } else { + break; + } + } + return maxErrors; + } + /** + * Get the region discovery fields + * + * @returns string + */ + getRegionDiscoveryFields() { + const regionDiscoveryFields = []; + regionDiscoveryFields.push(this.regionUsed || ""); + regionDiscoveryFields.push(this.regionSource || ""); + regionDiscoveryFields.push(this.regionOutcome || ""); + return regionDiscoveryFields.join(","); + } + /** + * Update the region discovery metadata + * + * @param regionDiscoveryMetadata + * @returns void + */ + updateRegionDiscoveryMetadata(regionDiscoveryMetadata) { + this.regionUsed = regionDiscoveryMetadata.region_used; + this.regionSource = regionDiscoveryMetadata.region_source; + this.regionOutcome = regionDiscoveryMetadata.region_outcome; + } + /** + * Set cache outcome + */ + setCacheOutcome(cacheOutcome) { + this.cacheOutcome = cacheOutcome; + } + setNativeBrokerErrorCode(errorCode) { + const lastRequests = this.getLastRequests(); + lastRequests.nativeBrokerErrorCode = errorCode; + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId); + } + getNativeBrokerErrorCode() { + return this.getLastRequests().nativeBrokerErrorCode; + } + clearNativeBrokerErrorCode() { + const lastRequests = this.getLastRequests(); + delete lastRequests.nativeBrokerErrorCode; + this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId); + } + static makeExtraSkuString(params) { + return makeExtraSkuString(params); + } + }; + var Deserializer = class { + /** + * Parse the JSON blob in memory and deserialize the content + * @param cachedJson - JSON blob cache + */ + static deserializeJSONBlob(jsonFile) { + const deserializedCache = !jsonFile ? {} : JSON.parse(jsonFile); + return deserializedCache; + } + /** + * Deserializes accounts to AccountEntity objects + * @param accounts - accounts of type SerializedAccountEntity + */ + static deserializeAccounts(accounts) { + const accountObjects = {}; + if (accounts) { + Object.keys(accounts).map(function(key) { + const serializedAcc = accounts[key]; + const mappedAcc = { + homeAccountId: serializedAcc.home_account_id, + environment: serializedAcc.environment, + realm: serializedAcc.realm, + localAccountId: serializedAcc.local_account_id, + username: serializedAcc.username, + authorityType: serializedAcc.authority_type, + name: serializedAcc.name, + clientInfo: serializedAcc.client_info, + lastModificationTime: serializedAcc.last_modification_time, + lastModificationApp: serializedAcc.last_modification_app, + tenantProfiles: serializedAcc.tenantProfiles?.map((serializedTenantProfile) => { + return JSON.parse(serializedTenantProfile); + }), + lastUpdatedAt: Date.now().toString() + }; + const account = {}; + CacheManager.toObject(account, mappedAcc); + accountObjects[key] = account; + }); + } + return accountObjects; + } + /** + * Deserializes id tokens to IdTokenEntity objects + * @param idTokens - credentials of type SerializedIdTokenEntity + */ + static deserializeIdTokens(idTokens) { + const idObjects = {}; + if (idTokens) { + Object.keys(idTokens).map(function(key) { + const serializedIdT = idTokens[key]; + const idToken = { + homeAccountId: serializedIdT.home_account_id, + environment: serializedIdT.environment, + credentialType: serializedIdT.credential_type, + clientId: serializedIdT.client_id, + secret: serializedIdT.secret, + realm: serializedIdT.realm, + lastUpdatedAt: Date.now().toString() + }; + idObjects[key] = idToken; + }); + } + return idObjects; + } + /** + * Deserializes access tokens to AccessTokenEntity objects + * @param accessTokens - access tokens of type SerializedAccessTokenEntity + */ + static deserializeAccessTokens(accessTokens) { + const atObjects = {}; + if (accessTokens) { + Object.keys(accessTokens).map(function(key) { + const serializedAT = accessTokens[key]; + const accessToken = { + homeAccountId: serializedAT.home_account_id, + environment: serializedAT.environment, + credentialType: serializedAT.credential_type, + clientId: serializedAT.client_id, + secret: serializedAT.secret, + realm: serializedAT.realm, + target: serializedAT.target, + cachedAt: serializedAT.cached_at, + expiresOn: serializedAT.expires_on, + extendedExpiresOn: serializedAT.extended_expires_on, + refreshOn: serializedAT.refresh_on, + keyId: serializedAT.key_id, + tokenType: serializedAT.token_type, + userAssertionHash: serializedAT.userAssertionHash, + resource: serializedAT.resource, + lastUpdatedAt: Date.now().toString() + }; + atObjects[key] = accessToken; + }); + } + return atObjects; + } + /** + * Deserializes refresh tokens to RefreshTokenEntity objects + * @param refreshTokens - refresh tokens of type SerializedRefreshTokenEntity + */ + static deserializeRefreshTokens(refreshTokens) { + const rtObjects = {}; + if (refreshTokens) { + Object.keys(refreshTokens).map(function(key) { + const serializedRT = refreshTokens[key]; + const refreshToken = { + homeAccountId: serializedRT.home_account_id, + environment: serializedRT.environment, + credentialType: serializedRT.credential_type, + clientId: serializedRT.client_id, + secret: serializedRT.secret, + familyId: serializedRT.family_id, + target: serializedRT.target, + realm: serializedRT.realm, + lastUpdatedAt: Date.now().toString() + }; + rtObjects[key] = refreshToken; + }); + } + return rtObjects; + } + /** + * Deserializes appMetadata to AppMetaData objects + * @param appMetadata - app metadata of type SerializedAppMetadataEntity + */ + static deserializeAppMetadata(appMetadata) { + const appMetadataObjects = {}; + if (appMetadata) { + Object.keys(appMetadata).map(function(key) { + const serializedAmdt = appMetadata[key]; + appMetadataObjects[key] = { + clientId: serializedAmdt.client_id, + environment: serializedAmdt.environment, + familyId: serializedAmdt.family_id + }; + }); + } + return appMetadataObjects; + } + /** + * Deserialize an inMemory Cache + * @param jsonCache - JSON blob cache + */ + static deserializeAllCache(jsonCache) { + return { + accounts: jsonCache.Account ? this.deserializeAccounts(jsonCache.Account) : {}, + idTokens: jsonCache.IdToken ? this.deserializeIdTokens(jsonCache.IdToken) : {}, + accessTokens: jsonCache.AccessToken ? this.deserializeAccessTokens(jsonCache.AccessToken) : {}, + refreshTokens: jsonCache.RefreshToken ? this.deserializeRefreshTokens(jsonCache.RefreshToken) : {}, + appMetadata: jsonCache.AppMetadata ? this.deserializeAppMetadata(jsonCache.AppMetadata) : {} + }; + } + }; + var internals = /* @__PURE__ */ Object.freeze({ + __proto__: null, + Deserializer, + Serializer + }); + var DEFAULT_MANAGED_IDENTITY_ID = "system_assigned_managed_identity"; + var MANAGED_IDENTITY_DEFAULT_TENANT = "managed_identity"; + var DEFAULT_AUTHORITY_FOR_MANAGED_IDENTITY = `https://login.microsoftonline.com/${MANAGED_IDENTITY_DEFAULT_TENANT}/`; + var ManagedIdentityHeaders = { + AUTHORIZATION_HEADER_NAME: "Authorization", + METADATA_HEADER_NAME: "Metadata", + APP_SERVICE_SECRET_HEADER_NAME: "X-IDENTITY-HEADER", + ML_AND_SF_SECRET_HEADER_NAME: "secret" + }; + var ManagedIdentityQueryParameters = { + API_VERSION: "api-version", + RESOURCE: "resource", + SHA256_TOKEN_TO_REFRESH: "token_sha256_to_refresh", + XMS_CC: "xms_cc" + }; + var ManagedIdentityEnvironmentVariableNames = { + AZURE_POD_IDENTITY_AUTHORITY_HOST: "AZURE_POD_IDENTITY_AUTHORITY_HOST", + DEFAULT_IDENTITY_CLIENT_ID: "DEFAULT_IDENTITY_CLIENT_ID", + IDENTITY_ENDPOINT: "IDENTITY_ENDPOINT", + IDENTITY_HEADER: "IDENTITY_HEADER", + IDENTITY_SERVER_THUMBPRINT: "IDENTITY_SERVER_THUMBPRINT", + IMDS_ENDPOINT: "IMDS_ENDPOINT", + MSI_ENDPOINT: "MSI_ENDPOINT", + MSI_SECRET: "MSI_SECRET" + }; + var ManagedIdentitySourceNames = { + APP_SERVICE: "AppService", + AZURE_ARC: "AzureArc", + CLOUD_SHELL: "CloudShell", + DEFAULT_TO_IMDS: "DefaultToImds", + IMDS: "Imds", + MACHINE_LEARNING: "MachineLearning", + SERVICE_FABRIC: "ServiceFabric" + }; + var ManagedIdentityIdType = { + SYSTEM_ASSIGNED: "system-assigned", + USER_ASSIGNED_CLIENT_ID: "user-assigned-client-id", + USER_ASSIGNED_RESOURCE_ID: "user-assigned-resource-id", + USER_ASSIGNED_OBJECT_ID: "user-assigned-object-id" + }; + var HttpMethod = { + GET: "GET", + POST: "POST" + }; + var REGION_ENVIRONMENT_VARIABLE = "REGION_NAME"; + var MSAL_FORCE_REGION = "MSAL_FORCE_REGION"; + var RANDOM_OCTET_SIZE = 32; + var Hash = { + SHA256: "sha256" + }; + var CharSet = { + CV_CHARSET: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" + }; + var CACHE = { + KEY_SEPARATOR: "-" + }; + var Constants = { + MSAL_SKU: "msal.js.node", + JWT_BEARER_ASSERTION_TYPE: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", + HTTP_PROTOCOL: "http://", + LOCALHOST: "localhost" + }; + var ApiId = { + acquireTokenSilent: 62, + acquireTokenByUsernamePassword: 371, + acquireTokenByDeviceCode: 671, + acquireTokenByClientCredential: 771, + acquireTokenByOBO: 772, + acquireTokenWithManagedIdentity: 773, + acquireTokenByCode: 871, + acquireTokenByRefreshToken: 872 + }; + var JwtConstants = { + RSA_256: "RS256", + PSS_256: "PS256", + X5T_256: "x5t#S256", + X5T: "x5t", + X5C: "x5c", + AUDIENCE: "aud", + EXPIRATION_TIME: "exp", + ISSUER: "iss", + SUBJECT: "sub", + NOT_BEFORE: "nbf", + JWT_ID: "jti" + }; + var LOOPBACK_SERVER_CONSTANTS = { + INTERVAL_MS: 100, + TIMEOUT_MS: 5e3 + }; + var AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES = 4096; + var HttpClient = class { + /** + * Sends an HTTP GET request to the specified URL. + * + * This method handles GET requests with optional timeout support. The timeout + * is implemented using AbortController, which provides a clean way to cancel + * fetch requests that take too long to complete. + * + * @param url - The target URL for the GET request + * @param options - Optional request configuration including headers + * @param timeout - Optional timeout in milliseconds. If specified, the request + * will be aborted if it doesn't complete within this time + * @returns Promise that resolves to a NetworkResponse containing headers, body, and status + * @throws {AuthError} When the request times out or response parsing fails + * @throws {NetworkError} When the network request fails + */ + async sendGetRequestAsync(url, options, timeout) { + return this.sendRequest(url, HttpMethod.GET, options, timeout); + } + /** + * Sends an HTTP POST request to the specified URL. + * + * This method handles POST requests with request body support. Currently, + * timeout functionality is not exposed for POST requests, but the underlying + * implementation supports it through the shared sendRequest method. + * + * @param url - The target URL for the POST request + * @param options - Optional request configuration including headers and body + * @returns Promise that resolves to a NetworkResponse containing headers, body, and status + * @throws {AuthError} When the request times out or response parsing fails + * @throws {NetworkError} When the network request fails + */ + async sendPostRequestAsync(url, options) { + return this.sendRequest(url, HttpMethod.POST, options); + } + /** + * Core HTTP request implementation using native fetch API. + * + * This method handles GET and POST HTTP requests with comprehensive + * timeout support and error handling. The timeout mechanism works as follows: + * + * 1. An AbortController is created for each request + * 2. If a timeout is specified, setTimeout is used to call abort() after the delay + * 3. The abort signal is passed to fetch, which will reject the promise if aborted + * 4. Cleanup occurs in both success and error cases to prevent timer leaks + * + * Error handling priority: + * 1. Timeout errors (AbortError) are converted to "Request timeout" messages + * 2. Network/connection errors are wrapped with "Network request failed" prefix + * 3. JSON parsing errors are wrapped with "Failed to parse response" prefix + * + * @param url - The target URL for the request + * @param method - HTTP method (GET or POST) + * @param options - Optional request configuration (headers, body) + * @param timeout - Optional timeout in milliseconds for request cancellation + * @returns Promise resolving to NetworkResponse with parsed JSON body + * @throws {AuthError} For timeouts or JSON parsing errors + * @throws {NetworkError} For network failures + */ + async sendRequest(url, method, options, timeout) { + const controller = new AbortController(); + let timeoutId; + if (timeout) { + timeoutId = setTimeout(() => { + controller.abort(); + }, timeout); + } + const fetchOptions = { + method, + headers: getFetchHeaders(options), + signal: controller.signal + // Enable cancellation via AbortController + }; + if (method === HttpMethod.POST) { + fetchOptions.body = options?.body || ""; + } + let response; + try { + response = await fetch(url, fetchOptions); + } catch (error) { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (error instanceof Error && error.name === "AbortError") { + throw createAuthError(networkError, "Request timeout"); + } + const baseAuthError = createAuthError(networkError, `Network request failed: ${error instanceof Error ? error.message : "unknown"}`); + throw createNetworkError(baseAuthError, void 0, void 0, error instanceof Error ? error : void 0); + } + if (timeoutId) { + clearTimeout(timeoutId); + } + try { + return { + headers: getHeaderDict(response.headers), + body: await response.json(), + status: response.status + }; + } catch (error) { + throw createAuthError(tokenParsingError, `Failed to parse response: ${error instanceof Error ? error.message : "unknown"}`); + } + } + }; + function getHeaderDict(headers) { + const headerDict = {}; + headers.forEach((value, key) => { + headerDict[key] = value; + }); + return headerDict; + } + function getFetchHeaders(options) { + const headers = new Headers(); + if (!(options && options.headers)) { + return headers; + } + Object.entries(options.headers).forEach(([key, value]) => { + headers.append(key, value); + }); + return headers; + } + var invalidFileExtension = "invalid_file_extension"; + var invalidFilePath = "invalid_file_path"; + var invalidManagedIdentityIdType = "invalid_managed_identity_id_type"; + var invalidSecret = "invalid_secret"; + var missingId = "missing_client_id"; + var networkUnavailable = "network_unavailable"; + var platformNotSupported = "platform_not_supported"; + var unableToCreateAzureArc = "unable_to_create_azure_arc"; + var unableToCreateCloudShell = "unable_to_create_cloud_shell"; + var unableToCreateSource = "unable_to_create_source"; + var unableToReadSecretFile = "unable_to_read_secret_file"; + var userAssignedNotAvailableAtRuntime = "user_assigned_not_available_at_runtime"; + var wwwAuthenticateHeaderMissing = "www_authenticate_header_missing"; + var wwwAuthenticateHeaderUnsupportedFormat = "www_authenticate_header_unsupported_format"; + var MsiEnvironmentVariableUrlMalformedErrorCodes = { + [ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST]: "azure_pod_identity_authority_host_url_malformed", + [ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT]: "identity_endpoint_url_malformed", + [ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT]: "imds_endpoint_url_malformed", + [ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT]: "msi_endpoint_url_malformed" + }; + var ManagedIdentityErrorMessages = { + [invalidFileExtension]: "The file path in the WWW-Authenticate header does not contain a .key file.", + [invalidFilePath]: "The file path in the WWW-Authenticate header is not in a valid Windows or Linux Format.", + [invalidManagedIdentityIdType]: "More than one ManagedIdentityIdType was provided.", + [invalidSecret]: "The secret in the file on the file path in the WWW-Authenticate header is greater than 4096 bytes.", + [platformNotSupported]: "The platform is not supported by Azure Arc. Azure Arc only supports Windows and Linux.", + [missingId]: "A ManagedIdentityId id was not provided.", + [MsiEnvironmentVariableUrlMalformedErrorCodes.AZURE_POD_IDENTITY_AUTHORITY_HOST]: `The Managed Identity's '${ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST}' environment variable is malformed.`, + [MsiEnvironmentVariableUrlMalformedErrorCodes.IDENTITY_ENDPOINT]: `The Managed Identity's '${ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT}' environment variable is malformed.`, + [MsiEnvironmentVariableUrlMalformedErrorCodes.IMDS_ENDPOINT]: `The Managed Identity's '${ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT}' environment variable is malformed.`, + [MsiEnvironmentVariableUrlMalformedErrorCodes.MSI_ENDPOINT]: `The Managed Identity's '${ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT}' environment variable is malformed.`, + [networkUnavailable]: "Authentication unavailable. The request to the managed identity endpoint timed out.", + [unableToCreateAzureArc]: "Azure Arc Managed Identities can only be system assigned.", + [unableToCreateCloudShell]: "Cloud Shell Managed Identities can only be system assigned.", + [unableToCreateSource]: "Unable to create a Managed Identity source based on environment variables.", + [unableToReadSecretFile]: "Unable to read the secret file.", + [userAssignedNotAvailableAtRuntime]: "Service Fabric user assigned managed identity ClientId or ResourceId is not configurable at runtime.", + [wwwAuthenticateHeaderMissing]: "A 401 response was received form the Azure Arc Managed Identity, but the www-authenticate header is missing.", + [wwwAuthenticateHeaderUnsupportedFormat]: "A 401 response was received form the Azure Arc Managed Identity, but the www-authenticate header is in an unsupported format." + }; + var ManagedIdentityError = class _ManagedIdentityError extends AuthError { + constructor(errorCode) { + super(errorCode, ManagedIdentityErrorMessages[errorCode]); + this.name = "ManagedIdentityError"; + Object.setPrototypeOf(this, _ManagedIdentityError.prototype); + } + }; + function createManagedIdentityError(errorCode) { + return new ManagedIdentityError(errorCode); + } + var ManagedIdentityId = class { + get id() { + return this._id; + } + set id(value) { + this._id = value; + } + get idType() { + return this._idType; + } + set idType(value) { + this._idType = value; + } + constructor(managedIdentityIdParams) { + const userAssignedClientId = managedIdentityIdParams?.userAssignedClientId; + const userAssignedResourceId = managedIdentityIdParams?.userAssignedResourceId; + const userAssignedObjectId = managedIdentityIdParams?.userAssignedObjectId; + if (userAssignedClientId) { + if (userAssignedResourceId || userAssignedObjectId) { + throw createManagedIdentityError(invalidManagedIdentityIdType); + } + this.id = userAssignedClientId; + this.idType = ManagedIdentityIdType.USER_ASSIGNED_CLIENT_ID; + } else if (userAssignedResourceId) { + if (userAssignedClientId || userAssignedObjectId) { + throw createManagedIdentityError(invalidManagedIdentityIdType); + } + this.id = userAssignedResourceId; + this.idType = ManagedIdentityIdType.USER_ASSIGNED_RESOURCE_ID; + } else if (userAssignedObjectId) { + if (userAssignedClientId || userAssignedResourceId) { + throw createManagedIdentityError(invalidManagedIdentityIdType); + } + this.id = userAssignedObjectId; + this.idType = ManagedIdentityIdType.USER_ASSIGNED_OBJECT_ID; + } else { + this.id = DEFAULT_MANAGED_IDENTITY_ID; + this.idType = ManagedIdentityIdType.SYSTEM_ASSIGNED; + } + } + }; + var NodeAuthErrorMessage = { + invalidLoopbackAddressType: { + code: "invalid_loopback_server_address_type", + desc: "Loopback server address is not type string. This is unexpected." + }, + unableToLoadRedirectUri: { + code: "unable_to_load_redirectUrl", + desc: "Loopback server callback was invoked without a url. This is unexpected." + }, + noAuthCodeInResponse: { + code: "no_auth_code_in_response", + desc: "No auth code found in the server response. Please check your network trace to determine what happened." + }, + noLoopbackServerExists: { + code: "no_loopback_server_exists", + desc: "No loopback server exists yet." + }, + loopbackServerAlreadyExists: { + code: "loopback_server_already_exists", + desc: "Loopback server already exists. Cannot create another." + }, + loopbackServerTimeout: { + code: "loopback_server_timeout", + desc: "Timed out waiting for auth code listener to be registered." + }, + stateNotFoundError: { + code: "state_not_found", + desc: "State not found. Please verify that the request originated from msal." + }, + thumbprintMissing: { + code: "thumbprint_missing_from_client_certificate", + desc: "Client certificate does not contain a SHA-1 or SHA-256 thumbprint." + }, + redirectUriNotSupported: { + code: "redirect_uri_not_supported", + desc: "RedirectUri is not supported in this scenario. Please remove redirectUri from the request." + } + }; + var NodeAuthError = class _NodeAuthError extends AuthError { + constructor(errorCode, errorMessage) { + super(errorCode, errorMessage); + this.name = "NodeAuthError"; + } + /** + * Creates an error thrown if loopback server address is of type string. + */ + static createInvalidLoopbackAddressTypeError() { + return new _NodeAuthError(NodeAuthErrorMessage.invalidLoopbackAddressType.code, `${NodeAuthErrorMessage.invalidLoopbackAddressType.desc}`); + } + /** + * Creates an error thrown if the loopback server is unable to get a url. + */ + static createUnableToLoadRedirectUrlError() { + return new _NodeAuthError(NodeAuthErrorMessage.unableToLoadRedirectUri.code, `${NodeAuthErrorMessage.unableToLoadRedirectUri.desc}`); + } + /** + * Creates an error thrown if the server response does not contain an auth code. + */ + static createNoAuthCodeInResponseError() { + return new _NodeAuthError(NodeAuthErrorMessage.noAuthCodeInResponse.code, `${NodeAuthErrorMessage.noAuthCodeInResponse.desc}`); + } + /** + * Creates an error thrown if the loopback server has not been spun up yet. + */ + static createNoLoopbackServerExistsError() { + return new _NodeAuthError(NodeAuthErrorMessage.noLoopbackServerExists.code, `${NodeAuthErrorMessage.noLoopbackServerExists.desc}`); + } + /** + * Creates an error thrown if a loopback server already exists when attempting to create another one. + */ + static createLoopbackServerAlreadyExistsError() { + return new _NodeAuthError(NodeAuthErrorMessage.loopbackServerAlreadyExists.code, `${NodeAuthErrorMessage.loopbackServerAlreadyExists.desc}`); + } + /** + * Creates an error thrown if the loopback server times out registering the auth code listener. + */ + static createLoopbackServerTimeoutError() { + return new _NodeAuthError(NodeAuthErrorMessage.loopbackServerTimeout.code, `${NodeAuthErrorMessage.loopbackServerTimeout.desc}`); + } + /** + * Creates an error thrown when the state is not present. + */ + static createStateNotFoundError() { + return new _NodeAuthError(NodeAuthErrorMessage.stateNotFoundError.code, NodeAuthErrorMessage.stateNotFoundError.desc); + } + /** + * Creates an error thrown when client certificate was provided, but neither the SHA-1 or SHA-256 thumbprints were provided + */ + static createThumbprintMissingError() { + return new _NodeAuthError(NodeAuthErrorMessage.thumbprintMissing.code, NodeAuthErrorMessage.thumbprintMissing.desc); + } + /** + * Creates an error thrown when redirectUri is provided in an unsupported scenario + */ + static createRedirectUriNotSupportedError() { + return new _NodeAuthError(NodeAuthErrorMessage.redirectUriNotSupported.code, NodeAuthErrorMessage.redirectUriNotSupported.desc); + } + }; + var DEFAULT_AUTH_OPTIONS = { + clientId: "", + authority: DEFAULT_AUTHORITY, + clientSecret: "", + clientAssertion: "", + clientCertificate: { + thumbprint: "", + thumbprintSha256: "", + privateKey: "", + x5c: "" + }, + knownAuthorities: [], + cloudDiscoveryMetadata: "", + authorityMetadata: "", + clientCapabilities: [], + azureCloudOptions: { + azureCloudInstance: AzureCloudInstance.None, + tenant: "" + }, + isMcp: false + }; + var DEFAULT_LOGGER_OPTIONS = { + loggerCallback: () => { + }, + piiLoggingEnabled: false, + logLevel: exports2.LogLevel.Info + }; + var DEFAULT_SYSTEM_OPTIONS = { + loggerOptions: DEFAULT_LOGGER_OPTIONS, + networkClient: new HttpClient(), + disableInternalRetries: false, + protocolMode: ProtocolMode.AAD + }; + var DEFAULT_TELEMETRY_OPTIONS = { + application: { + appName: "", + appVersion: "" + } + }; + function buildAppConfiguration({ auth, broker, cache, system, telemetry }) { + const systemOptions = { + ...DEFAULT_SYSTEM_OPTIONS, + networkClient: new HttpClient(), + loggerOptions: system?.loggerOptions || DEFAULT_LOGGER_OPTIONS, + disableInternalRetries: system?.disableInternalRetries || false + }; + if (!!auth.clientCertificate && !!!auth.clientCertificate.thumbprint && !!!auth.clientCertificate.thumbprintSha256) { + throw NodeAuthError.createStateNotFoundError(); + } + return { + auth: { ...DEFAULT_AUTH_OPTIONS, ...auth }, + broker: { ...broker }, + cache: { ...cache }, + system: { ...systemOptions, ...system }, + telemetry: { ...DEFAULT_TELEMETRY_OPTIONS, ...telemetry } + }; + } + function buildManagedIdentityConfiguration({ clientCapabilities, managedIdentityIdParams, system }) { + const managedIdentityId = new ManagedIdentityId(managedIdentityIdParams); + const loggerOptions = system?.loggerOptions || DEFAULT_LOGGER_OPTIONS; + let networkClient; + if (system?.networkClient) { + networkClient = system.networkClient; + } else { + networkClient = new HttpClient(); + } + return { + clientCapabilities: clientCapabilities || [], + managedIdentityId, + system: { + loggerOptions, + networkClient + }, + disableInternalRetries: system?.disableInternalRetries || false + }; + } + var GuidGenerator = class { + /** + * + * RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or pseudo-random numbers. + * uuidv4 generates guids from cryprtographically-string random + */ + generateGuid() { + return uuid.v4(); + } + /** + * verifies if a string is GUID + * @param guid + */ + isGuid(guid) { + const regexGuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return regexGuid.test(guid); + } + }; + var EncodingUtils = class _EncodingUtils { + /** + * 'utf8': Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8. + * 'base64': Base64 encoding. + * + * @param str text + */ + static base64Encode(str, encoding) { + return Buffer.from(str, encoding).toString(EncodingTypes.BASE64); + } + /** + * encode a URL + * @param str + */ + static base64EncodeUrl(str, encoding) { + return _EncodingUtils.base64Encode(str, encoding).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_"); + } + /** + * 'utf8': Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8. + * 'base64': Base64 encoding. + * + * @param base64Str Base64 encoded text + */ + static base64Decode(base64Str) { + return Buffer.from(base64Str, EncodingTypes.BASE64).toString("utf8"); + } + /** + * @param base64Str Base64 encoded Url + */ + static base64DecodeUrl(base64Str) { + let str = base64Str.replace(/-/g, "+").replace(/_/g, "/"); + while (str.length % 4) { + str += "="; + } + return _EncodingUtils.base64Decode(str); + } + }; + var HashUtils = class { + /** + * generate 'SHA256' hash + * @param buffer + */ + sha256(buffer) { + return crypto12.createHash(Hash.SHA256).update(buffer).digest(); + } + }; + var PkceGenerator = class { + constructor() { + this.hashUtils = new HashUtils(); + } + /** + * generates the codeVerfier and the challenge from the codeVerfier + * reference: https://tools.ietf.org/html/rfc7636#section-4.1 and https://tools.ietf.org/html/rfc7636#section-4.2 + */ + async generatePkceCodes() { + const verifier = this.generateCodeVerifier(); + const challenge = this.generateCodeChallengeFromVerifier(verifier); + return { verifier, challenge }; + } + /** + * generates the codeVerfier; reference: https://tools.ietf.org/html/rfc7636#section-4.1 + */ + generateCodeVerifier() { + const charArr = []; + const maxNumber = 256 - 256 % CharSet.CV_CHARSET.length; + while (charArr.length <= RANDOM_OCTET_SIZE) { + const byte = crypto12.randomBytes(1)[0]; + if (byte >= maxNumber) { + continue; + } + const index = byte % CharSet.CV_CHARSET.length; + charArr.push(CharSet.CV_CHARSET[index]); + } + const verifier = charArr.join(""); + return EncodingUtils.base64EncodeUrl(verifier); + } + /** + * generate the challenge from the codeVerfier; reference: https://tools.ietf.org/html/rfc7636#section-4.2 + * @param codeVerifier + */ + generateCodeChallengeFromVerifier(codeVerifier) { + return EncodingUtils.base64EncodeUrl(this.hashUtils.sha256(codeVerifier).toString(EncodingTypes.BASE64), EncodingTypes.BASE64); + } + }; + var CryptoProvider = class { + constructor() { + this.pkceGenerator = new PkceGenerator(); + this.guidGenerator = new GuidGenerator(); + this.hashUtils = new HashUtils(); + } + /** + * base64 URL safe encoded string + */ + base64UrlEncode() { + throw new Error("Method not implemented."); + } + /** + * Stringifies and base64Url encodes input public key + * @param inputKid - public key id + * @returns Base64Url encoded public key + */ + encodeKid() { + throw new Error("Method not implemented."); + } + /** + * Creates a new random GUID - used to populate state and nonce. + * @returns string (GUID) + */ + createNewGuid() { + return this.guidGenerator.generateGuid(); + } + /** + * Encodes input string to base64. + * @param input - string to be encoded + */ + base64Encode(input) { + return EncodingUtils.base64Encode(input); + } + /** + * Decodes input string from base64. + * @param input - string to be decoded + */ + base64Decode(input) { + return EncodingUtils.base64Decode(input); + } + /** + * Generates PKCE codes used in Authorization Code Flow. + */ + generatePkceCodes() { + return this.pkceGenerator.generatePkceCodes(); + } + /** + * Generates a keypair, stores it and returns a thumbprint - not yet implemented for node + */ + getPublicKeyThumbprint() { + throw new Error("Method not implemented."); + } + /** + * Removes cryptographic keypair from key store matching the keyId passed in + * @param kid - public key id + */ + removeTokenBindingKey() { + throw new Error("Method not implemented."); + } + /** + * Removes all cryptographic keys from Keystore + */ + clearKeystore() { + throw new Error("Method not implemented."); + } + /** + * Signs the given object as a jwt payload with private key retrieved by given kid - currently not implemented for node + */ + signJwt() { + throw new Error("Method not implemented."); + } + /** + * Returns the SHA-256 hash of an input string + */ + async hashString(plainText) { + return EncodingUtils.base64EncodeUrl(this.hashUtils.sha256(plainText).toString(EncodingTypes.BASE64), EncodingTypes.BASE64); + } + }; + function generateCredentialKey(credential) { + const familyId = credential.credentialType === CredentialType.REFRESH_TOKEN && credential.familyId || credential.clientId; + const scheme = credential.tokenType && credential.tokenType.toLowerCase() !== AuthenticationScheme.BEARER.toLowerCase() ? credential.tokenType.toLowerCase() : ""; + const credentialKey = [ + credential.homeAccountId, + credential.environment, + credential.credentialType, + familyId, + credential.realm || "", + credential.target || "", + scheme + ]; + return credentialKey.join(CACHE.KEY_SEPARATOR).toLowerCase(); + } + function generateAccountKey(account) { + const homeTenantId = account.homeAccountId.split(".")[1]; + const accountKey = [ + account.homeAccountId, + account.environment, + homeTenantId || account.tenantId || "" + ]; + return accountKey.join(CACHE.KEY_SEPARATOR).toLowerCase(); + } + var NodeStorage = class extends CacheManager { + constructor(logger, clientId, cryptoImpl, staticAuthorityOptions) { + super(clientId, cryptoImpl, logger, new StubPerformanceClient(), staticAuthorityOptions); + this.cache = {}; + this.changeEmitters = []; + this.logger = logger; + } + /** + * Queue up callbacks + * @param func - a callback function for cache change indication + */ + registerChangeEmitter(func) { + this.changeEmitters.push(func); + } + /** + * Invoke the callback when cache changes + */ + emitChange() { + this.changeEmitters.forEach((func) => func.call(null)); + } + /** + * Converts cacheKVStore to InMemoryCache + * @param cache - key value store + */ + cacheToInMemoryCache(cache) { + const inMemoryCache = { + accounts: {}, + idTokens: {}, + accessTokens: {}, + refreshTokens: {}, + appMetadata: {} + }; + for (const key in cache) { + const value = cache[key]; + if (typeof value !== "object") { + continue; + } + if (isAccountEntity(value)) { + inMemoryCache.accounts[key] = value; + } else if (isIdTokenEntity(value)) { + inMemoryCache.idTokens[key] = value; + } else if (isAccessTokenEntity(value)) { + inMemoryCache.accessTokens[key] = value; + } else if (isRefreshTokenEntity(value)) { + inMemoryCache.refreshTokens[key] = value; + } else if (isAppMetadataEntity(key, value)) { + inMemoryCache.appMetadata[key] = value; + } else { + continue; + } + } + return inMemoryCache; + } + /** + * converts inMemoryCache to CacheKVStore + * @param inMemoryCache - kvstore map for inmemory + */ + inMemoryCacheToCache(inMemoryCache) { + let cache = this.getCache(); + cache = { + ...cache, + ...inMemoryCache.accounts, + ...inMemoryCache.idTokens, + ...inMemoryCache.accessTokens, + ...inMemoryCache.refreshTokens, + ...inMemoryCache.appMetadata + }; + return cache; + } + /** + * gets the current in memory cache for the client + */ + getInMemoryCache() { + this.logger.trace("Getting in-memory cache", ""); + const inMemoryCache = this.cacheToInMemoryCache(this.getCache()); + return inMemoryCache; + } + /** + * sets the current in memory cache for the client + * @param inMemoryCache - key value map in memory + */ + setInMemoryCache(inMemoryCache) { + this.logger.trace("Setting in-memory cache", ""); + const cache = this.inMemoryCacheToCache(inMemoryCache); + this.setCache(cache); + this.emitChange(); + } + /** + * get the current cache key-value store + */ + getCache() { + this.logger.trace("Getting cache key-value store", ""); + return this.cache; + } + /** + * sets the current cache (key value store) + * @param cacheMap - key value map + */ + setCache(cache) { + this.logger.trace("Setting cache key value store", ""); + this.cache = cache; + this.emitChange(); + } + /** + * Gets cache item with given key. + * @param key - lookup key for the cache entry + */ + getItem(key) { + this.logger.tracePii(`Item key: ${key}`, ""); + const cache = this.getCache(); + return cache[key]; + } + /** + * Gets cache item with given key-value + * @param key - lookup key for the cache entry + * @param value - value of the cache entry + */ + setItem(key, value) { + this.logger.tracePii(`Item key: ${key}`, ""); + const cache = this.getCache(); + cache[key] = value; + this.setCache(cache); + } + generateCredentialKey(credential) { + return generateCredentialKey(credential); + } + generateAccountKey(account) { + return generateAccountKey(account); + } + getAccountKeys() { + const inMemoryCache = this.getInMemoryCache(); + const accountKeys = Object.keys(inMemoryCache.accounts); + return accountKeys; + } + getTokenKeys() { + const inMemoryCache = this.getInMemoryCache(); + const tokenKeys = { + idToken: Object.keys(inMemoryCache.idTokens), + accessToken: Object.keys(inMemoryCache.accessTokens), + refreshToken: Object.keys(inMemoryCache.refreshTokens) + }; + return tokenKeys; + } + /** + * Reads account from cache, builds it into an account entity and returns it. + * @param accountKey - lookup key to fetch cache type AccountEntity + * @returns + */ + getAccount(accountKey) { + const cachedAccount = this.getItem(accountKey); + return cachedAccount && typeof cachedAccount === "object" ? { ...cachedAccount } : null; + } + /** + * set account entity + * @param account - cache value to be set of type AccountEntity + */ + async setAccount(account) { + const accountKey = this.generateAccountKey(getAccountInfo(account)); + this.setItem(accountKey, account); + } + /** + * fetch the idToken credential + * @param idTokenKey - lookup key to fetch cache type IdTokenEntity + */ + getIdTokenCredential(idTokenKey) { + const idToken = this.getItem(idTokenKey); + if (isIdTokenEntity(idToken)) { + return idToken; + } + return null; + } + /** + * set idToken credential + * @param idToken - cache value to be set of type IdTokenEntity + */ + async setIdTokenCredential(idToken) { + const idTokenKey = this.generateCredentialKey(idToken); + this.setItem(idTokenKey, idToken); + } + /** + * fetch the accessToken credential + * @param accessTokenKey - lookup key to fetch cache type AccessTokenEntity + */ + getAccessTokenCredential(accessTokenKey) { + const accessToken = this.getItem(accessTokenKey); + if (isAccessTokenEntity(accessToken)) { + return accessToken; + } + return null; + } + /** + * set accessToken credential + * @param accessToken - cache value to be set of type AccessTokenEntity + */ + async setAccessTokenCredential(accessToken) { + const accessTokenKey = this.generateCredentialKey(accessToken); + this.setItem(accessTokenKey, accessToken); + } + /** + * fetch the refreshToken credential + * @param refreshTokenKey - lookup key to fetch cache type RefreshTokenEntity + */ + getRefreshTokenCredential(refreshTokenKey) { + const refreshToken = this.getItem(refreshTokenKey); + if (isRefreshTokenEntity(refreshToken)) { + return refreshToken; + } + return null; + } + /** + * set refreshToken credential + * @param refreshToken - cache value to be set of type RefreshTokenEntity + */ + async setRefreshTokenCredential(refreshToken) { + const refreshTokenKey = this.generateCredentialKey(refreshToken); + this.setItem(refreshTokenKey, refreshToken); + } + /** + * fetch appMetadata entity from the platform cache + * @param appMetadataKey - lookup key to fetch cache type AppMetadataEntity + */ + getAppMetadata(appMetadataKey) { + const appMetadata = this.getItem(appMetadataKey); + if (isAppMetadataEntity(appMetadataKey, appMetadata)) { + return appMetadata; + } + return null; + } + /** + * set appMetadata entity to the platform cache + * @param appMetadata - cache value to be set of type AppMetadataEntity + */ + setAppMetadata(appMetadata) { + const appMetadataKey = generateAppMetadataKey(appMetadata); + this.setItem(appMetadataKey, appMetadata); + } + /** + * fetch server telemetry entity from the platform cache + * @param serverTelemetrykey - lookup key to fetch cache type ServerTelemetryEntity + */ + getServerTelemetry(serverTelemetrykey) { + const serverTelemetryEntity = this.getItem(serverTelemetrykey); + if (serverTelemetryEntity && isServerTelemetryEntity(serverTelemetrykey, serverTelemetryEntity)) { + return serverTelemetryEntity; + } + return null; + } + /** + * set server telemetry entity to the platform cache + * @param serverTelemetryKey - lookup key to fetch cache type ServerTelemetryEntity + * @param serverTelemetry - cache value to be set of type ServerTelemetryEntity + */ + setServerTelemetry(serverTelemetryKey, serverTelemetry) { + this.setItem(serverTelemetryKey, serverTelemetry); + } + /** + * fetch authority metadata entity from the platform cache + * @param key - lookup key to fetch cache type AuthorityMetadataEntity + */ + getAuthorityMetadata(key) { + const authorityMetadataEntity = this.getItem(key); + if (authorityMetadataEntity && isAuthorityMetadataEntity(key, authorityMetadataEntity)) { + return authorityMetadataEntity; + } + return null; + } + /** + * Get all authority metadata keys + */ + getAuthorityMetadataKeys() { + return this.getKeys().filter((key) => { + return this.isAuthorityMetadata(key); + }); + } + /** + * set authority metadata entity to the platform cache + * @param key - lookup key to fetch cache type AuthorityMetadataEntity + * @param metadata - cache value to be set of type AuthorityMetadataEntity + */ + setAuthorityMetadata(key, metadata) { + this.setItem(key, metadata); + } + /** + * fetch throttling entity from the platform cache + * @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity + */ + getThrottlingCache(throttlingCacheKey) { + const throttlingCache = this.getItem(throttlingCacheKey); + if (throttlingCache && isThrottlingEntity(throttlingCacheKey, throttlingCache)) { + return throttlingCache; + } + return null; + } + /** + * set throttling entity to the platform cache + * @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity + * @param throttlingCache - cache value to be set of type ThrottlingEntity + */ + setThrottlingCache(throttlingCacheKey, throttlingCache) { + this.setItem(throttlingCacheKey, throttlingCache); + } + /** + * Removes the cache item from memory with the given key. + * @param key - lookup key to remove a cache entity + * @param inMemory - key value map of the cache + */ + removeItem(key) { + this.logger.tracePii(`Item key: ${key}`, ""); + let result = false; + const cache = this.getCache(); + if (!!cache[key]) { + delete cache[key]; + result = true; + } + if (result) { + this.setCache(cache); + this.emitChange(); + } + return result; + } + /** + * Remove account entity from the platform cache if it's outdated + * @param accountKey - lookup key to fetch cache type AccountEntity + */ + removeOutdatedAccount(accountKey) { + this.removeItem(accountKey); + } + /** + * Checks whether key is in cache. + * @param key - look up key for a cache entity + */ + containsKey(key) { + return this.getKeys().includes(key); + } + /** + * Gets all keys in window. + */ + getKeys() { + this.logger.trace("Retrieving all cache keys", ""); + const cache = this.getCache(); + return [...Object.keys(cache)]; + } + /** + * Clears all cache entries created by MSAL (except tokens). + */ + clear() { + this.logger.trace("Clearing cache entries created by MSAL", ""); + const cacheKeys = this.getKeys(); + cacheKeys.forEach((key) => { + this.removeItem(key); + }); + this.emitChange(); + } + /** + * Initialize in memory cache from an exisiting cache vault + * @param cache - blob formatted cache (JSON) + */ + static generateInMemoryCache(cache) { + return Deserializer.deserializeAllCache(Deserializer.deserializeJSONBlob(cache)); + } + /** + * retrieves the final JSON + * @param inMemoryCache - itemised cache read from the JSON + */ + static generateJsonCache(inMemoryCache) { + return Serializer.serializeAllCache(inMemoryCache); + } + /** + * Updates a credential's cache key if the current cache key is outdated + */ + updateCredentialCacheKey(currentCacheKey, credential) { + const updatedCacheKey = this.generateCredentialKey(credential); + if (currentCacheKey !== updatedCacheKey) { + const cacheItem = this.getItem(currentCacheKey); + if (cacheItem) { + this.removeItem(currentCacheKey); + this.setItem(updatedCacheKey, cacheItem); + this.logger.verbose(`Updated an outdated ${credential.credentialType} cache key`, ""); + return updatedCacheKey; + } else { + this.logger.error(`Attempted to update an outdated ${credential.credentialType} cache key but no item matching the outdated key was found in storage`, ""); + } + } + return currentCacheKey; + } + }; + var defaultSerializedCache = { + Account: {}, + IdToken: {}, + AccessToken: {}, + RefreshToken: {}, + AppMetadata: {} + }; + var TokenCache = class { + constructor(storage, logger, cachePlugin) { + this.cacheHasChanged = false; + this.storage = storage; + this.storage.registerChangeEmitter(this.handleChangeEvent.bind(this)); + if (cachePlugin) { + this.persistence = cachePlugin; + } + this.logger = logger; + } + /** + * Set to true if cache state has changed since last time serialize or writeToPersistence was called + */ + hasChanged() { + return this.cacheHasChanged; + } + /** + * Serializes in memory cache to JSON + */ + serialize() { + this.logger.trace("Serializing in-memory cache", ""); + let finalState = Serializer.serializeAllCache(this.storage.getInMemoryCache()); + if (this.cacheSnapshot) { + this.logger.trace("Reading cache snapshot from disk", ""); + finalState = this.mergeState(JSON.parse(this.cacheSnapshot), finalState); + } else { + this.logger.trace("No cache snapshot to merge", ""); + } + this.cacheHasChanged = false; + return JSON.stringify(finalState); + } + /** + * Deserializes JSON to in-memory cache. JSON should be in MSAL cache schema format + * @param cache - blob formatted cache + */ + deserialize(cache) { + this.logger.trace("Deserializing JSON to in-memory cache", ""); + this.cacheSnapshot = cache; + if (this.cacheSnapshot) { + this.logger.trace("Reading cache snapshot from disk", ""); + const deserializedCache = Deserializer.deserializeAllCache(this.overlayDefaults(JSON.parse(this.cacheSnapshot))); + this.storage.setInMemoryCache(deserializedCache); + } else { + this.logger.trace("No cache snapshot to deserialize", ""); + } + } + /** + * Fetches the cache key-value map + */ + getKVStore() { + return this.storage.getCache(); + } + /** + * Gets cache snapshot in CacheKVStore format + */ + getCacheSnapshot() { + const deserializedPersistentStorage = NodeStorage.generateInMemoryCache(this.cacheSnapshot); + return this.storage.inMemoryCacheToCache(deserializedPersistentStorage); + } + /** + * API that retrieves all accounts currently in cache to the user + */ + async getAllAccounts(correlationId = new CryptoProvider().createNewGuid()) { + this.logger.trace("getAllAccounts called", correlationId); + let cacheContext; + try { + if (this.persistence) { + cacheContext = new TokenCacheContext(this, false); + await this.persistence.beforeCacheAccess(cacheContext); + } + return this.storage.getAllAccounts({}, correlationId); + } finally { + if (this.persistence && cacheContext) { + await this.persistence.afterCacheAccess(cacheContext); + } + } + } + /** + * Returns the signed in account matching homeAccountId. + * (the account object is created at the time of successful login) + * or null when no matching account is found + * @param homeAccountId - unique identifier for an account (uid.utid) + */ + async getAccountByHomeId(homeAccountId) { + const allAccounts = await this.getAllAccounts(); + if (homeAccountId && allAccounts && allAccounts.length) { + return allAccounts.filter((accountObj) => accountObj.homeAccountId === homeAccountId)[0] || null; + } else { + return null; + } + } + /** + * Returns the signed in account matching localAccountId. + * (the account object is created at the time of successful login) + * or null when no matching account is found + * @param localAccountId - unique identifier of an account (sub/obj when homeAccountId cannot be populated) + */ + async getAccountByLocalId(localAccountId) { + const allAccounts = await this.getAllAccounts(); + if (localAccountId && allAccounts && allAccounts.length) { + return allAccounts.filter((accountObj) => accountObj.localAccountId === localAccountId)[0] || null; + } else { + return null; + } + } + /** + * API to remove a specific account and the relevant data from cache + * @param account - AccountInfo passed by the user + */ + async removeAccount(account, correlationId) { + this.logger.trace("removeAccount called", correlationId || ""); + let cacheContext; + try { + if (this.persistence) { + cacheContext = new TokenCacheContext(this, true); + await this.persistence.beforeCacheAccess(cacheContext); + } + this.storage.removeAccount(account, correlationId || new GuidGenerator().generateGuid()); + } finally { + if (this.persistence && cacheContext) { + await this.persistence.afterCacheAccess(cacheContext); + } + } + } + /** + * Overwrites in-memory cache with persistent cache + */ + async overwriteCache() { + if (!this.persistence) { + this.logger.info("No persistence layer specified, cache cannot be overwritten", ""); + return; + } + this.logger.info("Overwriting in-memory cache with persistent cache", ""); + this.storage.clear(); + const cacheContext = new TokenCacheContext(this, false); + await this.persistence.beforeCacheAccess(cacheContext); + const cacheSnapshot = this.getCacheSnapshot(); + this.storage.setCache(cacheSnapshot); + await this.persistence.afterCacheAccess(cacheContext); + } + /** + * Called when the cache has changed state. + */ + handleChangeEvent() { + this.cacheHasChanged = true; + } + /** + * Merge in memory cache with the cache snapshot. + * @param oldState - cache before changes + * @param currentState - current cache state in the library + */ + mergeState(oldState, currentState) { + this.logger.trace("Merging in-memory cache with cache snapshot", ""); + const stateAfterRemoval = this.mergeRemovals(oldState, currentState); + return this.mergeUpdates(stateAfterRemoval, currentState); + } + /** + * Deep update of oldState based on newState values + * @param oldState - cache before changes + * @param newState - updated cache + */ + mergeUpdates(oldState, newState) { + Object.keys(newState).forEach((newKey) => { + const newValue = newState[newKey]; + if (!oldState.hasOwnProperty(newKey)) { + if (newValue !== null) { + oldState[newKey] = newValue; + } + } else { + const newValueNotNull = newValue !== null; + const newValueIsObject = typeof newValue === "object"; + const newValueIsNotArray = !Array.isArray(newValue); + const oldStateNotUndefinedOrNull = typeof oldState[newKey] !== "undefined" && oldState[newKey] !== null; + if (newValueNotNull && newValueIsObject && newValueIsNotArray && oldStateNotUndefinedOrNull) { + this.mergeUpdates(oldState[newKey], newValue); + } else { + oldState[newKey] = newValue; + } + } + }); + return oldState; + } + /** + * Removes entities in oldState that the were removed from newState. If there are any unknown values in root of + * oldState that are not recognized, they are left untouched. + * @param oldState - cache before changes + * @param newState - updated cache + */ + mergeRemovals(oldState, newState) { + this.logger.trace("Remove updated entries in cache", ""); + const accounts = oldState.Account ? this.mergeRemovalsDict(oldState.Account, newState.Account) : oldState.Account; + const accessTokens = oldState.AccessToken ? this.mergeRemovalsDict(oldState.AccessToken, newState.AccessToken) : oldState.AccessToken; + const refreshTokens = oldState.RefreshToken ? this.mergeRemovalsDict(oldState.RefreshToken, newState.RefreshToken) : oldState.RefreshToken; + const idTokens = oldState.IdToken ? this.mergeRemovalsDict(oldState.IdToken, newState.IdToken) : oldState.IdToken; + const appMetadata = oldState.AppMetadata ? this.mergeRemovalsDict(oldState.AppMetadata, newState.AppMetadata) : oldState.AppMetadata; + return { + ...oldState, + Account: accounts, + AccessToken: accessTokens, + RefreshToken: refreshTokens, + IdToken: idTokens, + AppMetadata: appMetadata + }; + } + /** + * Helper to merge new cache with the old one + * @param oldState - cache before changes + * @param newState - updated cache + */ + mergeRemovalsDict(oldState, newState) { + const finalState = { ...oldState }; + Object.keys(oldState).forEach((oldKey) => { + if (!newState || !newState.hasOwnProperty(oldKey)) { + delete finalState[oldKey]; + } + }); + return finalState; + } + /** + * Helper to overlay as a part of cache merge + * @param passedInCache - cache read from the blob + */ + overlayDefaults(passedInCache) { + this.logger.trace("Overlaying input cache with the default cache", ""); + return { + Account: { + ...defaultSerializedCache.Account, + ...passedInCache.Account + }, + IdToken: { + ...defaultSerializedCache.IdToken, + ...passedInCache.IdToken + }, + AccessToken: { + ...defaultSerializedCache.AccessToken, + ...passedInCache.AccessToken + }, + RefreshToken: { + ...defaultSerializedCache.RefreshToken, + ...passedInCache.RefreshToken + }, + AppMetadata: { + ...defaultSerializedCache.AppMetadata, + ...passedInCache.AppMetadata + } + }; + } + }; + var missingTenantIdError = "missing_tenant_id_error"; + var userTimeoutReached = "user_timeout_reached"; + var invalidAssertion = "invalid_assertion"; + var invalidClientCredential = "invalid_client_credential"; + var deviceCodePollingCancelled = "device_code_polling_cancelled"; + var deviceCodeExpired = "device_code_expired"; + var deviceCodeUnknownError = "device_code_unknown_error"; + var ClientAssertion = class _ClientAssertion { + /** + * Initialize the ClientAssertion class from the clientAssertion passed by the user + * @param assertion - refer https://tools.ietf.org/html/rfc7521 + */ + static fromAssertion(assertion) { + const clientAssertion = new _ClientAssertion(); + clientAssertion.jwt = assertion; + return clientAssertion; + } + /** + * @deprecated Use fromCertificateWithSha256Thumbprint instead, with a SHA-256 thumprint + * Initialize the ClientAssertion class from the certificate passed by the user + * @param thumbprint - identifier of a certificate + * @param privateKey - secret key + * @param publicCertificate - electronic document provided to prove the ownership of the public key + */ + static fromCertificate(thumbprint, privateKey, publicCertificate) { + const clientAssertion = new _ClientAssertion(); + clientAssertion.privateKey = privateKey; + clientAssertion.thumbprint = thumbprint; + clientAssertion.useSha256 = false; + if (publicCertificate) { + clientAssertion.publicCertificate = this.parseCertificate(publicCertificate); + } + return clientAssertion; + } + /** + * Initialize the ClientAssertion class from the certificate passed by the user + * @param thumbprint - identifier of a certificate + * @param privateKey - secret key + * @param publicCertificate - electronic document provided to prove the ownership of the public key + */ + static fromCertificateWithSha256Thumbprint(thumbprint, privateKey, publicCertificate) { + const clientAssertion = new _ClientAssertion(); + clientAssertion.privateKey = privateKey; + clientAssertion.thumbprint = thumbprint; + clientAssertion.useSha256 = true; + if (publicCertificate) { + clientAssertion.publicCertificate = this.parseCertificate(publicCertificate); + } + return clientAssertion; + } + /** + * Update JWT for certificate based clientAssertion, if passed by the user, uses it as is + * @param cryptoProvider - library's crypto helper + * @param issuer - iss claim + * @param jwtAudience - aud claim + */ + getJwt(cryptoProvider, issuer, jwtAudience) { + if (this.privateKey && this.thumbprint) { + if (this.jwt && !this.isExpired() && issuer === this.issuer && jwtAudience === this.jwtAudience) { + return this.jwt; + } + return this.createJwt(cryptoProvider, issuer, jwtAudience); + } + if (this.jwt) { + return this.jwt; + } + throw createClientAuthError(invalidAssertion); + } + /** + * JWT format and required claims specified: https://tools.ietf.org/html/rfc7523#section-3 + */ + createJwt(cryptoProvider, issuer, jwtAudience) { + this.issuer = issuer; + this.jwtAudience = jwtAudience; + const issuedAt = nowSeconds(); + this.expirationTime = issuedAt + 600; + const algorithm = this.useSha256 ? JwtConstants.PSS_256 : JwtConstants.RSA_256; + const header = { + alg: algorithm + }; + const thumbprintHeader = this.useSha256 ? JwtConstants.X5T_256 : JwtConstants.X5T; + Object.assign(header, { + [thumbprintHeader]: EncodingUtils.base64EncodeUrl(this.thumbprint, EncodingTypes.HEX) + }); + if (this.publicCertificate) { + Object.assign(header, { + [JwtConstants.X5C]: this.publicCertificate + }); + } + const payload = { + [JwtConstants.AUDIENCE]: this.jwtAudience, + [JwtConstants.EXPIRATION_TIME]: this.expirationTime, + [JwtConstants.ISSUER]: this.issuer, + [JwtConstants.SUBJECT]: this.issuer, + [JwtConstants.NOT_BEFORE]: issuedAt, + [JwtConstants.JWT_ID]: cryptoProvider.createNewGuid() + }; + this.jwt = jwt.sign(payload, this.privateKey, { header }); + return this.jwt; + } + /** + * Utility API to check expiration + */ + isExpired() { + return this.expirationTime < nowSeconds(); + } + /** + * Extracts the raw certs from a given certificate string and returns them in an array. + * @param publicCertificate - electronic document provided to prove the ownership of the public key + */ + static parseCertificate(publicCertificate) { + const regexToFindCerts = /-----BEGIN CERTIFICATE-----\r*\n(.+?)\r*\n-----END CERTIFICATE-----/gs; + const certs = []; + let matches; + while ((matches = regexToFindCerts.exec(publicCertificate)) !== null) { + certs.push(matches[1].replace(/\r*\n/g, "")); + } + return certs; + } + }; + var name = "@azure/msal-node"; + var version4 = "5.1.2"; + var BaseClient = class { + constructor(configuration) { + this.config = buildClientConfiguration(configuration); + this.logger = new Logger(this.config.loggerOptions, name, version4); + this.cryptoUtils = this.config.cryptoInterface; + this.cacheManager = this.config.storageInterface; + this.networkClient = this.config.networkInterface; + this.serverTelemetryManager = this.config.serverTelemetryManager; + this.authority = this.config.authOptions.authority; + this.performanceClient = new StubPerformanceClient(); + } + /** + * Creates default headers for requests to token endpoint + */ + createTokenRequestHeaders(ccsCred) { + return createTokenRequestHeaders(this.logger, false, ccsCred); + } + /** + * Http post to token endpoint + * @param tokenEndpoint + * @param queryString + * @param headers + * @param thumbprint + */ + async executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint, correlationId) { + return executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint, correlationId, this.cacheManager, this.networkClient, this.logger, this.performanceClient, this.serverTelemetryManager); + } + /** + * Wraps sendPostRequestAsync with necessary preflight and postflight logic + * @param thumbprint - Request thumbprint for throttling + * @param tokenEndpoint - Endpoint to make the POST to + * @param options - Body and Headers to include on the POST request + * @param correlationId - CorrelationId for telemetry + */ + async sendPostRequest(thumbprint, tokenEndpoint, options, correlationId) { + return sendPostRequest(thumbprint, tokenEndpoint, options, correlationId, this.cacheManager, this.networkClient, this.logger, this.performanceClient); + } + /** + * Creates query string for the /token request + * @param request + */ + createTokenQueryParameters(request) { + return createTokenQueryParameters(request, this.config.authOptions.clientId, this.config.authOptions.redirectUri, this.performanceClient); + } + }; + var UsernamePasswordClient = class extends BaseClient { + constructor(configuration) { + super(configuration); + } + /** + * API to acquire a token by passing the username and password to the service in exchage of credentials + * password_grant + * @param request - CommonUsernamePasswordRequest + */ + async acquireToken(request) { + this.logger.info("in acquireToken call in username-password client", request.correlationId); + const reqTimestamp = nowSeconds(); + const response = await this.executeTokenRequest(this.authority, request); + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.performanceClient, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response.body, request.correlationId); + const tokenResponse = responseHandler.handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, ApiId.acquireTokenByUsernamePassword); + return tokenResponse; + } + /** + * Executes POST request to token endpoint + * @param authority - authority object + * @param request - CommonUsernamePasswordRequest provided by the developer + */ + async executeTokenRequest(authority, request) { + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await this.createTokenRequestBody(request); + const headers = this.createTokenRequestHeaders({ + credential: request.username, + type: CcsCredentialType.UPN + }); + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: authority.canonicalAuthority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + return this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId); + } + /** + * Generates a map for all the params to be sent to the service + * @param request - CommonUsernamePasswordRequest provided by the developer + */ + async createTokenRequestBody(request) { + const parameters = /* @__PURE__ */ new Map(); + addClientId(parameters, this.config.authOptions.clientId); + addUsername(parameters, request.username); + addPassword(parameters, request.password); + addScopes(parameters, request.scopes); + addResponseType(parameters, OAuthResponseType.IDTOKEN_TOKEN); + addGrantType(parameters, GrantType.RESOURCE_OWNER_PASSWORD_GRANT); + addClientInfo(parameters); + addLibraryInfo(parameters, this.config.libraryInfo); + addApplicationTelemetry(parameters, this.config.telemetry.application); + addThrottling(parameters); + if (this.serverTelemetryManager) { + addServerTelemetry(parameters, this.serverTelemetryManager); + } + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + addCorrelationId(parameters, correlationId); + if (this.config.clientCredentials.clientSecret) { + addClientSecret(parameters, this.config.clientCredentials.clientSecret); + } + const clientAssertion = this.config.clientCredentials.clientAssertion; + if (clientAssertion) { + addClientAssertion(parameters, await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + addClientAssertionType(parameters, clientAssertion.assertionType); + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + addClaims(parameters, request.claims, this.config.authOptions.clientCapabilities); + } + if (this.config.systemOptions.preventCorsPreflight && request.username) { + addCcsUpn(parameters, request.username); + } + return mapToQueryString(parameters); + } + }; + function getAuthCodeRequestUrl(config, authority, request, logger) { + const parameters = getStandardAuthorizeRequestParameters({ + ...config.auth, + authority, + redirectUri: request.redirectUri || "" + }, request, logger); + addLibraryInfo(parameters, { + sku: Constants.MSAL_SKU, + version: version4, + cpu: process.arch || "", + os: process.platform || "" + }); + if (config.system.protocolMode !== ProtocolMode.OIDC) { + addApplicationTelemetry(parameters, config.telemetry.application); + } + addResponseType(parameters, OAuthResponseType.CODE); + if (request.codeChallenge && request.codeChallengeMethod) { + addCodeChallengeParams(parameters, request.codeChallenge, request.codeChallengeMethod); + } + addExtraParameters(parameters, request.extraQueryParameters || {}); + return getAuthorizeUrl(authority, parameters); + } + var ClientApplication = class { + /** + * Constructor for the ClientApplication + */ + constructor(configuration) { + this.config = buildAppConfiguration(configuration); + this.cryptoProvider = new CryptoProvider(); + this.logger = new Logger(this.config.system.loggerOptions, name, version4); + this.storage = new NodeStorage(this.logger, this.config.auth.clientId, this.cryptoProvider, buildStaticAuthorityOptions(this.config.auth)); + this.tokenCache = new TokenCache(this.storage, this.logger, this.config.cache.cachePlugin); + } + /** + * Creates the URL of the authorization request, letting the user input credentials and consent to the + * application. The URL targets the /authorize endpoint of the authority configured in the + * application object. + * + * Once the user inputs their credentials and consents, the authority will send a response to the redirect URI + * sent in the request and should contain an authorization code, which can then be used to acquire tokens via + * `acquireTokenByCode(AuthorizationCodeRequest)`. + */ + async getAuthCodeUrl(request) { + this.logger.info("getAuthCodeUrl called", request.correlationId || ""); + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request), + responseMode: request.responseMode || ResponseMode$1.QUERY, + authenticationScheme: AuthenticationScheme.BEARER, + state: request.state || "", + nonce: request.nonce || "" + }; + const discoveredAuthority = await this.createAuthority(validRequest.authority, validRequest.correlationId, void 0, request.azureCloudOptions); + return getAuthCodeRequestUrl(this.config, discoveredAuthority, validRequest, this.logger); + } + /** + * Acquires a token by exchanging the Authorization Code received from the first step of OAuth2.0 + * Authorization Code flow. + * + * `getAuthCodeUrl(AuthorizationCodeUrlRequest)` can be used to create the URL for the first step of OAuth2.0 + * Authorization Code flow. Ensure that values for redirectUri and scopes in AuthorizationCodeUrlRequest and + * AuthorizationCodeRequest are the same. + */ + async acquireTokenByCode(request, authCodePayLoad) { + this.logger.info("acquireTokenByCode called", request.correlationId || ""); + if (request.state && authCodePayLoad) { + this.logger.info("acquireTokenByCode - validating state", request.correlationId || ""); + this.validateState(request.state, authCodePayLoad.state || ""); + authCodePayLoad = { ...authCodePayLoad, state: "" }; + } + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request), + authenticationScheme: AuthenticationScheme.BEARER + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByCode, validRequest.correlationId); + try { + const discoveredAuthority = await this.createAuthority(validRequest.authority, validRequest.correlationId, void 0, request.azureCloudOptions); + const authClientConfig = await this.buildOauthClientConfiguration(discoveredAuthority, validRequest.correlationId, validRequest.redirectUri, serverTelemetryManager); + const authorizationCodeClient = new AuthorizationCodeClient(authClientConfig, new StubPerformanceClient()); + this.logger.verbose("Auth code client created", validRequest.correlationId); + return await authorizationCodeClient.acquireToken(validRequest, ApiId.acquireTokenByCode, authCodePayLoad); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires a token by exchanging the refresh token provided for a new set of tokens. + * + * This API is provided only for scenarios where you would like to migrate from ADAL to MSAL. Otherwise, it is + * recommended that you use `acquireTokenSilent()` for silent scenarios. When using `acquireTokenSilent()`, MSAL will + * handle the caching and refreshing of tokens automatically. + */ + async acquireTokenByRefreshToken(request) { + this.logger.info("acquireTokenByRefreshToken called", request.correlationId || ""); + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request), + authenticationScheme: AuthenticationScheme.BEARER + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByRefreshToken, validRequest.correlationId); + try { + const discoveredAuthority = await this.createAuthority(validRequest.authority, validRequest.correlationId, void 0, request.azureCloudOptions); + const refreshTokenClientConfig = await this.buildOauthClientConfiguration(discoveredAuthority, validRequest.correlationId, validRequest.redirectUri || "", serverTelemetryManager); + const refreshTokenClient = new RefreshTokenClient(refreshTokenClientConfig, new StubPerformanceClient()); + this.logger.verbose("Refresh token client created", validRequest.correlationId); + return await refreshTokenClient.acquireToken(validRequest, ApiId.acquireTokenByRefreshToken); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires a token silently when a user specifies the account the token is requested for. + * + * This API expects the user to provide an account object and looks into the cache to retrieve the token if present. + * There is also an optional "forceRefresh" boolean the user can send to bypass the cache for access_token and id_token. + * In case the refresh_token is expired or not found, an error is thrown + * and the guidance is for the user to call any interactive token acquisition API (eg: `acquireTokenByCode()`). + */ + async acquireTokenSilent(request) { + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request), + forceRefresh: request.forceRefresh || false + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenSilent, validRequest.correlationId, validRequest.forceRefresh); + try { + const discoveredAuthority = await this.createAuthority(validRequest.authority, validRequest.correlationId, void 0, request.azureCloudOptions); + const clientConfiguration = await this.buildOauthClientConfiguration(discoveredAuthority, validRequest.correlationId, validRequest.redirectUri || "", serverTelemetryManager); + const silentFlowClient = new SilentFlowClient(clientConfiguration, new StubPerformanceClient()); + this.logger.verbose("Silent flow client created", validRequest.correlationId); + try { + await this.tokenCache.overwriteCache(); + return await this.acquireCachedTokenSilent(validRequest, silentFlowClient, clientConfiguration); + } catch (error) { + if (error instanceof ClientAuthError && error.errorCode === tokenRefreshRequired) { + const refreshTokenClient = new RefreshTokenClient(clientConfiguration, new StubPerformanceClient()); + return refreshTokenClient.acquireTokenByRefreshToken(validRequest, ApiId.acquireTokenSilent); + } + throw error; + } + } catch (error) { + if (error instanceof AuthError) { + error.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(error); + throw error; + } + } + async acquireCachedTokenSilent(validRequest, silentFlowClient, clientConfiguration) { + const [authResponse, cacheOutcome] = await silentFlowClient.acquireCachedToken({ + ...validRequest, + scopes: validRequest.scopes?.length ? validRequest.scopes : [...OIDC_DEFAULT_SCOPES] + }); + if (cacheOutcome === CacheOutcome.PROACTIVELY_REFRESHED) { + this.logger.info("ClientApplication:acquireCachedTokenSilent - Cached access token's refreshOn property has been exceeded'. It's not expired, but must be refreshed.", validRequest.correlationId); + const refreshTokenClient = new RefreshTokenClient(clientConfiguration, new StubPerformanceClient()); + try { + await refreshTokenClient.acquireTokenByRefreshToken(validRequest, ApiId.acquireTokenSilent); + } catch { + } + } + return authResponse; + } + /** + * Acquires tokens with password grant by exchanging client applications username and password for credentials + * + * The latest OAuth 2.0 Security Best Current Practice disallows the password grant entirely. + * More details on this recommendation at https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13#section-3.4 + * Microsoft's documentation and recommendations are at: + * https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-authentication-flows#usernamepassword + * + * @param request - UsenamePasswordRequest + * @deprecated - Use a more secure flow instead + */ + async acquireTokenByUsernamePassword(request) { + this.logger.info("acquireTokenByUsernamePassword called", request.correlationId || ""); + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request) + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByUsernamePassword, validRequest.correlationId); + try { + const discoveredAuthority = await this.createAuthority(validRequest.authority, validRequest.correlationId, void 0, request.azureCloudOptions); + const usernamePasswordClientConfig = await this.buildOauthClientConfiguration(discoveredAuthority, validRequest.correlationId, "", serverTelemetryManager); + const usernamePasswordClient = new UsernamePasswordClient(usernamePasswordClientConfig); + this.logger.verbose("Username password client created", validRequest.correlationId); + return await usernamePasswordClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Gets the token cache for the application. + */ + getTokenCache() { + this.logger.info("getTokenCache called", ""); + return this.tokenCache; + } + /** + * Validates OIDC state by comparing the user cached state with the state received from the server. + * + * This API is provided for scenarios where you would use OAuth2.0 state parameter to mitigate against + * CSRF attacks. + * For more information about state, visit https://datatracker.ietf.org/doc/html/rfc6819#section-3.6. + * @param state - Unique GUID generated by the user that is cached by the user and sent to the server during the first leg of the flow + * @param cachedState - This string is sent back by the server with the authorization code + */ + validateState(state, cachedState) { + if (!state) { + throw NodeAuthError.createStateNotFoundError(); + } + if (state !== cachedState) { + throw createClientAuthError(stateMismatch); + } + } + /** + * Returns the logger instance + */ + getLogger() { + return this.logger; + } + /** + * Replaces the default logger set in configurations with new Logger with new configurations + * @param logger - Logger instance + */ + setLogger(logger) { + this.logger = logger; + } + /** + * Builds the common configuration to be passed to the common component based on the platform configurarion + * @param authority - user passed authority in configuration + * @param serverTelemetryManager - initializes servertelemetry if passed + */ + async buildOauthClientConfiguration(discoveredAuthority, requestCorrelationId, redirectUri, serverTelemetryManager) { + this.logger.verbose("buildOauthClientConfiguration called", requestCorrelationId); + this.logger.info(`Building oauth client configuration with the following authority: ${discoveredAuthority.tokenEndpoint}.`, requestCorrelationId); + serverTelemetryManager?.updateRegionDiscoveryMetadata(discoveredAuthority.regionDiscoveryMetadata); + const clientConfiguration = { + authOptions: { + clientId: this.config.auth.clientId, + authority: discoveredAuthority, + clientCapabilities: this.config.auth.clientCapabilities, + redirectUri, + isMcp: this.config.auth.isMcp + }, + loggerOptions: { + logLevel: this.config.system.loggerOptions.logLevel, + loggerCallback: this.config.system.loggerOptions.loggerCallback, + piiLoggingEnabled: this.config.system.loggerOptions.piiLoggingEnabled, + correlationId: requestCorrelationId + }, + cryptoInterface: this.cryptoProvider, + networkInterface: this.config.system.networkClient, + storageInterface: this.storage, + serverTelemetryManager, + clientCredentials: { + clientSecret: this.clientSecret, + clientAssertion: await this.getClientAssertion(discoveredAuthority) + }, + libraryInfo: { + sku: Constants.MSAL_SKU, + version: version4, + cpu: process.arch || "", + os: process.platform || "" + }, + telemetry: this.config.telemetry, + persistencePlugin: this.config.cache.cachePlugin, + serializableCache: this.tokenCache + }; + return clientConfiguration; + } + async getClientAssertion(authority) { + if (this.developerProvidedClientAssertion) { + this.clientAssertion = ClientAssertion.fromAssertion(await getClientAssertion(this.developerProvidedClientAssertion, this.config.auth.clientId, authority.tokenEndpoint)); + } + return this.clientAssertion && { + assertion: this.clientAssertion.getJwt(this.cryptoProvider, this.config.auth.clientId, authority.tokenEndpoint), + assertionType: Constants.JWT_BEARER_ASSERTION_TYPE + }; + } + /** + * Generates a request with the default scopes & generates a correlationId. + * @param authRequest - BaseAuthRequest for initialization + */ + async initializeBaseRequest(authRequest) { + const correlationId = authRequest.correlationId || this.cryptoProvider.createNewGuid(); + this.logger.verbose("initializeRequestScopes called", correlationId); + if (authRequest.authenticationScheme && authRequest.authenticationScheme === AuthenticationScheme.POP) { + this.logger.verbose("Authentication Scheme 'pop' is not supported yet, setting Authentication Scheme to 'Bearer' for request", correlationId); + } + authRequest.authenticationScheme = AuthenticationScheme.BEARER; + return { + ...authRequest, + scopes: [ + ...authRequest && authRequest.scopes || [], + ...OIDC_DEFAULT_SCOPES + ], + correlationId, + authority: authRequest.authority || this.config.auth.authority + }; + } + /** + * Initializes the server telemetry payload + * @param apiId - Id for a specific request + * @param correlationId - GUID + * @param forceRefresh - boolean to indicate network call + */ + initializeServerTelemetryManager(apiId, correlationId, forceRefresh) { + const telemetryPayload = { + clientId: this.config.auth.clientId, + correlationId, + apiId, + forceRefresh: forceRefresh || false + }; + return new ServerTelemetryManager(telemetryPayload, this.storage); + } + /** + * Create authority instance. If authority not passed in request, default to authority set on the application + * object. If no authority set in application object, then default to common authority. + * @param authorityString - authority from user configuration + */ + async createAuthority(authorityString, requestCorrelationId, azureRegionConfiguration, azureCloudOptions) { + this.logger.verbose("createAuthority called", requestCorrelationId); + const authorityUrl = Authority.generateAuthority(authorityString, azureCloudOptions || this.config.auth.azureCloudOptions); + const authorityOptions = { + protocolMode: this.config.system.protocolMode, + knownAuthorities: this.config.auth.knownAuthorities, + cloudDiscoveryMetadata: this.config.auth.cloudDiscoveryMetadata, + authorityMetadata: this.config.auth.authorityMetadata, + azureRegionConfiguration + }; + return createDiscoveredInstance(authorityUrl, this.config.system.networkClient, this.storage, authorityOptions, this.logger, requestCorrelationId, new StubPerformanceClient()); + } + /** + * Clear the cache + */ + clearCache() { + this.storage.clear(); + } + }; + var LoopbackClient = class { + /** + * Spins up a loopback server which returns the server response when the localhost redirectUri is hit + * @param successTemplate + * @param errorTemplate + * @returns + */ + async listenForAuthCode(successTemplate, errorTemplate) { + if (this.server) { + throw NodeAuthError.createLoopbackServerAlreadyExistsError(); + } + return new Promise((resolve, reject) => { + this.server = http.createServer((req, res) => { + const url = req.url; + if (!url) { + res.end(errorTemplate || "Error occurred loading redirectUrl"); + reject(NodeAuthError.createUnableToLoadRedirectUrlError()); + return; + } else if (url === FORWARD_SLASH) { + res.end(successTemplate || "Auth code was successfully acquired. You can close this window now."); + return; + } + const redirectUri = this.getRedirectUri(); + const parsedUrl = new URL(url, redirectUri); + const authCodeResponse = getDeserializedResponse(parsedUrl.search) || {}; + if (authCodeResponse.code) { + res.writeHead(HTTP_REDIRECT, { + location: redirectUri + }); + res.end(); + } + if (authCodeResponse.error) { + res.end(errorTemplate || `Error occurred: ${authCodeResponse.error}`); + } + resolve(authCodeResponse); + }); + this.server.listen(0, "127.0.0.1"); + }); + } + /** + * Get the port that the loopback server is running on + * @returns + */ + getRedirectUri() { + if (!this.server || !this.server.listening) { + throw NodeAuthError.createNoLoopbackServerExistsError(); + } + const address = this.server.address(); + if (!address || typeof address === "string" || !address.port) { + this.closeServer(); + throw NodeAuthError.createInvalidLoopbackAddressTypeError(); + } + const port = address && address.port; + return `${Constants.HTTP_PROTOCOL}${Constants.LOCALHOST}:${port}`; + } + /** + * Close the loopback server + */ + closeServer() { + if (this.server) { + this.server.close(); + if (typeof this.server.closeAllConnections === "function") { + this.server.closeAllConnections(); + } + this.server.unref(); + this.server = void 0; + } + } + }; + var DeviceCodeClient = class extends BaseClient { + constructor(configuration) { + super(configuration); + } + /** + * Gets device code from device code endpoint, calls back to with device code response, and + * polls token endpoint to exchange device code for tokens + * @param request - developer provided CommonDeviceCodeRequest + */ + async acquireToken(request) { + const deviceCodeResponse = await this.getDeviceCode(request); + request.deviceCodeCallback(deviceCodeResponse); + const reqTimestamp = nowSeconds(); + const response = await this.acquireTokenWithDeviceCode(request, deviceCodeResponse); + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.performanceClient, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response, request.correlationId); + return responseHandler.handleServerTokenResponse(response, this.authority, reqTimestamp, request, ApiId.acquireTokenByDeviceCode); + } + /** + * Creates device code request and executes http GET + * @param request - developer provided CommonDeviceCodeRequest + */ + async getDeviceCode(request) { + const queryParametersString = this.createExtraQueryParameters(request); + const endpoint = UrlString.appendQueryString(this.authority.deviceCodeEndpoint, queryParametersString); + const queryString = this.createQueryString(request); + const headers = this.createTokenRequestHeaders(); + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: request.authority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + return this.executePostRequestToDeviceCodeEndpoint(endpoint, queryString, headers, thumbprint, request.correlationId); + } + /** + * Creates query string for the device code request + * @param request - developer provided CommonDeviceCodeRequest + */ + createExtraQueryParameters(request) { + const parameters = /* @__PURE__ */ new Map(); + if (request.extraQueryParameters) { + addExtraParameters(parameters, request.extraQueryParameters); + } + return mapToQueryString(parameters); + } + /** + * Executes POST request to device code endpoint + * @param deviceCodeEndpoint - token endpoint + * @param queryString - string to be used in the body of the request + * @param headers - headers for the request + * @param thumbprint - unique request thumbprint + * @param correlationId - correlation id to be used in the request + */ + async executePostRequestToDeviceCodeEndpoint(deviceCodeEndpoint, queryString, headers, thumbprint, correlationId) { + const { body: { user_code: userCode, device_code: deviceCode, verification_uri: verificationUri, expires_in: expiresIn, interval, message } } = await this.sendPostRequest(thumbprint, deviceCodeEndpoint, { + body: queryString, + headers + }, correlationId); + return { + userCode, + deviceCode, + verificationUri, + expiresIn, + interval, + message + }; + } + /** + * Create device code endpoint query parameters and returns string + * @param request - developer provided CommonDeviceCodeRequest + */ + createQueryString(request) { + const parameters = /* @__PURE__ */ new Map(); + addScopes(parameters, request.scopes); + addClientId(parameters, this.config.authOptions.clientId); + if (request.extraQueryParameters) { + addExtraParameters(parameters, request.extraQueryParameters); + } + if (request.claims || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + addClaims(parameters, request.claims, this.config.authOptions.clientCapabilities); + } + return mapToQueryString(parameters); + } + /** + * Breaks the polling with specific conditions + * @param deviceCodeExpirationTime - expiration time for the device code request + * @param userSpecifiedTimeout - developer provided timeout, to be compared against deviceCodeExpirationTime + * @param userSpecifiedCancelFlag - boolean indicating the developer would like to cancel the request + */ + continuePolling(deviceCodeExpirationTime, userSpecifiedTimeout, userSpecifiedCancelFlag) { + if (userSpecifiedCancelFlag) { + this.logger.error("Token request cancelled by setting DeviceCodeRequest.cancel = true", ""); + throw createClientAuthError(deviceCodePollingCancelled); + } else if (userSpecifiedTimeout && userSpecifiedTimeout < deviceCodeExpirationTime && nowSeconds() > userSpecifiedTimeout) { + this.logger.error(`User defined timeout for device code polling reached. The timeout was set for ${userSpecifiedTimeout}`, ""); + throw createClientAuthError(userTimeoutReached); + } else if (nowSeconds() > deviceCodeExpirationTime) { + if (userSpecifiedTimeout) { + this.logger.verbose(`User specified timeout ignored as the device code has expired before the timeout elapsed. The user specified timeout was set for ${userSpecifiedTimeout}`, ""); + } + this.logger.error(`Device code expired. Expiration time of device code was ${deviceCodeExpirationTime}`, ""); + throw createClientAuthError(deviceCodeExpired); + } + return true; + } + /** + * Creates token request with device code response and polls token endpoint at interval set by the device code response + * @param request - developer provided CommonDeviceCodeRequest + * @param deviceCodeResponse - DeviceCodeResponse returned by the security token service device code endpoint + */ + async acquireTokenWithDeviceCode(request, deviceCodeResponse) { + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(this.authority.tokenEndpoint, queryParametersString); + const requestBody = this.createTokenRequestBody(request, deviceCodeResponse); + const headers = this.createTokenRequestHeaders(); + const userSpecifiedTimeout = request.timeout ? nowSeconds() + request.timeout : void 0; + const deviceCodeExpirationTime = nowSeconds() + deviceCodeResponse.expiresIn; + const pollingIntervalMilli = deviceCodeResponse.interval * 1e3; + while (this.continuePolling(deviceCodeExpirationTime, userSpecifiedTimeout, request.cancel)) { + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: request.authority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + const response = await this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId); + if (response.body && response.body.error) { + if (response.body.error === AUTHORIZATION_PENDING) { + this.logger.info("Authorization pending. Continue polling.", request.correlationId); + await delay(pollingIntervalMilli); + } else { + this.logger.info("Unexpected error in polling from the server", request.correlationId); + throw createAuthError(postRequestFailed, response.body.error); + } + } else { + this.logger.verbose("Authorization completed successfully. Polling stopped.", request.correlationId); + return response.body; + } + } + this.logger.error("Polling stopped for unknown reasons.", request.correlationId); + throw createClientAuthError(deviceCodeUnknownError); + } + /** + * Creates query parameters and converts to string. + * @param request - developer provided CommonDeviceCodeRequest + * @param deviceCodeResponse - DeviceCodeResponse returned by the security token service device code endpoint + */ + createTokenRequestBody(request, deviceCodeResponse) { + const parameters = /* @__PURE__ */ new Map(); + addScopes(parameters, request.scopes); + addClientId(parameters, this.config.authOptions.clientId); + addGrantType(parameters, GrantType.DEVICE_CODE_GRANT); + addDeviceCode(parameters, deviceCodeResponse.deviceCode); + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + addCorrelationId(parameters, correlationId); + addClientInfo(parameters); + addLibraryInfo(parameters, this.config.libraryInfo); + addApplicationTelemetry(parameters, this.config.telemetry.application); + addThrottling(parameters); + if (this.serverTelemetryManager) { + addServerTelemetry(parameters, this.serverTelemetryManager); + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + addClaims(parameters, request.claims, this.config.authOptions.clientCapabilities); + } + return mapToQueryString(parameters); + } + }; + var PublicClientApplication = class extends ClientApplication { + /** + * Important attributes in the Configuration object for auth are: + * - clientID: the application ID of your application. You can obtain one by registering your application with our Application registration portal. + * - authority: the authority URL for your application. + * + * AAD authorities are of the form https://login.microsoftonline.com/\{Enter_the_Tenant_Info_Here\}. + * - If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com). + * - If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations. + * - If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common. + * - To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers. + * + * Azure B2C authorities are of the form https://\{instance\}/\{tenant\}/\{policy\}. Each policy is considered + * its own authority. You will have to set the all of the knownAuthorities at the time of the client application + * construction. + * + * ADFS authorities are of the form https://\{instance\}/adfs. + */ + constructor(configuration) { + super(configuration); + if (this.config.broker.nativeBrokerPlugin) { + if (this.config.broker.nativeBrokerPlugin.isBrokerAvailable) { + this.nativeBrokerPlugin = this.config.broker.nativeBrokerPlugin; + this.nativeBrokerPlugin.setLogger(this.config.system.loggerOptions); + } else { + this.logger.warning("NativeBroker implementation was provided but the broker is unavailable.", ""); + } + } + this.skus = ServerTelemetryManager.makeExtraSkuString({ + libraryName: Constants.MSAL_SKU, + libraryVersion: version4 + }); + } + /** + * Acquires a token from the authority using OAuth2.0 device code flow. + * This flow is designed for devices that do not have access to a browser or have input constraints. + * The authorization server issues a DeviceCode object with a verification code, an end-user code, + * and the end-user verification URI. The DeviceCode object is provided through a callback, and the end-user should be + * instructed to use another device to navigate to the verification URI to input credentials. + * Since the client cannot receive incoming requests, it polls the authorization server repeatedly + * until the end-user completes input of credentials. + */ + async acquireTokenByDeviceCode(request) { + this.logger.info("acquireTokenByDeviceCode called", request.correlationId || ""); + enforceResourceParameter(this.config.auth.isMcp, request); + const validRequest = Object.assign(request, await this.initializeBaseRequest(request)); + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByDeviceCode, validRequest.correlationId); + try { + const discoveredAuthority = await this.createAuthority(validRequest.authority, validRequest.correlationId, void 0, request.azureCloudOptions); + const deviceCodeConfig = await this.buildOauthClientConfiguration(discoveredAuthority, validRequest.correlationId, "", serverTelemetryManager); + const deviceCodeClient = new DeviceCodeClient(deviceCodeConfig); + this.logger.verbose("Device code client created", validRequest.correlationId); + return await deviceCodeClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires a token interactively via the browser by requesting an authorization code then exchanging it for a token. + */ + async acquireTokenInteractive(request) { + const correlationId = request.correlationId || this.cryptoProvider.createNewGuid(); + this.logger.trace("acquireTokenInteractive called", correlationId); + enforceResourceParameter(this.config.auth.isMcp, request); + const { openBrowser, successTemplate, errorTemplate, windowHandle, loopbackClient: customLoopbackClient, ...remainingProperties } = request; + if (this.nativeBrokerPlugin) { + const brokerRequest = { + ...remainingProperties, + clientId: this.config.auth.clientId, + scopes: request.scopes || OIDC_DEFAULT_SCOPES, + redirectUri: request.redirectUri || "", + authority: request.authority || this.config.auth.authority, + correlationId, + extraParameters: { + ...remainingProperties.extraQueryParameters, + ...remainingProperties.extraParameters, + [X_CLIENT_EXTRA_SKU]: this.skus + }, + accountId: remainingProperties.account?.nativeAccountId + }; + return this.nativeBrokerPlugin.acquireTokenInteractive(brokerRequest, windowHandle); + } + if (request.redirectUri) { + if (!this.config.broker.nativeBrokerPlugin) { + throw NodeAuthError.createRedirectUriNotSupportedError(); + } + request.redirectUri = ""; + } + const { verifier, challenge } = await this.cryptoProvider.generatePkceCodes(); + const loopbackClient = customLoopbackClient || new LoopbackClient(); + let authCodeResponse = {}; + let authCodeListenerError = null; + try { + const authCodeListener = loopbackClient.listenForAuthCode(successTemplate, errorTemplate).then((response) => { + authCodeResponse = response; + }).catch((e) => { + authCodeListenerError = e; + }); + const redirectUri = await this.waitForRedirectUri(loopbackClient); + const validRequest = { + ...remainingProperties, + correlationId, + scopes: request.scopes || OIDC_DEFAULT_SCOPES, + redirectUri, + responseMode: ResponseMode$1.QUERY, + codeChallenge: challenge, + codeChallengeMethod: CodeChallengeMethodValues.S256 + }; + const authCodeUrl = await this.getAuthCodeUrl(validRequest); + await openBrowser(authCodeUrl); + await authCodeListener; + if (authCodeListenerError) { + throw authCodeListenerError; + } + if (authCodeResponse.error) { + throw new ServerError(authCodeResponse.error, authCodeResponse.error_description, authCodeResponse.suberror); + } else if (!authCodeResponse.code) { + throw NodeAuthError.createNoAuthCodeInResponseError(); + } + const clientInfo = authCodeResponse.client_info; + const tokenRequest = { + code: authCodeResponse.code, + codeVerifier: verifier, + clientInfo: clientInfo || "", + ...validRequest + }; + return await this.acquireTokenByCode(tokenRequest); + } finally { + loopbackClient.closeServer(); + } + } + /** + * Returns a token retrieved either from the cache or by exchanging the refresh token for a fresh access token. If brokering is enabled the token request will be serviced by the broker. + * @param request - developer provided SilentFlowRequest + * @returns + */ + async acquireTokenSilent(request) { + const correlationId = request.correlationId || this.cryptoProvider.createNewGuid(); + this.logger.trace("acquireTokenSilent called", correlationId); + enforceResourceParameter(this.config.auth.isMcp, request); + if (this.nativeBrokerPlugin) { + const brokerRequest = { + ...request, + clientId: this.config.auth.clientId, + scopes: request.scopes || OIDC_DEFAULT_SCOPES, + redirectUri: request.redirectUri || "", + authority: request.authority || this.config.auth.authority, + correlationId, + extraParameters: { + ...request.extraQueryParameters, + ...request.extraParameters, + [X_CLIENT_EXTRA_SKU]: this.skus + }, + accountId: request.account.nativeAccountId, + forceRefresh: request.forceRefresh || false + }; + return this.nativeBrokerPlugin.acquireTokenSilent(brokerRequest); + } + if (request.redirectUri) { + if (!this.config.broker.nativeBrokerPlugin) { + throw NodeAuthError.createRedirectUriNotSupportedError(); + } + request.redirectUri = ""; + } + return super.acquireTokenSilent(request); + } + /** + * Acquires a token by exchanging the authorization code received from the first step of OAuth 2.0 Authorization Code Flow. + * In MCP mode, a resource parameter is required on the request. + */ + async acquireTokenByCode(request, authCodePayLoad) { + enforceResourceParameter(this.config.auth.isMcp, request); + return super.acquireTokenByCode(request, authCodePayLoad); + } + /** + * Acquires a token by exchanging the refresh token provided for a new set of tokens. + * In MCP mode, a resource parameter is required on the request. + */ + async acquireTokenByRefreshToken(request) { + enforceResourceParameter(this.config.auth.isMcp, request); + return super.acquireTokenByRefreshToken(request); + } + /** + * Removes cache artifacts associated with the given account + * @param request - developer provided SignOutRequest + * @returns + */ + async signOut(request) { + if (this.nativeBrokerPlugin && request.account.nativeAccountId) { + const signoutRequest = { + clientId: this.config.auth.clientId, + accountId: request.account.nativeAccountId, + correlationId: request.correlationId || this.cryptoProvider.createNewGuid() + }; + await this.nativeBrokerPlugin.signOut(signoutRequest); + } + await this.getTokenCache().removeAccount(request.account, request.correlationId); + } + /** + * Returns all cached accounts for this application. If brokering is enabled this request will be serviced by the broker. + * @returns + */ + async getAllAccounts() { + if (this.nativeBrokerPlugin) { + const correlationId = this.cryptoProvider.createNewGuid(); + return this.nativeBrokerPlugin.getAllAccounts(this.config.auth.clientId, correlationId); + } + return this.getTokenCache().getAllAccounts(); + } + /** + * Attempts to retrieve the redirectUri from the loopback server. If the loopback server does not start listening for requests within the timeout this will throw. + * @param loopbackClient - developer provided custom loopback server implementation + * @returns + */ + async waitForRedirectUri(loopbackClient) { + return new Promise((resolve, reject) => { + let ticks = 0; + const id = setInterval(() => { + if (LOOPBACK_SERVER_CONSTANTS.TIMEOUT_MS / LOOPBACK_SERVER_CONSTANTS.INTERVAL_MS < ticks) { + clearInterval(id); + reject(NodeAuthError.createLoopbackServerTimeoutError()); + return; + } + try { + const r = loopbackClient.getRedirectUri(); + clearInterval(id); + resolve(r); + return; + } catch (e) { + if (e instanceof AuthError && e.errorCode === NodeAuthErrorMessage.noLoopbackServerExists.code) { + ticks++; + return; + } + clearInterval(id); + reject(e); + return; + } + }, LOOPBACK_SERVER_CONSTANTS.INTERVAL_MS); + }); + } + }; + var ClientCredentialClient = class extends BaseClient { + constructor(configuration, appTokenProvider) { + super(configuration); + this.appTokenProvider = appTokenProvider; + } + /** + * Public API to acquire a token with ClientCredential Flow for Confidential clients + * @param request - CommonClientCredentialRequest provided by the developer + */ + async acquireToken(request) { + if (request.skipCache || request.claims) { + return this.executeTokenRequest(request, this.authority); + } + const [cachedAuthenticationResult, lastCacheOutcome] = await this.getCachedAuthenticationResult(request, this.config, this.cryptoUtils, this.authority, this.cacheManager, this.serverTelemetryManager); + if (cachedAuthenticationResult) { + if (lastCacheOutcome === CacheOutcome.PROACTIVELY_REFRESHED) { + this.logger.info("ClientCredentialClient:getCachedAuthenticationResult - Cached access token's refreshOn property has been exceeded'. It's not expired, but must be refreshed.", request.correlationId); + const refreshAccessToken = true; + await this.executeTokenRequest(request, this.authority, refreshAccessToken); + } + return cachedAuthenticationResult; + } else { + return this.executeTokenRequest(request, this.authority); + } + } + /** + * looks up cache if the tokens are cached already + */ + async getCachedAuthenticationResult(request, config, cryptoUtils, authority, cacheManager, serverTelemetryManager) { + const clientConfiguration = config; + const managedIdentityConfiguration = config; + let lastCacheOutcome = CacheOutcome.NOT_APPLICABLE; + let cacheContext; + if (clientConfiguration.serializableCache && clientConfiguration.persistencePlugin) { + cacheContext = new TokenCacheContext(clientConfiguration.serializableCache, false); + await clientConfiguration.persistencePlugin.beforeCacheAccess(cacheContext); + } + const cachedAccessToken = this.readAccessTokenFromCache(authority, managedIdentityConfiguration.managedIdentityId?.id || clientConfiguration.authOptions.clientId, new ScopeSet(request.scopes || []), cacheManager, request.correlationId); + if (clientConfiguration.serializableCache && clientConfiguration.persistencePlugin && cacheContext) { + await clientConfiguration.persistencePlugin.afterCacheAccess(cacheContext); + } + if (!cachedAccessToken) { + serverTelemetryManager?.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN); + return [null, CacheOutcome.NO_CACHED_ACCESS_TOKEN]; + } + if (isTokenExpired(cachedAccessToken.expiresOn, clientConfiguration.systemOptions?.tokenRenewalOffsetSeconds || DEFAULT_TOKEN_RENEWAL_OFFSET_SEC)) { + serverTelemetryManager?.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED); + return [null, CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED]; + } + if (cachedAccessToken.refreshOn && isTokenExpired(cachedAccessToken.refreshOn.toString(), 0)) { + lastCacheOutcome = CacheOutcome.PROACTIVELY_REFRESHED; + serverTelemetryManager?.setCacheOutcome(CacheOutcome.PROACTIVELY_REFRESHED); + } + return [ + await ResponseHandler.generateAuthenticationResult(cryptoUtils, authority, { + account: null, + idToken: null, + accessToken: cachedAccessToken, + refreshToken: null, + appMetadata: null + }, true, request, this.performanceClient), + lastCacheOutcome + ]; + } + /** + * Reads access token from the cache + */ + readAccessTokenFromCache(authority, id, scopeSet, cacheManager, correlationId) { + const accessTokenFilter = { + homeAccountId: "", + environment: authority.canonicalAuthorityUrlComponents.HostNameAndPort, + credentialType: CredentialType.ACCESS_TOKEN, + clientId: id, + realm: authority.tenant, + target: ScopeSet.createSearchScopes(scopeSet.asArray()) + }; + const accessTokens = cacheManager.getAccessTokensByFilter(accessTokenFilter, correlationId); + if (accessTokens.length < 1) { + return null; + } else if (accessTokens.length > 1) { + throw createClientAuthError(multipleMatchingTokens); + } + return accessTokens[0]; + } + /** + * Makes a network call to request the token from the service + * @param request - CommonClientCredentialRequest provided by the developer + * @param authority - authority object + */ + async executeTokenRequest(request, authority, refreshAccessToken) { + let serverTokenResponse; + let reqTimestamp; + if (this.appTokenProvider) { + this.logger.info("Using appTokenProvider extensibility.", request.correlationId); + const appTokenPropviderParameters = { + correlationId: request.correlationId, + tenantId: this.config.authOptions.authority.tenant, + scopes: request.scopes, + claims: request.claims + }; + reqTimestamp = nowSeconds(); + const appTokenProviderResult = await this.appTokenProvider(appTokenPropviderParameters); + serverTokenResponse = { + access_token: appTokenProviderResult.accessToken, + expires_in: appTokenProviderResult.expiresInSeconds, + refresh_in: appTokenProviderResult.refreshInSeconds, + token_type: AuthenticationScheme.BEARER + }; + } else { + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await this.createTokenRequestBody(request); + const headers = this.createTokenRequestHeaders(); + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: request.authority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + this.logger.info("Sending token request to endpoint: " + authority.tokenEndpoint, request.correlationId); + reqTimestamp = nowSeconds(); + const response = await this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId); + serverTokenResponse = response.body; + serverTokenResponse.status = response.status; + } + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.performanceClient, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(serverTokenResponse, request.correlationId, refreshAccessToken); + const tokenResponse = await responseHandler.handleServerTokenResponse(serverTokenResponse, this.authority, reqTimestamp, request, ApiId.acquireTokenByClientCredential); + return tokenResponse; + } + /** + * generate the request to the server in the acceptable format + * @param request - CommonClientCredentialRequest provided by the developer + */ + async createTokenRequestBody(request) { + const parameters = /* @__PURE__ */ new Map(); + addClientId(parameters, this.config.authOptions.clientId); + addScopes(parameters, request.scopes, false); + addGrantType(parameters, GrantType.CLIENT_CREDENTIALS_GRANT); + addLibraryInfo(parameters, this.config.libraryInfo); + addApplicationTelemetry(parameters, this.config.telemetry.application); + addThrottling(parameters); + if (this.serverTelemetryManager) { + addServerTelemetry(parameters, this.serverTelemetryManager); + } + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + addCorrelationId(parameters, correlationId); + if (this.config.clientCredentials.clientSecret) { + addClientSecret(parameters, this.config.clientCredentials.clientSecret); + } + const clientAssertion = request.clientAssertion || this.config.clientCredentials.clientAssertion; + if (clientAssertion) { + addClientAssertion(parameters, await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + addClientAssertionType(parameters, clientAssertion.assertionType); + } + if (!StringUtils.isEmptyObj(request.claims) || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + addClaims(parameters, request.claims, this.config.authOptions.clientCapabilities); + } + return mapToQueryString(parameters); + } + }; + var OnBehalfOfClient = class extends BaseClient { + constructor(configuration) { + super(configuration); + } + /** + * Public API to acquire tokens with on behalf of flow + * @param request - developer provided CommonOnBehalfOfRequest + */ + async acquireToken(request) { + this.scopeSet = new ScopeSet(request.scopes || []); + this.userAssertionHash = await this.cryptoUtils.hashString(request.oboAssertion); + if (request.skipCache || request.claims) { + return this.executeTokenRequest(request, this.authority, this.userAssertionHash); + } + try { + return await this.getCachedAuthenticationResult(request); + } catch (e) { + return await this.executeTokenRequest(request, this.authority, this.userAssertionHash); + } + } + /** + * look up cache for tokens + * Find idtoken in the cache + * Find accessToken based on user assertion and account info in the cache + * Please note we are not yet supported OBO tokens refreshed with long lived RT. User will have to send a new assertion if the current access token expires + * This is to prevent security issues when the assertion changes over time, however, longlived RT helps retaining the session + * @param request - developer provided CommonOnBehalfOfRequest + */ + async getCachedAuthenticationResult(request) { + const cachedAccessToken = this.readAccessTokenFromCacheForOBO(this.config.authOptions.clientId, request); + if (!cachedAccessToken) { + this.serverTelemetryManager?.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN); + this.logger.info("SilentFlowClient:acquireCachedToken - No access token found in cache for the given properties.", request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } else if (isTokenExpired(cachedAccessToken.expiresOn, this.config.systemOptions.tokenRenewalOffsetSeconds)) { + this.serverTelemetryManager?.setCacheOutcome(CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED); + this.logger.info(`OnbehalfofFlow:getCachedAuthenticationResult - Cached access token is expired or will expire within ${this.config.systemOptions.tokenRenewalOffsetSeconds} seconds.`, request.correlationId); + throw createClientAuthError(tokenRefreshRequired); + } + const cachedIdToken = this.readIdTokenFromCacheForOBO(cachedAccessToken.homeAccountId, request.correlationId); + let idTokenClaims; + let cachedAccount = null; + if (cachedIdToken) { + idTokenClaims = extractTokenClaims(cachedIdToken.secret, EncodingUtils.base64Decode); + const localAccountId = idTokenClaims.oid || idTokenClaims.sub; + const accountInfo = { + homeAccountId: cachedIdToken.homeAccountId, + environment: cachedIdToken.environment, + tenantId: cachedIdToken.realm, + username: "", + localAccountId: localAccountId || "" + }; + cachedAccount = this.cacheManager.getAccount(this.cacheManager.generateAccountKey(accountInfo), request.correlationId); + } + if (this.config.serverTelemetryManager) { + this.config.serverTelemetryManager.incrementCacheHits(); + } + return ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, { + account: cachedAccount, + accessToken: cachedAccessToken, + idToken: cachedIdToken, + refreshToken: null, + appMetadata: null + }, true, request, this.performanceClient, idTokenClaims); + } + /** + * read idtoken from cache, this is a specific implementation for OBO as the requirements differ from a generic lookup in the cacheManager + * Certain use cases of OBO flow do not expect an idToken in the cache/or from the service + * @param atHomeAccountId - account id + */ + readIdTokenFromCacheForOBO(atHomeAccountId, correlationId) { + const idTokenFilter = { + homeAccountId: atHomeAccountId, + environment: this.authority.canonicalAuthorityUrlComponents.HostNameAndPort, + credentialType: CredentialType.ID_TOKEN, + clientId: this.config.authOptions.clientId, + realm: this.authority.tenant + }; + const idTokenMap = this.cacheManager.getIdTokensByFilter(idTokenFilter, correlationId); + if (Object.values(idTokenMap).length < 1) { + return null; + } + return Object.values(idTokenMap)[0]; + } + /** + * Fetches the cached access token based on incoming assertion + * @param clientId - client id + * @param request - developer provided CommonOnBehalfOfRequest + */ + readAccessTokenFromCacheForOBO(clientId, request) { + const authScheme = request.authenticationScheme || AuthenticationScheme.BEARER; + const credentialType = authScheme.toLowerCase() !== AuthenticationScheme.BEARER.toLowerCase() ? CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME : CredentialType.ACCESS_TOKEN; + const accessTokenFilter = { + credentialType, + clientId, + target: ScopeSet.createSearchScopes(this.scopeSet.asArray()), + tokenType: authScheme, + keyId: request.sshKid, + userAssertionHash: this.userAssertionHash + }; + const accessTokens = this.cacheManager.getAccessTokensByFilter(accessTokenFilter, request.correlationId); + const numAccessTokens = accessTokens.length; + if (numAccessTokens < 1) { + return null; + } else if (numAccessTokens > 1) { + throw createClientAuthError(multipleMatchingTokens); + } + return accessTokens[0]; + } + /** + * Make a network call to the server requesting credentials + * @param request - developer provided CommonOnBehalfOfRequest + * @param authority - authority object + */ + async executeTokenRequest(request, authority, userAssertionHash) { + const queryParametersString = this.createTokenQueryParameters(request); + const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString); + const requestBody = await this.createTokenRequestBody(request); + const headers = this.createTokenRequestHeaders(); + const thumbprint = { + clientId: this.config.authOptions.clientId, + authority: request.authority, + scopes: request.scopes, + claims: request.claims, + authenticationScheme: request.authenticationScheme, + resourceRequestMethod: request.resourceRequestMethod, + resourceRequestUri: request.resourceRequestUri, + shrClaims: request.shrClaims, + sshKid: request.sshKid + }; + const reqTimestamp = nowSeconds(); + const response = await this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId); + const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.performanceClient, this.config.serializableCache, this.config.persistencePlugin); + responseHandler.validateTokenResponse(response.body, request.correlationId); + const tokenResponse = await responseHandler.handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, ApiId.acquireTokenByOBO, void 0, userAssertionHash); + return tokenResponse; + } + /** + * generate a server request in accepable format + * @param request - developer provided CommonOnBehalfOfRequest + */ + async createTokenRequestBody(request) { + const parameters = /* @__PURE__ */ new Map(); + addClientId(parameters, this.config.authOptions.clientId); + addScopes(parameters, request.scopes); + addGrantType(parameters, GrantType.JWT_BEARER); + addClientInfo(parameters); + addLibraryInfo(parameters, this.config.libraryInfo); + addApplicationTelemetry(parameters, this.config.telemetry.application); + addThrottling(parameters); + if (this.serverTelemetryManager) { + addServerTelemetry(parameters, this.serverTelemetryManager); + } + const correlationId = request.correlationId || this.config.cryptoInterface.createNewGuid(); + addCorrelationId(parameters, correlationId); + addRequestTokenUse(parameters, ON_BEHALF_OF); + addOboAssertion(parameters, request.oboAssertion); + if (this.config.clientCredentials.clientSecret) { + addClientSecret(parameters, this.config.clientCredentials.clientSecret); + } + const clientAssertion = this.config.clientCredentials.clientAssertion; + if (clientAssertion) { + addClientAssertion(parameters, await getClientAssertion(clientAssertion.assertion, this.config.authOptions.clientId, request.resourceRequestUri)); + addClientAssertionType(parameters, clientAssertion.assertionType); + } + if (request.claims || this.config.authOptions.clientCapabilities && this.config.authOptions.clientCapabilities.length > 0) { + addClaims(parameters, request.claims, this.config.authOptions.clientCapabilities); + } + return mapToQueryString(parameters); + } + }; + var ConfidentialClientApplication = class extends ClientApplication { + /** + * Constructor for the ConfidentialClientApplication + * + * Required attributes in the Configuration object are: + * - clientID: the application ID of your application. You can obtain one by registering your application with our application registration portal + * - authority: the authority URL for your application. + * - client credential: Must set either client secret, certificate, or assertion for confidential clients. You can obtain a client secret from the application registration portal. + * + * In Azure AD, authority is a URL indicating of the form https://login.microsoftonline.com/\{Enter_the_Tenant_Info_Here\}. + * If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com). + * If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations. + * If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common. + * To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers. + * + * In Azure B2C, authority is of the form https://\{instance\}/tfp/\{tenant\}/\{policyName\}/ + * Full B2C functionality will be available in this library in future versions. + * + * @param Configuration - configuration object for the MSAL ConfidentialClientApplication instance + */ + constructor(configuration) { + super(configuration); + const clientSecretNotEmpty = !!this.config.auth.clientSecret; + const clientAssertionNotEmpty = !!this.config.auth.clientAssertion; + const certificateNotEmpty = (!!this.config.auth.clientCertificate?.thumbprint || !!this.config.auth.clientCertificate?.thumbprintSha256) && !!this.config.auth.clientCertificate?.privateKey; + if (this.appTokenProvider) { + return; + } + if (clientSecretNotEmpty && clientAssertionNotEmpty || clientAssertionNotEmpty && certificateNotEmpty || clientSecretNotEmpty && certificateNotEmpty) { + throw createClientAuthError(invalidClientCredential); + } + if (this.config.auth.clientSecret) { + this.clientSecret = this.config.auth.clientSecret; + return; + } + if (this.config.auth.clientAssertion) { + this.developerProvidedClientAssertion = this.config.auth.clientAssertion; + return; + } + if (!certificateNotEmpty) { + throw createClientAuthError(invalidClientCredential); + } else { + this.clientAssertion = !!this.config.auth.clientCertificate.thumbprintSha256 ? ClientAssertion.fromCertificateWithSha256Thumbprint(this.config.auth.clientCertificate.thumbprintSha256, this.config.auth.clientCertificate.privateKey, this.config.auth.clientCertificate.x5c) : ClientAssertion.fromCertificate( + // guaranteed to be a string, due to prior error checking in this function + this.config.auth.clientCertificate.thumbprint, + this.config.auth.clientCertificate.privateKey, + this.config.auth.clientCertificate.x5c + ); + } + this.appTokenProvider = void 0; + } + /** + * This extensibility point only works for the client_credential flow, i.e. acquireTokenByClientCredential and + * is meant for Azure SDK to enhance Managed Identity support. + * + * @param IAppTokenProvider - Extensibility interface, which allows the app developer to return a token from a custom source. + */ + SetAppTokenProvider(provider) { + this.appTokenProvider = provider; + } + /** + * Acquires tokens from the authority for the application (not for an end user). + */ + async acquireTokenByClientCredential(request) { + this.logger.info("acquireTokenByClientCredential called", request.correlationId || ""); + let clientAssertion; + if (request.clientAssertion) { + clientAssertion = { + assertion: await getClientAssertion( + request.clientAssertion, + this.config.auth.clientId + // tokenEndpoint will be undefined. resourceRequestUri is omitted in ClientCredentialRequest + ), + assertionType: Constants.JWT_BEARER_ASSERTION_TYPE + }; + } + const baseRequest = await this.initializeBaseRequest(request); + const validBaseRequest = { + ...baseRequest, + scopes: baseRequest.scopes.filter((scope) => !OIDC_DEFAULT_SCOPES.includes(scope)) + }; + const validRequest = { + ...request, + ...validBaseRequest, + clientAssertion + }; + const authority = new UrlString(validRequest.authority); + const tenantId = authority.getUrlComponents().PathSegments[0]; + if (Object.values(AADAuthority).includes(tenantId)) { + throw createClientAuthError(missingTenantIdError); + } + const ENV_MSAL_FORCE_REGION = process.env[MSAL_FORCE_REGION]; + let region; + if (validRequest.azureRegion !== "DisableMsalForceRegion") { + if (!validRequest.azureRegion && ENV_MSAL_FORCE_REGION) { + region = ENV_MSAL_FORCE_REGION; + } else { + region = validRequest.azureRegion; + } + } + const azureRegionConfiguration = { + azureRegion: region, + environmentRegion: process.env[REGION_ENVIRONMENT_VARIABLE] + }; + const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByClientCredential, validRequest.correlationId, validRequest.skipCache); + try { + const discoveredAuthority = await this.createAuthority(validRequest.authority, validRequest.correlationId, azureRegionConfiguration, request.azureCloudOptions); + const clientCredentialConfig = await this.buildOauthClientConfiguration(discoveredAuthority, validRequest.correlationId, "", serverTelemetryManager); + const clientCredentialClient = new ClientCredentialClient(clientCredentialConfig, this.appTokenProvider); + this.logger.verbose("Client credential client created", validRequest.correlationId); + return await clientCredentialClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + serverTelemetryManager.cacheFailedRequest(e); + throw e; + } + } + /** + * Acquires tokens from the authority for the application. + * + * Used in scenarios where the current app is a middle-tier service which was called with a token + * representing an end user. The current app can use the token (oboAssertion) to request another + * token to access downstream web API, on behalf of that user. + * + * The current middle-tier app has no user interaction to obtain consent. + * See how to gain consent upfront for your middle-tier app from this article. + * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow#gaining-consent-for-the-middle-tier-application + */ + async acquireTokenOnBehalfOf(request) { + this.logger.info("acquireTokenOnBehalfOf called", request.correlationId || ""); + const validRequest = { + ...request, + ...await this.initializeBaseRequest(request) + }; + try { + const discoveredAuthority = await this.createAuthority(validRequest.authority, validRequest.correlationId, void 0, request.azureCloudOptions); + const onBehalfOfConfig = await this.buildOauthClientConfiguration(discoveredAuthority, validRequest.correlationId, "", void 0); + const oboClient = new OnBehalfOfClient(onBehalfOfConfig); + this.logger.verbose("On behalf of client created", validRequest.correlationId); + return await oboClient.acquireToken(validRequest); + } catch (e) { + if (e instanceof AuthError) { + e.setCorrelationId(validRequest.correlationId); + } + throw e; + } + } + }; + function isIso8601(dateString) { + if (typeof dateString !== "string") { + return false; + } + const date = new Date(dateString); + return !isNaN(date.getTime()) && date.toISOString() === dateString; + } + var HttpClientWithRetries = class { + constructor(httpClientNoRetries, retryPolicy2, logger) { + this.httpClientNoRetries = httpClientNoRetries; + this.retryPolicy = retryPolicy2; + this.logger = logger; + } + async sendNetworkRequestAsyncHelper(httpMethod, url, options) { + if (httpMethod === HttpMethod.GET) { + return this.httpClientNoRetries.sendGetRequestAsync(url, options); + } else { + return this.httpClientNoRetries.sendPostRequestAsync(url, options); + } + } + async sendNetworkRequestAsync(httpMethod, url, options) { + let response = await this.sendNetworkRequestAsyncHelper(httpMethod, url, options); + if ("isNewRequest" in this.retryPolicy) { + this.retryPolicy.isNewRequest = true; + } + let currentRetry = 0; + while (await this.retryPolicy.pauseForRetry(response.status, currentRetry, this.logger, response.headers[HeaderNames.RETRY_AFTER])) { + response = await this.sendNetworkRequestAsyncHelper(httpMethod, url, options); + currentRetry++; + } + return response; + } + async sendGetRequestAsync(url, options) { + return this.sendNetworkRequestAsync(HttpMethod.GET, url, options); + } + async sendPostRequestAsync(url, options) { + return this.sendNetworkRequestAsync(HttpMethod.POST, url, options); + } + }; + var ManagedIdentityUserAssignedIdQueryParameterNames = { + MANAGED_IDENTITY_CLIENT_ID_2017: "clientid", + MANAGED_IDENTITY_CLIENT_ID: "client_id", + MANAGED_IDENTITY_OBJECT_ID: "object_id", + MANAGED_IDENTITY_RESOURCE_ID_IMDS: "msi_res_id", + MANAGED_IDENTITY_RESOURCE_ID_NON_IMDS: "mi_res_id" + }; + var BaseManagedIdentitySource = class { + /** + * Creates an instance of BaseManagedIdentitySource. + * + * @param logger - Logger instance for diagnostic information + * @param nodeStorage - Storage interface for caching tokens + * @param networkClient - Network client for making HTTP requests + * @param cryptoProvider - Cryptographic provider for token operations + * @param disableInternalRetries - Whether to disable automatic retry logic + */ + constructor(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries) { + this.logger = logger; + this.nodeStorage = nodeStorage; + this.networkClient = networkClient; + this.cryptoProvider = cryptoProvider; + this.disableInternalRetries = disableInternalRetries; + } + /** + * Processes the network response and converts it to a standardized server token response. + * This async version allows for source-specific response processing logic while maintaining + * backward compatibility with the synchronous version. + * + * @param response - The network response containing the managed identity token + * @param _networkClient - Network client used for the request (unused in base implementation) + * @param _networkRequest - The original network request parameters (unused in base implementation) + * @param _networkRequestOptions - The network request options (unused in base implementation) + * + * @returns Promise resolving to a standardized server authorization token response + */ + async getServerTokenResponseAsync(response, _networkClient, _networkRequest, _networkRequestOptions) { + return this.getServerTokenResponse(response); + } + /** + * Converts a managed identity token response to a standardized server authorization token response. + * Handles time format conversion, expiration calculation, and error mapping to ensure + * compatibility with the MSAL response handling pipeline. + * + * @param response - The network response containing the managed identity token + * + * @returns Standardized server authorization token response with normalized fields + */ + getServerTokenResponse(response) { + let refreshIn, expiresIn; + if (response.body.expires_on) { + if (isIso8601(response.body.expires_on)) { + response.body.expires_on = new Date(response.body.expires_on).getTime() / 1e3; + } + expiresIn = response.body.expires_on - nowSeconds(); + if (expiresIn > 2 * 3600) { + refreshIn = expiresIn / 2; + } + } + const serverTokenResponse = { + status: response.status, + // success + access_token: response.body.access_token, + expires_in: expiresIn, + scope: response.body.resource, + token_type: response.body.token_type, + refresh_in: refreshIn, + // error + correlation_id: response.body.correlation_id || response.body.correlationId, + error: typeof response.body.error === "string" ? response.body.error : response.body.error?.code, + error_description: response.body.message || (typeof response.body.error === "string" ? response.body.error_description : response.body.error?.message), + error_codes: response.body.error_codes, + timestamp: response.body.timestamp, + trace_id: response.body.trace_id + }; + return serverTokenResponse; + } + /** + * Acquires an access token using the managed identity endpoint for the specified resource. + * This is the primary method for token acquisition, handling the complete flow from + * request creation through response processing and token caching. + * + * @param managedIdentityRequest - The managed identity request containing resource and optional parameters + * @param managedIdentityId - The managed identity configuration (system or user-assigned) + * @param fakeAuthority - Authority instance used for token caching (managed identity uses a placeholder authority) + * @param refreshAccessToken - Whether this is a token refresh operation + * + * @returns Promise resolving to an authentication result containing the access token and metadata + * + * @throws {AuthError} When network requests fail or token validation fails + * @throws {ClientAuthError} When network errors occur during the request + */ + async acquireTokenWithManagedIdentity(managedIdentityRequest, managedIdentityId, fakeAuthority, refreshAccessToken) { + const networkRequest = this.createRequest(managedIdentityRequest.resource, managedIdentityId); + if (managedIdentityRequest.revokedTokenSha256Hash) { + this.logger.info(`[Managed Identity] The following claims are present in the request: ${managedIdentityRequest.claims}`, ""); + networkRequest.queryParameters[ManagedIdentityQueryParameters.SHA256_TOKEN_TO_REFRESH] = managedIdentityRequest.revokedTokenSha256Hash; + } + if (managedIdentityRequest.clientCapabilities?.length) { + const clientCapabilities = managedIdentityRequest.clientCapabilities.toString(); + this.logger.info(`[Managed Identity] The following client capabilities are present in the request: ${clientCapabilities}`, ""); + networkRequest.queryParameters[ManagedIdentityQueryParameters.XMS_CC] = clientCapabilities; + } + const headers = networkRequest.headers; + headers[HeaderNames.CONTENT_TYPE] = URL_FORM_CONTENT_TYPE; + const networkRequestOptions = { headers }; + if (Object.keys(networkRequest.bodyParameters).length) { + networkRequestOptions.body = networkRequest.computeParametersBodyString(); + } + const networkClientHelper = this.disableInternalRetries ? this.networkClient : new HttpClientWithRetries(this.networkClient, networkRequest.retryPolicy, this.logger); + const reqTimestamp = nowSeconds(); + let response; + try { + if (networkRequest.httpMethod === HttpMethod.POST) { + response = await networkClientHelper.sendPostRequestAsync(networkRequest.computeUri(), networkRequestOptions); + } else { + response = await networkClientHelper.sendGetRequestAsync(networkRequest.computeUri(), networkRequestOptions); + } + } catch (error) { + if (error instanceof AuthError) { + throw error; + } else { + throw createClientAuthError(networkError); + } + } + const responseHandler = new ResponseHandler(managedIdentityId.id, this.nodeStorage, this.cryptoProvider, this.logger, new StubPerformanceClient(), null, null); + const serverTokenResponse = await this.getServerTokenResponseAsync(response, networkClientHelper, networkRequest, networkRequestOptions); + responseHandler.validateTokenResponse(serverTokenResponse, serverTokenResponse.correlation_id || "", refreshAccessToken); + return responseHandler.handleServerTokenResponse(serverTokenResponse, fakeAuthority, reqTimestamp, managedIdentityRequest, ApiId.acquireTokenWithManagedIdentity); + } + /** + * Determines the appropriate query parameter name for user-assigned managed identity + * based on the identity type, API version, and endpoint characteristics. + * Different Azure services and API versions use different parameter names for the same identity types. + * + * @param managedIdentityIdType - The type of user-assigned managed identity (client ID, object ID, or resource ID) + * @param isImds - Whether the request is being made to the IMDS (Instance Metadata Service) endpoint + * @param usesApi2017 - Whether the endpoint uses the 2017-09-01 API version (affects client ID parameter name) + * + * @returns The correct query parameter name for the specified identity type and endpoint + * + * @throws {ManagedIdentityError} When an invalid managed identity ID type is provided + */ + getManagedIdentityUserAssignedIdQueryParameterKey(managedIdentityIdType, isImds, usesApi2017) { + switch (managedIdentityIdType) { + case ManagedIdentityIdType.USER_ASSIGNED_CLIENT_ID: + this.logger.info(`[Managed Identity] [API version ${usesApi2017 ? "2017+" : "2019+"}] Adding user assigned client id to the request.`, ""); + return usesApi2017 ? ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_CLIENT_ID_2017 : ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_CLIENT_ID; + case ManagedIdentityIdType.USER_ASSIGNED_RESOURCE_ID: + this.logger.info("[Managed Identity] Adding user assigned resource id to the request.", ""); + return isImds ? ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_RESOURCE_ID_IMDS : ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_RESOURCE_ID_NON_IMDS; + case ManagedIdentityIdType.USER_ASSIGNED_OBJECT_ID: + this.logger.info("[Managed Identity] Adding user assigned object id to the request.", ""); + return ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_OBJECT_ID; + default: + throw createManagedIdentityError(invalidManagedIdentityIdType); + } + } + }; + BaseManagedIdentitySource.getValidatedEnvVariableUrlString = (envVariableStringName, envVariable, sourceName, logger) => { + try { + return new UrlString(envVariable).urlString; + } catch (error) { + logger.info(`[Managed Identity] ${sourceName} managed identity is unavailable because the '${envVariableStringName}' environment variable is malformed.`, ""); + throw createManagedIdentityError(MsiEnvironmentVariableUrlMalformedErrorCodes[envVariableStringName]); + } + }; + var LinearRetryStrategy = class { + /** + * Calculates the number of milliseconds to sleep based on the `retry-after` HTTP header. + * + * @param retryHeader - The value of the `retry-after` HTTP header. This can be either a number of seconds + * or an HTTP date string. + * @returns The number of milliseconds to sleep before retrying the request. If the `retry-after` header is not + * present or cannot be parsed, returns 0. + */ + calculateDelay(retryHeader, minimumDelay) { + if (!retryHeader) { + return minimumDelay; + } + let millisToSleep = Math.round(parseFloat(retryHeader) * 1e3); + if (isNaN(millisToSleep)) { + millisToSleep = new Date(retryHeader).valueOf() - (/* @__PURE__ */ new Date()).valueOf(); + } + return Math.max(minimumDelay, millisToSleep); + } + }; + var DEFAULT_MANAGED_IDENTITY_MAX_RETRIES = 3; + var DEFAULT_MANAGED_IDENTITY_RETRY_DELAY_MS = 1e3; + var DEFAULT_MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON = [ + HTTP_NOT_FOUND, + HTTP_REQUEST_TIMEOUT, + HTTP_TOO_MANY_REQUESTS, + HTTP_SERVER_ERROR, + HTTP_SERVICE_UNAVAILABLE, + HTTP_GATEWAY_TIMEOUT + ]; + var DefaultManagedIdentityRetryPolicy = class _DefaultManagedIdentityRetryPolicy { + constructor() { + this.linearRetryStrategy = new LinearRetryStrategy(); + } + /* + * this is defined here as a static variable despite being defined as a constant outside of the + * class because it needs to be overridden in the unit tests so that the unit tests run faster + */ + static get DEFAULT_MANAGED_IDENTITY_RETRY_DELAY_MS() { + return DEFAULT_MANAGED_IDENTITY_RETRY_DELAY_MS; + } + async pauseForRetry(httpStatusCode, currentRetry, logger, retryAfterHeader) { + if (DEFAULT_MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON.includes(httpStatusCode) && currentRetry < DEFAULT_MANAGED_IDENTITY_MAX_RETRIES) { + const retryAfterDelay = this.linearRetryStrategy.calculateDelay(retryAfterHeader, _DefaultManagedIdentityRetryPolicy.DEFAULT_MANAGED_IDENTITY_RETRY_DELAY_MS); + logger.verbose(`Retrying request in ${retryAfterDelay}ms (retry attempt: ${currentRetry + 1})`, ""); + await new Promise((resolve) => { + return setTimeout(resolve, retryAfterDelay); + }); + return true; + } + return false; + } + }; + var ManagedIdentityRequestParameters = class { + constructor(httpMethod, endpoint, retryPolicy2) { + this.httpMethod = httpMethod; + this._baseEndpoint = endpoint; + this.headers = {}; + this.bodyParameters = {}; + this.queryParameters = {}; + this.retryPolicy = retryPolicy2 || new DefaultManagedIdentityRetryPolicy(); + } + computeUri() { + const parameters = /* @__PURE__ */ new Map(); + if (this.queryParameters) { + addExtraParameters(parameters, this.queryParameters); + } + const queryParametersString = mapToQueryString(parameters); + return UrlString.appendQueryString(this._baseEndpoint, queryParametersString); + } + computeParametersBodyString() { + const parameters = /* @__PURE__ */ new Map(); + if (this.bodyParameters) { + addExtraParameters(parameters, this.bodyParameters); + } + return mapToQueryString(parameters); + } + }; + var APP_SERVICE_MSI_API_VERSION = "2019-08-01"; + var AppService = class _AppService extends BaseManagedIdentitySource { + /** + * Creates a new instance of the AppService managed identity source. + * + * @param logger - Logger instance for diagnostic output + * @param nodeStorage - Node.js storage implementation for caching + * @param networkClient - Network client for making HTTP requests + * @param cryptoProvider - Cryptographic operations provider + * @param disableInternalRetries - Whether to disable internal retry logic + * @param identityEndpoint - The App Service identity endpoint URL + * @param identityHeader - The secret header value required for authentication + */ + constructor(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, identityEndpoint, identityHeader) { + super(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries); + this.identityEndpoint = identityEndpoint; + this.identityHeader = identityHeader; + } + /** + * Retrieves the required environment variables for App Service managed identity. + * + * App Service managed identity requires two environment variables: + * - IDENTITY_ENDPOINT: The URL of the local metadata service + * - IDENTITY_HEADER: A secret header value for authentication + * + * @returns An array containing [identityEndpoint, identityHeader] values from environment variables. + * Either value may be undefined if the environment variable is not set. + */ + static getEnvironmentVariables() { + const identityEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT]; + const identityHeader = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_HEADER]; + return [identityEndpoint, identityHeader]; + } + /** + * Attempts to create an AppService managed identity source if the environment supports it. + * + * This method checks for the presence of required environment variables and validates + * the identity endpoint URL. If the environment is not suitable for App Service managed + * identity (missing environment variables or invalid endpoint), it returns null. + * + * @param logger - Logger instance for diagnostic output + * @param nodeStorage - Node.js storage implementation for caching + * @param networkClient - Network client for making HTTP requests + * @param cryptoProvider - Cryptographic operations provider + * @param disableInternalRetries - Whether to disable internal retry logic + * + * @returns A new AppService instance if the environment is suitable, null otherwise + */ + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries) { + const [identityEndpoint, identityHeader] = _AppService.getEnvironmentVariables(); + if (!identityEndpoint || !identityHeader) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.APP_SERVICE} managed identity is unavailable because one or both of the '${ManagedIdentityEnvironmentVariableNames.IDENTITY_HEADER}' and '${ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT}' environment variables are not defined.`, ""); + return null; + } + const validatedIdentityEndpoint = _AppService.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT, identityEndpoint, ManagedIdentitySourceNames.APP_SERVICE, logger); + logger.info(`[Managed Identity] Environment variables validation passed for ${ManagedIdentitySourceNames.APP_SERVICE} managed identity. Endpoint URI: ${validatedIdentityEndpoint}. Creating ${ManagedIdentitySourceNames.APP_SERVICE} managed identity.`, ""); + return new _AppService(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, identityEndpoint, identityHeader); + } + /** + * Creates a managed identity token request for the App Service environment. + * + * This method constructs an HTTP GET request to the App Service identity endpoint + * with the required headers, query parameters, and managed identity configuration. + * The request includes the secret header for authentication and appropriate API version. + * + * @param resource - The target resource/scope for which to request an access token (e.g., "https://graph.microsoft.com/.default") + * @param managedIdentityId - The managed identity configuration specifying whether to use system-assigned or user-assigned identity + * + * @returns A configured ManagedIdentityRequestParameters object ready for network execution + */ + createRequest(resource, managedIdentityId) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.identityEndpoint); + request.headers[ManagedIdentityHeaders.APP_SERVICE_SECRET_HEADER_NAME] = this.identityHeader; + request.queryParameters[ManagedIdentityQueryParameters.API_VERSION] = APP_SERVICE_MSI_API_VERSION; + request.queryParameters[ManagedIdentityQueryParameters.RESOURCE] = resource; + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + request.queryParameters[this.getManagedIdentityUserAssignedIdQueryParameterKey(managedIdentityId.idType)] = managedIdentityId.id; + } + return request; + } + }; + var ARC_API_VERSION = "2019-11-01"; + var DEFAULT_AZURE_ARC_IDENTITY_ENDPOINT = "http://127.0.0.1:40342/metadata/identity/oauth2/token"; + var HIMDS_EXECUTABLE_HELPER_STRING = "N/A: himds executable exists"; + var SUPPORTED_AZURE_ARC_PLATFORMS = { + win32: `${process.env["ProgramData"]}\\AzureConnectedMachineAgent\\Tokens\\`, + linux: "/var/opt/azcmagent/tokens/" + }; + var AZURE_ARC_FILE_DETECTION = { + win32: `${process.env["ProgramFiles"]}\\AzureConnectedMachineAgent\\himds.exe`, + linux: "/opt/azcmagent/bin/himds" + }; + var AzureArc = class _AzureArc extends BaseManagedIdentitySource { + /** + * Creates a new instance of the AzureArc managed identity source. + * + * @param logger - Logger instance for capturing telemetry and diagnostic information + * @param nodeStorage - Storage implementation for caching tokens and metadata + * @param networkClient - Network client for making HTTP requests to the identity endpoint + * @param cryptoProvider - Cryptographic operations provider for token validation and encryption + * @param disableInternalRetries - Flag to disable automatic retry logic for failed requests + * @param identityEndpoint - The Azure Arc identity endpoint URL for token requests + */ + constructor(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, identityEndpoint) { + super(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries); + this.identityEndpoint = identityEndpoint; + } + /** + * Retrieves and validates Azure Arc environment variables for managed identity configuration. + * + * This method checks for IDENTITY_ENDPOINT and IMDS_ENDPOINT environment variables. + * If either is missing, it attempts to detect the Azure Arc environment by checking for + * the HIMDS executable at platform-specific paths. On successful detection, it returns + * the default identity endpoint and a helper string indicating file-based detection. + * + * @returns An array containing [identityEndpoint, imdsEndpoint] where both values are + * strings if Azure Arc is available, or undefined if not available. + */ + static getEnvironmentVariables() { + let identityEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT]; + let imdsEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT]; + if (!identityEndpoint || !imdsEndpoint) { + const fileDetectionPath = AZURE_ARC_FILE_DETECTION[process.platform]; + try { + fs6.accessSync(fileDetectionPath, fs6.constants.F_OK | fs6.constants.R_OK); + identityEndpoint = DEFAULT_AZURE_ARC_IDENTITY_ENDPOINT; + imdsEndpoint = HIMDS_EXECUTABLE_HELPER_STRING; + } catch (err) { + } + } + return [identityEndpoint, imdsEndpoint]; + } + /** + * Attempts to create an AzureArc managed identity source instance. + * + * Validates the Azure Arc environment by checking environment variables + * and performing file-based detection. It ensures that only system-assigned managed identities + * are supported for Azure Arc scenarios. The method performs comprehensive validation of + * endpoint URLs and logs detailed information about the detection process. + * + * @param logger - Logger instance for capturing creation and validation steps + * @param nodeStorage - Storage implementation for the managed identity source + * @param networkClient - Network client for HTTP communication + * @param cryptoProvider - Cryptographic operations provider + * @param disableInternalRetries - Whether to disable automatic retry mechanisms + * @param managedIdentityId - The managed identity configuration, must be system-assigned + * + * @returns AzureArc instance if the environment supports Azure Arc managed identity, null otherwise + * + * @throws {ManagedIdentityError} When a user-assigned managed identity is specified (not supported for Azure Arc) + */ + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, managedIdentityId) { + const [identityEndpoint, imdsEndpoint] = _AzureArc.getEnvironmentVariables(); + if (!identityEndpoint || !imdsEndpoint) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.AZURE_ARC} managed identity is unavailable through environment variables because one or both of '${ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT}' and '${ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT}' are not defined. ${ManagedIdentitySourceNames.AZURE_ARC} managed identity is also unavailable through file detection.`, ""); + return null; + } + if (imdsEndpoint === HIMDS_EXECUTABLE_HELPER_STRING) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.AZURE_ARC} managed identity is available through file detection. Defaulting to known ${ManagedIdentitySourceNames.AZURE_ARC} endpoint: ${DEFAULT_AZURE_ARC_IDENTITY_ENDPOINT}. Creating ${ManagedIdentitySourceNames.AZURE_ARC} managed identity.`, ""); + } else { + const validatedIdentityEndpoint = _AzureArc.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT, identityEndpoint, ManagedIdentitySourceNames.AZURE_ARC, logger); + validatedIdentityEndpoint.endsWith("/") ? validatedIdentityEndpoint.slice(0, -1) : validatedIdentityEndpoint; + _AzureArc.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.IMDS_ENDPOINT, imdsEndpoint, ManagedIdentitySourceNames.AZURE_ARC, logger); + logger.info(`[Managed Identity] Environment variables validation passed for ${ManagedIdentitySourceNames.AZURE_ARC} managed identity. Endpoint URI: ${validatedIdentityEndpoint}. Creating ${ManagedIdentitySourceNames.AZURE_ARC} managed identity.`, ""); + } + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + throw createManagedIdentityError(unableToCreateAzureArc); + } + return new _AzureArc(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, identityEndpoint); + } + /** + * Creates a properly formatted HTTP request for acquiring tokens from the Azure Arc identity endpoint. + * + * This method constructs a GET request to the Azure Arc HIMDS endpoint with the required metadata header + * and query parameters. The endpoint URL is normalized to use 127.0.0.1 instead of localhost for + * consistency. Additional body parameters are calculated by the base class during token acquisition. + * + * @param resource - The target resource/scope for which to request an access token (e.g., "https://graph.microsoft.com/.default") + * + * @returns A configured ManagedIdentityRequestParameters object ready for network execution + */ + createRequest(resource) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.identityEndpoint.replace("localhost", "127.0.0.1")); + request.headers[ManagedIdentityHeaders.METADATA_HEADER_NAME] = "true"; + request.queryParameters[ManagedIdentityQueryParameters.API_VERSION] = ARC_API_VERSION; + request.queryParameters[ManagedIdentityQueryParameters.RESOURCE] = resource; + return request; + } + /** + * Processes the server response and handles Azure Arc-specific authentication challenges. + * + * This method implements the Azure Arc authentication flow which may require reading a secret file + * for authorization. When the initial request returns HTTP 401 Unauthorized, it extracts the file + * path from the WWW-Authenticate header, validates the file location and size, reads the secret, + * and retries the request with Basic authentication. The method includes comprehensive security + * validations to prevent path traversal and ensure file integrity. + * + * @param originalResponse - The initial HTTP response from the identity endpoint + * @param networkClient - Network client for making the retry request if needed + * @param networkRequest - The original request parameters (modified with auth header for retry) + * @param networkRequestOptions - Additional options for network requests + * + * @returns A promise that resolves to the server token response with access token and metadata + * + * @throws {ManagedIdentityError} When: + * - WWW-Authenticate header is missing or has unsupported format + * - Platform is not supported (not Windows or Linux) + * - Secret file has invalid extension (not .key) + * - Secret file path doesn't match expected platform path + * - Secret file cannot be read or is too large (>4096 bytes) + * @throws {ClientAuthError} When network errors occur during retry request + */ + async getServerTokenResponseAsync(originalResponse, networkClient, networkRequest, networkRequestOptions) { + let retryResponse; + if (originalResponse.status === HTTP_UNAUTHORIZED) { + const wwwAuthHeader = originalResponse.headers["www-authenticate"]; + if (!wwwAuthHeader) { + throw createManagedIdentityError(wwwAuthenticateHeaderMissing); + } + if (!wwwAuthHeader.includes("Basic realm=")) { + throw createManagedIdentityError(wwwAuthenticateHeaderUnsupportedFormat); + } + const secretFilePath = wwwAuthHeader.split("Basic realm=")[1]; + if (!SUPPORTED_AZURE_ARC_PLATFORMS.hasOwnProperty(process.platform)) { + throw createManagedIdentityError(platformNotSupported); + } + const expectedSecretFilePath = SUPPORTED_AZURE_ARC_PLATFORMS[process.platform]; + const fileName = path3.basename(secretFilePath); + if (!fileName.endsWith(".key")) { + throw createManagedIdentityError(invalidFileExtension); + } + if (expectedSecretFilePath + fileName !== secretFilePath) { + throw createManagedIdentityError(invalidFilePath); + } + let secretFileSize; + try { + secretFileSize = await fs6.statSync(secretFilePath).size; + } catch (e) { + throw createManagedIdentityError(unableToReadSecretFile); + } + if (secretFileSize > AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES) { + throw createManagedIdentityError(invalidSecret); + } + let secret; + try { + secret = fs6.readFileSync(secretFilePath, EncodingTypes.UTF8); + } catch (e) { + throw createManagedIdentityError(unableToReadSecretFile); + } + const authHeaderValue = `Basic ${secret}`; + this.logger.info(`[Managed Identity] Adding authorization header to the request.`, ""); + networkRequest.headers[ManagedIdentityHeaders.AUTHORIZATION_HEADER_NAME] = authHeaderValue; + try { + retryResponse = await networkClient.sendGetRequestAsync(networkRequest.computeUri(), networkRequestOptions); + } catch (error) { + if (error instanceof AuthError) { + throw error; + } else { + throw createClientAuthError(networkError); + } + } + } + return this.getServerTokenResponse(retryResponse || originalResponse); + } + }; + var CloudShell = class _CloudShell extends BaseManagedIdentitySource { + /** + * Creates a new CloudShell managed identity source instance. + * + * @param logger - Logger instance for diagnostic logging + * @param nodeStorage - Node.js storage implementation for caching + * @param networkClient - HTTP client for making requests to the managed identity endpoint + * @param cryptoProvider - Cryptographic operations provider + * @param disableInternalRetries - Whether to disable automatic retry logic for failed requests + * @param msiEndpoint - The MSI endpoint URL obtained from environment variables + */ + constructor(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, msiEndpoint) { + super(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries); + this.msiEndpoint = msiEndpoint; + } + /** + * Retrieves the required environment variables for Cloud Shell managed identity. + * + * Cloud Shell requires the MSI_ENDPOINT environment variable to be set, which + * contains the URL of the managed identity service endpoint. + * + * @returns An array containing the MSI_ENDPOINT environment variable value (or undefined if not set) + */ + static getEnvironmentVariables() { + const msiEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT]; + return [msiEndpoint]; + } + /** + * Attempts to create a CloudShell managed identity source instance. + * + * This method validates that the required environment variables are present and + * creates a CloudShell instance if the environment is properly configured. + * Cloud Shell only supports system-assigned managed identities. + * + * @param logger - Logger instance for diagnostic logging + * @param nodeStorage - Node.js storage implementation for caching + * @param networkClient - HTTP client for making requests + * @param cryptoProvider - Cryptographic operations provider + * @param disableInternalRetries - Whether to disable automatic retry logic + * @param managedIdentityId - The managed identity configuration (must be system-assigned) + * + * @returns A CloudShell instance if the environment is valid, null otherwise + * + * @throws {ManagedIdentityError} When a user-assigned managed identity is requested, + * as Cloud Shell only supports system-assigned identities + */ + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, managedIdentityId) { + const [msiEndpoint] = _CloudShell.getEnvironmentVariables(); + if (!msiEndpoint) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.CLOUD_SHELL} managed identity is unavailable because the '${ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT} environment variable is not defined.`, ""); + return null; + } + const validatedMsiEndpoint = _CloudShell.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT, msiEndpoint, ManagedIdentitySourceNames.CLOUD_SHELL, logger); + logger.info(`[Managed Identity] Environment variable validation passed for ${ManagedIdentitySourceNames.CLOUD_SHELL} managed identity. Endpoint URI: ${validatedMsiEndpoint}. Creating ${ManagedIdentitySourceNames.CLOUD_SHELL} managed identity.`, ""); + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + throw createManagedIdentityError(unableToCreateCloudShell); + } + return new _CloudShell(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, msiEndpoint); + } + /** + * Creates an HTTP request to acquire an access token from the Cloud Shell managed identity endpoint. + * + * This method constructs a POST request to the MSI endpoint with the required headers and + * body parameters for Cloud Shell authentication. The request includes the target resource + * for which the access token is being requested. + * + * @param resource - The target resource/scope for which to request an access token (e.g., "https://graph.microsoft.com/.default") + * + * @returns A configured ManagedIdentityRequestParameters object ready for network execution + */ + createRequest(resource) { + const request = new ManagedIdentityRequestParameters(HttpMethod.POST, this.msiEndpoint); + request.headers[ManagedIdentityHeaders.METADATA_HEADER_NAME] = "true"; + request.bodyParameters[ManagedIdentityQueryParameters.RESOURCE] = resource; + return request; + } + }; + var ExponentialRetryStrategy = class { + constructor(minExponentialBackoff, maxExponentialBackoff, exponentialDeltaBackoff) { + this.minExponentialBackoff = minExponentialBackoff; + this.maxExponentialBackoff = maxExponentialBackoff; + this.exponentialDeltaBackoff = exponentialDeltaBackoff; + } + /** + * Calculates the exponential delay based on the current retry attempt. + * + * @param {number} currentRetry - The current retry attempt number. + * @returns {number} - The calculated exponential delay in milliseconds. + * + * The delay is calculated using the formula: + * - If `currentRetry` is 0, it returns the minimum backoff time. + * - Otherwise, it calculates the delay as the minimum of: + * - `(2^(currentRetry - 1)) * deltaBackoff` + * - `maxBackoff` + * + * This ensures that the delay increases exponentially with each retry attempt, + * but does not exceed the maximum backoff time. + */ + calculateDelay(currentRetry) { + if (currentRetry === 0) { + return this.minExponentialBackoff; + } + const exponentialDelay = Math.min(Math.pow(2, currentRetry - 1) * this.exponentialDeltaBackoff, this.maxExponentialBackoff); + return exponentialDelay; + } + }; + var HTTP_STATUS_400_CODES_FOR_EXPONENTIAL_STRATEGY = [ + HTTP_NOT_FOUND, + HTTP_REQUEST_TIMEOUT, + HTTP_GONE, + HTTP_TOO_MANY_REQUESTS + ]; + var EXPONENTIAL_STRATEGY_NUM_RETRIES = 3; + var LINEAR_STRATEGY_NUM_RETRIES = 7; + var MIN_EXPONENTIAL_BACKOFF_MS = 1e3; + var MAX_EXPONENTIAL_BACKOFF_MS = 4e3; + var EXPONENTIAL_DELTA_BACKOFF_MS = 2e3; + var HTTP_STATUS_GONE_RETRY_AFTER_MS = 10 * 1e3; + var ImdsRetryPolicy = class _ImdsRetryPolicy { + constructor() { + this.exponentialRetryStrategy = new ExponentialRetryStrategy(_ImdsRetryPolicy.MIN_EXPONENTIAL_BACKOFF_MS, _ImdsRetryPolicy.MAX_EXPONENTIAL_BACKOFF_MS, _ImdsRetryPolicy.EXPONENTIAL_DELTA_BACKOFF_MS); + } + /* + * these are defined here as static variables despite being defined as constants outside of the + * class because they need to be overridden in the unit tests so that the unit tests run faster + */ + static get MIN_EXPONENTIAL_BACKOFF_MS() { + return MIN_EXPONENTIAL_BACKOFF_MS; + } + static get MAX_EXPONENTIAL_BACKOFF_MS() { + return MAX_EXPONENTIAL_BACKOFF_MS; + } + static get EXPONENTIAL_DELTA_BACKOFF_MS() { + return EXPONENTIAL_DELTA_BACKOFF_MS; + } + static get HTTP_STATUS_GONE_RETRY_AFTER_MS() { + return HTTP_STATUS_GONE_RETRY_AFTER_MS; + } + set isNewRequest(value) { + this._isNewRequest = value; + } + /** + * Pauses execution for a calculated delay before retrying a request. + * + * @param httpStatusCode - The HTTP status code of the response. + * @param currentRetry - The current retry attempt number. + * @param retryAfterHeader - The value of the "retry-after" header from the response. + * @returns A promise that resolves to a boolean indicating whether a retry should be attempted. + */ + async pauseForRetry(httpStatusCode, currentRetry, logger) { + if (this._isNewRequest) { + this._isNewRequest = false; + this.maxRetries = httpStatusCode === HTTP_GONE ? LINEAR_STRATEGY_NUM_RETRIES : EXPONENTIAL_STRATEGY_NUM_RETRIES; + } + if ((HTTP_STATUS_400_CODES_FOR_EXPONENTIAL_STRATEGY.includes(httpStatusCode) || httpStatusCode >= HTTP_SERVER_ERROR_RANGE_START && httpStatusCode <= HTTP_SERVER_ERROR_RANGE_END && currentRetry < this.maxRetries) && currentRetry < this.maxRetries) { + const retryAfterDelay = httpStatusCode === HTTP_GONE ? _ImdsRetryPolicy.HTTP_STATUS_GONE_RETRY_AFTER_MS : this.exponentialRetryStrategy.calculateDelay(currentRetry); + logger.verbose(`Retrying request in ${retryAfterDelay}ms (retry attempt: ${currentRetry + 1})`, ""); + await new Promise((resolve) => { + return setTimeout(resolve, retryAfterDelay); + }); + return true; + } + return false; + } + }; + var IMDS_TOKEN_PATH = "/metadata/identity/oauth2/token"; + var DEFAULT_IMDS_ENDPOINT = `http://169.254.169.254${IMDS_TOKEN_PATH}`; + var IMDS_API_VERSION = "2018-02-01"; + var Imds = class _Imds extends BaseManagedIdentitySource { + /** + * Constructs an Imds instance with the specified configuration. + * + * @param logger - Logger instance for recording debug information and errors + * @param nodeStorage - NodeStorage instance used for token caching operations + * @param networkClient - Network client implementation for making HTTP requests to IMDS + * @param cryptoProvider - CryptoProvider for generating correlation IDs and other cryptographic operations + * @param disableInternalRetries - When true, disables the built-in retry logic for IMDS requests + * @param identityEndpoint - The complete IMDS endpoint URL including the token path + */ + constructor(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, identityEndpoint) { + super(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries); + this.identityEndpoint = identityEndpoint; + } + /** + * Creates an Imds instance with the appropriate endpoint configuration. + * + * This method checks for the presence of the AZURE_POD_IDENTITY_AUTHORITY_HOST environment + * variable, which is used in Azure Kubernetes Service (AKS) environments with Azure AD + * Pod Identity. If found, it uses that endpoint; otherwise, it falls back to the standard + * IMDS endpoint (169.254.169.254). + * + * @param logger - Logger instance for recording endpoint discovery and validation + * @param nodeStorage - NodeStorage instance for token caching + * @param networkClient - Network client for HTTP requests + * @param cryptoProvider - CryptoProvider for cryptographic operations + * @param disableInternalRetries - Whether to disable built-in retry logic + * + * @returns A configured Imds instance ready to make token requests + */ + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries) { + let validatedIdentityEndpoint; + if (process.env[ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST]) { + logger.info(`[Managed Identity] Environment variable ${ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST} for ${ManagedIdentitySourceNames.IMDS} returned endpoint: ${process.env[ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST]}`, ""); + validatedIdentityEndpoint = _Imds.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST, `${process.env[ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST]}${IMDS_TOKEN_PATH}`, ManagedIdentitySourceNames.IMDS, logger); + } else { + logger.info(`[Managed Identity] Unable to find ${ManagedIdentityEnvironmentVariableNames.AZURE_POD_IDENTITY_AUTHORITY_HOST} environment variable for ${ManagedIdentitySourceNames.IMDS}, using the default endpoint.`, ""); + validatedIdentityEndpoint = DEFAULT_IMDS_ENDPOINT; + } + return new _Imds(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, validatedIdentityEndpoint); + } + /** + * Creates a properly configured HTTP request for acquiring an access token from IMDS. + * + * This method builds a complete request object with all necessary headers, query parameters, + * and retry policies required by the Azure Instance Metadata Service. + * + * Key request components: + * - HTTP GET method to the IMDS token endpoint + * - Metadata header set to "true" (required by IMDS) + * - API version parameter (currently "2018-02-01") + * - Resource parameter specifying the target audience + * - Identity-specific parameters for user-assigned managed identities + * - IMDS-specific retry policy + * + * @param resource - The target resource/scope for which to request an access token (e.g., "https://graph.microsoft.com/.default") + * @param managedIdentityId - The managed identity configuration specifying whether to use system-assigned or user-assigned identity + * + * @returns A configured ManagedIdentityRequestParameters object ready for network execution + */ + createRequest(resource, managedIdentityId) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.identityEndpoint); + request.headers[ManagedIdentityHeaders.METADATA_HEADER_NAME] = "true"; + request.queryParameters[ManagedIdentityQueryParameters.API_VERSION] = IMDS_API_VERSION; + request.queryParameters[ManagedIdentityQueryParameters.RESOURCE] = resource; + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + request.queryParameters[this.getManagedIdentityUserAssignedIdQueryParameterKey( + managedIdentityId.idType, + true + // indicates source is IMDS + )] = managedIdentityId.id; + } + request.retryPolicy = new ImdsRetryPolicy(); + return request; + } + }; + var SERVICE_FABRIC_MSI_API_VERSION = "2019-07-01-preview"; + var ServiceFabric = class _ServiceFabric extends BaseManagedIdentitySource { + /** + * Constructs a new ServiceFabric managed identity source for acquiring tokens from Azure Service Fabric clusters. + * + * Service Fabric managed identity allows applications running in Service Fabric clusters to authenticate + * without storing credentials in code. This source handles token acquisition using the Service Fabric + * Managed Identity Token Service (MITS). + * + * @param logger - Logger instance for logging authentication events and debugging information + * @param nodeStorage - NodeStorage instance for caching tokens and other authentication artifacts + * @param networkClient - Network client for making HTTP requests to the Service Fabric identity endpoint + * @param cryptoProvider - Crypto provider for cryptographic operations like token validation + * @param disableInternalRetries - Whether to disable internal retry logic for failed requests + * @param identityEndpoint - The Service Fabric managed identity endpoint URL + * @param identityHeader - The Service Fabric managed identity secret header value + */ + constructor(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, identityEndpoint, identityHeader) { + super(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries); + this.identityEndpoint = identityEndpoint; + this.identityHeader = identityHeader; + } + /** + * Retrieves the environment variables required for Service Fabric managed identity authentication. + * + * Service Fabric managed identity requires three specific environment variables to be set by the + * Service Fabric runtime: + * - IDENTITY_ENDPOINT: The endpoint URL for the Managed Identity Token Service (MITS) + * - IDENTITY_HEADER: A secret value used for authentication with the MITS + * - IDENTITY_SERVER_THUMBPRINT: The thumbprint of the MITS server certificate for secure communication + * + * @returns An array containing the identity endpoint, identity header, and identity server thumbprint values. + * Elements will be undefined if the corresponding environment variables are not set. + */ + static getEnvironmentVariables() { + const identityEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT]; + const identityHeader = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_HEADER]; + const identityServerThumbprint = process.env[ManagedIdentityEnvironmentVariableNames.IDENTITY_SERVER_THUMBPRINT]; + return [identityEndpoint, identityHeader, identityServerThumbprint]; + } + /** + * Attempts to create a ServiceFabric managed identity source if the runtime environment supports it. + * + * Checks for the presence of all required Service Fabric environment variables + * and validates the endpoint URL format. It will only create a ServiceFabric instance if the application + * is running in a properly configured Service Fabric cluster with managed identity enabled. + * + * Note: User-assigned managed identities must be configured at the cluster level, not at runtime. + * This method will log a warning if a user-assigned identity is requested. + * + * @param logger - Logger instance for logging creation events and validation results + * @param nodeStorage - NodeStorage instance for caching tokens and authentication artifacts + * @param networkClient - Network client for making HTTP requests to the identity endpoint + * @param cryptoProvider - Crypto provider for cryptographic operations + * @param disableInternalRetries - Whether to disable internal retry logic for failed requests + * @param managedIdentityId - Managed identity identifier specifying system-assigned or user-assigned identity + * + * @returns A ServiceFabric instance if all environment variables are valid and present, otherwise null + */ + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, managedIdentityId) { + const [identityEndpoint, identityHeader, identityServerThumbprint] = _ServiceFabric.getEnvironmentVariables(); + if (!identityEndpoint || !identityHeader || !identityServerThumbprint) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.SERVICE_FABRIC} managed identity is unavailable because one or all of the '${ManagedIdentityEnvironmentVariableNames.IDENTITY_HEADER}', '${ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT}' or '${ManagedIdentityEnvironmentVariableNames.IDENTITY_SERVER_THUMBPRINT}' environment variables are not defined.`, ""); + return null; + } + const validatedIdentityEndpoint = _ServiceFabric.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.IDENTITY_ENDPOINT, identityEndpoint, ManagedIdentitySourceNames.SERVICE_FABRIC, logger); + logger.info(`[Managed Identity] Environment variables validation passed for ${ManagedIdentitySourceNames.SERVICE_FABRIC} managed identity. Endpoint URI: ${validatedIdentityEndpoint}. Creating ${ManagedIdentitySourceNames.SERVICE_FABRIC} managed identity.`, ""); + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + logger.warning(`[Managed Identity] ${ManagedIdentitySourceNames.SERVICE_FABRIC} user assigned managed identity is configured in the cluster, not during runtime. See also: https://learn.microsoft.com/en-us/azure/service-fabric/configure-existing-cluster-enable-managed-identity-token-service.`, ""); + } + return new _ServiceFabric(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, identityEndpoint, identityHeader); + } + /** + * Creates HTTP request parameters for acquiring an access token from the Service Fabric Managed Identity Token Service (MITS). + * + * This method constructs a properly formatted HTTP GET request that includes: + * - The secret header for authentication with MITS + * - API version parameter for the Service Fabric MSI endpoint + * - Resource parameter specifying the target Azure service + * - Optional identity parameters for user-assigned managed identities + * + * The request follows the Service Fabric managed identity protocol and uses the 2019-07-01-preview API version. + * For user-assigned identities, the appropriate query parameter (client_id, object_id, or resource_id) is added + * based on the identity type. + * + * @param resource - The Azure resource URI for which the access token is requested (e.g., "https://vault.azure.net/") + * @param managedIdentityId - The managed identity configuration specifying system-assigned or user-assigned identity details + * + * @returns A configured ManagedIdentityRequestParameters object ready for network execution + */ + createRequest(resource, managedIdentityId) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.identityEndpoint); + request.headers[ManagedIdentityHeaders.ML_AND_SF_SECRET_HEADER_NAME] = this.identityHeader; + request.queryParameters[ManagedIdentityQueryParameters.API_VERSION] = SERVICE_FABRIC_MSI_API_VERSION; + request.queryParameters[ManagedIdentityQueryParameters.RESOURCE] = resource; + if (managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED) { + request.queryParameters[this.getManagedIdentityUserAssignedIdQueryParameterKey(managedIdentityId.idType)] = managedIdentityId.id; + } + return request; + } + }; + var MACHINE_LEARNING_MSI_API_VERSION = "2017-09-01"; + var MANAGED_IDENTITY_MACHINE_LEARNING_UNSUPPORTED_ID_TYPE_ERROR = `Only client id is supported for user-assigned managed identity in ${ManagedIdentitySourceNames.MACHINE_LEARNING}.`; + var MachineLearning = class _MachineLearning extends BaseManagedIdentitySource { + /** + * Creates a new MachineLearning managed identity source instance. + * + * @param logger - Logger instance for diagnostic information + * @param nodeStorage - Node storage implementation for caching + * @param networkClient - Network client for making HTTP requests + * @param cryptoProvider - Cryptographic operations provider + * @param disableInternalRetries - Whether to disable automatic request retries + * @param msiEndpoint - The MSI endpoint URL from environment variables + * @param secret - The MSI secret from environment variables + */ + constructor(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, msiEndpoint, secret) { + super(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries); + this.msiEndpoint = msiEndpoint; + this.secret = secret; + } + /** + * Retrieves the required environment variables for Azure Machine Learning managed identity. + * + * This method checks for the presence of MSI_ENDPOINT and MSI_SECRET environment variables + * that are automatically set by the Azure Machine Learning platform when managed identity + * is enabled for the compute instance or cluster. + * + * @returns An array containing [msiEndpoint, secret] where either value may be undefined + * if the corresponding environment variable is not set + */ + static getEnvironmentVariables() { + const msiEndpoint = process.env[ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT]; + const secret = process.env[ManagedIdentityEnvironmentVariableNames.MSI_SECRET]; + return [msiEndpoint, secret]; + } + /** + * Attempts to create a MachineLearning managed identity source. + * + * This method validates the Azure Machine Learning environment by checking for the required + * MSI_ENDPOINT and MSI_SECRET environment variables. If both are present and valid, + * it creates and returns a MachineLearning instance. If either is missing or invalid, + * it returns null, indicating that this managed identity source is not available + * in the current environment. + * + * @param logger - Logger instance for diagnostic information + * @param nodeStorage - Node storage implementation for caching + * @param networkClient - Network client for making HTTP requests + * @param cryptoProvider - Cryptographic operations provider + * @param disableInternalRetries - Whether to disable automatic request retries + * + * @returns A new MachineLearning instance if the environment is valid, null otherwise + */ + static tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries) { + const [msiEndpoint, secret] = _MachineLearning.getEnvironmentVariables(); + if (!msiEndpoint || !secret) { + logger.info(`[Managed Identity] ${ManagedIdentitySourceNames.MACHINE_LEARNING} managed identity is unavailable because one or both of the '${ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT}' and '${ManagedIdentityEnvironmentVariableNames.MSI_SECRET}' environment variables are not defined.`, ""); + return null; + } + const validatedMsiEndpoint = _MachineLearning.getValidatedEnvVariableUrlString(ManagedIdentityEnvironmentVariableNames.MSI_ENDPOINT, msiEndpoint, ManagedIdentitySourceNames.MACHINE_LEARNING, logger); + logger.info(`[Managed Identity] Environment variables validation passed for ${ManagedIdentitySourceNames.MACHINE_LEARNING} managed identity. Endpoint URI: ${validatedMsiEndpoint}. Creating ${ManagedIdentitySourceNames.MACHINE_LEARNING} managed identity.`, ""); + return new _MachineLearning(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, msiEndpoint, secret); + } + /** + * Creates a managed identity token request for Azure Machine Learning environments. + * + * This method constructs the HTTP request parameters needed to acquire an access token + * from the Azure Machine Learning managed identity endpoint. It handles both system-assigned + * and user-assigned managed identities with specific logic for each type: + * + * - System-assigned: Uses the DEFAULT_IDENTITY_CLIENT_ID environment variable + * - User-assigned: Only supports client ID-based identification (not object ID or resource ID) + * + * The request uses the 2017-09-01 API version and includes the required secret header + * for authentication with the MSI endpoint. + * + * @param resource - The target resource/scope for which to request an access token (e.g., "https://graph.microsoft.com/.default") + * @param managedIdentityId - The managed identity configuration specifying whether to use system-assigned or user-assigned identity + * + * @returns A configured ManagedIdentityRequestParameters object ready for network execution + * + * @throws Error if an unsupported managed identity ID type is specified (only client ID is supported for user-assigned) + */ + createRequest(resource, managedIdentityId) { + const request = new ManagedIdentityRequestParameters(HttpMethod.GET, this.msiEndpoint); + request.headers[ManagedIdentityHeaders.METADATA_HEADER_NAME] = "true"; + request.headers[ManagedIdentityHeaders.ML_AND_SF_SECRET_HEADER_NAME] = this.secret; + request.queryParameters[ManagedIdentityQueryParameters.API_VERSION] = MACHINE_LEARNING_MSI_API_VERSION; + request.queryParameters[ManagedIdentityQueryParameters.RESOURCE] = resource; + if (managedIdentityId.idType === ManagedIdentityIdType.SYSTEM_ASSIGNED) { + request.queryParameters[ManagedIdentityUserAssignedIdQueryParameterNames.MANAGED_IDENTITY_CLIENT_ID_2017] = process.env[ManagedIdentityEnvironmentVariableNames.DEFAULT_IDENTITY_CLIENT_ID]; + } else if (managedIdentityId.idType === ManagedIdentityIdType.USER_ASSIGNED_CLIENT_ID) { + request.queryParameters[this.getManagedIdentityUserAssignedIdQueryParameterKey( + managedIdentityId.idType, + false, + // isIMDS + true + // uses2017API + )] = managedIdentityId.id; + } else { + throw new Error(MANAGED_IDENTITY_MACHINE_LEARNING_UNSUPPORTED_ID_TYPE_ERROR); + } + return request; + } + }; + var ManagedIdentityClient = class _ManagedIdentityClient { + constructor(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries) { + this.logger = logger; + this.nodeStorage = nodeStorage; + this.networkClient = networkClient; + this.cryptoProvider = cryptoProvider; + this.disableInternalRetries = disableInternalRetries; + } + async sendManagedIdentityTokenRequest(managedIdentityRequest, managedIdentityId, fakeAuthority, refreshAccessToken) { + if (!_ManagedIdentityClient.identitySource) { + _ManagedIdentityClient.identitySource = this.selectManagedIdentitySource(this.logger, this.nodeStorage, this.networkClient, this.cryptoProvider, this.disableInternalRetries, managedIdentityId); + } + return _ManagedIdentityClient.identitySource.acquireTokenWithManagedIdentity(managedIdentityRequest, managedIdentityId, fakeAuthority, refreshAccessToken); + } + allEnvironmentVariablesAreDefined(environmentVariables) { + return Object.values(environmentVariables).every((environmentVariable) => { + return environmentVariable !== void 0; + }); + } + /** + * Determine the Managed Identity Source based on available environment variables. This API is consumed by ManagedIdentityApplication's getManagedIdentitySource. + * @returns ManagedIdentitySourceNames - The Managed Identity source's name + */ + getManagedIdentitySource() { + _ManagedIdentityClient.sourceName = this.allEnvironmentVariablesAreDefined(ServiceFabric.getEnvironmentVariables()) ? ManagedIdentitySourceNames.SERVICE_FABRIC : this.allEnvironmentVariablesAreDefined(AppService.getEnvironmentVariables()) ? ManagedIdentitySourceNames.APP_SERVICE : this.allEnvironmentVariablesAreDefined(MachineLearning.getEnvironmentVariables()) ? ManagedIdentitySourceNames.MACHINE_LEARNING : this.allEnvironmentVariablesAreDefined(CloudShell.getEnvironmentVariables()) ? ManagedIdentitySourceNames.CLOUD_SHELL : this.allEnvironmentVariablesAreDefined(AzureArc.getEnvironmentVariables()) ? ManagedIdentitySourceNames.AZURE_ARC : ManagedIdentitySourceNames.DEFAULT_TO_IMDS; + return _ManagedIdentityClient.sourceName; + } + /** + * Tries to create a managed identity source for all sources + * @returns the managed identity Source + */ + selectManagedIdentitySource(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, managedIdentityId) { + const source = ServiceFabric.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, managedIdentityId) || AppService.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries) || MachineLearning.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries) || CloudShell.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, managedIdentityId) || AzureArc.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries, managedIdentityId) || Imds.tryCreate(logger, nodeStorage, networkClient, cryptoProvider, disableInternalRetries); + if (!source) { + throw createManagedIdentityError(unableToCreateSource); + } + return source; + } + }; + var SOURCES_THAT_SUPPORT_TOKEN_REVOCATION = [ManagedIdentitySourceNames.SERVICE_FABRIC]; + var ManagedIdentityApplication = class _ManagedIdentityApplication { + constructor(configuration) { + this.config = buildManagedIdentityConfiguration(configuration || {}); + this.logger = new Logger(this.config.system.loggerOptions, name, version4); + const fakeStatusAuthorityOptions = { + canonicalAuthority: DEFAULT_AUTHORITY + }; + if (!_ManagedIdentityApplication.nodeStorage) { + _ManagedIdentityApplication.nodeStorage = new NodeStorage(this.logger, this.config.managedIdentityId.id, DEFAULT_CRYPTO_IMPLEMENTATION, fakeStatusAuthorityOptions); + } + this.networkClient = this.config.system.networkClient; + this.cryptoProvider = new CryptoProvider(); + const fakeAuthorityOptions = { + protocolMode: ProtocolMode.AAD, + knownAuthorities: [DEFAULT_AUTHORITY_FOR_MANAGED_IDENTITY], + cloudDiscoveryMetadata: "", + authorityMetadata: "" + }; + this.fakeAuthority = new Authority( + DEFAULT_AUTHORITY_FOR_MANAGED_IDENTITY, + this.networkClient, + _ManagedIdentityApplication.nodeStorage, + fakeAuthorityOptions, + this.logger, + this.cryptoProvider.createNewGuid(), + // correlationID + new StubPerformanceClient(), + true + ); + this.fakeClientCredentialClient = new ClientCredentialClient({ + authOptions: { + clientId: this.config.managedIdentityId.id, + authority: this.fakeAuthority + } + }); + this.managedIdentityClient = new ManagedIdentityClient(this.logger, _ManagedIdentityApplication.nodeStorage, this.networkClient, this.cryptoProvider, this.config.disableInternalRetries); + this.hashUtils = new HashUtils(); + } + /** + * Acquire an access token from the cache or the managed identity + * @param managedIdentityRequest - the ManagedIdentityRequestParams object passed in by the developer + * @returns the access token + */ + async acquireToken(managedIdentityRequestParams) { + if (!managedIdentityRequestParams.resource) { + throw createClientConfigurationError(urlEmptyError); + } + const managedIdentityRequest = { + forceRefresh: managedIdentityRequestParams.forceRefresh, + resource: managedIdentityRequestParams.resource.replace("/.default", ""), + scopes: [ + managedIdentityRequestParams.resource.replace("/.default", "") + ], + authority: this.fakeAuthority.canonicalAuthority, + correlationId: this.cryptoProvider.createNewGuid(), + claims: managedIdentityRequestParams.claims, + clientCapabilities: this.config.clientCapabilities + }; + if (managedIdentityRequest.forceRefresh) { + return this.acquireTokenFromManagedIdentity(managedIdentityRequest, this.config.managedIdentityId, this.fakeAuthority); + } + const [cachedAuthenticationResult, lastCacheOutcome] = await this.fakeClientCredentialClient.getCachedAuthenticationResult(managedIdentityRequest, this.config, this.cryptoProvider, this.fakeAuthority, _ManagedIdentityApplication.nodeStorage); + if (managedIdentityRequest.claims) { + const sourceName = this.managedIdentityClient.getManagedIdentitySource(); + if (cachedAuthenticationResult && SOURCES_THAT_SUPPORT_TOKEN_REVOCATION.includes(sourceName)) { + const revokedTokenSha256Hash = this.hashUtils.sha256(cachedAuthenticationResult.accessToken).toString(EncodingTypes.HEX); + managedIdentityRequest.revokedTokenSha256Hash = revokedTokenSha256Hash; + } + return this.acquireTokenFromManagedIdentity(managedIdentityRequest, this.config.managedIdentityId, this.fakeAuthority); + } + if (cachedAuthenticationResult) { + if (lastCacheOutcome === CacheOutcome.PROACTIVELY_REFRESHED) { + this.logger.info("ClientCredentialClient:getCachedAuthenticationResult - Cached access token's refreshOn property has been exceeded'. It's not expired, but must be refreshed.", managedIdentityRequest.correlationId); + const refreshAccessToken = true; + await this.acquireTokenFromManagedIdentity(managedIdentityRequest, this.config.managedIdentityId, this.fakeAuthority, refreshAccessToken); + } + return cachedAuthenticationResult; + } else { + return this.acquireTokenFromManagedIdentity(managedIdentityRequest, this.config.managedIdentityId, this.fakeAuthority); + } + } + /** + * Acquires a token from a managed identity endpoint. + * + * @param managedIdentityRequest - The request object containing parameters for the managed identity token request. + * @param managedIdentityId - The identifier for the managed identity (e.g., client ID or resource ID). + * @param fakeAuthority - A placeholder authority used for the token request. + * @param refreshAccessToken - Optional flag indicating whether to force a refresh of the access token. + * @returns A promise that resolves to an AuthenticationResult containing the acquired token and related information. + */ + async acquireTokenFromManagedIdentity(managedIdentityRequest, managedIdentityId, fakeAuthority, refreshAccessToken) { + return this.managedIdentityClient.sendManagedIdentityTokenRequest(managedIdentityRequest, managedIdentityId, fakeAuthority, refreshAccessToken); + } + /** + * Determine the Managed Identity Source based on available environment variables. This API is consumed by Azure Identity SDK. + * @returns ManagedIdentitySourceNames - The Managed Identity source's name + */ + getManagedIdentitySource() { + return ManagedIdentityClient.sourceName || this.managedIdentityClient.getManagedIdentitySource(); + } + }; + var DistributedCachePlugin = class { + constructor(client, partitionManager) { + this.client = client; + this.partitionManager = partitionManager; + } + /** + * Deserializes the cache before accessing it + * @param cacheContext - TokenCacheContext + */ + async beforeCacheAccess(cacheContext) { + const partitionKey = await this.partitionManager.getKey(); + const cacheData = await this.client.get(partitionKey); + cacheContext.tokenCache.deserialize(cacheData); + } + /** + * Serializes the cache after accessing it + * @param cacheContext - TokenCacheContext + */ + async afterCacheAccess(cacheContext) { + if (cacheContext.cacheHasChanged) { + const kvStore = cacheContext.tokenCache.getKVStore(); + const accountEntities = Object.values(kvStore).filter((value) => isAccountEntity(value)); + let partitionKey; + if (accountEntities.length > 0) { + const accountEntity = accountEntities[0]; + partitionKey = await this.partitionManager.extractKey(accountEntity); + } else { + partitionKey = await this.partitionManager.getKey(); + } + await this.client.set(partitionKey, cacheContext.tokenCache.serialize()); + } + } + }; + var PromptValue = PromptValue$1; + var ResponseMode = ResponseMode$1; + exports2.AuthError = AuthError; + exports2.AuthErrorCodes = AuthErrorCodes; + exports2.AzureCloudInstance = AzureCloudInstance; + exports2.ClientAssertion = ClientAssertion; + exports2.ClientAuthError = ClientAuthError; + exports2.ClientAuthErrorCodes = ClientAuthErrorCodes; + exports2.ClientConfigurationError = ClientConfigurationError; + exports2.ClientConfigurationErrorCodes = ClientConfigurationErrorCodes; + exports2.ConfidentialClientApplication = ConfidentialClientApplication; + exports2.CryptoProvider = CryptoProvider; + exports2.DistributedCachePlugin = DistributedCachePlugin; + exports2.InteractionRequiredAuthError = InteractionRequiredAuthError; + exports2.InteractionRequiredAuthErrorCodes = InteractionRequiredAuthErrorCodes; + exports2.Logger = Logger; + exports2.ManagedIdentityApplication = ManagedIdentityApplication; + exports2.ManagedIdentitySourceNames = ManagedIdentitySourceNames; + exports2.PromptValue = PromptValue; + exports2.ProtocolMode = ProtocolMode; + exports2.PublicClientApplication = PublicClientApplication; + exports2.ResponseMode = ResponseMode; + exports2.ServerError = ServerError; + exports2.TokenCache = TokenCache; + exports2.TokenCacheContext = TokenCacheContext; + exports2.internals = internals; + exports2.version = version4; + } +}); + +// node_modules/@azure/identity/dist/commonjs/msal/msal.js +var require_msal = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/msal/msal.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.msalCommon = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var msalCommon = tslib_1.__importStar(require_msal_node2()); + exports2.msalCommon = msalCommon; + } +}); + +// node_modules/@azure/identity/dist/commonjs/msal/utils.js +var require_utils6 = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/msal/utils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.defaultLoggerCallback = void 0; + exports2.ensureValidMsalToken = ensureValidMsalToken; + exports2.getAuthorityHost = getAuthorityHost; + exports2.getAuthority = getAuthority; + exports2.getKnownAuthorities = getKnownAuthorities; + exports2.getMSALLogLevel = getMSALLogLevel; + exports2.randomUUID = randomUUID2; + exports2.handleMsalError = handleMsalError; + exports2.publicToMsal = publicToMsal; + exports2.msalToPublic = msalToPublic; + exports2.serializeAuthenticationRecord = serializeAuthenticationRecord; + exports2.deserializeAuthenticationRecord = deserializeAuthenticationRecord; + var errors_js_1 = require_errors2(); + var logging_js_1 = require_logging(); + var constants_js_1 = require_constants4(); + var core_util_1 = require_commonjs4(); + var abort_controller_1 = require_commonjs3(); + var msal_js_1 = require_msal(); + var logger = (0, logging_js_1.credentialLogger)("IdentityUtils"); + var LatestAuthenticationRecordVersion = "1.0"; + function ensureValidMsalToken(scopes, msalToken, getTokenOptions) { + const error = (message) => { + logger.getToken.info(message); + return new errors_js_1.AuthenticationRequiredError({ + scopes: Array.isArray(scopes) ? scopes : [scopes], + getTokenOptions, + message + }); + }; + if (!msalToken) { + throw error("No response"); + } + if (!msalToken.expiresOn) { + throw error(`Response had no "expiresOn" property.`); + } + if (!msalToken.accessToken) { + throw error(`Response had no "accessToken" property.`); + } + } + function getAuthorityHost(options) { + let authorityHost = options?.authorityHost; + if (!authorityHost && core_util_1.isNodeLike) { + authorityHost = process.env.AZURE_AUTHORITY_HOST; + } + return authorityHost ?? constants_js_1.DefaultAuthorityHost; + } + function getAuthority(tenantId, host) { + if (!host) { + host = constants_js_1.DefaultAuthorityHost; + } + if (new RegExp(`${tenantId}/?$`).test(host)) { + return host; + } + if (host.endsWith("/")) { + return host + tenantId; + } else { + return `${host}/${tenantId}`; + } + } + function getKnownAuthorities(tenantId, authorityHost, disableInstanceDiscovery) { + if (tenantId === "adfs" && authorityHost || disableInstanceDiscovery) { + return [authorityHost]; + } + return []; + } + var defaultLoggerCallback = (credLogger, platform2 = core_util_1.isNode ? "Node" : "Browser") => (level, message, containsPii) => { + if (containsPii) { + return; + } + switch (level) { + case msal_js_1.msalCommon.LogLevel.Error: + credLogger.info(`MSAL ${platform2} V2 error: ${message}`); + return; + case msal_js_1.msalCommon.LogLevel.Info: + credLogger.info(`MSAL ${platform2} V2 info message: ${message}`); + return; + case msal_js_1.msalCommon.LogLevel.Verbose: + credLogger.info(`MSAL ${platform2} V2 verbose message: ${message}`); + return; + case msal_js_1.msalCommon.LogLevel.Warning: + credLogger.info(`MSAL ${platform2} V2 warning: ${message}`); + return; + } + }; + exports2.defaultLoggerCallback = defaultLoggerCallback; + function getMSALLogLevel(logLevel) { + switch (logLevel) { + case "error": + return msal_js_1.msalCommon.LogLevel.Error; + case "info": + return msal_js_1.msalCommon.LogLevel.Info; + case "verbose": + return msal_js_1.msalCommon.LogLevel.Verbose; + case "warning": + return msal_js_1.msalCommon.LogLevel.Warning; + default: + return msal_js_1.msalCommon.LogLevel.Info; + } + } + function randomUUID2() { + return (0, core_util_1.randomUUID)(); + } + function handleMsalError(scopes, error, getTokenOptions) { + if (error.name === "AuthError" || error.name === "ClientAuthError" || error.name === "BrowserAuthError") { + const msalError = error; + switch (msalError.errorCode) { + case "endpoints_resolution_error": + logger.info((0, logging_js_1.formatError)(scopes, error.message)); + return new errors_js_1.CredentialUnavailableError(error.message); + case "device_code_polling_cancelled": + return new abort_controller_1.AbortError("The authentication has been aborted by the caller."); + case "consent_required": + case "interaction_required": + case "login_required": + logger.info((0, logging_js_1.formatError)(scopes, `Authentication returned errorCode ${msalError.errorCode}`)); + break; + default: + logger.info((0, logging_js_1.formatError)(scopes, `Failed to acquire token: ${error.message}`)); + break; + } + } + if (error.name === "ClientConfigurationError" || error.name === "BrowserConfigurationAuthError" || error.name === "AbortError" || error.name === "AuthenticationError") { + return error; + } + if (error.name === "NativeAuthError") { + logger.info((0, logging_js_1.formatError)(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`)); + return error; + } + return new errors_js_1.AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message }); + } + function publicToMsal(account) { + return { + localAccountId: account.homeAccountId, + environment: account.authority, + username: account.username, + homeAccountId: account.homeAccountId, + tenantId: account.tenantId + }; + } + function msalToPublic(clientId, account) { + const record = { + authority: account.environment ?? constants_js_1.DefaultAuthority, + homeAccountId: account.homeAccountId, + tenantId: account.tenantId || constants_js_1.DefaultTenantId, + username: account.username, + clientId, + version: LatestAuthenticationRecordVersion + }; + return record; + } + function serializeAuthenticationRecord(record) { + return JSON.stringify(record); + } + function deserializeAuthenticationRecord(serializedRecord) { + const parsed = JSON.parse(serializedRecord); + if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) { + throw Error("Unsupported AuthenticationRecord version"); + } + return parsed; + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/util/identityTokenEndpoint.js +var require_identityTokenEndpoint = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/util/identityTokenEndpoint.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getIdentityTokenEndpointSuffix = getIdentityTokenEndpointSuffix; + function getIdentityTokenEndpointSuffix(tenantId) { + if (tenantId === "adfs") { + return "oauth2/token"; + } else { + return "oauth2/v2.0/token"; + } + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/utils.js +var require_utils7 = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/utils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.serviceFabricErrorMessage = void 0; + exports2.mapScopesToResource = mapScopesToResource; + exports2.parseExpirationTimestamp = parseExpirationTimestamp; + exports2.parseRefreshTimestamp = parseRefreshTimestamp; + var DefaultScopeSuffix = "/.default"; + exports2.serviceFabricErrorMessage = "Specifying a `clientId` or `resourceId` is not supported by the Service Fabric managed identity environment. The managed identity configuration is determined by the Service Fabric cluster resource configuration. See https://aka.ms/servicefabricmi for more information"; + function mapScopesToResource(scopes) { + let scope = ""; + if (Array.isArray(scopes)) { + if (scopes.length !== 1) { + return; + } + scope = scopes[0]; + } else if (typeof scopes === "string") { + scope = scopes; + } + if (!scope.endsWith(DefaultScopeSuffix)) { + return scope; + } + return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix)); + } + function parseExpirationTimestamp(body) { + if (typeof body.expires_on === "number") { + return body.expires_on * 1e3; + } + if (typeof body.expires_on === "string") { + const asNumber = +body.expires_on; + if (!isNaN(asNumber)) { + return asNumber * 1e3; + } + const asDate = Date.parse(body.expires_on); + if (!isNaN(asDate)) { + return asDate; + } + } + if (typeof body.expires_in === "number") { + return Date.now() + body.expires_in * 1e3; + } + throw new Error(`Failed to parse token expiration from body. expires_in="${body.expires_in}", expires_on="${body.expires_on}"`); + } + function parseRefreshTimestamp(body) { + if (body.refresh_on) { + if (typeof body.refresh_on === "number") { + return body.refresh_on * 1e3; + } + if (typeof body.refresh_on === "string") { + const asNumber = +body.refresh_on; + if (!isNaN(asNumber)) { + return asNumber * 1e3; + } + const asDate = Date.parse(body.refresh_on); + if (!isNaN(asDate)) { + return asDate; + } + } + throw new Error(`Failed to parse refresh_on from body. refresh_on="${body.refresh_on}"`); + } else { + return void 0; + } + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/client/identityClient.js +var require_identityClient = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/client/identityClient.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.IdentityClient = void 0; + exports2.getIdentityClientAuthorityHost = getIdentityClientAuthorityHost; + var core_client_1 = require_commonjs8(); + var core_util_1 = require_commonjs4(); + var core_rest_pipeline_1 = require_commonjs6(); + var errors_js_1 = require_errors2(); + var identityTokenEndpoint_js_1 = require_identityTokenEndpoint(); + var constants_js_1 = require_constants4(); + var tracing_js_1 = require_tracing(); + var logging_js_1 = require_logging(); + var utils_js_1 = require_utils7(); + var noCorrelationId = "noCorrelationId"; + function getIdentityClientAuthorityHost(options) { + let authorityHost = options?.authorityHost; + if (core_util_1.isNode) { + authorityHost = authorityHost ?? process.env.AZURE_AUTHORITY_HOST; + } + return authorityHost ?? constants_js_1.DefaultAuthorityHost; + } + var IdentityClient = class extends core_client_1.ServiceClient { + authorityHost; + allowLoggingAccountIdentifiers; + abortControllers; + allowInsecureConnection = false; + // used for WorkloadIdentity + tokenCredentialOptions; + constructor(options) { + const packageDetails = `azsdk-js-identity/${constants_js_1.SDK_VERSION}`; + const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}` : `${packageDetails}`; + const baseUri = getIdentityClientAuthorityHost(options); + if (!baseUri.startsWith("https:")) { + throw new Error("The authorityHost address must use the 'https' protocol."); + } + super({ + requestContentType: "application/json; charset=utf-8", + retryOptions: { + maxRetries: 3 + }, + ...options, + userAgentOptions: { + userAgentPrefix + }, + baseUri + }); + this.authorityHost = baseUri; + this.abortControllers = /* @__PURE__ */ new Map(); + this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers; + this.tokenCredentialOptions = { ...options }; + if (options?.allowInsecureConnection) { + this.allowInsecureConnection = options.allowInsecureConnection; + } + } + async sendTokenRequest(request) { + logging_js_1.logger.info(`IdentityClient: sending token request to [${request.url}]`); + const response = await this.sendRequest(request); + if (response.bodyAsText && (response.status === 200 || response.status === 201)) { + const parsedBody = JSON.parse(response.bodyAsText); + if (!parsedBody.access_token) { + return null; + } + this.logIdentifiers(response); + const token = { + accessToken: { + token: parsedBody.access_token, + expiresOnTimestamp: (0, utils_js_1.parseExpirationTimestamp)(parsedBody), + refreshAfterTimestamp: (0, utils_js_1.parseRefreshTimestamp)(parsedBody), + tokenType: "Bearer" + }, + refreshToken: parsedBody.refresh_token + }; + logging_js_1.logger.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`); + return token; + } else { + const error = new errors_js_1.AuthenticationError(response.status, response.bodyAsText); + logging_js_1.logger.warning(`IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`); + throw error; + } + } + async refreshAccessToken(tenantId, clientId, scopes, refreshToken, clientSecret, options = {}) { + if (refreshToken === void 0) { + return null; + } + logging_js_1.logger.info(`IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`); + const refreshParams = { + grant_type: "refresh_token", + client_id: clientId, + refresh_token: refreshToken, + scope: scopes + }; + if (clientSecret !== void 0) { + refreshParams.client_secret = clientSecret; + } + const query = new URLSearchParams(refreshParams); + return tracing_js_1.tracingClient.withSpan("IdentityClient.refreshAccessToken", options, async (updatedOptions) => { + try { + const urlSuffix = (0, identityTokenEndpoint_js_1.getIdentityTokenEndpointSuffix)(tenantId); + const request = (0, core_rest_pipeline_1.createPipelineRequest)({ + url: `${this.authorityHost}/${tenantId}/${urlSuffix}`, + method: "POST", + body: query.toString(), + abortSignal: options.abortSignal, + headers: (0, core_rest_pipeline_1.createHttpHeaders)({ + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded" + }), + tracingOptions: updatedOptions.tracingOptions + }); + const response = await this.sendTokenRequest(request); + logging_js_1.logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`); + return response; + } catch (err) { + if (err.name === errors_js_1.AuthenticationErrorName && err.errorResponse.error === "interaction_required") { + logging_js_1.logger.info(`IdentityClient: interaction required for client ID: ${clientId}`); + return null; + } else { + logging_js_1.logger.warning(`IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`); + throw err; + } + } + }); + } + // Here is a custom layer that allows us to abort requests that go through MSAL, + // since MSAL doesn't allow us to pass options all the way through. + generateAbortSignal(correlationId) { + const controller = new AbortController(); + const controllers = this.abortControllers.get(correlationId) || []; + controllers.push(controller); + this.abortControllers.set(correlationId, controllers); + const existingOnAbort = controller.signal.onabort; + controller.signal.onabort = (...params) => { + this.abortControllers.set(correlationId, void 0); + if (existingOnAbort) { + existingOnAbort.apply(controller.signal, params); + } + }; + return controller.signal; + } + abortRequests(correlationId) { + const key = correlationId || noCorrelationId; + const controllers = [ + ...this.abortControllers.get(key) || [], + // MSAL passes no correlation ID to the get requests... + ...this.abortControllers.get(noCorrelationId) || [] + ]; + if (!controllers.length) { + return; + } + for (const controller of controllers) { + controller.abort(); + } + this.abortControllers.set(key, void 0); + } + getCorrelationId(options) { + const parameter = options?.body?.split("&").map((part) => part.split("=")).find(([key]) => key === "client-request-id"); + return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId; + } + // The MSAL network module methods follow + async sendGetRequestAsync(url, options) { + const request = (0, core_rest_pipeline_1.createPipelineRequest)({ + url, + method: "GET", + body: options?.body, + allowInsecureConnection: this.allowInsecureConnection, + headers: (0, core_rest_pipeline_1.createHttpHeaders)(options?.headers), + abortSignal: this.generateAbortSignal(noCorrelationId) + }); + const response = await this.sendRequest(request); + this.logIdentifiers(response); + return { + body: response.bodyAsText ? JSON.parse(response.bodyAsText) : void 0, + headers: response.headers.toJSON(), + status: response.status + }; + } + async sendPostRequestAsync(url, options) { + const request = (0, core_rest_pipeline_1.createPipelineRequest)({ + url, + method: "POST", + body: options?.body, + headers: (0, core_rest_pipeline_1.createHttpHeaders)(options?.headers), + allowInsecureConnection: this.allowInsecureConnection, + // MSAL doesn't send the correlation ID on the get requests. + abortSignal: this.generateAbortSignal(this.getCorrelationId(options)) + }); + const response = await this.sendRequest(request); + this.logIdentifiers(response); + return { + body: response.bodyAsText ? JSON.parse(response.bodyAsText) : void 0, + headers: response.headers.toJSON(), + status: response.status + }; + } + /** + * + * @internal + */ + getTokenCredentialOptions() { + return this.tokenCredentialOptions; + } + /** + * If allowLoggingAccountIdentifiers was set on the constructor options + * we try to log the account identifiers by parsing the received access token. + * + * The account identifiers we try to log are: + * - `appid`: The application or Client Identifier. + * - `upn`: User Principal Name. + * - It might not be available in some authentication scenarios. + * - If it's not available, we put a placeholder: "No User Principal Name available". + * - `tid`: Tenant Identifier. + * - `oid`: Object Identifier of the authenticated user. + */ + logIdentifiers(response) { + if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) { + return; + } + const unavailableUpn = "No User Principal Name available"; + try { + const parsed = response.parsedBody || JSON.parse(response.bodyAsText); + const accessToken = parsed.access_token; + if (!accessToken) { + return; + } + const base64Metadata = accessToken.split(".")[1]; + const { appid, upn, tid, oid } = JSON.parse(Buffer.from(base64Metadata, "base64").toString("utf8")); + logging_js_1.logger.info(`[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${upn || unavailableUpn}. Object ID (user): ${oid}`); + } catch (e) { + logging_js_1.logger.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message); + } + } + }; + exports2.IdentityClient = IdentityClient; + } +}); + +// node_modules/@azure/identity/dist/commonjs/regionalAuthority.js +var require_regionalAuthority = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/regionalAuthority.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RegionalAuthority = void 0; + exports2.calculateRegionalAuthority = calculateRegionalAuthority; + var RegionalAuthority; + (function(RegionalAuthority2) { + RegionalAuthority2["AutoDiscoverRegion"] = "AutoDiscoverRegion"; + RegionalAuthority2["USWest"] = "westus"; + RegionalAuthority2["USWest2"] = "westus2"; + RegionalAuthority2["USCentral"] = "centralus"; + RegionalAuthority2["USEast"] = "eastus"; + RegionalAuthority2["USEast2"] = "eastus2"; + RegionalAuthority2["USNorthCentral"] = "northcentralus"; + RegionalAuthority2["USSouthCentral"] = "southcentralus"; + RegionalAuthority2["USWestCentral"] = "westcentralus"; + RegionalAuthority2["CanadaCentral"] = "canadacentral"; + RegionalAuthority2["CanadaEast"] = "canadaeast"; + RegionalAuthority2["BrazilSouth"] = "brazilsouth"; + RegionalAuthority2["EuropeNorth"] = "northeurope"; + RegionalAuthority2["EuropeWest"] = "westeurope"; + RegionalAuthority2["UKSouth"] = "uksouth"; + RegionalAuthority2["UKWest"] = "ukwest"; + RegionalAuthority2["FranceCentral"] = "francecentral"; + RegionalAuthority2["FranceSouth"] = "francesouth"; + RegionalAuthority2["SwitzerlandNorth"] = "switzerlandnorth"; + RegionalAuthority2["SwitzerlandWest"] = "switzerlandwest"; + RegionalAuthority2["GermanyNorth"] = "germanynorth"; + RegionalAuthority2["GermanyWestCentral"] = "germanywestcentral"; + RegionalAuthority2["NorwayWest"] = "norwaywest"; + RegionalAuthority2["NorwayEast"] = "norwayeast"; + RegionalAuthority2["AsiaEast"] = "eastasia"; + RegionalAuthority2["AsiaSouthEast"] = "southeastasia"; + RegionalAuthority2["JapanEast"] = "japaneast"; + RegionalAuthority2["JapanWest"] = "japanwest"; + RegionalAuthority2["AustraliaEast"] = "australiaeast"; + RegionalAuthority2["AustraliaSouthEast"] = "australiasoutheast"; + RegionalAuthority2["AustraliaCentral"] = "australiacentral"; + RegionalAuthority2["AustraliaCentral2"] = "australiacentral2"; + RegionalAuthority2["IndiaCentral"] = "centralindia"; + RegionalAuthority2["IndiaSouth"] = "southindia"; + RegionalAuthority2["IndiaWest"] = "westindia"; + RegionalAuthority2["KoreaSouth"] = "koreasouth"; + RegionalAuthority2["KoreaCentral"] = "koreacentral"; + RegionalAuthority2["UAECentral"] = "uaecentral"; + RegionalAuthority2["UAENorth"] = "uaenorth"; + RegionalAuthority2["SouthAfricaNorth"] = "southafricanorth"; + RegionalAuthority2["SouthAfricaWest"] = "southafricawest"; + RegionalAuthority2["ChinaNorth"] = "chinanorth"; + RegionalAuthority2["ChinaEast"] = "chinaeast"; + RegionalAuthority2["ChinaNorth2"] = "chinanorth2"; + RegionalAuthority2["ChinaEast2"] = "chinaeast2"; + RegionalAuthority2["GermanyCentral"] = "germanycentral"; + RegionalAuthority2["GermanyNorthEast"] = "germanynortheast"; + RegionalAuthority2["GovernmentUSVirginia"] = "usgovvirginia"; + RegionalAuthority2["GovernmentUSIowa"] = "usgoviowa"; + RegionalAuthority2["GovernmentUSArizona"] = "usgovarizona"; + RegionalAuthority2["GovernmentUSTexas"] = "usgovtexas"; + RegionalAuthority2["GovernmentUSDodEast"] = "usdodeast"; + RegionalAuthority2["GovernmentUSDodCentral"] = "usdodcentral"; + })(RegionalAuthority || (exports2.RegionalAuthority = RegionalAuthority = {})); + function calculateRegionalAuthority(regionalAuthority) { + let azureRegion = regionalAuthority; + if (azureRegion === void 0 && globalThis.process?.env?.AZURE_REGIONAL_AUTHORITY_NAME !== void 0) { + azureRegion = process.env.AZURE_REGIONAL_AUTHORITY_NAME; + } + if (azureRegion === RegionalAuthority.AutoDiscoverRegion) { + return "AUTO_DISCOVER"; + } + return azureRegion; + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/util/processMultiTenantRequest.js +var require_processMultiTenantRequest = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/util/processMultiTenantRequest.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.processMultiTenantRequest = processMultiTenantRequest; + var errors_js_1 = require_errors2(); + function createConfigurationErrorMessage(tenantId) { + return `The current credential is not configured to acquire tokens for tenant ${tenantId}. To enable acquiring tokens for this tenant add it to the AdditionallyAllowedTenants on the credential options, or add "*" to AdditionallyAllowedTenants to allow acquiring tokens for any tenant.`; + } + function processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowedTenantIds = [], logger) { + let resolvedTenantId; + if (process.env.AZURE_IDENTITY_DISABLE_MULTITENANTAUTH) { + resolvedTenantId = tenantId; + } else if (tenantId === "adfs") { + resolvedTenantId = tenantId; + } else { + resolvedTenantId = getTokenOptions?.tenantId ?? tenantId; + } + if (tenantId && resolvedTenantId !== tenantId && !additionallyAllowedTenantIds.includes("*") && !additionallyAllowedTenantIds.some((t) => t.localeCompare(resolvedTenantId) === 0)) { + const message = createConfigurationErrorMessage(resolvedTenantId); + logger?.info(message); + throw new errors_js_1.CredentialUnavailableError(message); + } + return resolvedTenantId; + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/util/tenantIdUtils.js +var require_tenantIdUtils = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/util/tenantIdUtils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.processMultiTenantRequest = void 0; + exports2.checkTenantId = checkTenantId; + exports2.resolveTenantId = resolveTenantId; + exports2.resolveAdditionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds; + var constants_js_1 = require_constants4(); + var logging_js_1 = require_logging(); + var processMultiTenantRequest_js_1 = require_processMultiTenantRequest(); + Object.defineProperty(exports2, "processMultiTenantRequest", { enumerable: true, get: function() { + return processMultiTenantRequest_js_1.processMultiTenantRequest; + } }); + function checkTenantId(logger, tenantId) { + if (!tenantId.match(/^[0-9a-zA-Z-.]+$/)) { + const error = new Error("Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://learn.microsoft.com/partner-center/find-ids-and-domain-names."); + logger.info((0, logging_js_1.formatError)("", error)); + throw error; + } + } + function resolveTenantId(logger, tenantId, clientId) { + if (tenantId) { + checkTenantId(logger, tenantId); + return tenantId; + } + if (!clientId) { + clientId = constants_js_1.DeveloperSignOnClientId; + } + if (clientId !== constants_js_1.DeveloperSignOnClientId) { + return "common"; + } + return "organizations"; + } + function resolveAdditionallyAllowedTenantIds(additionallyAllowedTenants) { + if (!additionallyAllowedTenants || additionallyAllowedTenants.length === 0) { + return []; + } + if (additionallyAllowedTenants.includes("*")) { + return constants_js_1.ALL_TENANTS; + } + return additionallyAllowedTenants; + } + } +}); + +// node_modules/is-docker/index.js +function hasDockerEnv() { + try { + import_node_fs.default.statSync("/.dockerenv"); + return true; + } catch { + return false; + } +} +function hasDockerCGroup() { + try { + return import_node_fs.default.readFileSync("/proc/self/cgroup", "utf8").includes("docker"); + } catch { + return false; + } +} +function isDocker() { + if (isDockerCached === void 0) { + isDockerCached = hasDockerEnv() || hasDockerCGroup(); + } + return isDockerCached; +} +var import_node_fs, isDockerCached; +var init_is_docker = __esm({ + "node_modules/is-docker/index.js"() { + import_node_fs = __toESM(require("node:fs"), 1); + } +}); + +// node_modules/is-inside-container/index.js +function isInsideContainer() { + if (cachedResult === void 0) { + cachedResult = hasContainerEnv() || isDocker(); + } + return cachedResult; +} +var import_node_fs2, cachedResult, hasContainerEnv; +var init_is_inside_container = __esm({ + "node_modules/is-inside-container/index.js"() { + import_node_fs2 = __toESM(require("node:fs"), 1); + init_is_docker(); + hasContainerEnv = () => { + try { + import_node_fs2.default.statSync("/run/.containerenv"); + return true; + } catch { + return false; + } + }; + } +}); + +// node_modules/is-wsl/index.js +var import_node_process, import_node_os, import_node_fs3, isWsl, is_wsl_default; +var init_is_wsl = __esm({ + "node_modules/is-wsl/index.js"() { + import_node_process = __toESM(require("node:process"), 1); + import_node_os = __toESM(require("node:os"), 1); + import_node_fs3 = __toESM(require("node:fs"), 1); + init_is_inside_container(); + isWsl = () => { + if (import_node_process.default.platform !== "linux") { + return false; + } + if (import_node_os.default.release().toLowerCase().includes("microsoft")) { + if (isInsideContainer()) { + return false; + } + return true; + } + try { + if (import_node_fs3.default.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) { + return !isInsideContainer(); + } + } catch { + } + if (import_node_fs3.default.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || import_node_fs3.default.existsSync("/run/WSL")) { + return !isInsideContainer(); + } + return false; + }; + is_wsl_default = import_node_process.default.env.__IS_WSL_TEST__ ? isWsl : isWsl(); + } +}); + +// node_modules/wsl-utils/index.js +var import_node_process2, import_promises, wslDrivesMountPoint, powerShellPathFromWsl, powerShellPath; +var init_wsl_utils = __esm({ + "node_modules/wsl-utils/index.js"() { + import_node_process2 = __toESM(require("node:process"), 1); + import_promises = __toESM(require("node:fs/promises"), 1); + init_is_wsl(); + init_is_wsl(); + wslDrivesMountPoint = /* @__PURE__ */ (() => { + const defaultMountPoint = "/mnt/"; + let mountPoint; + return async function() { + if (mountPoint) { + return mountPoint; + } + const configFilePath = "/etc/wsl.conf"; + let isConfigFileExists = false; + try { + await import_promises.default.access(configFilePath, import_promises.constants.F_OK); + isConfigFileExists = true; + } catch { + } + if (!isConfigFileExists) { + return defaultMountPoint; + } + const configContent = await import_promises.default.readFile(configFilePath, { encoding: "utf8" }); + const configMountPoint = /(?.*)/g.exec(configContent); + if (!configMountPoint) { + return defaultMountPoint; + } + mountPoint = configMountPoint.groups.mountPoint.trim(); + mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`; + return mountPoint; + }; + })(); + powerShellPathFromWsl = async () => { + const mountPoint = await wslDrivesMountPoint(); + return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`; + }; + powerShellPath = async () => { + if (is_wsl_default) { + return powerShellPathFromWsl(); + } + return `${import_node_process2.default.env.SYSTEMROOT || import_node_process2.default.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`; + }; + } +}); + +// node_modules/define-lazy-prop/index.js +function defineLazyProperty(object, propertyName, valueGetter) { + const define2 = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true }); + Object.defineProperty(object, propertyName, { + configurable: true, + enumerable: true, + get() { + const result = valueGetter(); + define2(result); + return result; + }, + set(value) { + define2(value); + } + }); + return object; +} +var init_define_lazy_prop = __esm({ + "node_modules/define-lazy-prop/index.js"() { + } +}); + +// node_modules/default-browser-id/index.js +async function defaultBrowserId() { + if (import_node_process3.default.platform !== "darwin") { + throw new Error("macOS only"); + } + const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]); + const match = /LSHandlerRoleAll = "(?!-)(?[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout); + const browserId = match?.groups.id ?? "com.apple.Safari"; + if (browserId === "com.apple.safari") { + return "com.apple.Safari"; + } + return browserId; +} +var import_node_util, import_node_process3, import_node_child_process, execFileAsync; +var init_default_browser_id = __esm({ + "node_modules/default-browser-id/index.js"() { + import_node_util = require("node:util"); + import_node_process3 = __toESM(require("node:process"), 1); + import_node_child_process = require("node:child_process"); + execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile); + } +}); + +// node_modules/run-applescript/index.js +async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) { + if (import_node_process4.default.platform !== "darwin") { + throw new Error("macOS only"); + } + const outputArguments = humanReadableOutput ? [] : ["-ss"]; + const execOptions = {}; + if (signal) { + execOptions.signal = signal; + } + const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions); + return stdout.trim(); +} +var import_node_process4, import_node_util2, import_node_child_process2, execFileAsync2; +var init_run_applescript = __esm({ + "node_modules/run-applescript/index.js"() { + import_node_process4 = __toESM(require("node:process"), 1); + import_node_util2 = require("node:util"); + import_node_child_process2 = require("node:child_process"); + execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile); + } +}); + +// node_modules/bundle-name/index.js +async function bundleName(bundleId) { + return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string +tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`); +} +var init_bundle_name = __esm({ + "node_modules/bundle-name/index.js"() { + init_run_applescript(); + } +}); + +// node_modules/default-browser/windows.js +async function defaultBrowser(_execFileAsync = execFileAsync3) { + const { stdout } = await _execFileAsync("reg", [ + "QUERY", + " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice", + "/v", + "ProgId" + ]); + const match = /ProgId\s*REG_SZ\s*(?\S+)/.exec(stdout); + if (!match) { + throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`); + } + const { id } = match.groups; + const dotIndex = id.lastIndexOf("."); + const hyphenIndex = id.lastIndexOf("-"); + const baseIdByDot = dotIndex === -1 ? void 0 : id.slice(0, dotIndex); + const baseIdByHyphen = hyphenIndex === -1 ? void 0 : id.slice(0, hyphenIndex); + return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id }; +} +var import_node_util3, import_node_child_process3, execFileAsync3, windowsBrowserProgIds, _windowsBrowserProgIdMap, UnknownBrowserError; +var init_windows = __esm({ + "node_modules/default-browser/windows.js"() { + import_node_util3 = require("node:util"); + import_node_child_process3 = require("node:child_process"); + execFileAsync3 = (0, import_node_util3.promisify)(import_node_child_process3.execFile); + windowsBrowserProgIds = { + MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" }, + // The missing `L` is correct. + MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" }, + MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" }, + AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" }, + ChromeHTML: { name: "Chrome", id: "com.google.chrome" }, + ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" }, + ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" }, + ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" }, + BraveHTML: { name: "Brave", id: "com.brave.Browser" }, + BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" }, + BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" }, + BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" }, + FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" }, + OperaStable: { name: "Opera", id: "com.operasoftware.Opera" }, + VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" }, + "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" } + }; + _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds)); + UnknownBrowserError = class extends Error { + }; + } +}); + +// node_modules/default-browser/index.js +async function defaultBrowser2() { + if (import_node_process5.default.platform === "darwin") { + const id = await defaultBrowserId(); + const name = await bundleName(id); + return { name, id }; + } + if (import_node_process5.default.platform === "linux") { + const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]); + const id = stdout.trim(); + const name = titleize(id.replace(/.desktop$/, "").replace("-", " ")); + return { name, id }; + } + if (import_node_process5.default.platform === "win32") { + return defaultBrowser(); + } + throw new Error("Only macOS, Linux, and Windows are supported"); +} +var import_node_util4, import_node_process5, import_node_child_process4, execFileAsync4, titleize; +var init_default_browser = __esm({ + "node_modules/default-browser/index.js"() { + import_node_util4 = require("node:util"); + import_node_process5 = __toESM(require("node:process"), 1); + import_node_child_process4 = require("node:child_process"); + init_default_browser_id(); + init_bundle_name(); + init_windows(); + execFileAsync4 = (0, import_node_util4.promisify)(import_node_child_process4.execFile); + titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase()); + } +}); + +// node_modules/open/index.js +var open_exports = {}; +__export(open_exports, { + apps: () => apps, + default: () => open_default, + openApp: () => openApp +}); +async function getWindowsDefaultBrowserFromWsl() { + const powershellPath = await powerShellPath(); + const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`; + const encodedCommand = import_node_buffer.Buffer.from(rawCommand, "utf16le").toString("base64"); + const { stdout } = await execFile5( + powershellPath, + [ + "-NoProfile", + "-NonInteractive", + "-ExecutionPolicy", + "Bypass", + "-EncodedCommand", + encodedCommand + ], + { encoding: "utf8" } + ); + const progId = stdout.trim(); + const browserMap = { + ChromeHTML: "com.google.chrome", + BraveHTML: "com.brave.Browser", + MSEdgeHTM: "com.microsoft.edge", + FirefoxURL: "org.mozilla.firefox" + }; + return browserMap[progId] ? { id: browserMap[progId] } : {}; +} +function detectArchBinary(binary) { + if (typeof binary === "string" || Array.isArray(binary)) { + return binary; + } + const { [arch]: archBinary } = binary; + if (!archBinary) { + throw new Error(`${arch} is not supported`); + } + return archBinary; +} +function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) { + if (wsl && is_wsl_default) { + return detectArchBinary(wsl); + } + if (!platformBinary) { + throw new Error(`${platform} is not supported`); + } + return detectArchBinary(platformBinary); +} +var import_node_process6, import_node_buffer, import_node_path, import_node_url, import_node_util5, import_node_child_process5, import_promises2, import_meta, execFile5, __dirname2, localXdgOpenPath, platform, arch, pTryEach, baseOpen, open, openApp, apps, open_default; +var init_open = __esm({ + "node_modules/open/index.js"() { + import_node_process6 = __toESM(require("node:process"), 1); + import_node_buffer = require("node:buffer"); + import_node_path = __toESM(require("node:path"), 1); + import_node_url = require("node:url"); + import_node_util5 = require("node:util"); + import_node_child_process5 = __toESM(require("node:child_process"), 1); + import_promises2 = __toESM(require("node:fs/promises"), 1); + init_wsl_utils(); + init_define_lazy_prop(); + init_default_browser(); + init_is_inside_container(); + import_meta = {}; + execFile5 = (0, import_node_util5.promisify)(import_node_child_process5.default.execFile); + __dirname2 = import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url)); + localXdgOpenPath = import_node_path.default.join(__dirname2, "xdg-open"); + ({ platform, arch } = import_node_process6.default); + pTryEach = async (array, mapper) => { + let latestError; + for (const item of array) { + try { + return await mapper(item); + } catch (error) { + latestError = error; + } + } + throw latestError; + }; + baseOpen = async (options) => { + options = { + wait: false, + background: false, + newInstance: false, + allowNonzeroExitCode: false, + ...options + }; + if (Array.isArray(options.app)) { + return pTryEach(options.app, (singleApp) => baseOpen({ + ...options, + app: singleApp + })); + } + let { name: app, arguments: appArguments = [] } = options.app ?? {}; + appArguments = [...appArguments]; + if (Array.isArray(app)) { + return pTryEach(app, (appName) => baseOpen({ + ...options, + app: { + name: appName, + arguments: appArguments + } + })); + } + if (app === "browser" || app === "browserPrivate") { + const ids = { + "com.google.chrome": "chrome", + "google-chrome.desktop": "chrome", + "com.brave.Browser": "brave", + "org.mozilla.firefox": "firefox", + "firefox.desktop": "firefox", + "com.microsoft.msedge": "edge", + "com.microsoft.edge": "edge", + "com.microsoft.edgemac": "edge", + "microsoft-edge.desktop": "edge" + }; + const flags = { + chrome: "--incognito", + brave: "--incognito", + firefox: "--private-window", + edge: "--inPrivate" + }; + const browser = is_wsl_default ? await getWindowsDefaultBrowserFromWsl() : await defaultBrowser2(); + if (browser.id in ids) { + const browserName = ids[browser.id]; + if (app === "browserPrivate") { + appArguments.push(flags[browserName]); + } + return baseOpen({ + ...options, + app: { + name: apps[browserName], + arguments: appArguments + } + }); + } + throw new Error(`${browser.name} is not supported as a default browser`); + } + let command; + const cliArguments = []; + const childProcessOptions = {}; + if (platform === "darwin") { + command = "open"; + if (options.wait) { + cliArguments.push("--wait-apps"); + } + if (options.background) { + cliArguments.push("--background"); + } + if (options.newInstance) { + cliArguments.push("--new"); + } + if (app) { + cliArguments.push("-a", app); + } + } else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) { + command = await powerShellPath(); + cliArguments.push( + "-NoProfile", + "-NonInteractive", + "-ExecutionPolicy", + "Bypass", + "-EncodedCommand" + ); + if (!is_wsl_default) { + childProcessOptions.windowsVerbatimArguments = true; + } + const encodedArguments = ["Start"]; + if (options.wait) { + encodedArguments.push("-Wait"); + } + if (app) { + encodedArguments.push(`"\`"${app}\`""`); + if (options.target) { + appArguments.push(options.target); + } + } else if (options.target) { + encodedArguments.push(`"${options.target}"`); + } + if (appArguments.length > 0) { + appArguments = appArguments.map((argument) => `"\`"${argument}\`""`); + encodedArguments.push("-ArgumentList", appArguments.join(",")); + } + options.target = import_node_buffer.Buffer.from(encodedArguments.join(" "), "utf16le").toString("base64"); + } else { + if (app) { + command = app; + } else { + const isBundled = !__dirname2 || __dirname2 === "/"; + let exeLocalXdgOpen = false; + try { + await import_promises2.default.access(localXdgOpenPath, import_promises2.constants.X_OK); + exeLocalXdgOpen = true; + } catch { + } + const useSystemXdgOpen = import_node_process6.default.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen); + command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath; + } + if (appArguments.length > 0) { + cliArguments.push(...appArguments); + } + if (!options.wait) { + childProcessOptions.stdio = "ignore"; + childProcessOptions.detached = true; + } + } + if (platform === "darwin" && appArguments.length > 0) { + cliArguments.push("--args", ...appArguments); + } + if (options.target) { + cliArguments.push(options.target); + } + const subprocess = import_node_child_process5.default.spawn(command, cliArguments, childProcessOptions); + if (options.wait) { + return new Promise((resolve, reject) => { + subprocess.once("error", reject); + subprocess.once("close", (exitCode) => { + if (!options.allowNonzeroExitCode && exitCode > 0) { + reject(new Error(`Exited with code ${exitCode}`)); + return; + } + resolve(subprocess); + }); + }); + } + subprocess.unref(); + return subprocess; + }; + open = (target, options) => { + if (typeof target !== "string") { + throw new TypeError("Expected a `target`"); + } + return baseOpen({ + ...options, + target + }); + }; + openApp = (name, options) => { + if (typeof name !== "string" && !Array.isArray(name)) { + throw new TypeError("Expected a valid `name`"); + } + const { arguments: appArguments = [] } = options ?? {}; + if (appArguments !== void 0 && appArguments !== null && !Array.isArray(appArguments)) { + throw new TypeError("Expected `appArguments` as Array type"); + } + return baseOpen({ + ...options, + app: { + name, + arguments: appArguments + } + }); + }; + apps = {}; + defineLazyProperty(apps, "chrome", () => detectPlatformBinary({ + darwin: "google chrome", + win32: "chrome", + linux: ["google-chrome", "google-chrome-stable", "chromium"] + }, { + wsl: { + ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe", + x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"] + } + })); + defineLazyProperty(apps, "brave", () => detectPlatformBinary({ + darwin: "brave browser", + win32: "brave", + linux: ["brave-browser", "brave"] + }, { + wsl: { + ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe", + x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"] + } + })); + defineLazyProperty(apps, "firefox", () => detectPlatformBinary({ + darwin: "firefox", + win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`, + linux: "firefox" + }, { + wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe" + })); + defineLazyProperty(apps, "edge", () => detectPlatformBinary({ + darwin: "microsoft edge", + win32: "msedge", + linux: ["microsoft-edge", "microsoft-edge-dev"] + }, { + wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe" + })); + defineLazyProperty(apps, "browser", () => "browser"); + defineLazyProperty(apps, "browserPrivate", () => "browserPrivate"); + open_default = open; + } +}); + +// node_modules/@azure/identity/dist/commonjs/msal/nodeFlows/msalClient.js +var require_msalClient = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/msal/nodeFlows/msalClient.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.generateMsalConfiguration = generateMsalConfiguration; + exports2.createMsalClient = createMsalClient; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var msal = tslib_1.__importStar(require_msal_node2()); + var logging_js_1 = require_logging(); + var msalPlugins_js_1 = require_msalPlugins(); + var utils_js_1 = require_utils6(); + var errors_js_1 = require_errors2(); + var identityClient_js_1 = require_identityClient(); + var regionalAuthority_js_1 = require_regionalAuthority(); + var logger_1 = require_commonjs2(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var msalLogger = (0, logging_js_1.credentialLogger)("MsalClient"); + function generateMsalConfiguration(clientId, tenantId, msalClientOptions = {}) { + const resolvedTenant = (0, tenantIdUtils_js_1.resolveTenantId)(msalClientOptions.logger ?? msalLogger, tenantId, clientId); + const authority = (0, utils_js_1.getAuthority)(resolvedTenant, (0, utils_js_1.getAuthorityHost)(msalClientOptions)); + const httpClient = new identityClient_js_1.IdentityClient({ + ...msalClientOptions.tokenCredentialOptions, + authorityHost: authority, + loggingOptions: msalClientOptions.loggingOptions + }); + const msalConfig = { + auth: { + clientId, + authority, + knownAuthorities: (0, utils_js_1.getKnownAuthorities)(resolvedTenant, authority, msalClientOptions.disableInstanceDiscovery) + }, + system: { + networkClient: httpClient, + loggerOptions: { + loggerCallback: (0, utils_js_1.defaultLoggerCallback)(msalClientOptions.logger ?? msalLogger), + logLevel: (0, utils_js_1.getMSALLogLevel)((0, logger_1.getLogLevel)()), + piiLoggingEnabled: msalClientOptions.loggingOptions?.enableUnsafeSupportLogging + } + } + }; + return msalConfig; + } + function createMsalClient(clientId, tenantId, createMsalClientOptions = {}) { + const state = { + msalConfig: generateMsalConfiguration(clientId, tenantId, createMsalClientOptions), + cachedAccount: createMsalClientOptions.authenticationRecord ? (0, utils_js_1.publicToMsal)(createMsalClientOptions.authenticationRecord) : null, + pluginConfiguration: msalPlugins_js_1.msalPlugins.generatePluginConfiguration(createMsalClientOptions), + logger: createMsalClientOptions.logger ?? msalLogger + }; + const publicApps = /* @__PURE__ */ new Map(); + async function getPublicApp(options = {}) { + const appKey = options.enableCae ? "CAE" : "default"; + let publicClientApp = publicApps.get(appKey); + if (publicClientApp) { + state.logger.getToken.info("Existing PublicClientApplication found in cache, returning it."); + return publicClientApp; + } + state.logger.getToken.info(`Creating new PublicClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`); + const cachePlugin = options.enableCae ? state.pluginConfiguration.cache.cachePluginCae : state.pluginConfiguration.cache.cachePlugin; + state.msalConfig.auth.clientCapabilities = options.enableCae ? ["cp1"] : void 0; + publicClientApp = new msal.PublicClientApplication({ + ...state.msalConfig, + broker: { nativeBrokerPlugin: state.pluginConfiguration.broker.nativeBrokerPlugin }, + cache: { cachePlugin: await cachePlugin } + }); + publicApps.set(appKey, publicClientApp); + return publicClientApp; + } + const confidentialApps = /* @__PURE__ */ new Map(); + async function getConfidentialApp(options = {}) { + const appKey = options.enableCae ? "CAE" : "default"; + let confidentialClientApp = confidentialApps.get(appKey); + if (confidentialClientApp) { + state.logger.getToken.info("Existing ConfidentialClientApplication found in cache, returning it."); + return confidentialClientApp; + } + state.logger.getToken.info(`Creating new ConfidentialClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`); + const cachePlugin = options.enableCae ? state.pluginConfiguration.cache.cachePluginCae : state.pluginConfiguration.cache.cachePlugin; + state.msalConfig.auth.clientCapabilities = options.enableCae ? ["cp1"] : void 0; + confidentialClientApp = new msal.ConfidentialClientApplication({ + ...state.msalConfig, + broker: { nativeBrokerPlugin: state.pluginConfiguration.broker.nativeBrokerPlugin }, + cache: { cachePlugin: await cachePlugin } + }); + confidentialApps.set(appKey, confidentialClientApp); + return confidentialClientApp; + } + async function getTokenSilent(app, scopes, options = {}) { + if (state.cachedAccount === null) { + state.logger.getToken.info("No cached account found in local state."); + throw new errors_js_1.AuthenticationRequiredError({ scopes }); + } + if (options.claims) { + state.cachedClaims = options.claims; + } + const silentRequest = { + account: state.cachedAccount, + scopes, + claims: state.cachedClaims + }; + if (state.pluginConfiguration.broker.isEnabled) { + silentRequest.extraQueryParameters ||= {}; + if (state.pluginConfiguration.broker.enableMsaPassthrough) { + silentRequest.extraQueryParameters["msal_request_type"] = "consumer_passthrough"; + } + } + if (options.proofOfPossessionOptions) { + silentRequest.shrNonce = options.proofOfPossessionOptions.nonce; + silentRequest.authenticationScheme = "pop"; + silentRequest.resourceRequestMethod = options.proofOfPossessionOptions.resourceRequestMethod; + silentRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl; + } + state.logger.getToken.info("Attempting to acquire token silently"); + try { + return await app.acquireTokenSilent(silentRequest); + } catch (err) { + throw (0, utils_js_1.handleMsalError)(scopes, err, options); + } + } + function calculateRequestAuthority(options) { + if (options?.tenantId) { + return (0, utils_js_1.getAuthority)(options.tenantId, (0, utils_js_1.getAuthorityHost)(createMsalClientOptions)); + } + return state.msalConfig.auth.authority; + } + async function withSilentAuthentication(msalApp, scopes, options, onAuthenticationRequired) { + let response = null; + try { + response = await getTokenSilent(msalApp, scopes, options); + } catch (e) { + if (e.name !== "AuthenticationRequiredError") { + throw e; + } + if (options.disableAutomaticAuthentication) { + throw new errors_js_1.AuthenticationRequiredError({ + scopes, + getTokenOptions: options, + message: "Automatic authentication has been disabled. You may call the authentication() method." + }); + } + } + if (response === null) { + try { + response = await onAuthenticationRequired(); + } catch (err) { + throw (0, utils_js_1.handleMsalError)(scopes, err, options); + } + } + (0, utils_js_1.ensureValidMsalToken)(scopes, response, options); + state.cachedAccount = response?.account ?? null; + state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + token: response.accessToken, + expiresOnTimestamp: response.expiresOn.getTime(), + refreshAfterTimestamp: response.refreshOn?.getTime(), + tokenType: response.tokenType + }; + } + async function getTokenByClientSecret(scopes, clientSecret, options = {}) { + state.logger.getToken.info(`Attempting to acquire token using client secret`); + state.msalConfig.auth.clientSecret = clientSecret; + const msalApp = await getConfidentialApp(options); + try { + const response = await msalApp.acquireTokenByClientCredential({ + scopes, + authority: calculateRequestAuthority(options), + azureRegion: (0, regionalAuthority_js_1.calculateRegionalAuthority)(), + claims: options?.claims + }); + (0, utils_js_1.ensureValidMsalToken)(scopes, response, options); + state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + token: response.accessToken, + expiresOnTimestamp: response.expiresOn.getTime(), + refreshAfterTimestamp: response.refreshOn?.getTime(), + tokenType: response.tokenType + }; + } catch (err) { + throw (0, utils_js_1.handleMsalError)(scopes, err, options); + } + } + async function getTokenByClientAssertion(scopes, clientAssertion, options = {}) { + state.logger.getToken.info(`Attempting to acquire token using client assertion`); + state.msalConfig.auth.clientAssertion = clientAssertion; + const msalApp = await getConfidentialApp(options); + try { + const response = await msalApp.acquireTokenByClientCredential({ + scopes, + authority: calculateRequestAuthority(options), + azureRegion: (0, regionalAuthority_js_1.calculateRegionalAuthority)(), + claims: options?.claims, + clientAssertion + }); + (0, utils_js_1.ensureValidMsalToken)(scopes, response, options); + state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + token: response.accessToken, + expiresOnTimestamp: response.expiresOn.getTime(), + refreshAfterTimestamp: response.refreshOn?.getTime(), + tokenType: response.tokenType + }; + } catch (err) { + throw (0, utils_js_1.handleMsalError)(scopes, err, options); + } + } + async function getTokenByClientCertificate(scopes, certificate, options = {}) { + state.logger.getToken.info(`Attempting to acquire token using client certificate`); + state.msalConfig.auth.clientCertificate = certificate; + const msalApp = await getConfidentialApp(options); + try { + const response = await msalApp.acquireTokenByClientCredential({ + scopes, + authority: calculateRequestAuthority(options), + azureRegion: (0, regionalAuthority_js_1.calculateRegionalAuthority)(), + claims: options?.claims + }); + (0, utils_js_1.ensureValidMsalToken)(scopes, response, options); + state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + token: response.accessToken, + expiresOnTimestamp: response.expiresOn.getTime(), + refreshAfterTimestamp: response.refreshOn?.getTime(), + tokenType: response.tokenType + }; + } catch (err) { + throw (0, utils_js_1.handleMsalError)(scopes, err, options); + } + } + async function getTokenByDeviceCode(scopes, deviceCodeCallback, options = {}) { + state.logger.getToken.info(`Attempting to acquire token using device code`); + const msalApp = await getPublicApp(options); + return withSilentAuthentication(msalApp, scopes, options, () => { + const requestOptions = { + scopes, + cancel: options?.abortSignal?.aborted ?? false, + deviceCodeCallback, + authority: calculateRequestAuthority(options), + claims: options?.claims + }; + const deviceCodeRequest = msalApp.acquireTokenByDeviceCode(requestOptions); + if (options.abortSignal) { + options.abortSignal.addEventListener("abort", () => { + requestOptions.cancel = true; + }); + } + return deviceCodeRequest; + }); + } + async function getTokenByUsernamePassword(scopes, username, password, options = {}) { + state.logger.getToken.info(`Attempting to acquire token using username and password`); + const msalApp = await getPublicApp(options); + return withSilentAuthentication(msalApp, scopes, options, () => { + const requestOptions = { + scopes, + username, + password, + authority: calculateRequestAuthority(options), + claims: options?.claims + }; + return msalApp.acquireTokenByUsernamePassword(requestOptions); + }); + } + function getActiveAccount() { + if (!state.cachedAccount) { + return void 0; + } + return (0, utils_js_1.msalToPublic)(clientId, state.cachedAccount); + } + async function getTokenByAuthorizationCode(scopes, redirectUri, authorizationCode, clientSecret, options = {}) { + state.logger.getToken.info(`Attempting to acquire token using authorization code`); + let msalApp; + if (clientSecret) { + state.msalConfig.auth.clientSecret = clientSecret; + msalApp = await getConfidentialApp(options); + } else { + msalApp = await getPublicApp(options); + } + return withSilentAuthentication(msalApp, scopes, options, () => { + return msalApp.acquireTokenByCode({ + scopes, + redirectUri, + code: authorizationCode, + authority: calculateRequestAuthority(options), + claims: options?.claims + }); + }); + } + async function getTokenOnBehalfOf(scopes, userAssertionToken, clientCredentials, options = {}) { + msalLogger.getToken.info(`Attempting to acquire token on behalf of another user`); + if (typeof clientCredentials === "string") { + msalLogger.getToken.info(`Using client secret for on behalf of flow`); + state.msalConfig.auth.clientSecret = clientCredentials; + } else if (typeof clientCredentials === "function") { + msalLogger.getToken.info(`Using client assertion callback for on behalf of flow`); + state.msalConfig.auth.clientAssertion = clientCredentials; + } else { + msalLogger.getToken.info(`Using client certificate for on behalf of flow`); + state.msalConfig.auth.clientCertificate = clientCredentials; + } + const msalApp = await getConfidentialApp(options); + try { + const response = await msalApp.acquireTokenOnBehalfOf({ + scopes, + authority: calculateRequestAuthority(options), + claims: options.claims, + oboAssertion: userAssertionToken + }); + (0, utils_js_1.ensureValidMsalToken)(scopes, response, options); + msalLogger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + token: response.accessToken, + expiresOnTimestamp: response.expiresOn.getTime(), + refreshAfterTimestamp: response.refreshOn?.getTime(), + tokenType: response.tokenType + }; + } catch (err) { + throw (0, utils_js_1.handleMsalError)(scopes, err, options); + } + } + function createBaseInteractiveRequest(scopes, options) { + return { + openBrowser: async (url) => { + const open2 = await Promise.resolve().then(() => (init_open(), open_exports)); + await open2.default(url, { newInstance: true }); + }, + scopes, + authority: calculateRequestAuthority(options), + claims: options?.claims, + loginHint: options?.loginHint, + errorTemplate: options?.browserCustomizationOptions?.errorMessage, + successTemplate: options?.browserCustomizationOptions?.successMessage, + prompt: options?.loginHint ? "login" : "select_account" + }; + } + async function getBrokeredTokenInternal(scopes, useDefaultBrokerAccount, options = {}) { + msalLogger.verbose("Authentication will resume through the broker"); + const app = await getPublicApp(options); + const interactiveRequest = createBaseInteractiveRequest(scopes, options); + if (state.pluginConfiguration.broker.parentWindowHandle) { + interactiveRequest.windowHandle = Buffer.from(state.pluginConfiguration.broker.parentWindowHandle); + } else { + msalLogger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle."); + } + if (state.pluginConfiguration.broker.enableMsaPassthrough) { + (interactiveRequest.extraQueryParameters ??= {})["msal_request_type"] = "consumer_passthrough"; + } + if (useDefaultBrokerAccount) { + interactiveRequest.prompt = "none"; + msalLogger.verbose("Attempting broker authentication using the default broker account"); + } else { + msalLogger.verbose("Attempting broker authentication without the default broker account"); + } + if (options.proofOfPossessionOptions) { + interactiveRequest.shrNonce = options.proofOfPossessionOptions.nonce; + interactiveRequest.authenticationScheme = "pop"; + interactiveRequest.resourceRequestMethod = options.proofOfPossessionOptions.resourceRequestMethod; + interactiveRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl; + } + try { + return await app.acquireTokenInteractive(interactiveRequest); + } catch (e) { + msalLogger.verbose(`Failed to authenticate through the broker: ${e.message}`); + if (options.disableAutomaticAuthentication) { + throw new errors_js_1.AuthenticationRequiredError({ + scopes, + getTokenOptions: options, + message: "Cannot silently authenticate with default broker account." + }); + } + if (useDefaultBrokerAccount) { + return getBrokeredTokenInternal(scopes, false, options); + } else { + throw e; + } + } + } + async function getBrokeredToken(scopes, useDefaultBrokerAccount, options = {}) { + msalLogger.getToken.info(`Attempting to acquire token using brokered authentication with useDefaultBrokerAccount: ${useDefaultBrokerAccount}`); + const response = await getBrokeredTokenInternal(scopes, useDefaultBrokerAccount, options); + (0, utils_js_1.ensureValidMsalToken)(scopes, response, options); + state.cachedAccount = response?.account ?? null; + state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + token: response.accessToken, + expiresOnTimestamp: response.expiresOn.getTime(), + refreshAfterTimestamp: response.refreshOn?.getTime(), + tokenType: response.tokenType + }; + } + async function getTokenByInteractiveRequest(scopes, options = {}) { + msalLogger.getToken.info(`Attempting to acquire token interactively`); + const app = await getPublicApp(options); + return withSilentAuthentication(app, scopes, options, async () => { + const interactiveRequest = createBaseInteractiveRequest(scopes, options); + if (state.pluginConfiguration.broker.isEnabled) { + return getBrokeredTokenInternal(scopes, state.pluginConfiguration.broker.useDefaultBrokerAccount ?? false, options); + } + if (options.proofOfPossessionOptions) { + interactiveRequest.shrNonce = options.proofOfPossessionOptions.nonce; + interactiveRequest.authenticationScheme = "pop"; + interactiveRequest.resourceRequestMethod = options.proofOfPossessionOptions.resourceRequestMethod; + interactiveRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl; + } + return app.acquireTokenInteractive(interactiveRequest); + }); + } + return { + getActiveAccount, + getBrokeredToken, + getTokenByClientSecret, + getTokenByClientAssertion, + getTokenByClientCertificate, + getTokenByDeviceCode, + getTokenByUsernamePassword, + getTokenByAuthorizationCode, + getTokenOnBehalfOf, + getTokenByInteractiveRequest + }; + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/clientCertificateCredential.js +var require_clientCertificateCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/clientCertificateCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ClientCertificateCredential = void 0; + exports2.parseCertificate = parseCertificate; + var msalClient_js_1 = require_msalClient(); + var node_crypto_1 = require("node:crypto"); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var logging_js_1 = require_logging(); + var promises_1 = require("node:fs/promises"); + var tracing_js_1 = require_tracing(); + var credentialName = "ClientCertificateCredential"; + var logger = (0, logging_js_1.credentialLogger)(credentialName); + var ClientCertificateCredential = class { + tenantId; + additionallyAllowedTenantIds; + certificateConfiguration; + sendCertificateChain; + msalClient; + constructor(tenantId, clientId, certificatePathOrConfiguration, options = {}) { + if (!tenantId || !clientId) { + throw new Error(`${credentialName}: tenantId and clientId are required parameters.`); + } + this.tenantId = tenantId; + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + this.sendCertificateChain = options.sendCertificateChain; + this.certificateConfiguration = { + ...typeof certificatePathOrConfiguration === "string" ? { + certificatePath: certificatePathOrConfiguration + } : certificatePathOrConfiguration + }; + const certificate = this.certificateConfiguration.certificate; + const certificatePath = this.certificateConfiguration.certificatePath; + if (!this.certificateConfiguration || !(certificate || certificatePath)) { + throw new Error(`${credentialName}: Provide either a PEM certificate in string form, or the path to that certificate in the filesystem. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`); + } + if (certificate && certificatePath) { + throw new Error(`${credentialName}: To avoid unexpected behaviors, providing both the contents of a PEM certificate and the path to a PEM certificate is forbidden. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`); + } + this.msalClient = (0, msalClient_js_1.createMsalClient)(clientId, tenantId, { + ...options, + logger, + tokenCredentialOptions: options + }); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => { + newOptions.tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger); + const arrayScopes = Array.isArray(scopes) ? scopes : [scopes]; + const certificate = await this.buildClientCertificate(); + return this.msalClient.getTokenByClientCertificate(arrayScopes, certificate, newOptions); + }); + } + async buildClientCertificate() { + const parts = await parseCertificate(this.certificateConfiguration, this.sendCertificateChain ?? false); + let privateKey; + if (this.certificateConfiguration.certificatePassword !== void 0) { + privateKey = (0, node_crypto_1.createPrivateKey)({ + key: parts.certificateContents, + passphrase: this.certificateConfiguration.certificatePassword, + format: "pem" + }).export({ + format: "pem", + type: "pkcs8" + }).toString(); + } else { + privateKey = parts.certificateContents; + } + return { + thumbprint: parts.thumbprint, + thumbprintSha256: parts.thumbprintSha256, + privateKey, + x5c: parts.x5c + }; + } + }; + exports2.ClientCertificateCredential = ClientCertificateCredential; + async function parseCertificate(certificateConfiguration, sendCertificateChain) { + const certificate = certificateConfiguration.certificate; + const certificatePath = certificateConfiguration.certificatePath; + const certificateContents = certificate || await (0, promises_1.readFile)(certificatePath, "utf8"); + const x5c = sendCertificateChain ? certificateContents : void 0; + const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\n\r?|\r\n?)([A-Za-z0-9+/\n\r]+=*)(\n\r?|\r\n?)(-+END CERTIFICATE-+)/g; + const publicKeys = []; + let match; + do { + match = certificatePattern.exec(certificateContents); + if (match) { + publicKeys.push(match[3]); + } + } while (match); + if (publicKeys.length === 0) { + throw new Error("The file at the specified path does not contain a PEM-encoded certificate."); + } + const thumbprint = (0, node_crypto_1.createHash)("sha1").update(Buffer.from(publicKeys[0], "base64")).digest("hex").toUpperCase(); + const thumbprintSha256 = (0, node_crypto_1.createHash)("sha256").update(Buffer.from(publicKeys[0], "base64")).digest("hex").toUpperCase(); + return { + certificateContents, + thumbprintSha256, + thumbprint, + x5c + }; + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/util/scopeUtils.js +var require_scopeUtils = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/util/scopeUtils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ensureScopes = ensureScopes; + exports2.ensureValidScopeForDevTimeCreds = ensureValidScopeForDevTimeCreds; + exports2.getScopeResource = getScopeResource; + var logging_js_1 = require_logging(); + function ensureScopes(scopes) { + return Array.isArray(scopes) ? scopes : [scopes]; + } + function ensureValidScopeForDevTimeCreds(scope, logger) { + if (!scope.match(/^[0-9a-zA-Z-_.:/]+$/)) { + const error = new Error("Invalid scope was specified by the user or calling client"); + logger.getToken.info((0, logging_js_1.formatError)(scope, error)); + throw error; + } + } + function getScopeResource(scope) { + return scope.replace(/\/.default$/, ""); + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/clientSecretCredential.js +var require_clientSecretCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/clientSecretCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ClientSecretCredential = void 0; + var msalClient_js_1 = require_msalClient(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var errors_js_1 = require_errors2(); + var logging_js_1 = require_logging(); + var scopeUtils_js_1 = require_scopeUtils(); + var tracing_js_1 = require_tracing(); + var logger = (0, logging_js_1.credentialLogger)("ClientSecretCredential"); + var ClientSecretCredential = class { + tenantId; + additionallyAllowedTenantIds; + msalClient; + clientSecret; + /** + * Creates an instance of the ClientSecretCredential with the details + * needed to authenticate against Microsoft Entra ID with a client + * secret. + * + * @param tenantId - The Microsoft Entra tenant (directory) ID. + * @param clientId - The client (application) ID of an App Registration in the tenant. + * @param clientSecret - A client secret that was generated for the App Registration. + * @param options - Options for configuring the client which makes the authentication request. + */ + constructor(tenantId, clientId, clientSecret, options = {}) { + if (!tenantId) { + throw new errors_js_1.CredentialUnavailableError("ClientSecretCredential: tenantId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot."); + } + if (!clientId) { + throw new errors_js_1.CredentialUnavailableError("ClientSecretCredential: clientId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot."); + } + if (!clientSecret) { + throw new errors_js_1.CredentialUnavailableError("ClientSecretCredential: clientSecret is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot."); + } + this.clientSecret = clientSecret; + this.tenantId = tenantId; + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + this.msalClient = (0, msalClient_js_1.createMsalClient)(clientId, tenantId, { + ...options, + logger, + tokenCredentialOptions: options + }); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => { + newOptions.tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger); + const arrayScopes = (0, scopeUtils_js_1.ensureScopes)(scopes); + return this.msalClient.getTokenByClientSecret(arrayScopes, this.clientSecret, newOptions); + }); + } + }; + exports2.ClientSecretCredential = ClientSecretCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/usernamePasswordCredential.js +var require_usernamePasswordCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/usernamePasswordCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.UsernamePasswordCredential = void 0; + var msalClient_js_1 = require_msalClient(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var errors_js_1 = require_errors2(); + var logging_js_1 = require_logging(); + var scopeUtils_js_1 = require_scopeUtils(); + var tracing_js_1 = require_tracing(); + var logger = (0, logging_js_1.credentialLogger)("UsernamePasswordCredential"); + var UsernamePasswordCredential = class { + tenantId; + additionallyAllowedTenantIds; + msalClient; + username; + password; + /** + * Creates an instance of the UsernamePasswordCredential with the details + * needed to authenticate against Microsoft Entra ID with a username + * and password. + * + * @param tenantId - The Microsoft Entra tenant (directory). + * @param clientId - The client (application) ID of an App Registration in the tenant. + * @param username - The user account's e-mail address (user name). + * @param password - The user account's account password + * @param options - Options for configuring the client which makes the authentication request. + */ + constructor(tenantId, clientId, username, password, options = {}) { + if (!tenantId) { + throw new errors_js_1.CredentialUnavailableError("UsernamePasswordCredential: tenantId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot."); + } + if (!clientId) { + throw new errors_js_1.CredentialUnavailableError("UsernamePasswordCredential: clientId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot."); + } + if (!username) { + throw new errors_js_1.CredentialUnavailableError("UsernamePasswordCredential: username is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot."); + } + if (!password) { + throw new errors_js_1.CredentialUnavailableError("UsernamePasswordCredential: password is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot."); + } + this.tenantId = tenantId; + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + this.username = username; + this.password = password; + this.msalClient = (0, msalClient_js_1.createMsalClient)(clientId, this.tenantId, { + ...options, + tokenCredentialOptions: options ?? {} + }); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * If the user provided the option `disableAutomaticAuthentication`, + * once the token can't be retrieved silently, + * this method won't attempt to request user interaction to retrieve the token. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => { + newOptions.tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger); + const arrayScopes = (0, scopeUtils_js_1.ensureScopes)(scopes); + return this.msalClient.getTokenByUsernamePassword(arrayScopes, this.username, this.password, newOptions); + }); + } + }; + exports2.UsernamePasswordCredential = UsernamePasswordCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/environmentCredential.js +var require_environmentCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/environmentCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.EnvironmentCredential = exports2.AllSupportedEnvironmentVariables = void 0; + exports2.getSendCertificateChain = getSendCertificateChain; + var errors_js_1 = require_errors2(); + var logging_js_1 = require_logging(); + var clientCertificateCredential_js_1 = require_clientCertificateCredential(); + var clientSecretCredential_js_1 = require_clientSecretCredential(); + var usernamePasswordCredential_js_1 = require_usernamePasswordCredential(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var tracing_js_1 = require_tracing(); + exports2.AllSupportedEnvironmentVariables = [ + "AZURE_TENANT_ID", + "AZURE_CLIENT_ID", + "AZURE_CLIENT_SECRET", + "AZURE_CLIENT_CERTIFICATE_PATH", + "AZURE_CLIENT_CERTIFICATE_PASSWORD", + "AZURE_USERNAME", + "AZURE_PASSWORD", + "AZURE_ADDITIONALLY_ALLOWED_TENANTS", + "AZURE_CLIENT_SEND_CERTIFICATE_CHAIN" + ]; + function getAdditionallyAllowedTenants() { + const additionallyAllowedValues = process.env.AZURE_ADDITIONALLY_ALLOWED_TENANTS ?? ""; + return additionallyAllowedValues.split(";"); + } + var credentialName = "EnvironmentCredential"; + var logger = (0, logging_js_1.credentialLogger)(credentialName); + function getSendCertificateChain() { + const sendCertificateChain = (process.env.AZURE_CLIENT_SEND_CERTIFICATE_CHAIN ?? "").toLowerCase(); + const result = sendCertificateChain === "true" || sendCertificateChain === "1"; + logger.verbose(`AZURE_CLIENT_SEND_CERTIFICATE_CHAIN: ${process.env.AZURE_CLIENT_SEND_CERTIFICATE_CHAIN}; sendCertificateChain: ${result}`); + return result; + } + var EnvironmentCredential = class { + _credential = void 0; + /** + * Creates an instance of the EnvironmentCredential class and decides what credential to use depending on the available environment variables. + * + * Required environment variables: + * - `AZURE_TENANT_ID`: The Microsoft Entra tenant (directory) ID. + * - `AZURE_CLIENT_ID`: The client (application) ID of an App Registration in the tenant. + * + * If setting the AZURE_TENANT_ID, then you can also set the additionally allowed tenants + * - `AZURE_ADDITIONALLY_ALLOWED_TENANTS`: For multi-tenant applications, specifies additional tenants for which the credential may acquire tokens with a single semicolon delimited string. Use * to allow all tenants. + * + * Environment variables used for client credential authentication: + * - `AZURE_CLIENT_SECRET`: A client secret that was generated for the App Registration. + * - `AZURE_CLIENT_CERTIFICATE_PATH`: The path to a PEM certificate to use during the authentication, instead of the client secret. + * - `AZURE_CLIENT_CERTIFICATE_PASSWORD`: (optional) password for the certificate file. + * - `AZURE_CLIENT_SEND_CERTIFICATE_CHAIN`: (optional) indicates that the certificate chain should be set in x5c header to support subject name / issuer based authentication. + * + * Username and password authentication is deprecated, since it doesn't support multifactor authentication (MFA). See https://aka.ms/azsdk/identity/mfa for more details. Users can still provide environment variables for this authentication method: + * - `AZURE_USERNAME`: Username to authenticate with. + * - `AZURE_PASSWORD`: Password to authenticate with. + * + * If the environment variables required to perform the authentication are missing, a {@link CredentialUnavailableError} will be thrown. + * If the authentication fails, or if there's an unknown error, an {@link AuthenticationError} will be thrown. + * + * @param options - Options for configuring the client which makes the authentication request. + */ + constructor(options) { + const assigned = (0, logging_js_1.processEnvVars)(exports2.AllSupportedEnvironmentVariables).assigned.join(", "); + logger.info(`Found the following environment variables: ${assigned}`); + const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET; + const additionallyAllowedTenantIds = getAdditionallyAllowedTenants(); + const sendCertificateChain = getSendCertificateChain(); + const newOptions = { ...options, additionallyAllowedTenantIds, sendCertificateChain }; + if (tenantId) { + (0, tenantIdUtils_js_1.checkTenantId)(logger, tenantId); + } + if (tenantId && clientId && clientSecret) { + logger.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`); + this._credential = new clientSecretCredential_js_1.ClientSecretCredential(tenantId, clientId, clientSecret, newOptions); + return; + } + const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH; + const certificatePassword = process.env.AZURE_CLIENT_CERTIFICATE_PASSWORD; + if (tenantId && clientId && certificatePath) { + logger.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`); + this._credential = new clientCertificateCredential_js_1.ClientCertificateCredential(tenantId, clientId, { certificatePath, certificatePassword }, newOptions); + return; + } + const username = process.env.AZURE_USERNAME; + const password = process.env.AZURE_PASSWORD; + if (tenantId && clientId && username && password) { + logger.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`); + logger.warning("Environment is configured to use username and password authentication. This authentication method is deprecated, as it doesn't support multifactor authentication (MFA). Use a more secure credential. For more details, see https://aka.ms/azsdk/identity/mfa."); + this._credential = new usernamePasswordCredential_js_1.UsernamePasswordCredential(tenantId, clientId, username, password, newOptions); + } + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - Optional parameters. See {@link GetTokenOptions}. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => { + if (this._credential) { + try { + const result = await this._credential.getToken(scopes, newOptions); + logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return result; + } catch (err) { + const authenticationError = new errors_js_1.AuthenticationError(400, { + error: `${credentialName} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`, + error_description: err.message.toString().split("More details:").join("") + }); + logger.getToken.info((0, logging_js_1.formatError)(scopes, authenticationError)); + throw authenticationError; + } + } + throw new errors_js_1.CredentialUnavailableError(`${credentialName} is unavailable. No underlying credential could be used. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`); + }); + } + }; + exports2.EnvironmentCredential = EnvironmentCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/imdsRetryPolicy.js +var require_imdsRetryPolicy = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/imdsRetryPolicy.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.imdsRetryPolicy = imdsRetryPolicy; + var core_rest_pipeline_1 = require_commonjs6(); + var core_util_1 = require_commonjs4(); + var DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1e3 * 64; + var MIN_DELAY_FOR_410_MS = 3e3; + function imdsRetryPolicy(msiRetryConfig) { + return (0, core_rest_pipeline_1.retryPolicy)([ + { + name: "imdsRetryPolicy", + retry: ({ retryCount, response }) => { + if (response?.status !== 404 && response?.status !== 410) { + return { skipStrategy: true }; + } + const initialDelayMs = response?.status === 410 ? Math.max(MIN_DELAY_FOR_410_MS, msiRetryConfig.startDelayInMs) : msiRetryConfig.startDelayInMs; + return (0, core_util_1.calculateRetryDelay)(retryCount, { + retryDelayInMs: initialDelayMs, + maxRetryDelayInMs: DEFAULT_CLIENT_MAX_RETRY_INTERVAL + }); + } + } + ], { + maxRetries: msiRetryConfig.maxRetries + }); + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/imdsMsi.js +var require_imdsMsi = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/imdsMsi.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.imdsMsi = void 0; + var core_rest_pipeline_1 = require_commonjs6(); + var core_util_1 = require_commonjs4(); + var logging_js_1 = require_logging(); + var utils_js_1 = require_utils7(); + var tracing_js_1 = require_tracing(); + var msiName = "ManagedIdentityCredential - IMDS"; + var logger = (0, logging_js_1.credentialLogger)(msiName); + var imdsHost = "http://169.254.169.254"; + var imdsEndpointPath = "/metadata/identity/oauth2/token"; + function prepareInvalidRequestOptions(scopes) { + const resource = (0, utils_js_1.mapScopesToResource)(scopes); + if (!resource) { + throw new Error(`${msiName}: Multiple scopes are not supported.`); + } + const url = new URL(imdsEndpointPath, process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST ?? imdsHost); + const rawHeaders = { + Accept: "application/json" + // intentionally leave out the Metadata header to invoke an error from IMDS endpoint. + }; + return { + // intentionally not including any query + url: `${url}`, + method: "GET", + headers: (0, core_rest_pipeline_1.createHttpHeaders)(rawHeaders) + }; + } + exports2.imdsMsi = { + name: "imdsMsi", + async isAvailable(options) { + const { scopes, identityClient, getTokenOptions } = options; + const resource = (0, utils_js_1.mapScopesToResource)(scopes); + if (!resource) { + logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`); + return false; + } + if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) { + return true; + } + if (!identityClient) { + throw new Error("Missing IdentityClient"); + } + const requestOptions = prepareInvalidRequestOptions(resource); + return tracing_js_1.tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions ?? {}, async (updatedOptions) => { + requestOptions.tracingOptions = updatedOptions.tracingOptions; + const request = (0, core_rest_pipeline_1.createPipelineRequest)(requestOptions); + request.timeout = updatedOptions.requestOptions?.timeout || 1e3; + request.allowInsecureConnection = true; + let response; + try { + logger.info(`${msiName}: Pinging the Azure IMDS endpoint`); + response = await identityClient.sendRequest(request); + } catch (err) { + if ((0, core_util_1.isError)(err)) { + logger.verbose(`${msiName}: Caught error ${err.name}: ${err.message}`); + } + logger.info(`${msiName}: The Azure IMDS endpoint is unavailable`); + return false; + } + if (response.status === 403) { + if (response.bodyAsText?.includes("unreachable")) { + logger.info(`${msiName}: The Azure IMDS endpoint is unavailable`); + logger.info(`${msiName}: ${response.bodyAsText}`); + return false; + } + } + logger.info(`${msiName}: The Azure IMDS endpoint is available`); + return true; + }); + } + }; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/clientAssertionCredential.js +var require_clientAssertionCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/clientAssertionCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ClientAssertionCredential = void 0; + var msalClient_js_1 = require_msalClient(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var errors_js_1 = require_errors2(); + var logging_js_1 = require_logging(); + var tracing_js_1 = require_tracing(); + var logger = (0, logging_js_1.credentialLogger)("ClientAssertionCredential"); + var ClientAssertionCredential = class { + msalClient; + tenantId; + additionallyAllowedTenantIds; + getAssertion; + options; + /** + * Creates an instance of the ClientAssertionCredential with the details + * needed to authenticate against Microsoft Entra ID with a client + * assertion provided by the developer through the `getAssertion` function parameter. + * + * @param tenantId - The Microsoft Entra tenant (directory) ID. + * @param clientId - The client (application) ID of an App Registration in the tenant. + * @param getAssertion - A function that retrieves the assertion for the credential to use. + * @param options - Options for configuring the client which makes the authentication request. + */ + constructor(tenantId, clientId, getAssertion, options = {}) { + if (!tenantId) { + throw new errors_js_1.CredentialUnavailableError("ClientAssertionCredential: tenantId is a required parameter."); + } + if (!clientId) { + throw new errors_js_1.CredentialUnavailableError("ClientAssertionCredential: clientId is a required parameter."); + } + if (!getAssertion) { + throw new errors_js_1.CredentialUnavailableError("ClientAssertionCredential: clientAssertion is a required parameter."); + } + this.tenantId = tenantId; + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + this.options = options; + this.getAssertion = getAssertion; + this.msalClient = (0, msalClient_js_1.createMsalClient)(clientId, tenantId, { + ...options, + logger, + tokenCredentialOptions: this.options + }); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => { + newOptions.tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger); + const arrayScopes = Array.isArray(scopes) ? scopes : [scopes]; + return this.msalClient.getTokenByClientAssertion(arrayScopes, this.getAssertion, newOptions); + }); + } + }; + exports2.ClientAssertionCredential = ClientAssertionCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/workloadIdentityCredential.js +var require_workloadIdentityCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/workloadIdentityCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.WorkloadIdentityCredential = exports2.SupportedWorkloadEnvironmentVariables = void 0; + var logging_js_1 = require_logging(); + var clientAssertionCredential_js_1 = require_clientAssertionCredential(); + var errors_js_1 = require_errors2(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var promises_1 = require("node:fs/promises"); + var credentialName = "WorkloadIdentityCredential"; + exports2.SupportedWorkloadEnvironmentVariables = [ + "AZURE_TENANT_ID", + "AZURE_CLIENT_ID", + "AZURE_FEDERATED_TOKEN_FILE" + ]; + var logger = (0, logging_js_1.credentialLogger)(credentialName); + var WorkloadIdentityCredential = class { + client; + azureFederatedTokenFileContent = void 0; + cacheDate = void 0; + federatedTokenFilePath; + /** + * WorkloadIdentityCredential supports Microsoft Entra Workload ID on Kubernetes. + * + * @param options - The identity client options to use for authentication. + */ + constructor(options) { + const assignedEnv = (0, logging_js_1.processEnvVars)(exports2.SupportedWorkloadEnvironmentVariables).assigned.join(", "); + logger.info(`Found the following environment variables: ${assignedEnv}`); + const workloadIdentityCredentialOptions = options ?? {}; + const tenantId = workloadIdentityCredentialOptions.tenantId || process.env.AZURE_TENANT_ID; + const clientId = workloadIdentityCredentialOptions.clientId || process.env.AZURE_CLIENT_ID; + this.federatedTokenFilePath = workloadIdentityCredentialOptions.tokenFilePath || process.env.AZURE_FEDERATED_TOKEN_FILE; + if (tenantId) { + (0, tenantIdUtils_js_1.checkTenantId)(logger, tenantId); + } + if (!clientId) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. clientId is a required parameter. In DefaultAzureCredential and ManagedIdentityCredential, this can be provided as an environment variable - "AZURE_CLIENT_ID". + See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot`); + } + if (!tenantId) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. tenantId is a required parameter. In DefaultAzureCredential and ManagedIdentityCredential, this can be provided as an environment variable - "AZURE_TENANT_ID". + See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot`); + } + if (!this.federatedTokenFilePath) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. federatedTokenFilePath is a required parameter. In DefaultAzureCredential and ManagedIdentityCredential, this can be provided as an environment variable - "AZURE_FEDERATED_TOKEN_FILE". + See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot`); + } + logger.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${workloadIdentityCredentialOptions.clientId} and federated token path: [REDACTED]`); + this.client = new clientAssertionCredential_js_1.ClientAssertionCredential(tenantId, clientId, this.readFileContents.bind(this), options); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options) { + if (!this.client) { + const errorMessage = `${credentialName}: is unavailable. tenantId, clientId, and federatedTokenFilePath are required parameters. + In DefaultAzureCredential and ManagedIdentityCredential, these can be provided as environment variables - + "AZURE_TENANT_ID", + "AZURE_CLIENT_ID", + "AZURE_FEDERATED_TOKEN_FILE". See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot`; + logger.info(errorMessage); + throw new errors_js_1.CredentialUnavailableError(errorMessage); + } + logger.info("Invoking getToken() of Client Assertion Credential"); + return this.client.getToken(scopes, options); + } + async readFileContents() { + if (this.cacheDate !== void 0 && Date.now() - this.cacheDate >= 1e3 * 60 * 5) { + this.azureFederatedTokenFileContent = void 0; + } + if (!this.federatedTokenFilePath) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. Invalid file path provided ${this.federatedTokenFilePath}.`); + } + if (!this.azureFederatedTokenFileContent) { + const file = await (0, promises_1.readFile)(this.federatedTokenFilePath, "utf8"); + const value = file.trim(); + if (!value) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. No content on the file ${this.federatedTokenFilePath}.`); + } else { + this.azureFederatedTokenFileContent = value; + this.cacheDate = Date.now(); + } + } + return this.azureFederatedTokenFileContent; + } + }; + exports2.WorkloadIdentityCredential = WorkloadIdentityCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/tokenExchangeMsi.js +var require_tokenExchangeMsi = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/tokenExchangeMsi.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.tokenExchangeMsi = void 0; + var workloadIdentityCredential_js_1 = require_workloadIdentityCredential(); + var logging_js_1 = require_logging(); + var msiName = "ManagedIdentityCredential - Token Exchange"; + var logger = (0, logging_js_1.credentialLogger)(msiName); + exports2.tokenExchangeMsi = { + name: "tokenExchangeMsi", + async isAvailable(clientId) { + const env = process.env; + const result = Boolean((clientId || env.AZURE_CLIENT_ID) && env.AZURE_TENANT_ID && process.env.AZURE_FEDERATED_TOKEN_FILE); + if (!result) { + logger.info(`${msiName}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`); + } + return result; + }, + async getToken(configuration, getTokenOptions = {}) { + const { scopes, clientId } = configuration; + const identityClientTokenCredentialOptions = {}; + const workloadIdentityCredential = new workloadIdentityCredential_js_1.WorkloadIdentityCredential({ + clientId, + tenantId: process.env.AZURE_TENANT_ID, + tokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE, + ...identityClientTokenCredentialOptions, + disableInstanceDiscovery: true + }); + return workloadIdentityCredential.getToken(scopes, getTokenOptions); + } + }; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/index.js +var require_managedIdentityCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/managedIdentityCredential/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ManagedIdentityCredential = void 0; + var logger_1 = require_commonjs2(); + var msal_node_1 = require_msal_node2(); + var identityClient_js_1 = require_identityClient(); + var errors_js_1 = require_errors2(); + var utils_js_1 = require_utils6(); + var imdsRetryPolicy_js_1 = require_imdsRetryPolicy(); + var logging_js_1 = require_logging(); + var tracing_js_1 = require_tracing(); + var imdsMsi_js_1 = require_imdsMsi(); + var tokenExchangeMsi_js_1 = require_tokenExchangeMsi(); + var utils_js_2 = require_utils7(); + var logger = (0, logging_js_1.credentialLogger)("ManagedIdentityCredential"); + var ManagedIdentityCredential = class { + managedIdentityApp; + identityClient; + clientId; + resourceId; + objectId; + msiRetryConfig = { + maxRetries: 5, + startDelayInMs: 800, + intervalIncrement: 2 + }; + isAvailableIdentityClient; + sendProbeRequest; + /** + * @internal + * @hidden + */ + constructor(clientIdOrOptions, options) { + let _options; + if (typeof clientIdOrOptions === "string") { + this.clientId = clientIdOrOptions; + _options = options ?? {}; + } else { + this.clientId = clientIdOrOptions?.clientId; + _options = clientIdOrOptions ?? {}; + } + this.resourceId = _options?.resourceId; + this.objectId = _options?.objectId; + this.sendProbeRequest = _options?.sendProbeRequest ?? false; + const providedIds = [ + { key: "clientId", value: this.clientId }, + { key: "resourceId", value: this.resourceId }, + { key: "objectId", value: this.objectId } + ].filter((id) => id.value); + if (providedIds.length > 1) { + throw new Error(`ManagedIdentityCredential: only one of 'clientId', 'resourceId', or 'objectId' can be provided. Received values: ${JSON.stringify({ clientId: this.clientId, resourceId: this.resourceId, objectId: this.objectId })}`); + } + _options.allowInsecureConnection = true; + if (_options.retryOptions?.maxRetries !== void 0) { + this.msiRetryConfig.maxRetries = _options.retryOptions.maxRetries; + } + this.identityClient = new identityClient_js_1.IdentityClient({ + ..._options, + additionalPolicies: [{ policy: (0, imdsRetryPolicy_js_1.imdsRetryPolicy)(this.msiRetryConfig), position: "perCall" }] + }); + this.managedIdentityApp = new msal_node_1.ManagedIdentityApplication({ + managedIdentityIdParams: { + userAssignedClientId: this.clientId, + userAssignedResourceId: this.resourceId, + userAssignedObjectId: this.objectId + }, + system: { + disableInternalRetries: true, + networkClient: this.identityClient, + loggerOptions: { + logLevel: (0, utils_js_1.getMSALLogLevel)((0, logger_1.getLogLevel)()), + piiLoggingEnabled: _options.loggingOptions?.enableUnsafeSupportLogging, + loggerCallback: (0, utils_js_1.defaultLoggerCallback)(logger) + } + } + }); + this.isAvailableIdentityClient = new identityClient_js_1.IdentityClient({ + ..._options, + retryOptions: { + maxRetries: 0 + } + }); + const managedIdentitySource = this.managedIdentityApp.getManagedIdentitySource(); + if (managedIdentitySource === "CloudShell") { + if (this.clientId || this.resourceId || this.objectId) { + logger.warning(`CloudShell MSI detected with user-provided IDs - throwing. Received values: ${JSON.stringify({ + clientId: this.clientId, + resourceId: this.resourceId, + objectId: this.objectId + })}.`); + throw new errors_js_1.CredentialUnavailableError("ManagedIdentityCredential: Specifying a user-assigned managed identity is not supported for CloudShell at runtime. When using Managed Identity in CloudShell, omit the clientId, resourceId, and objectId parameters."); + } + } + if (managedIdentitySource === "ServiceFabric") { + if (this.clientId || this.resourceId || this.objectId) { + logger.warning(`Service Fabric detected with user-provided IDs - throwing. Received values: ${JSON.stringify({ + clientId: this.clientId, + resourceId: this.resourceId, + objectId: this.objectId + })}.`); + throw new errors_js_1.CredentialUnavailableError(`ManagedIdentityCredential: ${utils_js_2.serviceFabricErrorMessage}`); + } + } + logger.info(`Using ${managedIdentitySource} managed identity.`); + if (providedIds.length === 1) { + const { key, value } = providedIds[0]; + logger.info(`${managedIdentitySource} with ${key}: ${value}`); + } + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * If an unexpected error occurs, an {@link AuthenticationError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + logger.getToken.info("Using the MSAL provider for Managed Identity."); + const resource = (0, utils_js_2.mapScopesToResource)(scopes); + if (!resource) { + throw new errors_js_1.CredentialUnavailableError(`ManagedIdentityCredential: Multiple scopes are not supported. Scopes: ${JSON.stringify(scopes)}`); + } + return tracing_js_1.tracingClient.withSpan("ManagedIdentityCredential.getToken", options, async () => { + try { + const isTokenExchangeMsi = await tokenExchangeMsi_js_1.tokenExchangeMsi.isAvailable(this.clientId); + const identitySource = this.managedIdentityApp.getManagedIdentitySource(); + const isImdsMsi = identitySource === "DefaultToImds" || identitySource === "Imds"; + logger.getToken.info(`MSAL Identity source: ${identitySource}`); + if (isTokenExchangeMsi) { + logger.getToken.info("Using the token exchange managed identity."); + const result = await tokenExchangeMsi_js_1.tokenExchangeMsi.getToken({ + scopes, + clientId: this.clientId, + identityClient: this.identityClient, + retryConfig: this.msiRetryConfig, + resourceId: this.resourceId + }); + if (result === null) { + throw new errors_js_1.CredentialUnavailableError("Attempted to use the token exchange managed identity, but received a null response."); + } + return result; + } else if (isImdsMsi && this.sendProbeRequest) { + logger.getToken.info("Using the IMDS endpoint to probe for availability."); + const isAvailable = await imdsMsi_js_1.imdsMsi.isAvailable({ + scopes, + clientId: this.clientId, + getTokenOptions: options, + identityClient: this.isAvailableIdentityClient, + resourceId: this.resourceId + }); + if (!isAvailable) { + throw new errors_js_1.CredentialUnavailableError(`Attempted to use the IMDS endpoint, but it is not available.`); + } + } + logger.getToken.info("Calling into MSAL for managed identity token."); + const token = await this.managedIdentityApp.acquireToken({ + resource + }); + this.ensureValidMsalToken(scopes, token, options); + logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + expiresOnTimestamp: token.expiresOn.getTime(), + token: token.accessToken, + refreshAfterTimestamp: token.refreshOn?.getTime(), + tokenType: "Bearer" + }; + } catch (err) { + logger.getToken.error((0, logging_js_1.formatError)(scopes, err)); + if (err.name === "AuthenticationRequiredError") { + throw err; + } + if (isNetworkError(err)) { + throw new errors_js_1.CredentialUnavailableError(`ManagedIdentityCredential: Network unreachable. Message: ${err.message}`, { cause: err }); + } + throw new errors_js_1.CredentialUnavailableError(`ManagedIdentityCredential: Authentication failed. Message ${err.message}`, { cause: err }); + } + }); + } + /** + * Ensures the validity of the MSAL token + */ + ensureValidMsalToken(scopes, msalToken, getTokenOptions) { + const createError = (message) => { + logger.getToken.info(message); + return new errors_js_1.AuthenticationRequiredError({ + scopes: Array.isArray(scopes) ? scopes : [scopes], + getTokenOptions, + message + }); + }; + if (!msalToken) { + throw createError("No response."); + } + if (!msalToken.expiresOn) { + throw createError(`Response had no "expiresOn" property.`); + } + if (!msalToken.accessToken) { + throw createError(`Response had no "accessToken" property.`); + } + } + }; + exports2.ManagedIdentityCredential = ManagedIdentityCredential; + function isNetworkError(err) { + if (err.errorCode === "network_error") { + return true; + } + if (err.code === "ENETUNREACH" || err.code === "EHOSTUNREACH") { + return true; + } + if (err.statusCode === 403 || err.code === 403) { + if (err.message.includes("unreachable")) { + return true; + } + } + return false; + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/azureDeveloperCliCredential.js +var require_azureDeveloperCliCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/azureDeveloperCliCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AzureDeveloperCliCredential = exports2.developerCliCredentialInternals = exports2.azureDeveloperCliPublicErrorMessages = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var logging_js_1 = require_logging(); + var errors_js_1 = require_errors2(); + var child_process_1 = tslib_1.__importDefault(require("child_process")); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var tracing_js_1 = require_tracing(); + var scopeUtils_js_1 = require_scopeUtils(); + var logger = (0, logging_js_1.credentialLogger)("AzureDeveloperCliCredential"); + exports2.azureDeveloperCliPublicErrorMessages = { + notInstalled: "Azure Developer CLI couldn't be found. To mitigate this issue, see the troubleshooting guidelines at https://aka.ms/azsdk/js/identity/azdevclicredential/troubleshoot.", + login: "Please run 'azd auth login' from a command prompt to authenticate before using this credential. For more information, see the troubleshooting guidelines at https://aka.ms/azsdk/js/identity/azdevclicredential/troubleshoot.", + unknown: "Unknown error while trying to retrieve the access token", + claim: "This credential doesn't support claims challenges. To authenticate with the required claims, please run the following command:" + }; + exports2.developerCliCredentialInternals = { + /** + * @internal + */ + getSafeWorkingDir() { + if (process.platform === "win32") { + let systemRoot = process.env.SystemRoot || process.env["SYSTEMROOT"]; + if (!systemRoot) { + logger.getToken.warning("The SystemRoot environment variable is not set. This may cause issues when using the Azure Developer CLI credential."); + systemRoot = "C:\\Windows"; + } + return systemRoot; + } else { + return "/bin"; + } + }, + /** + * Gets the access token from Azure Developer CLI + * @param scopes - The scopes to use when getting the token + * @internal + */ + async getAzdAccessToken(scopes, tenantId, timeout, claims) { + let tenantSection = []; + if (tenantId) { + tenantSection = ["--tenant-id", tenantId]; + } + let claimsSections = []; + if (claims) { + const encodedClaims = btoa(claims); + claimsSections = ["--claims", encodedClaims]; + } + return new Promise((resolve, reject) => { + try { + const args = [ + "auth", + "token", + "--output", + "json", + "--no-prompt", + ...scopes.reduce((previous, current) => previous.concat("--scope", current), []), + ...tenantSection, + ...claimsSections + ]; + const command = ["azd", ...args].join(" "); + child_process_1.default.exec(command, { + cwd: exports2.developerCliCredentialInternals.getSafeWorkingDir(), + timeout + }, (error, stdout, stderr) => { + resolve({ stdout, stderr, error }); + }); + } catch (err) { + reject(err); + } + }); + } + }; + var AzureDeveloperCliCredential = class { + tenantId; + additionallyAllowedTenantIds; + timeout; + /** + * Creates an instance of the {@link AzureDeveloperCliCredential}. + * + * To use this credential, ensure that you have already logged + * in via the 'azd' tool using the command "azd auth login" from the commandline. + * + * @param options - Options, to optionally allow multi-tenant requests. + */ + constructor(options) { + if (options?.tenantId) { + (0, tenantIdUtils_js_1.checkTenantId)(logger, options?.tenantId); + this.tenantId = options?.tenantId; + } + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + this.timeout = options?.processTimeoutInMs; + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + const tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, options, this.additionallyAllowedTenantIds); + if (tenantId) { + (0, tenantIdUtils_js_1.checkTenantId)(logger, tenantId); + } + let scopeList; + if (typeof scopes === "string") { + scopeList = [scopes]; + } else { + scopeList = scopes; + } + logger.getToken.info(`Using the scopes ${scopes}`); + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => { + try { + scopeList.forEach((scope) => { + (0, scopeUtils_js_1.ensureValidScopeForDevTimeCreds)(scope, logger); + }); + const obj = await exports2.developerCliCredentialInternals.getAzdAccessToken(scopeList, tenantId, this.timeout, options.claims); + const isMFARequiredError = obj.stderr?.match("must use multi-factor authentication") || obj.stderr?.match("reauthentication required"); + const isNotLoggedInError = obj.stderr?.match("not logged in, run `azd login` to login") || obj.stderr?.match("not logged in, run `azd auth login` to login"); + const isNotInstallError = obj.stderr?.match("azd:(.*)not found") || obj.stderr?.startsWith("'azd' is not recognized"); + if (isNotInstallError || obj.error && obj.error.code === "ENOENT") { + const error = new errors_js_1.CredentialUnavailableError(exports2.azureDeveloperCliPublicErrorMessages.notInstalled); + logger.getToken.info((0, logging_js_1.formatError)(scopes, error)); + throw error; + } + if (isNotLoggedInError) { + const error = new errors_js_1.CredentialUnavailableError(exports2.azureDeveloperCliPublicErrorMessages.login); + logger.getToken.info((0, logging_js_1.formatError)(scopes, error)); + throw error; + } + if (isMFARequiredError) { + const scope = scopeList.reduce((previous, current) => previous.concat("--scope", current), []).join(" "); + const loginCmd = `azd auth login ${scope}`; + const error = new errors_js_1.CredentialUnavailableError(`${exports2.azureDeveloperCliPublicErrorMessages.claim} ${loginCmd}`); + logger.getToken.info((0, logging_js_1.formatError)(scopes, error)); + throw error; + } + try { + const resp = JSON.parse(obj.stdout); + logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + token: resp.token, + expiresOnTimestamp: new Date(resp.expiresOn).getTime(), + tokenType: "Bearer" + }; + } catch (e) { + if (obj.stderr) { + throw new errors_js_1.CredentialUnavailableError(obj.stderr); + } + throw e; + } + } catch (err) { + const error = err.name === "CredentialUnavailableError" ? err : new errors_js_1.CredentialUnavailableError(err.message || exports2.azureDeveloperCliPublicErrorMessages.unknown); + logger.getToken.info((0, logging_js_1.formatError)(scopes, error)); + throw error; + } + }); + } + }; + exports2.AzureDeveloperCliCredential = AzureDeveloperCliCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/util/subscriptionUtils.js +var require_subscriptionUtils = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/util/subscriptionUtils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.checkSubscription = checkSubscription; + var logging_js_1 = require_logging(); + function checkSubscription(logger, subscription) { + if (!subscription.match(/^[0-9a-zA-Z-._ ]+$/)) { + const error = new Error(`Subscription '${subscription}' contains invalid characters. If this is the name of a subscription, use its ID instead. You can locate your subscription by following the instructions listed here: https://learn.microsoft.com/azure/azure-portal/get-subscription-tenant-id`); + logger.info((0, logging_js_1.formatError)("", error)); + throw error; + } + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/azureCliCredential.js +var require_azureCliCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/azureCliCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AzureCliCredential = exports2.cliCredentialInternals = exports2.azureCliPublicErrorMessages = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var logging_js_1 = require_logging(); + var scopeUtils_js_1 = require_scopeUtils(); + var errors_js_1 = require_errors2(); + var child_process_1 = tslib_1.__importDefault(require("child_process")); + var tracing_js_1 = require_tracing(); + var subscriptionUtils_js_1 = require_subscriptionUtils(); + var logger = (0, logging_js_1.credentialLogger)("AzureCliCredential"); + exports2.azureCliPublicErrorMessages = { + claim: "This credential doesn't support claims challenges. To authenticate with the required claims, please run the following command:", + notInstalled: "Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'.", + login: "Please run 'az login' from a command prompt to authenticate before using this credential.", + unknown: "Unknown error while trying to retrieve the access token", + unexpectedResponse: 'Unexpected response from Azure CLI when getting token. Expected "expiresOn" to be a RFC3339 date string. Got:' + }; + exports2.cliCredentialInternals = { + /** + * @internal + */ + getSafeWorkingDir() { + if (process.platform === "win32") { + let systemRoot = process.env.SystemRoot || process.env["SYSTEMROOT"]; + if (!systemRoot) { + logger.getToken.warning("The SystemRoot environment variable is not set. This may cause issues when using the Azure CLI credential."); + systemRoot = "C:\\Windows"; + } + return systemRoot; + } else { + return "/bin"; + } + }, + /** + * Gets the access token from Azure CLI + * @param resource - The resource to use when getting the token + * @internal + */ + async getAzureCliAccessToken(resource, tenantId, subscription, timeout) { + let tenantSection = []; + let subscriptionSection = []; + if (tenantId) { + tenantSection = ["--tenant", tenantId]; + } + if (subscription) { + subscriptionSection = ["--subscription", `"${subscription}"`]; + } + return new Promise((resolve, reject) => { + try { + const args = [ + "account", + "get-access-token", + "--output", + "json", + "--resource", + resource, + ...tenantSection, + ...subscriptionSection + ]; + const command = ["az", ...args].join(" "); + child_process_1.default.exec(command, { cwd: exports2.cliCredentialInternals.getSafeWorkingDir(), timeout }, (error, stdout, stderr) => { + resolve({ stdout, stderr, error }); + }); + } catch (err) { + reject(err); + } + }); + } + }; + var AzureCliCredential = class { + tenantId; + additionallyAllowedTenantIds; + timeout; + subscription; + /** + * Creates an instance of the {@link AzureCliCredential}. + * + * To use this credential, ensure that you have already logged + * in via the 'az' tool using the command "az login" from the commandline. + * + * @param options - Options, to optionally allow multi-tenant requests. + */ + constructor(options) { + if (options?.tenantId) { + (0, tenantIdUtils_js_1.checkTenantId)(logger, options?.tenantId); + this.tenantId = options?.tenantId; + } + if (options?.subscription) { + (0, subscriptionUtils_js_1.checkSubscription)(logger, options?.subscription); + this.subscription = options?.subscription; + } + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + this.timeout = options?.processTimeoutInMs; + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + const scope = typeof scopes === "string" ? scopes : scopes[0]; + const claimsValue = options.claims; + if (claimsValue && claimsValue.trim()) { + const encodedClaims = btoa(claimsValue); + let loginCmd = `az login --claims-challenge ${encodedClaims} --scope ${scope}`; + const tenantIdFromOptions = options.tenantId; + if (tenantIdFromOptions) { + loginCmd += ` --tenant ${tenantIdFromOptions}`; + } + const error = new errors_js_1.CredentialUnavailableError(`${exports2.azureCliPublicErrorMessages.claim} ${loginCmd}`); + logger.getToken.info((0, logging_js_1.formatError)(scope, error)); + throw error; + } + const tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, options, this.additionallyAllowedTenantIds); + if (tenantId) { + (0, tenantIdUtils_js_1.checkTenantId)(logger, tenantId); + } + if (this.subscription) { + (0, subscriptionUtils_js_1.checkSubscription)(logger, this.subscription); + } + logger.getToken.info(`Using the scope ${scope}`); + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => { + try { + (0, scopeUtils_js_1.ensureValidScopeForDevTimeCreds)(scope, logger); + const resource = (0, scopeUtils_js_1.getScopeResource)(scope); + const obj = await exports2.cliCredentialInternals.getAzureCliAccessToken(resource, tenantId, this.subscription, this.timeout); + const specificScope = obj.stderr?.match("(.*)az login --scope(.*)"); + const isLoginError = obj.stderr?.match("(.*)az login(.*)") && !specificScope; + const isNotInstallError = obj.stderr?.match("az:(.*)not found") || obj.stderr?.startsWith("'az' is not recognized"); + if (isNotInstallError) { + const error = new errors_js_1.CredentialUnavailableError(exports2.azureCliPublicErrorMessages.notInstalled); + logger.getToken.info((0, logging_js_1.formatError)(scopes, error)); + throw error; + } + if (isLoginError) { + const error = new errors_js_1.CredentialUnavailableError(exports2.azureCliPublicErrorMessages.login); + logger.getToken.info((0, logging_js_1.formatError)(scopes, error)); + throw error; + } + try { + const responseData = obj.stdout; + const response = this.parseRawResponse(responseData); + logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return response; + } catch (e) { + if (obj.stderr) { + throw new errors_js_1.CredentialUnavailableError(obj.stderr); + } + throw e; + } + } catch (err) { + const error = err.name === "CredentialUnavailableError" ? err : new errors_js_1.CredentialUnavailableError(err.message || exports2.azureCliPublicErrorMessages.unknown); + logger.getToken.info((0, logging_js_1.formatError)(scopes, error)); + throw error; + } + }); + } + /** + * Parses the raw JSON response from the Azure CLI into a usable AccessToken object + * + * @param rawResponse - The raw JSON response from the Azure CLI + * @returns An access token with the expiry time parsed from the raw response + * + * The expiryTime of the credential's access token, in milliseconds, is calculated as follows: + * + * When available, expires_on (introduced in Azure CLI v2.54.0) will be preferred. Otherwise falls back to expiresOn. + */ + parseRawResponse(rawResponse) { + const response = JSON.parse(rawResponse); + const token = response.accessToken; + let expiresOnTimestamp = Number.parseInt(response.expires_on, 10) * 1e3; + if (!isNaN(expiresOnTimestamp)) { + logger.getToken.info("expires_on is available and is valid, using it"); + return { + token, + expiresOnTimestamp, + tokenType: "Bearer" + }; + } + expiresOnTimestamp = new Date(response.expiresOn).getTime(); + if (isNaN(expiresOnTimestamp)) { + throw new errors_js_1.CredentialUnavailableError(`${exports2.azureCliPublicErrorMessages.unexpectedResponse} "${response.expiresOn}"`); + } + return { + token, + expiresOnTimestamp, + tokenType: "Bearer" + }; + } + }; + exports2.AzureCliCredential = AzureCliCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/util/processUtils.js +var require_processUtils = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/util/processUtils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.processUtils = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var node_child_process_1 = tslib_1.__importDefault(require("node:child_process")); + exports2.processUtils = { + /** + * Promisifying childProcess.execFile + * @internal + */ + execFile(file, params, options) { + return new Promise((resolve, reject) => { + node_child_process_1.default.execFile(file, params, options, (error, stdout, stderr) => { + if (Buffer.isBuffer(stdout)) { + stdout = stdout.toString("utf8"); + } + if (Buffer.isBuffer(stderr)) { + stderr = stderr.toString("utf8"); + } + if (stderr || error) { + reject(stderr ? new Error(stderr) : error); + } else { + resolve(stdout); + } + }); + }); + } + }; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/azurePowerShellCredential.js +var require_azurePowerShellCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/azurePowerShellCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AzurePowerShellCredential = exports2.commandStack = exports2.powerShellPublicErrorMessages = exports2.powerShellErrors = void 0; + exports2.formatCommand = formatCommand; + exports2.parseJsonToken = parseJsonToken; + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var logging_js_1 = require_logging(); + var scopeUtils_js_1 = require_scopeUtils(); + var errors_js_1 = require_errors2(); + var processUtils_js_1 = require_processUtils(); + var tracing_js_1 = require_tracing(); + var logger = (0, logging_js_1.credentialLogger)("AzurePowerShellCredential"); + var isWindows = process.platform === "win32"; + function formatCommand(commandName) { + if (isWindows) { + return `${commandName}.exe`; + } else { + return commandName; + } + } + async function runCommands(commands, timeout) { + const results = []; + for (const command of commands) { + const [file, ...parameters] = command; + const result = await processUtils_js_1.processUtils.execFile(file, parameters, { + encoding: "utf8", + timeout + }); + results.push(result); + } + return results; + } + exports2.powerShellErrors = { + login: "Run Connect-AzAccount to login", + installed: "The specified module 'Az.Accounts' with version '2.2.0' was not loaded because no valid module file was found in any module directory" + }; + exports2.powerShellPublicErrorMessages = { + login: "Please run 'Connect-AzAccount' from PowerShell to authenticate before using this credential.", + installed: `The 'Az.Account' module >= 2.2.0 is not installed. Install the Azure Az PowerShell module with: "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force".`, + claim: "This credential doesn't support claims challenges. To authenticate with the required claims, please run the following command:", + troubleshoot: `To troubleshoot, visit https://aka.ms/azsdk/js/identity/powershellcredential/troubleshoot.` + }; + var isLoginError = (err) => err.message.match(`(.*)${exports2.powerShellErrors.login}(.*)`); + var isNotInstalledError = (err) => err.message.match(exports2.powerShellErrors.installed); + exports2.commandStack = [formatCommand("pwsh")]; + if (isWindows) { + exports2.commandStack.push(formatCommand("powershell")); + } + var AzurePowerShellCredential = class { + tenantId; + additionallyAllowedTenantIds; + timeout; + /** + * Creates an instance of the {@link AzurePowerShellCredential}. + * + * To use this credential: + * - Install the Azure Az PowerShell module with: + * `Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force`. + * - You have already logged in to Azure PowerShell using the command + * `Connect-AzAccount` from the command line. + * + * @param options - Options, to optionally allow multi-tenant requests. + */ + constructor(options) { + if (options?.tenantId) { + (0, tenantIdUtils_js_1.checkTenantId)(logger, options?.tenantId); + this.tenantId = options?.tenantId; + } + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + this.timeout = options?.processTimeoutInMs; + } + /** + * Gets the access token from Azure PowerShell + * @param resource - The resource to use when getting the token + */ + async getAzurePowerShellAccessToken(resource, tenantId, timeout) { + for (const powerShellCommand of [...exports2.commandStack]) { + try { + await runCommands([[powerShellCommand, "/?"]], timeout); + } catch (e) { + exports2.commandStack.shift(); + continue; + } + const results = await runCommands([ + [ + powerShellCommand, + "-NoProfile", + "-NonInteractive", + "-Command", + ` + $tenantId = "${tenantId ?? ""}" + $m = Import-Module Az.Accounts -MinimumVersion 2.2.0 -PassThru + $useSecureString = $m.Version -ge [version]'2.17.0' -and $m.Version -lt [version]'5.0.0' + + $params = @{ + ResourceUrl = "${resource}" + } + + if ($tenantId.Length -gt 0) { + $params["TenantId"] = $tenantId + } + + if ($useSecureString) { + $params["AsSecureString"] = $true + } + + $token = Get-AzAccessToken @params + + $result = New-Object -TypeName PSObject + $result | Add-Member -MemberType NoteProperty -Name ExpiresOn -Value $token.ExpiresOn + + if ($token.Token -is [System.Security.SecureString]) { + if ($PSVersionTable.PSVersion.Major -lt 7) { + $ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($token.Token) + try { + $result | Add-Member -MemberType NoteProperty -Name Token -Value ([System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)) + } + finally { + [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr) + } + } + else { + $result | Add-Member -MemberType NoteProperty -Name Token -Value ($token.Token | ConvertFrom-SecureString -AsPlainText) + } + } + else { + $result | Add-Member -MemberType NoteProperty -Name Token -Value $token.Token + } + + Write-Output (ConvertTo-Json $result) + ` + ] + ]); + const result = results[0]; + return parseJsonToken(result); + } + throw new Error(`Unable to execute PowerShell. Ensure that it is installed in your system`); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If the authentication cannot be performed through PowerShell, a {@link CredentialUnavailableError} will be thrown. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => { + const scope = typeof scopes === "string" ? scopes : scopes[0]; + const claimsValue = options.claims; + if (claimsValue && claimsValue.trim()) { + const encodedClaims = btoa(claimsValue); + let loginCmd = `Connect-AzAccount -ClaimsChallenge ${encodedClaims}`; + const tenantIdFromOptions = options.tenantId; + if (tenantIdFromOptions) { + loginCmd += ` -Tenant ${tenantIdFromOptions}`; + } + const error = new errors_js_1.CredentialUnavailableError(`${exports2.powerShellPublicErrorMessages.claim} ${loginCmd}`); + logger.getToken.info((0, logging_js_1.formatError)(scope, error)); + throw error; + } + const tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, options, this.additionallyAllowedTenantIds); + if (tenantId) { + (0, tenantIdUtils_js_1.checkTenantId)(logger, tenantId); + } + try { + (0, scopeUtils_js_1.ensureValidScopeForDevTimeCreds)(scope, logger); + logger.getToken.info(`Using the scope ${scope}`); + const resource = (0, scopeUtils_js_1.getScopeResource)(scope); + const response = await this.getAzurePowerShellAccessToken(resource, tenantId, this.timeout); + logger.getToken.info((0, logging_js_1.formatSuccess)(scopes)); + return { + token: response.Token, + expiresOnTimestamp: new Date(response.ExpiresOn).getTime(), + tokenType: "Bearer" + }; + } catch (err) { + if (isNotInstalledError(err)) { + const error2 = new errors_js_1.CredentialUnavailableError(exports2.powerShellPublicErrorMessages.installed); + logger.getToken.info((0, logging_js_1.formatError)(scope, error2)); + throw error2; + } else if (isLoginError(err)) { + const error2 = new errors_js_1.CredentialUnavailableError(exports2.powerShellPublicErrorMessages.login); + logger.getToken.info((0, logging_js_1.formatError)(scope, error2)); + throw error2; + } + const error = new errors_js_1.CredentialUnavailableError(`${err}. ${exports2.powerShellPublicErrorMessages.troubleshoot}`); + logger.getToken.info((0, logging_js_1.formatError)(scope, error)); + throw error; + } + }); + } + }; + exports2.AzurePowerShellCredential = AzurePowerShellCredential; + async function parseJsonToken(result) { + const jsonRegex = /{[^{}]*}/g; + const matches = result.match(jsonRegex); + let resultWithoutToken = result; + if (matches) { + try { + for (const item of matches) { + try { + const jsonContent = JSON.parse(item); + if (jsonContent?.Token) { + resultWithoutToken = resultWithoutToken.replace(item, ""); + if (resultWithoutToken) { + logger.getToken.warning(resultWithoutToken); + } + return jsonContent; + } + } catch (e) { + continue; + } + } + } catch (e) { + throw new Error(`Unable to parse the output of PowerShell. Received output: ${result}`); + } + } + throw new Error(`No access token found in the output. Received output: ${result}`); + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/visualStudioCodeCredential.js +var require_visualStudioCodeCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/visualStudioCodeCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.VisualStudioCodeCredential = void 0; + var logging_js_1 = require_logging(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var errors_js_1 = require_errors2(); + var tenantIdUtils_js_2 = require_tenantIdUtils(); + var msalClient_js_1 = require_msalClient(); + var scopeUtils_js_1 = require_scopeUtils(); + var msalPlugins_js_1 = require_msalPlugins(); + var utils_js_1 = require_utils6(); + var promises_1 = require("node:fs/promises"); + var CommonTenantId = "common"; + var VSCodeClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; + var logger = (0, logging_js_1.credentialLogger)("VisualStudioCodeCredential"); + var unsupportedTenantIds = { + adfs: "The VisualStudioCodeCredential does not support authentication with ADFS tenants." + }; + function checkUnsupportedTenant(tenantId) { + const unsupportedTenantError = unsupportedTenantIds[tenantId]; + if (unsupportedTenantError) { + throw new errors_js_1.CredentialUnavailableError(unsupportedTenantError); + } + } + var VisualStudioCodeCredential = class { + tenantId; + additionallyAllowedTenantIds; + msalClient; + options; + /** + * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode. + * + * **Note**: `VisualStudioCodeCredential` is provided by a plugin package: + * `@azure/identity-vscode`. If this package is not installed, then authentication using + * `VisualStudioCodeCredential` will not be available. + * + * @param options - Options for configuring the client which makes the authentication request. + */ + constructor(options) { + this.options = options || {}; + if (options && options.tenantId) { + (0, tenantIdUtils_js_2.checkTenantId)(logger, options.tenantId); + this.tenantId = options.tenantId; + } else { + this.tenantId = CommonTenantId; + } + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + checkUnsupportedTenant(this.tenantId); + } + /** + * Runs preparations for any further getToken request: + * - Validates that the plugin is available. + * - Loads the authentication record from VSCode if available. + * - Creates the MSAL client with the loaded plugin and authentication record. + */ + async prepare(scopes) { + const tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, this.options, this.additionallyAllowedTenantIds, logger) || this.tenantId; + if (!(0, msalPlugins_js_1.hasVSCodePlugin)() || !msalPlugins_js_1.vsCodeAuthRecordPath) { + throw new errors_js_1.CredentialUnavailableError("Visual Studio Code Authentication is not available. Ensure you have have Azure Resources Extension installed in VS Code, signed into Azure via VS Code, installed the @azure/identity-vscode package, and properly configured the extension."); + } + const authenticationRecord = await this.loadAuthRecord(msalPlugins_js_1.vsCodeAuthRecordPath, scopes); + this.msalClient = (0, msalClient_js_1.createMsalClient)(VSCodeClientId, tenantId, { + ...this.options, + isVSCodeCredential: true, + brokerOptions: { + enabled: true, + parentWindowHandle: new Uint8Array(0), + useDefaultBrokerAccount: true + }, + authenticationRecord + }); + } + /** + * The promise of the single preparation that will be executed at the first getToken request for an instance of this class. + */ + preparePromise; + /** + * Runs preparations for any further getToken, but only once. + */ + prepareOnce(scopes) { + if (!this.preparePromise) { + this.preparePromise = this.prepare(scopes); + } + return this.preparePromise; + } + /** + * Returns the token found by searching VSCode's authentication cache or + * returns null if no token could be found. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * `TokenCredential` implementation might make. + */ + async getToken(scopes, options) { + const scopeArray = (0, scopeUtils_js_1.ensureScopes)(scopes); + await this.prepareOnce(scopeArray); + if (!this.msalClient) { + throw new errors_js_1.CredentialUnavailableError("Visual Studio Code Authentication failed to initialize. Ensure you have have Azure Resources Extension installed in VS Code, signed into Azure via VS Code, installed the @azure/identity-vscode package, and properly configured the extension."); + } + return this.msalClient.getTokenByInteractiveRequest(scopeArray, { + ...options, + disableAutomaticAuthentication: true + }); + } + /** + * Loads the authentication record from the specified path. + * @param authRecordPath - The path to the authentication record file. + * @param scopes - The list of scopes for which the token will have access. + * @returns The authentication record or undefined if loading fails. + */ + async loadAuthRecord(authRecordPath, scopes) { + try { + const authRecordContent = await (0, promises_1.readFile)(authRecordPath, { encoding: "utf8" }); + return (0, utils_js_1.deserializeAuthenticationRecord)(authRecordContent); + } catch (error) { + logger.getToken.info((0, logging_js_1.formatError)(scopes, error)); + throw new errors_js_1.CredentialUnavailableError("Cannot load authentication record in Visual Studio Code. Ensure you have have Azure Resources Extension installed in VS Code, signed into Azure via VS Code, installed the @azure/identity-vscode package, and properly configured the extension."); + } + } + }; + exports2.VisualStudioCodeCredential = VisualStudioCodeCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/brokerCredential.js +var require_brokerCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/brokerCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BrokerCredential = void 0; + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var logging_js_1 = require_logging(); + var scopeUtils_js_1 = require_scopeUtils(); + var tracing_js_1 = require_tracing(); + var msalClient_js_1 = require_msalClient(); + var constants_js_1 = require_constants4(); + var errors_js_1 = require_errors2(); + var logger = (0, logging_js_1.credentialLogger)("BrokerCredential"); + var BrokerCredential = class { + brokerMsalClient; + brokerTenantId; + brokerAdditionallyAllowedTenantIds; + /** + * Creates an instance of BrokerCredential with the required broker options. + * + * This credential uses WAM (Web Account Manager) for authentication, which provides + * better security and user experience on Windows platforms. + * + * @param options - Options for configuring the broker credential, including required broker options. + */ + constructor(options) { + this.brokerTenantId = (0, tenantIdUtils_js_1.resolveTenantId)(logger, options.tenantId); + this.brokerAdditionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + const msalClientOptions = { + ...options, + tokenCredentialOptions: options, + logger, + brokerOptions: { + enabled: true, + parentWindowHandle: new Uint8Array(0), + useDefaultBrokerAccount: true + } + }; + this.brokerMsalClient = (0, msalClient_js_1.createMsalClient)(constants_js_1.DeveloperSignOnClientId, this.brokerTenantId, msalClientOptions); + } + /** + * Authenticates with Microsoft Entra ID using WAM broker and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * This method extends the base getToken method to support silentAuthenticationOnly option + * when using broker authentication. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure the token request, including silentAuthenticationOnly option. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => { + newOptions.tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.brokerTenantId, newOptions, this.brokerAdditionallyAllowedTenantIds, logger); + const arrayScopes = (0, scopeUtils_js_1.ensureScopes)(scopes); + try { + return this.brokerMsalClient.getBrokeredToken(arrayScopes, true, { + ...newOptions, + disableAutomaticAuthentication: true + }); + } catch (e) { + logger.getToken.info((0, logging_js_1.formatError)(arrayScopes, e)); + throw new errors_js_1.CredentialUnavailableError("Failed to acquire token using broker authentication", { cause: e }); + } + }); + } + }; + exports2.BrokerCredential = BrokerCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/defaultAzureCredentialFunctions.js +var require_defaultAzureCredentialFunctions = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/defaultAzureCredentialFunctions.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createDefaultBrokerCredential = createDefaultBrokerCredential; + exports2.createDefaultVisualStudioCodeCredential = createDefaultVisualStudioCodeCredential; + exports2.createDefaultManagedIdentityCredential = createDefaultManagedIdentityCredential; + exports2.createDefaultWorkloadIdentityCredential = createDefaultWorkloadIdentityCredential; + exports2.createDefaultAzureDeveloperCliCredential = createDefaultAzureDeveloperCliCredential; + exports2.createDefaultAzureCliCredential = createDefaultAzureCliCredential; + exports2.createDefaultAzurePowershellCredential = createDefaultAzurePowershellCredential; + exports2.createDefaultEnvironmentCredential = createDefaultEnvironmentCredential; + var environmentCredential_js_1 = require_environmentCredential(); + var index_js_1 = require_managedIdentityCredential(); + var workloadIdentityCredential_js_1 = require_workloadIdentityCredential(); + var azureDeveloperCliCredential_js_1 = require_azureDeveloperCliCredential(); + var azureCliCredential_js_1 = require_azureCliCredential(); + var azurePowerShellCredential_js_1 = require_azurePowerShellCredential(); + var visualStudioCodeCredential_js_1 = require_visualStudioCodeCredential(); + var brokerCredential_js_1 = require_brokerCredential(); + function createDefaultBrokerCredential(options = {}) { + return new brokerCredential_js_1.BrokerCredential(options); + } + function createDefaultVisualStudioCodeCredential(options = {}) { + return new visualStudioCodeCredential_js_1.VisualStudioCodeCredential(options); + } + function createDefaultManagedIdentityCredential(options = {}) { + options.retryOptions ??= { + maxRetries: 5, + retryDelayInMs: 800 + }; + options.sendProbeRequest ??= true; + const managedIdentityClientId = options?.managedIdentityClientId ?? process.env.AZURE_CLIENT_ID; + const workloadIdentityClientId = options?.workloadIdentityClientId ?? managedIdentityClientId; + const managedResourceId = options?.managedIdentityResourceId; + const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE; + const tenantId = options?.tenantId ?? process.env.AZURE_TENANT_ID; + if (managedResourceId) { + const managedIdentityResourceIdOptions = { + ...options, + resourceId: managedResourceId + }; + return new index_js_1.ManagedIdentityCredential(managedIdentityResourceIdOptions); + } + if (workloadFile && workloadIdentityClientId) { + const workloadIdentityCredentialOptions = { + ...options, + tenantId + }; + return new index_js_1.ManagedIdentityCredential(workloadIdentityClientId, workloadIdentityCredentialOptions); + } + if (managedIdentityClientId) { + const managedIdentityClientOptions = { + ...options, + clientId: managedIdentityClientId + }; + return new index_js_1.ManagedIdentityCredential(managedIdentityClientOptions); + } + return new index_js_1.ManagedIdentityCredential(options); + } + function createDefaultWorkloadIdentityCredential(options) { + const managedIdentityClientId = options?.managedIdentityClientId ?? process.env.AZURE_CLIENT_ID; + const workloadIdentityClientId = options?.workloadIdentityClientId ?? managedIdentityClientId; + const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE; + const tenantId = options?.tenantId ?? process.env.AZURE_TENANT_ID; + if (workloadFile && workloadIdentityClientId) { + const workloadIdentityCredentialOptions = { + ...options, + tenantId, + clientId: workloadIdentityClientId, + tokenFilePath: workloadFile + }; + return new workloadIdentityCredential_js_1.WorkloadIdentityCredential(workloadIdentityCredentialOptions); + } + if (tenantId) { + const workloadIdentityClientTenantOptions = { + ...options, + tenantId + }; + return new workloadIdentityCredential_js_1.WorkloadIdentityCredential(workloadIdentityClientTenantOptions); + } + return new workloadIdentityCredential_js_1.WorkloadIdentityCredential(options); + } + function createDefaultAzureDeveloperCliCredential(options = {}) { + return new azureDeveloperCliCredential_js_1.AzureDeveloperCliCredential(options); + } + function createDefaultAzureCliCredential(options = {}) { + return new azureCliCredential_js_1.AzureCliCredential(options); + } + function createDefaultAzurePowershellCredential(options = {}) { + return new azurePowerShellCredential_js_1.AzurePowerShellCredential(options); + } + function createDefaultEnvironmentCredential(options = {}) { + return new environmentCredential_js_1.EnvironmentCredential(options); + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/defaultAzureCredential.js +var require_defaultAzureCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/defaultAzureCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DefaultAzureCredential = exports2.UnavailableDefaultCredential = void 0; + var chainedTokenCredential_js_1 = require_chainedTokenCredential(); + var logging_js_1 = require_logging(); + var defaultAzureCredentialFunctions_js_1 = require_defaultAzureCredentialFunctions(); + var logger = (0, logging_js_1.credentialLogger)("DefaultAzureCredential"); + var UnavailableDefaultCredential = class { + credentialUnavailableErrorMessage; + credentialName; + constructor(credentialName, message) { + this.credentialName = credentialName; + this.credentialUnavailableErrorMessage = message; + } + getToken() { + logger.getToken.info(`Skipping ${this.credentialName}, reason: ${this.credentialUnavailableErrorMessage}`); + return Promise.resolve(null); + } + }; + exports2.UnavailableDefaultCredential = UnavailableDefaultCredential; + var DefaultAzureCredential = class extends chainedTokenCredential_js_1.ChainedTokenCredential { + constructor(options) { + validateRequiredEnvVars(options); + const azureTokenCredentials = process.env.AZURE_TOKEN_CREDENTIALS ? process.env.AZURE_TOKEN_CREDENTIALS.trim().toLowerCase() : void 0; + const devCredentialFunctions = [ + defaultAzureCredentialFunctions_js_1.createDefaultVisualStudioCodeCredential, + defaultAzureCredentialFunctions_js_1.createDefaultAzureCliCredential, + defaultAzureCredentialFunctions_js_1.createDefaultAzurePowershellCredential, + defaultAzureCredentialFunctions_js_1.createDefaultAzureDeveloperCliCredential, + defaultAzureCredentialFunctions_js_1.createDefaultBrokerCredential + ]; + const prodCredentialFunctions = [ + defaultAzureCredentialFunctions_js_1.createDefaultEnvironmentCredential, + defaultAzureCredentialFunctions_js_1.createDefaultWorkloadIdentityCredential, + defaultAzureCredentialFunctions_js_1.createDefaultManagedIdentityCredential + ]; + let credentialFunctions = []; + const validCredentialNames = "EnvironmentCredential, WorkloadIdentityCredential, ManagedIdentityCredential, VisualStudioCodeCredential, AzureCliCredential, AzurePowerShellCredential, AzureDeveloperCliCredential"; + if (azureTokenCredentials) { + switch (azureTokenCredentials) { + case "dev": + credentialFunctions = devCredentialFunctions; + break; + case "prod": + credentialFunctions = prodCredentialFunctions; + break; + case "environmentcredential": + credentialFunctions = [defaultAzureCredentialFunctions_js_1.createDefaultEnvironmentCredential]; + break; + case "workloadidentitycredential": + credentialFunctions = [defaultAzureCredentialFunctions_js_1.createDefaultWorkloadIdentityCredential]; + break; + case "managedidentitycredential": + credentialFunctions = [ + () => (0, defaultAzureCredentialFunctions_js_1.createDefaultManagedIdentityCredential)({ sendProbeRequest: false }) + ]; + break; + case "visualstudiocodecredential": + credentialFunctions = [defaultAzureCredentialFunctions_js_1.createDefaultVisualStudioCodeCredential]; + break; + case "azureclicredential": + credentialFunctions = [defaultAzureCredentialFunctions_js_1.createDefaultAzureCliCredential]; + break; + case "azurepowershellcredential": + credentialFunctions = [defaultAzureCredentialFunctions_js_1.createDefaultAzurePowershellCredential]; + break; + case "azuredeveloperclicredential": + credentialFunctions = [defaultAzureCredentialFunctions_js_1.createDefaultAzureDeveloperCliCredential]; + break; + default: { + const errorMessage = `Invalid value for AZURE_TOKEN_CREDENTIALS = ${process.env.AZURE_TOKEN_CREDENTIALS}. Valid values are 'prod' or 'dev' or any of these credentials - ${validCredentialNames}.`; + logger.warning(errorMessage); + throw new Error(errorMessage); + } + } + } else { + credentialFunctions = [...prodCredentialFunctions, ...devCredentialFunctions]; + } + const credentials = credentialFunctions.map((createCredentialFn) => { + try { + return createCredentialFn(options ?? {}); + } catch (err) { + logger.warning(`Skipped ${createCredentialFn.name} because of an error creating the credential: ${err}`); + return new UnavailableDefaultCredential(createCredentialFn.name, err.message); + } + }); + super(...credentials); + } + }; + exports2.DefaultAzureCredential = DefaultAzureCredential; + function validateRequiredEnvVars(options) { + if (options?.requiredEnvVars) { + const requiredVars = Array.isArray(options.requiredEnvVars) ? options.requiredEnvVars : [options.requiredEnvVars]; + const missing = requiredVars.filter((envVar) => !process.env[envVar]); + if (missing.length > 0) { + const errorMessage = `Required environment ${missing.length === 1 ? "variable" : "variables"} '${missing.join(", ")}' for DefaultAzureCredential ${missing.length === 1 ? "is" : "are"} not set or empty.`; + logger.warning(errorMessage); + throw new Error(errorMessage); + } + } + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/interactiveBrowserCredential.js +var require_interactiveBrowserCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/interactiveBrowserCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.InteractiveBrowserCredential = void 0; + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var logging_js_1 = require_logging(); + var scopeUtils_js_1 = require_scopeUtils(); + var tracing_js_1 = require_tracing(); + var msalClient_js_1 = require_msalClient(); + var constants_js_1 = require_constants4(); + var logger = (0, logging_js_1.credentialLogger)("InteractiveBrowserCredential"); + var InteractiveBrowserCredential = class { + tenantId; + additionallyAllowedTenantIds; + msalClient; + disableAutomaticAuthentication; + browserCustomizationOptions; + loginHint; + /** + * Creates an instance of InteractiveBrowserCredential with the details needed. + * + * This credential uses the [Authorization Code Flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow). + * On Node.js, it will open a browser window while it listens for a redirect response from the authentication service. + * On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started. + * + * For Node.js, if a `clientId` is provided, the Microsoft Entra application will need to be configured to have a "Mobile and desktop applications" redirect endpoint. + * Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://learn.microsoft.com/entra/identity-platform/scenario-desktop-app-registration#redirect-uris). + * + * @param options - Options for configuring the client which makes the authentication requests. + */ + constructor(options) { + this.tenantId = (0, tenantIdUtils_js_1.resolveTenantId)(logger, options.tenantId, options.clientId); + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + const msalClientOptions = { + ...options, + tokenCredentialOptions: options, + logger + }; + const ibcNodeOptions = options; + this.browserCustomizationOptions = ibcNodeOptions.browserCustomizationOptions; + this.loginHint = ibcNodeOptions.loginHint; + if (ibcNodeOptions?.brokerOptions?.enabled) { + if (!ibcNodeOptions?.brokerOptions?.parentWindowHandle) { + throw new Error("In order to do WAM authentication, `parentWindowHandle` under `brokerOptions` is a required parameter"); + } else { + msalClientOptions.brokerOptions = { + enabled: true, + parentWindowHandle: ibcNodeOptions.brokerOptions.parentWindowHandle, + legacyEnableMsaPassthrough: ibcNodeOptions.brokerOptions?.legacyEnableMsaPassthrough, + useDefaultBrokerAccount: ibcNodeOptions.brokerOptions?.useDefaultBrokerAccount + }; + } + } + this.msalClient = (0, msalClient_js_1.createMsalClient)(options.clientId ?? constants_js_1.DeveloperSignOnClientId, this.tenantId, msalClientOptions); + this.disableAutomaticAuthentication = options?.disableAutomaticAuthentication; + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * If the user provided the option `disableAutomaticAuthentication`, + * once the token can't be retrieved silently, + * this method won't attempt to request user interaction to retrieve the token. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => { + newOptions.tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger); + const arrayScopes = (0, scopeUtils_js_1.ensureScopes)(scopes); + return this.msalClient.getTokenByInteractiveRequest(arrayScopes, { + ...newOptions, + disableAutomaticAuthentication: this.disableAutomaticAuthentication, + browserCustomizationOptions: this.browserCustomizationOptions, + loginHint: this.loginHint + }); + }); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * If the token can't be retrieved silently, this method will always generate a challenge for the user. + * + * On Node.js, this credential has [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636) enabled by default. + * PKCE is a security feature that mitigates authentication code interception attacks. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async authenticate(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => { + const arrayScopes = (0, scopeUtils_js_1.ensureScopes)(scopes); + await this.msalClient.getTokenByInteractiveRequest(arrayScopes, { + ...newOptions, + disableAutomaticAuthentication: false, + // this method should always allow user interaction + browserCustomizationOptions: this.browserCustomizationOptions, + loginHint: this.loginHint + }); + return this.msalClient.getActiveAccount(); + }); + } + }; + exports2.InteractiveBrowserCredential = InteractiveBrowserCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/deviceCodeCredential.js +var require_deviceCodeCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/deviceCodeCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DeviceCodeCredential = void 0; + exports2.defaultDeviceCodePromptCallback = defaultDeviceCodePromptCallback; + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var logging_js_1 = require_logging(); + var scopeUtils_js_1 = require_scopeUtils(); + var tracing_js_1 = require_tracing(); + var msalClient_js_1 = require_msalClient(); + var constants_js_1 = require_constants4(); + var logger = (0, logging_js_1.credentialLogger)("DeviceCodeCredential"); + function defaultDeviceCodePromptCallback(deviceCodeInfo) { + console.log(deviceCodeInfo.message); + } + var DeviceCodeCredential = class { + tenantId; + additionallyAllowedTenantIds; + disableAutomaticAuthentication; + msalClient; + userPromptCallback; + /** + * Creates an instance of DeviceCodeCredential with the details needed + * to initiate the device code authorization flow with Microsoft Entra ID. + * + * A message will be logged, giving users a code that they can use to authenticate once they go to https://microsoft.com/devicelogin + * + * Developers can configure how this message is shown by passing a custom `userPromptCallback`: + * + * ```ts snippet:device_code_credential_example + * import { DeviceCodeCredential } from "@azure/identity"; + * + * const credential = new DeviceCodeCredential({ + * tenantId: process.env.AZURE_TENANT_ID, + * clientId: process.env.AZURE_CLIENT_ID, + * userPromptCallback: (info) => { + * console.log("CUSTOMIZED PROMPT CALLBACK", info.message); + * }, + * }); + * ``` + * + * @param options - Options for configuring the client which makes the authentication requests. + */ + constructor(options) { + this.tenantId = options?.tenantId; + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + const clientId = options?.clientId ?? constants_js_1.DeveloperSignOnClientId; + const tenantId = (0, tenantIdUtils_js_1.resolveTenantId)(logger, options?.tenantId, clientId); + this.userPromptCallback = options?.userPromptCallback ?? defaultDeviceCodePromptCallback; + this.msalClient = (0, msalClient_js_1.createMsalClient)(clientId, tenantId, { + ...options, + logger, + tokenCredentialOptions: options || {} + }); + this.disableAutomaticAuthentication = options?.disableAutomaticAuthentication; + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * If the user provided the option `disableAutomaticAuthentication`, + * once the token can't be retrieved silently, + * this method won't attempt to request user interaction to retrieve the token. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => { + newOptions.tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger); + const arrayScopes = (0, scopeUtils_js_1.ensureScopes)(scopes); + return this.msalClient.getTokenByDeviceCode(arrayScopes, this.userPromptCallback, { + ...newOptions, + disableAutomaticAuthentication: this.disableAutomaticAuthentication + }); + }); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * If the token can't be retrieved silently, this method will always generate a challenge for the user. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async authenticate(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => { + const arrayScopes = Array.isArray(scopes) ? scopes : [scopes]; + await this.msalClient.getTokenByDeviceCode(arrayScopes, this.userPromptCallback, { + ...newOptions, + disableAutomaticAuthentication: false + // this method should always allow user interaction + }); + return this.msalClient.getActiveAccount(); + }); + } + }; + exports2.DeviceCodeCredential = DeviceCodeCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/azurePipelinesCredential.js +var require_azurePipelinesCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/azurePipelinesCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AzurePipelinesCredential = void 0; + exports2.handleOidcResponse = handleOidcResponse; + var errors_js_1 = require_errors2(); + var core_rest_pipeline_1 = require_commonjs6(); + var clientAssertionCredential_js_1 = require_clientAssertionCredential(); + var identityClient_js_1 = require_identityClient(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var logging_js_1 = require_logging(); + var credentialName = "AzurePipelinesCredential"; + var logger = (0, logging_js_1.credentialLogger)(credentialName); + var OIDC_API_VERSION = "7.1"; + var AzurePipelinesCredential = class { + clientAssertionCredential; + identityClient; + /** + * AzurePipelinesCredential supports Federated Identity on Azure Pipelines through Service Connections. + * @param tenantId - tenantId associated with the service connection + * @param clientId - clientId associated with the service connection + * @param serviceConnectionId - Unique ID for the service connection, as found in the querystring's resourceId key + * @param systemAccessToken - The pipeline's System.AccessToken value. + * @param options - The identity client options to use for authentication. + */ + constructor(tenantId, clientId, serviceConnectionId, systemAccessToken, options = {}) { + if (!clientId) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. clientId is a required parameter.`); + } + if (!tenantId) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. tenantId is a required parameter.`); + } + if (!serviceConnectionId) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. serviceConnectionId is a required parameter.`); + } + if (!systemAccessToken) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. systemAccessToken is a required parameter.`); + } + options.loggingOptions = { + ...options?.loggingOptions, + additionalAllowedHeaderNames: [ + ...options.loggingOptions?.additionalAllowedHeaderNames ?? [], + "x-vss-e2eid", + "x-msedge-ref" + ] + }; + this.identityClient = new identityClient_js_1.IdentityClient(options); + (0, tenantIdUtils_js_1.checkTenantId)(logger, tenantId); + logger.info(`Invoking AzurePipelinesCredential with tenant ID: ${tenantId}, client ID: ${clientId}, and service connection ID: ${serviceConnectionId}`); + if (!process.env.SYSTEM_OIDCREQUESTURI) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: is unavailable. Ensure that you're running this task in an Azure Pipeline, so that following missing system variable(s) can be defined- "SYSTEM_OIDCREQUESTURI"`); + } + const oidcRequestUrl = `${process.env.SYSTEM_OIDCREQUESTURI}?api-version=${OIDC_API_VERSION}&serviceConnectionId=${serviceConnectionId}`; + logger.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, client ID: ${clientId} and service connection ID: ${serviceConnectionId}`); + this.clientAssertionCredential = new clientAssertionCredential_js_1.ClientAssertionCredential(tenantId, clientId, this.requestOidcToken.bind(this, oidcRequestUrl, systemAccessToken), options); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} or {@link AuthenticationError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options) { + if (!this.clientAssertionCredential) { + const errorMessage = `${credentialName}: is unavailable. To use Federation Identity in Azure Pipelines, the following parameters are required - + tenantId, + clientId, + serviceConnectionId, + systemAccessToken, + "SYSTEM_OIDCREQUESTURI". + See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`; + logger.error(errorMessage); + throw new errors_js_1.CredentialUnavailableError(errorMessage); + } + logger.info("Invoking getToken() of Client Assertion Credential"); + return this.clientAssertionCredential.getToken(scopes, options); + } + /** + * + * @param oidcRequestUrl - oidc request url + * @param systemAccessToken - system access token + * @returns OIDC token from Azure Pipelines + */ + async requestOidcToken(oidcRequestUrl, systemAccessToken) { + logger.info("Requesting OIDC token from Azure Pipelines..."); + logger.info(oidcRequestUrl); + const request = (0, core_rest_pipeline_1.createPipelineRequest)({ + url: oidcRequestUrl, + method: "POST", + headers: (0, core_rest_pipeline_1.createHttpHeaders)({ + "Content-Type": "application/json", + Authorization: `Bearer ${systemAccessToken}`, + // Prevents the service from responding with a redirect HTTP status code (useful for automation). + "X-TFS-FedAuthRedirect": "Suppress" + }) + }); + const response = await this.identityClient.sendRequest(request); + return handleOidcResponse(response); + } + }; + exports2.AzurePipelinesCredential = AzurePipelinesCredential; + function handleOidcResponse(response) { + const text = response.bodyAsText; + if (!text) { + logger.error(`${credentialName}: Authentication Failed. Received null token from OIDC request. Response status- ${response.status}. Complete response - ${JSON.stringify(response)}`); + throw new errors_js_1.AuthenticationError(response.status, { + error: `${credentialName}: Authentication Failed. Received null token from OIDC request.`, + error_description: `${JSON.stringify(response)}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot` + }); + } + try { + const result = JSON.parse(text); + if (result?.oidcToken) { + return result.oidcToken; + } else { + const errorMessage = `${credentialName}: Authentication Failed. oidcToken field not detected in the response.`; + let errorDescription = ``; + if (response.status !== 200) { + errorDescription = `Response body = ${text}. Response Headers ["x-vss-e2eid"] = ${response.headers.get("x-vss-e2eid")} and ["x-msedge-ref"] = ${response.headers.get("x-msedge-ref")}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`; + } + logger.error(errorMessage); + logger.error(errorDescription); + throw new errors_js_1.AuthenticationError(response.status, { + error: errorMessage, + error_description: errorDescription + }); + } + } catch (e) { + const errorDetails = `${credentialName}: Authentication Failed. oidcToken field not detected in the response.`; + logger.error(`Response from service = ${text}, Response Headers ["x-vss-e2eid"] = ${response.headers.get("x-vss-e2eid")} + and ["x-msedge-ref"] = ${response.headers.get("x-msedge-ref")}, error message = ${e.message}`); + logger.error(errorDetails); + throw new errors_js_1.AuthenticationError(response.status, { + error: errorDetails, + error_description: `Response = ${text}. Response headers ["x-vss-e2eid"] = ${response.headers.get("x-vss-e2eid")} and ["x-msedge-ref"] = ${response.headers.get("x-msedge-ref")}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot` + }); + } + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/authorizationCodeCredential.js +var require_authorizationCodeCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/authorizationCodeCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AuthorizationCodeCredential = void 0; + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var tenantIdUtils_js_2 = require_tenantIdUtils(); + var logging_js_1 = require_logging(); + var scopeUtils_js_1 = require_scopeUtils(); + var tracing_js_1 = require_tracing(); + var msalClient_js_1 = require_msalClient(); + var logger = (0, logging_js_1.credentialLogger)("AuthorizationCodeCredential"); + var AuthorizationCodeCredential = class { + msalClient; + disableAutomaticAuthentication; + authorizationCode; + redirectUri; + tenantId; + additionallyAllowedTenantIds; + clientSecret; + /** + * @hidden + * @internal + */ + constructor(tenantId, clientId, clientSecretOrAuthorizationCode, authorizationCodeOrRedirectUri, redirectUriOrOptions, options) { + (0, tenantIdUtils_js_2.checkTenantId)(logger, tenantId); + this.clientSecret = clientSecretOrAuthorizationCode; + if (typeof redirectUriOrOptions === "string") { + this.authorizationCode = authorizationCodeOrRedirectUri; + this.redirectUri = redirectUriOrOptions; + } else { + this.authorizationCode = clientSecretOrAuthorizationCode; + this.redirectUri = authorizationCodeOrRedirectUri; + this.clientSecret = void 0; + options = redirectUriOrOptions; + } + this.tenantId = tenantId; + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(options?.additionallyAllowedTenants); + this.msalClient = (0, msalClient_js_1.createMsalClient)(clientId, tenantId, { + ...options, + logger, + tokenCredentialOptions: options ?? {} + }); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => { + const tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, newOptions, this.additionallyAllowedTenantIds); + newOptions.tenantId = tenantId; + const arrayScopes = (0, scopeUtils_js_1.ensureScopes)(scopes); + return this.msalClient.getTokenByAuthorizationCode(arrayScopes, this.redirectUri, this.authorizationCode, this.clientSecret, { + ...newOptions, + disableAutomaticAuthentication: this.disableAutomaticAuthentication + }); + }); + } + }; + exports2.AuthorizationCodeCredential = AuthorizationCodeCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/credentials/onBehalfOfCredential.js +var require_onBehalfOfCredential = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/credentials/onBehalfOfCredential.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.OnBehalfOfCredential = void 0; + var msalClient_js_1 = require_msalClient(); + var logging_js_1 = require_logging(); + var tenantIdUtils_js_1 = require_tenantIdUtils(); + var errors_js_1 = require_errors2(); + var node_crypto_1 = require("node:crypto"); + var scopeUtils_js_1 = require_scopeUtils(); + var promises_1 = require("node:fs/promises"); + var tracing_js_1 = require_tracing(); + var credentialName = "OnBehalfOfCredential"; + var logger = (0, logging_js_1.credentialLogger)(credentialName); + var OnBehalfOfCredential = class { + tenantId; + additionallyAllowedTenantIds; + msalClient; + sendCertificateChain; + certificatePath; + clientSecret; + userAssertionToken; + clientAssertion; + constructor(options) { + const { clientSecret } = options; + const { certificatePath, sendCertificateChain } = options; + const { getAssertion } = options; + const { tenantId, clientId, userAssertionToken, additionallyAllowedTenants: additionallyAllowedTenantIds } = options; + if (!tenantId) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: tenantId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`); + } + if (!clientId) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: clientId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`); + } + if (!clientSecret && !certificatePath && !getAssertion) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: You must provide one of clientSecret, certificatePath, or a getAssertion callback but none were provided. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`); + } + if (!userAssertionToken) { + throw new errors_js_1.CredentialUnavailableError(`${credentialName}: userAssertionToken is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`); + } + this.certificatePath = certificatePath; + this.clientSecret = clientSecret; + this.userAssertionToken = userAssertionToken; + this.sendCertificateChain = sendCertificateChain; + this.clientAssertion = getAssertion; + this.tenantId = tenantId; + this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)(additionallyAllowedTenantIds); + this.msalClient = (0, msalClient_js_1.createMsalClient)(clientId, this.tenantId, { + ...options, + logger, + tokenCredentialOptions: options + }); + } + /** + * Authenticates with Microsoft Entra ID and returns an access token if successful. + * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure the underlying network requests. + */ + async getToken(scopes, options = {}) { + return tracing_js_1.tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => { + newOptions.tenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger); + const arrayScopes = (0, scopeUtils_js_1.ensureScopes)(scopes); + if (this.certificatePath) { + const clientCertificate = await this.buildClientCertificate(this.certificatePath); + return this.msalClient.getTokenOnBehalfOf(arrayScopes, this.userAssertionToken, clientCertificate, newOptions); + } else if (this.clientSecret) { + return this.msalClient.getTokenOnBehalfOf(arrayScopes, this.userAssertionToken, this.clientSecret, options); + } else if (this.clientAssertion) { + return this.msalClient.getTokenOnBehalfOf(arrayScopes, this.userAssertionToken, this.clientAssertion, options); + } else { + throw new Error("Expected either clientSecret or certificatePath or clientAssertion to be defined."); + } + }); + } + async buildClientCertificate(certificatePath) { + try { + const parts = await this.parseCertificate({ certificatePath }, this.sendCertificateChain); + return { + thumbprint: parts.thumbprint, + thumbprintSha256: parts.thumbprintSha256, + privateKey: parts.certificateContents, + x5c: parts.x5c + }; + } catch (error) { + logger.info((0, logging_js_1.formatError)("", error)); + throw error; + } + } + async parseCertificate(configuration, sendCertificateChain) { + const certificatePath = configuration.certificatePath; + const certificateContents = await (0, promises_1.readFile)(certificatePath, "utf8"); + const x5c = sendCertificateChain ? certificateContents : void 0; + const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\n\r?|\r\n?)([A-Za-z0-9+/\n\r]+=*)(\n\r?|\r\n?)(-+END CERTIFICATE-+)/g; + const publicKeys = []; + let match; + do { + match = certificatePattern.exec(certificateContents); + if (match) { + publicKeys.push(match[3]); + } + } while (match); + if (publicKeys.length === 0) { + throw new Error("The file at the specified path does not contain a PEM-encoded certificate."); + } + const thumbprint = (0, node_crypto_1.createHash)("sha1").update(Buffer.from(publicKeys[0], "base64")).digest("hex").toUpperCase(); + const thumbprintSha256 = (0, node_crypto_1.createHash)("sha256").update(Buffer.from(publicKeys[0], "base64")).digest("hex").toUpperCase(); + return { + certificateContents, + thumbprintSha256, + thumbprint, + x5c + }; + } + }; + exports2.OnBehalfOfCredential = OnBehalfOfCredential; + } +}); + +// node_modules/@azure/identity/dist/commonjs/tokenProvider.js +var require_tokenProvider = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/tokenProvider.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getBearerTokenProvider = getBearerTokenProvider; + var core_rest_pipeline_1 = require_commonjs6(); + function getBearerTokenProvider(credential, scopes, options) { + const { abortSignal, tracingOptions } = options || {}; + const pipeline = (0, core_rest_pipeline_1.createEmptyPipeline)(); + pipeline.addPolicy((0, core_rest_pipeline_1.bearerTokenAuthenticationPolicy)({ credential, scopes })); + async function getRefreshedToken() { + const res = await pipeline.sendRequest({ + sendRequest: (request) => Promise.resolve({ + request, + status: 200, + headers: request.headers + }) + }, (0, core_rest_pipeline_1.createPipelineRequest)({ + url: "https://example.com", + abortSignal, + tracingOptions + })); + const accessToken = res.headers.get("authorization")?.split(" ")[1]; + if (!accessToken) { + throw new Error("Failed to get access token"); + } + return accessToken; + } + return getRefreshedToken; + } + } +}); + +// node_modules/@azure/identity/dist/commonjs/index.js +var require_commonjs10 = __commonJS({ + "node_modules/@azure/identity/dist/commonjs/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getBearerTokenProvider = exports2.AzureAuthorityHosts = exports2.logger = exports2.WorkloadIdentityCredential = exports2.OnBehalfOfCredential = exports2.VisualStudioCodeCredential = exports2.UsernamePasswordCredential = exports2.AzurePowerShellCredential = exports2.AuthorizationCodeCredential = exports2.AzurePipelinesCredential = exports2.DeviceCodeCredential = exports2.ManagedIdentityCredential = exports2.InteractiveBrowserCredential = exports2.AzureDeveloperCliCredential = exports2.AzureCliCredential = exports2.ClientAssertionCredential = exports2.ClientCertificateCredential = exports2.EnvironmentCredential = exports2.DefaultAzureCredential = exports2.ClientSecretCredential = exports2.ChainedTokenCredential = exports2.deserializeAuthenticationRecord = exports2.serializeAuthenticationRecord = exports2.AuthenticationRequiredError = exports2.CredentialUnavailableErrorName = exports2.CredentialUnavailableError = exports2.AggregateAuthenticationErrorName = exports2.AuthenticationErrorName = exports2.AggregateAuthenticationError = exports2.AuthenticationError = void 0; + exports2.getDefaultAzureCredential = getDefaultAzureCredential; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + tslib_1.__exportStar(require_consumer(), exports2); + var defaultAzureCredential_js_1 = require_defaultAzureCredential(); + var errors_js_1 = require_errors2(); + Object.defineProperty(exports2, "AuthenticationError", { enumerable: true, get: function() { + return errors_js_1.AuthenticationError; + } }); + Object.defineProperty(exports2, "AggregateAuthenticationError", { enumerable: true, get: function() { + return errors_js_1.AggregateAuthenticationError; + } }); + Object.defineProperty(exports2, "AuthenticationErrorName", { enumerable: true, get: function() { + return errors_js_1.AuthenticationErrorName; + } }); + Object.defineProperty(exports2, "AggregateAuthenticationErrorName", { enumerable: true, get: function() { + return errors_js_1.AggregateAuthenticationErrorName; + } }); + Object.defineProperty(exports2, "CredentialUnavailableError", { enumerable: true, get: function() { + return errors_js_1.CredentialUnavailableError; + } }); + Object.defineProperty(exports2, "CredentialUnavailableErrorName", { enumerable: true, get: function() { + return errors_js_1.CredentialUnavailableErrorName; + } }); + Object.defineProperty(exports2, "AuthenticationRequiredError", { enumerable: true, get: function() { + return errors_js_1.AuthenticationRequiredError; + } }); + var utils_js_1 = require_utils6(); + Object.defineProperty(exports2, "serializeAuthenticationRecord", { enumerable: true, get: function() { + return utils_js_1.serializeAuthenticationRecord; + } }); + Object.defineProperty(exports2, "deserializeAuthenticationRecord", { enumerable: true, get: function() { + return utils_js_1.deserializeAuthenticationRecord; + } }); + var chainedTokenCredential_js_1 = require_chainedTokenCredential(); + Object.defineProperty(exports2, "ChainedTokenCredential", { enumerable: true, get: function() { + return chainedTokenCredential_js_1.ChainedTokenCredential; + } }); + var clientSecretCredential_js_1 = require_clientSecretCredential(); + Object.defineProperty(exports2, "ClientSecretCredential", { enumerable: true, get: function() { + return clientSecretCredential_js_1.ClientSecretCredential; + } }); + var defaultAzureCredential_js_2 = require_defaultAzureCredential(); + Object.defineProperty(exports2, "DefaultAzureCredential", { enumerable: true, get: function() { + return defaultAzureCredential_js_2.DefaultAzureCredential; + } }); + var environmentCredential_js_1 = require_environmentCredential(); + Object.defineProperty(exports2, "EnvironmentCredential", { enumerable: true, get: function() { + return environmentCredential_js_1.EnvironmentCredential; + } }); + var clientCertificateCredential_js_1 = require_clientCertificateCredential(); + Object.defineProperty(exports2, "ClientCertificateCredential", { enumerable: true, get: function() { + return clientCertificateCredential_js_1.ClientCertificateCredential; + } }); + var clientAssertionCredential_js_1 = require_clientAssertionCredential(); + Object.defineProperty(exports2, "ClientAssertionCredential", { enumerable: true, get: function() { + return clientAssertionCredential_js_1.ClientAssertionCredential; + } }); + var azureCliCredential_js_1 = require_azureCliCredential(); + Object.defineProperty(exports2, "AzureCliCredential", { enumerable: true, get: function() { + return azureCliCredential_js_1.AzureCliCredential; + } }); + var azureDeveloperCliCredential_js_1 = require_azureDeveloperCliCredential(); + Object.defineProperty(exports2, "AzureDeveloperCliCredential", { enumerable: true, get: function() { + return azureDeveloperCliCredential_js_1.AzureDeveloperCliCredential; + } }); + var interactiveBrowserCredential_js_1 = require_interactiveBrowserCredential(); + Object.defineProperty(exports2, "InteractiveBrowserCredential", { enumerable: true, get: function() { + return interactiveBrowserCredential_js_1.InteractiveBrowserCredential; + } }); + var index_js_1 = require_managedIdentityCredential(); + Object.defineProperty(exports2, "ManagedIdentityCredential", { enumerable: true, get: function() { + return index_js_1.ManagedIdentityCredential; + } }); + var deviceCodeCredential_js_1 = require_deviceCodeCredential(); + Object.defineProperty(exports2, "DeviceCodeCredential", { enumerable: true, get: function() { + return deviceCodeCredential_js_1.DeviceCodeCredential; + } }); + var azurePipelinesCredential_js_1 = require_azurePipelinesCredential(); + Object.defineProperty(exports2, "AzurePipelinesCredential", { enumerable: true, get: function() { + return azurePipelinesCredential_js_1.AzurePipelinesCredential; + } }); + var authorizationCodeCredential_js_1 = require_authorizationCodeCredential(); + Object.defineProperty(exports2, "AuthorizationCodeCredential", { enumerable: true, get: function() { + return authorizationCodeCredential_js_1.AuthorizationCodeCredential; + } }); + var azurePowerShellCredential_js_1 = require_azurePowerShellCredential(); + Object.defineProperty(exports2, "AzurePowerShellCredential", { enumerable: true, get: function() { + return azurePowerShellCredential_js_1.AzurePowerShellCredential; + } }); + var usernamePasswordCredential_js_1 = require_usernamePasswordCredential(); + Object.defineProperty(exports2, "UsernamePasswordCredential", { enumerable: true, get: function() { + return usernamePasswordCredential_js_1.UsernamePasswordCredential; + } }); + var visualStudioCodeCredential_js_1 = require_visualStudioCodeCredential(); + Object.defineProperty(exports2, "VisualStudioCodeCredential", { enumerable: true, get: function() { + return visualStudioCodeCredential_js_1.VisualStudioCodeCredential; + } }); + var onBehalfOfCredential_js_1 = require_onBehalfOfCredential(); + Object.defineProperty(exports2, "OnBehalfOfCredential", { enumerable: true, get: function() { + return onBehalfOfCredential_js_1.OnBehalfOfCredential; + } }); + var workloadIdentityCredential_js_1 = require_workloadIdentityCredential(); + Object.defineProperty(exports2, "WorkloadIdentityCredential", { enumerable: true, get: function() { + return workloadIdentityCredential_js_1.WorkloadIdentityCredential; + } }); + var logging_js_1 = require_logging(); + Object.defineProperty(exports2, "logger", { enumerable: true, get: function() { + return logging_js_1.logger; + } }); + var constants_js_1 = require_constants4(); + Object.defineProperty(exports2, "AzureAuthorityHosts", { enumerable: true, get: function() { + return constants_js_1.AzureAuthorityHosts; + } }); + function getDefaultAzureCredential() { + return new defaultAzureCredential_js_1.DefaultAzureCredential(); + } + var tokenProvider_js_1 = require_tokenProvider(); + Object.defineProperty(exports2, "getBearerTokenProvider", { enumerable: true, get: function() { + return tokenProvider_js_1.getBearerTokenProvider; + } }); + } +}); + +// node_modules/botframework-connector/lib/auth/jwtTokenProviderFactory.js +var require_jwtTokenProviderFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/jwtTokenProviderFactory.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.JwtTokenProviderFactory = void 0; + var identity_1 = require_commonjs10(); + var assert_1 = require("assert"); + var JwtTokenProviderFactory = class { + /** + * @inheritdoc + */ + createAzureServiceTokenProvider(appId) { + (0, assert_1.ok)(appId === null || appId === void 0 ? void 0 : appId.trim(), "jwtTokenProviderFactory.createAzureServiceTokenProvider(): missing appId."); + return new identity_1.DefaultAzureCredential({ managedIdentityClientId: appId }); + } + }; + exports2.JwtTokenProviderFactory = JwtTokenProviderFactory; + } +}); + +// node_modules/botframework-connector/lib/auth/managedIdentityAuthenticator.js +var require_managedIdentityAuthenticator = __commonJS({ + "node_modules/botframework-connector/lib/auth/managedIdentityAuthenticator.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ManagedIdentityAuthenticator = void 0; + var assert_1 = require("assert"); + var botbuilder_stdlib_1 = require_lib5(); + var ManagedIdentityAuthenticator = class { + /** + * Initializes a new instance of the ManagedIdentityAuthenticator class. + * + * @param appId Client id for the managed identity to be used for acquiring tokens. + * @param resource Resource for which to acquire the token. + * @param tokenProviderFactory The JWT token provider factory to use. + */ + constructor(appId, resource, tokenProviderFactory) { + (0, assert_1.ok)(appId === null || appId === void 0 ? void 0 : appId.trim(), "ManagedIdentityAuthenticator.constructor(): missing appId."); + (0, assert_1.ok)(resource === null || resource === void 0 ? void 0 : resource.trim(), "ManagedIdentityAuthenticator.constructor(): missing resource."); + (0, assert_1.ok)(tokenProviderFactory, "ManagedIdentityAuthenticator.constructor(): missing tokenProviderFactory."); + const scopePostfix = "/.default"; + if (!resource.endsWith(scopePostfix)) { + resource = `${resource}${scopePostfix}`; + } + this.resource = resource; + this.tokenProvider = tokenProviderFactory.createAzureServiceTokenProvider(appId); + } + /** + * Acquires the security token. + * + * @returns {Promise} A promise with the `AccessToken` provided by the [IJwtTokenProviderFactory](xref:botframework-connector.IJwtTokenProviderFactory) class. + */ + getToken() { + return __awaiter2(this, void 0, void 0, function* () { + return (0, botbuilder_stdlib_1.retry)(() => this.tokenProvider.getToken(this.resource), 5, 10); + }); + } + }; + exports2.ManagedIdentityAuthenticator = ManagedIdentityAuthenticator; + } +}); + +// node_modules/botframework-connector/lib/auth/managedIdentityAppCredentials.js +var require_managedIdentityAppCredentials = __commonJS({ + "node_modules/botframework-connector/lib/auth/managedIdentityAppCredentials.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ManagedIdentityAppCredentials = void 0; + var assert_1 = require("assert"); + var appCredentials_1 = require_appCredentials(); + var managedIdentityAuthenticator_1 = require_managedIdentityAuthenticator(); + var ManagedIdentityAppCredentials = class extends appCredentials_1.AppCredentials { + /** + * Managed Identity for AAD credentials auth and caching. + * + * @param appId Client ID for the managed identity assigned to the bot. + * @param oAuthScope The scope for the token. + * @param tokenProviderFactory The JWT token provider factory to use. + */ + constructor(appId, oAuthScope, tokenProviderFactory) { + super(appId, null, oAuthScope); + (0, assert_1.ok)(appId === null || appId === void 0 ? void 0 : appId.trim(), "ManagedIdentityAppCredentials.constructor(): missing appId."); + (0, assert_1.ok)(tokenProviderFactory, "ManagedIdentityAppCredentials.constructor(): missing tokenProviderFactory."); + this.tokenProviderFactory = tokenProviderFactory; + super.appId = appId; + this.authenticator = new managedIdentityAuthenticator_1.ManagedIdentityAuthenticator(this.appId, this.oAuthScope, this.tokenProviderFactory); + } + /** + * @inheritdoc + */ + refreshToken() { + return __awaiter2(this, void 0, void 0, function* () { + const token = yield this.authenticator.getToken(); + return { + accessToken: token.token, + expiresOn: new Date(token.expiresOnTimestamp) + }; + }); + } + }; + exports2.ManagedIdentityAppCredentials = ManagedIdentityAppCredentials; + } +}); + +// node_modules/botframework-connector/lib/auth/managedIdentityServiceClientCredentialsFactory.js +var require_managedIdentityServiceClientCredentialsFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/managedIdentityServiceClientCredentialsFactory.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ManagedIdentityServiceClientCredentialsFactory = void 0; + var managedIdentityAppCredentials_1 = require_managedIdentityAppCredentials(); + var serviceClientCredentialsFactory_1 = require_serviceClientCredentialsFactory(); + var assert_1 = require("assert"); + var ManagedIdentityServiceClientCredentialsFactory = class extends serviceClientCredentialsFactory_1.ServiceClientCredentialsFactory { + /** + * Initializes a new instance of the ManagedIdentityServiceClientCredentialsFactory class. + * + * @param appId Client ID for the managed identity assigned to the bot. + * @param tokenProviderFactory The JWT token provider factory to use. + */ + constructor(appId, tokenProviderFactory) { + super(); + (0, assert_1.ok)(appId === null || appId === void 0 ? void 0 : appId.trim(), "ManagedIdentityServiceClientCredentialsFactory.constructor(): missing appId."); + (0, assert_1.ok)(tokenProviderFactory, "ManagedIdentityServiceClientCredentialsFactory.constructor(): missing tokenProviderFactory."); + this.appId = appId; + this.tokenProviderFactory = tokenProviderFactory; + } + /** + * @inheritdoc + */ + isValidAppId(appId) { + return __awaiter2(this, void 0, void 0, function* () { + return appId === this.appId; + }); + } + /** + * @inheritdoc + */ + isAuthenticationDisabled() { + return __awaiter2(this, void 0, void 0, function* () { + return false; + }); + } + /** + * @inheritdoc + */ + createCredentials(appId, audience) { + return __awaiter2(this, void 0, void 0, function* () { + (0, assert_1.ok)(yield this.isValidAppId(appId), "ManagedIdentityServiceClientCredentialsFactory.createCredentials(): Invalid Managed ID."); + return new managedIdentityAppCredentials_1.ManagedIdentityAppCredentials(this.appId, audience, this.tokenProviderFactory); + }); + } + }; + exports2.ManagedIdentityServiceClientCredentialsFactory = ManagedIdentityServiceClientCredentialsFactory; + } +}); + +// node_modules/botframework-connector/lib/auth/microsoftAppCredentials.js +var require_microsoftAppCredentials = __commonJS({ + "node_modules/botframework-connector/lib/auth/microsoftAppCredentials.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MicrosoftAppCredentials = void 0; + var appCredentials_1 = require_appCredentials(); + var msalAppCredentials_1 = require_msalAppCredentials(); + var MicrosoftAppCredentials = class extends appCredentials_1.AppCredentials { + /** + * Initializes a new instance of the [MicrosoftAppCredentials](xref:botframework-connector.MicrosoftAppCredentials) class. + * + * @param {string} appId The Microsoft app ID. + * @param {string} appPassword The Microsoft app password. + * @param {string} channelAuthTenant Tenant ID of the Azure AD tenant where the bot is created. + * - Required for SingleTenant app types. + * - Optional for MultiTenant app types. **Note**: '_botframework.com_' is the default tenant when no value is provided. + * + * More information: https://learn.microsoft.com/en-us/security/zero-trust/develop/identity-supported-account-types. + * @param {string} oAuthScope Optional. The scope for the token. + */ + constructor(appId, appPassword, channelAuthTenant, oAuthScope) { + super(appId, channelAuthTenant, oAuthScope); + this.appPassword = appPassword; + } + /** + * @inheritdoc + */ + getToken(forceRefresh = false) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + (_a = this.credentials) !== null && _a !== void 0 ? _a : this.credentials = new msalAppCredentials_1.MsalAppCredentials(this.appId, this.appPassword, this.oAuthEndpoint, this.oAuthScope); + return this.credentials.getToken(forceRefresh); + }); + } + /** + * @inheritdoc + */ + refreshToken() { + throw new Error("Method not implemented."); + } + }; + exports2.MicrosoftAppCredentials = MicrosoftAppCredentials; + MicrosoftAppCredentials.Empty = new MicrosoftAppCredentials(null, null); + } +}); + +// node_modules/botframework-connector/lib/auth/microsoftGovernmentAppCredentials.js +var require_microsoftGovernmentAppCredentials = __commonJS({ + "node_modules/botframework-connector/lib/auth/microsoftGovernmentAppCredentials.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MicrosoftGovernmentAppCredentials = void 0; + var governmentConstants_1 = require_governmentConstants(); + var microsoftAppCredentials_1 = require_microsoftAppCredentials(); + var MicrosoftGovernmentAppCredentials = class extends microsoftAppCredentials_1.MicrosoftAppCredentials { + /** + * Initializes a new instance of the [MicrosoftGovernmentAppCredentials](xref:botframework-connector.MicrosoftGovernmentAppCredentials) class. + * + * @param {string} appId The Microsoft app ID. + * @param {string} appPassword The Microsoft app password. + * @param {string} channelAuthTenant Optional. The oauth token tenant. + * @param {string} oAuthScope Optional. The scope for the token. + */ + constructor(appId, appPassword, channelAuthTenant, oAuthScope) { + super(appId, appPassword, channelAuthTenant, oAuthScope); + this.appPassword = appPassword; + } + GetToChannelFromBotOAuthScope() { + return governmentConstants_1.GovernmentConstants.ToChannelFromBotOAuthScope; + } + GetToChannelFromBotLoginUrlPrefix() { + return governmentConstants_1.GovernmentConstants.ToChannelFromBotLoginUrlPrefix; + } + GetDefaultChannelAuthTenant() { + return governmentConstants_1.GovernmentConstants.DefaultChannelAuthTenant; + } + }; + exports2.MicrosoftGovernmentAppCredentials = MicrosoftGovernmentAppCredentials; + } +}); + +// node_modules/botframework-connector/lib/auth/passwordServiceClientCredentialFactory.js +var require_passwordServiceClientCredentialFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/passwordServiceClientCredentialFactory.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PasswordServiceClientCredentialFactory = void 0; + var authenticationConstants_1 = require_authenticationConstants(); + var governmentConstants_1 = require_governmentConstants(); + var microsoftAppCredentials_1 = require_microsoftAppCredentials(); + var microsoftGovernmentAppCredentials_1 = require_microsoftGovernmentAppCredentials(); + var botbuilder_stdlib_1 = require_lib5(); + var PasswordServiceClientCredentialFactory = class { + /** + * @internal + */ + constructor(appId, password, tenantId) { + this.appId = appId; + this.password = password; + this.tenantId = tenantId !== null && tenantId !== void 0 ? tenantId : null; + } + // Protects against JSON.stringify leaking secrets + toJSON() { + return { + name: this.constructor.name, + appId: this.appId + }; + } + /** + * Validates an app ID. + * + * @param appId The appId to validate. + * @returns Promise with the validation result. + */ + isValidAppId(appId = "") { + return __awaiter2(this, void 0, void 0, function* () { + return appId === this.appId; + }); + } + /** + * Checks whether bot authentication is disabled. + * + * @returns Promise with the validation result. + */ + isAuthenticationDisabled() { + return __awaiter2(this, void 0, void 0, function* () { + return botbuilder_stdlib_1.stringExt.isNilOrEmpty(this.appId); + }); + } + /** + * A factory method for creating ServiceClientCredentials. + * + * @param appId The appId. + * @param audience The audience. + * @param loginEndpoint The login url. + * @param validateAuthority The validate authority value to use. + * @returns A Promise representing the result of the operation. + */ + createCredentials(appId, audience, loginEndpoint, validateAuthority) { + return __awaiter2(this, void 0, void 0, function* () { + if (yield this.isAuthenticationDisabled()) { + return microsoftAppCredentials_1.MicrosoftAppCredentials.Empty; + } + if (!(yield this.isValidAppId(appId))) { + throw new Error("Invalid appId."); + } + let credentials; + const normalizedEndpoint = loginEndpoint === null || loginEndpoint === void 0 ? void 0 : loginEndpoint.toLowerCase(); + if (normalizedEndpoint === null || normalizedEndpoint === void 0 ? void 0 : normalizedEndpoint.startsWith(authenticationConstants_1.AuthenticationConstants.ToChannelFromBotLoginUrlPrefix)) { + credentials = new microsoftAppCredentials_1.MicrosoftAppCredentials(appId, this.password, this.tenantId, audience); + } else if (normalizedEndpoint === null || normalizedEndpoint === void 0 ? void 0 : normalizedEndpoint.startsWith(governmentConstants_1.GovernmentConstants.ToChannelFromBotLoginUrlPrefix)) { + credentials = new microsoftGovernmentAppCredentials_1.MicrosoftGovernmentAppCredentials(appId, this.password, this.tenantId, audience); + } else { + credentials = new PrivateCloudAppCredentials(appId, this.password, this.tenantId, audience, normalizedEndpoint, validateAuthority); + } + return credentials; + }); + } + }; + exports2.PasswordServiceClientCredentialFactory = PasswordServiceClientCredentialFactory; + var PrivateCloudAppCredentials = class extends microsoftAppCredentials_1.MicrosoftAppCredentials { + constructor(appId, password, tenantId, oAuthScope, oAuthEndpoint, validateAuthority) { + super(appId, password, tenantId, oAuthScope); + this.oAuthEndpoint = oAuthEndpoint; + this._validateAuthority = validateAuthority; + } + /** + * Gets a value indicating whether to validate the Authority. + * + * @returns The ValidateAuthority value to use. + */ + get validateAuthority() { + return this._validateAuthority; + } + /** + * Gets the OAuth endpoint to use. + * + * @returns The OAuthEndpoint to use. + */ + get oAuthEndpoint() { + return this.__oAuthEndpoint; + } + /** + * Sets the OAuth endpoint to use. + */ + set oAuthEndpoint(value) { + this.__oAuthEndpoint = value; + } + }; + } +}); + +// node_modules/botframework-connector/lib/auth/msalServiceClientCredentialsFactory.js +var require_msalServiceClientCredentialsFactory = __commonJS({ + "node_modules/botframework-connector/lib/auth/msalServiceClientCredentialsFactory.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MsalServiceClientCredentialsFactory = void 0; + var msalAppCredentials_1 = require_msalAppCredentials(); + var authenticationConstants_1 = require_authenticationConstants(); + var governmentConstants_1 = require_governmentConstants(); + var MsalServiceClientCredentialsFactory = class { + /** + * Create an MsalServiceClientCredentialsFactory instance using runtime configuration and an + * `@azure/msal-node` `ConfidentialClientApplication`. + * + * @param appId App ID for validation. + * @param clientApplication An `@azure/msal-node` `ConfidentialClientApplication` instance. + */ + constructor(appId, clientApplication) { + this.clientApplication = clientApplication; + this.appId = appId; + } + /** + * @inheritdoc + */ + isValidAppId(appId) { + return __awaiter2(this, void 0, void 0, function* () { + return appId === this.appId; + }); + } + /** + * @inheritdoc + */ + isAuthenticationDisabled() { + return __awaiter2(this, void 0, void 0, function* () { + return !this.appId; + }); + } + /** + * @inheritdoc + */ + createCredentials(appId, audience, loginEndpoint, _validateAuthority) { + return __awaiter2(this, void 0, void 0, function* () { + if (yield this.isAuthenticationDisabled()) { + return msalAppCredentials_1.MsalAppCredentials.Empty; + } + if (!(yield this.isValidAppId(appId))) { + throw new Error("Invalid appId."); + } + const normalizedEndpoint = loginEndpoint.toLowerCase(); + if (normalizedEndpoint.startsWith(authenticationConstants_1.AuthenticationConstants.ToChannelFromBotLoginUrlPrefix)) { + return new msalAppCredentials_1.MsalAppCredentials(this.clientApplication, appId, void 0, audience || authenticationConstants_1.AuthenticationConstants.ToBotFromChannelTokenIssuer); + } + if (normalizedEndpoint.startsWith(governmentConstants_1.GovernmentConstants.ToChannelFromBotLoginUrlPrefix)) { + return new msalAppCredentials_1.MsalAppCredentials(this.clientApplication, appId, void 0, audience || governmentConstants_1.GovernmentConstants.ToChannelFromBotOAuthScope); + } + return new msalAppCredentials_1.MsalAppCredentials(this.clientApplication, appId, loginEndpoint, audience); + }); + } + }; + exports2.MsalServiceClientCredentialsFactory = MsalServiceClientCredentialsFactory; + } +}); + +// node_modules/botframework-connector/lib/auth/index.js +var require_auth = __commonJS({ + "node_modules/botframework-connector/lib/auth/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TokenCredentials = exports2.MsalServiceClientCredentialsFactory = exports2.MsalAppCredentials = void 0; + __exportStar2(require_allowedCallersClaimsValidator(), exports2); + __exportStar2(require_appCredentials(), exports2); + __exportStar2(require_aseChannelValidation(), exports2); + __exportStar2(require_authenticateRequestResult(), exports2); + __exportStar2(require_authenticationConfiguration(), exports2); + __exportStar2(require_authenticationConstants(), exports2); + __exportStar2(require_authenticationError(), exports2); + __exportStar2(require_authenticatorResult(), exports2); + __exportStar2(require_botFrameworkAuthentication(), exports2); + __exportStar2(require_botFrameworkAuthenticationFactory(), exports2); + __exportStar2(require_certificateAppCredentials(), exports2); + __exportStar2(require_certificateServiceClientCredentialsFactory(), exports2); + __exportStar2(require_channelValidation(), exports2); + __exportStar2(require_claimsIdentity(), exports2); + __exportStar2(require_connectorFactory(), exports2); + __exportStar2(require_credentialProvider(), exports2); + __exportStar2(require_emulatorValidation(), exports2); + __exportStar2(require_endorsementsValidator(), exports2); + __exportStar2(require_enterpriseChannelValidation(), exports2); + __exportStar2(require_federatedAppCredentials(), exports2); + __exportStar2(require_federatedServiceClientCredentialsFactory(), exports2); + __exportStar2(require_governmentChannelValidation(), exports2); + __exportStar2(require_governmentConstants(), exports2); + __exportStar2(require_jwtTokenProviderFactory(), exports2); + __exportStar2(require_jwtTokenValidation(), exports2); + __exportStar2(require_managedIdentityAppCredentials(), exports2); + __exportStar2(require_managedIdentityAuthenticator(), exports2); + __exportStar2(require_managedIdentityServiceClientCredentialsFactory(), exports2); + __exportStar2(require_microsoftAppCredentials(), exports2); + __exportStar2(require_microsoftGovernmentAppCredentials(), exports2); + __exportStar2(require_passwordServiceClientCredentialFactory(), exports2); + __exportStar2(require_serviceClientCredentialsFactory(), exports2); + __exportStar2(require_skillValidation(), exports2); + __exportStar2(require_tokenValidationParameters(), exports2); + __exportStar2(require_userTokenClient(), exports2); + var msalAppCredentials_1 = require_msalAppCredentials(); + Object.defineProperty(exports2, "MsalAppCredentials", { enumerable: true, get: function() { + return msalAppCredentials_1.MsalAppCredentials; + } }); + var msalServiceClientCredentialsFactory_1 = require_msalServiceClientCredentialsFactory(); + Object.defineProperty(exports2, "MsalServiceClientCredentialsFactory", { enumerable: true, get: function() { + return msalServiceClientCredentialsFactory_1.MsalServiceClientCredentialsFactory; + } }); + var tokenCredentials_1 = require_tokenCredentials(); + Object.defineProperty(exports2, "TokenCredentials", { enumerable: true, get: function() { + return tokenCredentials_1.TokenCredentials; + } }); + } +}); + +// node_modules/botframework-connector/lib/teams/models/index.js +var require_models3 = __commonJS({ + "node_modules/botframework-connector/lib/teams/models/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-connector/lib/teams/models/mappers.js +var require_mappers3 = __commonJS({ + "node_modules/botframework-connector/lib/teams/models/mappers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MessageActionsPayloadReaction = exports2.MessageActionsPayloadMention = exports2.MessageActionsPayloadAttachment = exports2.MessageActionsPayloadBody = exports2.MessageActionsPayloadFrom = exports2.MessageActionsPayloadConversation = exports2.MessageActionsPayloadApp = exports2.MessageActionsPayloadUser = exports2.Activity = exports2.MessagingExtensionQuery = exports2.MessagingExtensionParameter = exports2.MessagingExtensionQueryOptions = exports2.SigninStateVerificationQuery = exports2.O365ConnectorCardActionQuery = exports2.O365ConnectorCardMultichoiceInput = exports2.O365ConnectorCardMultichoiceInputChoice = exports2.O365ConnectorCardDateInput = exports2.O365ConnectorCardTextInput = exports2.O365ConnectorCardActionCard = exports2.O365ConnectorCardInputBase = exports2.O365ConnectorCardHttpPOST = exports2.O365ConnectorCardOpenUri = exports2.O365ConnectorCardOpenUriTarget = exports2.O365ConnectorCardViewAction = exports2.O365ConnectorCard = exports2.O365ConnectorCardSection = exports2.O365ConnectorCardActionBase = exports2.O365ConnectorCardImage = exports2.O365ConnectorCardFact = exports2.CardImage = exports2.CardAction = exports2.MeetingNotificationResponse = exports2.MeetingNotificationRecipientFailureInfo = exports2.OnBehalfOf = exports2.MeetingNotificationChannelData = exports2.MeetingNotification = exports2.TeamsMeetingDetails = exports2.TeamsMeetingInfo = exports2.TeamsMeetingParticipant = exports2.Meeting = exports2.TeamsChannelAccount = exports2.ChannelAccount = exports2.TeamsChannelDataSettings = exports2.TeamsChannelData = exports2.TenantInfo = exports2.NotificationInfo = exports2.TeamInfo = exports2.TeamDetails = exports2.ConversationList = exports2.ChannelInfo = void 0; + exports2.TeamsMember = exports2.GetTeamsFailedEntriesResponse = exports2.GetTeamsOperationStateResponse = exports2.BatchOperationResponse = exports2.BatchOperationRequest = exports2.AppBasedLinkQuery = exports2.TaskModuleRequestContext = exports2.TaskModuleResponse = exports2.TaskModuleMessageResponse = exports2.TaskModuleContinueResponse = exports2.TaskModuleTaskInfo = exports2.FileConsentCardResponse = exports2.FileUploadInfo = exports2.FileInfoCard = exports2.FileDownloadInfo = exports2.FileConsentCard = exports2.MessagingExtensionResponse = exports2.MessagingExtensionActionResponse = exports2.CacheInfo = exports2.MessagingExtensionResult = exports2.MessagingExtensionSuggestedAction = exports2.MessagingExtensionAttachment = exports2.Attachment = exports2.TaskModuleResponseBase = exports2.MessagingExtensionAction = exports2.TaskModuleRequest = exports2.MessageActionsPayload = void 0; + exports2.ChannelInfo = { + serializedName: "ChannelInfo", + type: { + name: "Composite", + className: "ChannelInfo", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + } + } + } + }; + exports2.ConversationList = { + serializedName: "ConversationList", + type: { + name: "Composite", + className: "ConversationList", + modelProperties: { + conversations: { + serializedName: "conversations", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ChannelInfo" + } + } + } + } + } + } + }; + exports2.TeamDetails = { + serializedName: "TeamDetails", + type: { + name: "Composite", + className: "TeamDetails", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + aadGroupId: { + serializedName: "aadGroupId", + type: { + name: "String" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + } + } + } + }; + exports2.TeamInfo = { + serializedName: "TeamInfo", + type: { + name: "Composite", + className: "TeamInfo", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + aadGroupId: { + serializedName: "aadGroupId", + type: { + name: "String" + } + } + } + } + }; + exports2.NotificationInfo = { + serializedName: "NotificationInfo", + type: { + name: "Composite", + className: "NotificationInfo", + modelProperties: { + alert: { + serializedName: "alert", + type: { + name: "Boolean" + } + }, + alertInMeeting: { + serializedName: "alertInMeeting", + type: { + name: "Boolean" + } + }, + externalResourceUrl: { + serializedName: "externalResourceUrl", + type: { + name: "String" + } + } + } + } + }; + exports2.TenantInfo = { + serializedName: "TenantInfo", + type: { + name: "Composite", + className: "TenantInfo", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + } + } + } + }; + exports2.TeamsChannelData = { + serializedName: "TeamsChannelData", + type: { + name: "Composite", + className: "TeamsChannelData", + modelProperties: { + channel: { + serializedName: "channel", + type: { + name: "Composite", + className: "ChannelInfo" + } + }, + eventType: { + serializedName: "eventType", + type: { + name: "String" + } + }, + team: { + serializedName: "team", + type: { + name: "Composite", + className: "TeamInfo" + } + }, + notification: { + serializedName: "notification", + type: { + name: "Composite", + className: "NotificationInfo" + } + }, + tenant: { + serializedName: "tenant", + type: { + name: "Composite", + className: "TenantInfo" + } + }, + settings: { + serializedName: "settings", + type: { + name: "Composite", + className: "TeamsChannelDataSettings" + } + } + } + } + }; + exports2.TeamsChannelDataSettings = { + serializedName: "TeamsChannelDataSettings", + type: { + name: "Composite", + className: "TeamsChannelDataSettings", + modelProperties: { + selectedChannel: { + serializedName: "selectedChannel", + type: { + name: "Composite", + className: "ChannelInfo" + } + } + } + } + }; + exports2.ChannelAccount = { + serializedName: "ChannelAccount", + type: { + name: "Composite", + className: "ChannelAccount", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + } + } + } + }; + exports2.TeamsChannelAccount = { + serializedName: "TeamsChannelAccount", + type: { + name: "Composite", + className: "TeamsChannelAccount", + modelProperties: Object.assign(Object.assign({}, exports2.ChannelAccount.type.modelProperties), { givenName: { + serializedName: "givenName", + type: { + name: "String" + } + }, surname: { + serializedName: "surname", + type: { + name: "String" + } + }, email: { + serializedName: "email", + type: { + name: "String" + } + }, userPrincipalName: { + serializedName: "userPrincipalName", + type: { + name: "String" + } + }, tenantId: { + serializedName: "tenantId", + type: { + name: "String" + } + }, userRole: { + serializedName: "userRole", + type: { + name: "String" + } + } }) + } + }; + exports2.Meeting = { + serializedName: "meeting", + type: { + name: "Composite", + className: "Meeting", + modelProperties: { + role: { + serializedName: "role", + type: { + name: "String" + } + }, + inMeeting: { + serializedName: "inMeeting", + type: { + name: "Boolean" + } + } + } + } + }; + exports2.TeamsMeetingParticipant = { + serializedName: "TeamsMeetingParticipant", + type: { + name: "Composite", + className: "TeamsMeetingParticipant", + modelProperties: { + user: { + serializedName: "user", + type: { + name: "Composite", + className: "TeamsChannelAccount" + } + }, + meeting: { + serializedName: "meeting", + type: { + name: "Composite", + className: "Meeting" + } + }, + conversation: { + serializedName: "conversation", + type: { + name: "Composite", + className: "MessageActionsPayloadConversation" + } + } + } + } + }; + exports2.TeamsMeetingInfo = { + serializedName: "TeamsMeetingInfo", + type: { + name: "Composite", + className: "TeamsMeetingInfo", + modelProperties: { + details: { + serializedName: "details", + type: { + name: "Composite", + className: "TeamsMeetingDetails" + } + }, + conversation: { + serializedName: "conversation", + type: { + name: "Composite", + className: "MessageActionsPayloadConversation" + } + }, + organizer: { + serializedName: "organizer", + type: { + name: "Composite", + className: "TeamsChannelAccount" + } + } + } + } + }; + exports2.TeamsMeetingDetails = { + serializedName: "TeamsMeetingDetails", + type: { + name: "Composite", + className: "TeamsMeetingDetails", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + msGraphResourceId: { + serializedName: "msGraphResourceId", + type: { + name: "String" + } + }, + scheduledStartTime: { + serializedName: "scheduledStartTime", + type: { + name: "DateTime" + } + }, + scheduledEndTime: { + serializedName: "scheduledEndTime", + type: { + name: "DateTime" + } + }, + joinUrl: { + serializedName: "joinUrl", + type: { + name: "String" + } + }, + title: { + serializedName: "title", + type: { + name: "String" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + } + } + } + }; + exports2.MeetingNotification = { + serializedName: "MeetingNotification", + type: { + name: "Composite", + className: "MeetingNotification", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "any" + } + }, + channelData: { + serializedName: "channelData", + type: { + name: "Composite", + className: "MeetingNotificationChannelData" + } + } + } + } + }; + exports2.MeetingNotificationChannelData = { + serializedName: "MeetingNotificationChannelData", + type: { + name: "Composite", + className: "MeetingNotificationChannelData", + modelProperties: { + onBehalfOf: { + serializedName: "onBehalfOf", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "OnBehalfOf" + } + } + } + } + } + } + }; + exports2.OnBehalfOf = { + serializedName: "OnBehalfOf", + type: { + name: "Composite", + className: "OnBehalfOf", + modelProperties: { + itemid: { + serializedName: "itemid", + type: { + name: "Number" + } + }, + mentionType: { + serializedName: "mentionType", + type: { + name: "String" + } + }, + mri: { + serializedName: "mri", + type: { + name: "String" + } + }, + displayName: { + serializedName: "displayName", + type: { + name: "String" + } + } + } + } + }; + exports2.MeetingNotificationRecipientFailureInfo = { + serializedName: "MeetingNotificationRecipientFailureInfo", + type: { + name: "Composite", + className: "MeetingNotificationRecipientFailureInfo", + modelProperties: { + recipientMri: { + serializedName: "recipientMri", + type: { + name: "String" + } + }, + failureReason: { + serializedName: "failureReason", + type: { + name: "String" + } + }, + errorCode: { + serializedName: "errorCode", + type: { + name: "String" + } + } + } + } + }; + exports2.MeetingNotificationResponse = { + serializedName: "MeetingNotificationResponse", + type: { + name: "Composite", + className: "MeetingNotificationResponse", + modelProperties: { + recipientsFailureInfo: { + serializedName: "recipientsFailureInfo", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MeetingNotificationRecipientFailureInfo" + } + } + } + } + } + } + }; + exports2.CardAction = { + serializedName: "CardAction", + type: { + name: "Composite", + className: "CardAction", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + }, + title: { + serializedName: "title", + type: { + name: "String" + } + }, + image: { + serializedName: "image", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "Object" + } + } + } + } + }; + exports2.CardImage = { + serializedName: "CardImage", + type: { + name: "Composite", + className: "CardImage", + modelProperties: { + url: { + serializedName: "url", + type: { + name: "String" + } + }, + alt: { + serializedName: "alt", + type: { + name: "String" + } + }, + tap: { + serializedName: "tap", + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + }; + exports2.O365ConnectorCardFact = { + serializedName: "O365ConnectorCardFact", + type: { + name: "Composite", + className: "O365ConnectorCardFact", + modelProperties: { + name: { + serializedName: "name", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "String" + } + } + } + } + }; + exports2.O365ConnectorCardImage = { + serializedName: "O365ConnectorCardImage", + type: { + name: "Composite", + className: "O365ConnectorCardImage", + modelProperties: { + image: { + serializedName: "image", + type: { + name: "String" + } + }, + title: { + serializedName: "title", + type: { + name: "String" + } + } + } + } + }; + exports2.O365ConnectorCardActionBase = { + serializedName: "O365ConnectorCardActionBase", + type: { + name: "Composite", + className: "O365ConnectorCardActionBase", + modelProperties: { + type: { + serializedName: "@type", + type: { + name: "String" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + id: { + serializedName: "@id", + type: { + name: "String" + } + } + } + } + }; + exports2.O365ConnectorCardSection = { + serializedName: "O365ConnectorCardSection", + type: { + name: "Composite", + className: "O365ConnectorCardSection", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + activityTitle: { + serializedName: "activityTitle", + type: { + name: "String" + } + }, + activitySubtitle: { + serializedName: "activitySubtitle", + type: { + name: "String" + } + }, + activityText: { + serializedName: "activityText", + type: { + name: "String" + } + }, + activityImage: { + serializedName: "activityImage", + type: { + name: "String" + } + }, + activityImageType: { + serializedName: "activityImageType", + type: { + name: "String" + } + }, + markdown: { + serializedName: "markdown", + type: { + name: "Boolean" + } + }, + facts: { + serializedName: "facts", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardFact" + } + } + } + }, + images: { + serializedName: "images", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardImage" + } + } + } + }, + potentialAction: { + serializedName: "potentialAction", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardActionBase" + } + } + } + } + } + } + }; + exports2.O365ConnectorCard = { + serializedName: "O365ConnectorCard", + type: { + name: "Composite", + className: "O365ConnectorCard", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + summary: { + serializedName: "summary", + type: { + name: "String" + } + }, + themeColor: { + serializedName: "themeColor", + type: { + name: "String" + } + }, + sections: { + serializedName: "sections", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardSection" + } + } + } + }, + potentialAction: { + serializedName: "potentialAction", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardActionBase" + } + } + } + } + } + } + }; + exports2.O365ConnectorCardViewAction = { + serializedName: "O365ConnectorCardViewAction", + type: { + name: "Composite", + className: "O365ConnectorCardViewAction", + modelProperties: Object.assign(Object.assign({}, exports2.O365ConnectorCardActionBase.type.modelProperties), { target: { + serializedName: "target", + type: { + name: "Sequence", + element: { + type: { + name: "String" + } + } + } + } }) + } + }; + exports2.O365ConnectorCardOpenUriTarget = { + serializedName: "O365ConnectorCardOpenUriTarget", + type: { + name: "Composite", + className: "O365ConnectorCardOpenUriTarget", + modelProperties: { + os: { + serializedName: "os", + type: { + name: "String" + } + }, + uri: { + serializedName: "uri", + type: { + name: "String" + } + } + } + } + }; + exports2.O365ConnectorCardOpenUri = { + serializedName: "O365ConnectorCardOpenUri", + type: { + name: "Composite", + className: "O365ConnectorCardOpenUri", + modelProperties: Object.assign(Object.assign({}, exports2.O365ConnectorCardActionBase.type.modelProperties), { targets: { + serializedName: "targets", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardOpenUriTarget" + } + } + } + } }) + } + }; + exports2.O365ConnectorCardHttpPOST = { + serializedName: "O365ConnectorCardHttpPOST", + type: { + name: "Composite", + className: "O365ConnectorCardHttpPOST", + modelProperties: Object.assign(Object.assign({}, exports2.O365ConnectorCardActionBase.type.modelProperties), { body: { + serializedName: "body", + type: { + name: "String" + } + } }) + } + }; + exports2.O365ConnectorCardInputBase = { + serializedName: "O365ConnectorCardInputBase", + type: { + name: "Composite", + className: "O365ConnectorCardInputBase", + modelProperties: { + type: { + serializedName: "@type", + type: { + name: "String" + } + }, + id: { + serializedName: "id", + type: { + name: "String" + } + }, + isRequired: { + serializedName: "isRequired", + type: { + name: "Boolean" + } + }, + title: { + serializedName: "title", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "String" + } + } + } + } + }; + exports2.O365ConnectorCardActionCard = { + serializedName: "O365ConnectorCardActionCard", + type: { + name: "Composite", + className: "O365ConnectorCardActionCard", + modelProperties: Object.assign(Object.assign({}, exports2.O365ConnectorCardActionBase.type.modelProperties), { inputs: { + serializedName: "inputs", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardInputBase" + } + } + } + }, actions: { + serializedName: "actions", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardActionBase" + } + } + } + } }) + } + }; + exports2.O365ConnectorCardTextInput = { + serializedName: "O365ConnectorCardTextInput", + type: { + name: "Composite", + className: "O365ConnectorCardTextInput", + modelProperties: Object.assign(Object.assign({}, exports2.O365ConnectorCardInputBase.type.modelProperties), { isMultiline: { + serializedName: "isMultiline", + type: { + name: "Boolean" + } + }, maxLength: { + serializedName: "maxLength", + type: { + name: "Number" + } + } }) + } + }; + exports2.O365ConnectorCardDateInput = { + serializedName: "O365ConnectorCardDateInput", + type: { + name: "Composite", + className: "O365ConnectorCardDateInput", + modelProperties: Object.assign(Object.assign({}, exports2.O365ConnectorCardInputBase.type.modelProperties), { includeTime: { + serializedName: "includeTime", + type: { + name: "Boolean" + } + } }) + } + }; + exports2.O365ConnectorCardMultichoiceInputChoice = { + serializedName: "O365ConnectorCardMultichoiceInputChoice", + type: { + name: "Composite", + className: "O365ConnectorCardMultichoiceInputChoice", + modelProperties: { + display: { + serializedName: "display", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "String" + } + } + } + } + }; + exports2.O365ConnectorCardMultichoiceInput = { + serializedName: "O365ConnectorCardMultichoiceInput", + type: { + name: "Composite", + className: "O365ConnectorCardMultichoiceInput", + modelProperties: Object.assign(Object.assign({}, exports2.O365ConnectorCardInputBase.type.modelProperties), { choices: { + serializedName: "choices", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "O365ConnectorCardMultichoiceInputChoice" + } + } + } + }, style: { + serializedName: "style", + type: { + name: "String" + } + }, isMultiSelect: { + serializedName: "isMultiSelect", + type: { + name: "Boolean" + } + } }) + } + }; + exports2.O365ConnectorCardActionQuery = { + serializedName: "O365ConnectorCardActionQuery", + type: { + name: "Composite", + className: "O365ConnectorCardActionQuery", + modelProperties: { + body: { + serializedName: "body", + type: { + name: "String" + } + }, + actionId: { + serializedName: "actionId", + type: { + name: "String" + } + } + } + } + }; + exports2.SigninStateVerificationQuery = { + serializedName: "SigninStateVerificationQuery", + type: { + name: "Composite", + className: "SigninStateVerificationQuery", + modelProperties: { + state: { + serializedName: "state", + type: { + name: "String" + } + } + } + } + }; + exports2.MessagingExtensionQueryOptions = { + serializedName: "MessagingExtensionQueryOptions", + type: { + name: "Composite", + className: "MessagingExtensionQueryOptions", + modelProperties: { + skip: { + serializedName: "skip", + type: { + name: "Number" + } + }, + count: { + serializedName: "count", + type: { + name: "Number" + } + } + } + } + }; + exports2.MessagingExtensionParameter = { + serializedName: "MessagingExtensionParameter", + type: { + name: "Composite", + className: "MessagingExtensionParameter", + modelProperties: { + name: { + serializedName: "name", + type: { + name: "String" + } + }, + value: { + serializedName: "value", + type: { + name: "Object" + } + } + } + } + }; + exports2.MessagingExtensionQuery = { + serializedName: "MessagingExtensionQuery", + type: { + name: "Composite", + className: "MessagingExtensionQuery", + modelProperties: { + commandId: { + serializedName: "commandId", + type: { + name: "String" + } + }, + parameters: { + serializedName: "parameters", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MessagingExtensionParameter" + } + } + } + }, + queryOptions: { + serializedName: "queryOptions", + type: { + name: "Composite", + className: "MessagingExtensionQueryOptions" + } + }, + state: { + serializedName: "state", + type: { + name: "String" + } + } + } + } + }; + exports2.Activity = { + serializedName: "Activity", + type: { + name: "Composite", + className: "Activity", + modelProperties: { + dummyProperty: { + serializedName: "dummyProperty", + type: { + name: "String" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + } + } + } + }; + exports2.MessageActionsPayloadUser = { + serializedName: "MessageActionsPayloadUser", + type: { + name: "Composite", + className: "MessageActionsPayloadUser", + modelProperties: { + userIdentityType: { + serializedName: "userIdentityType", + type: { + name: "String" + } + }, + id: { + serializedName: "id", + type: { + name: "String" + } + }, + displayName: { + serializedName: "displayName", + type: { + name: "String" + } + } + } + } + }; + exports2.MessageActionsPayloadApp = { + serializedName: "MessageActionsPayloadApp", + type: { + name: "Composite", + className: "MessageActionsPayloadApp", + modelProperties: { + applicationIdentityType: { + serializedName: "applicationIdentityType", + type: { + name: "String" + } + }, + id: { + serializedName: "id", + type: { + name: "String" + } + }, + displayName: { + serializedName: "displayName", + type: { + name: "String" + } + } + } + } + }; + exports2.MessageActionsPayloadConversation = { + serializedName: "MessageActionsPayloadConversation", + type: { + name: "Composite", + className: "MessageActionsPayloadConversation", + modelProperties: { + conversationIdentityType: { + serializedName: "conversationIdentityType", + type: { + name: "String" + } + }, + id: { + serializedName: "id", + type: { + name: "String" + } + }, + displayName: { + serializedName: "displayName", + type: { + name: "String" + } + } + } + } + }; + exports2.MessageActionsPayloadFrom = { + serializedName: "MessageActionsPayloadFrom", + type: { + name: "Composite", + className: "MessageActionsPayloadFrom", + modelProperties: { + user: { + serializedName: "user", + type: { + name: "Composite", + className: "MessageActionsPayloadUser" + } + }, + application: { + serializedName: "application", + type: { + name: "Composite", + className: "MessageActionsPayloadApp" + } + }, + conversation: { + serializedName: "conversation", + type: { + name: "Composite", + className: "MessageActionsPayloadConversation" + } + } + } + } + }; + exports2.MessageActionsPayloadBody = { + serializedName: "MessageActionsPayload_body", + type: { + name: "Composite", + className: "MessageActionsPayloadBody", + modelProperties: { + contentType: { + serializedName: "contentType", + type: { + name: "String" + } + }, + content: { + serializedName: "content", + type: { + name: "String" + } + }, + textContent: { + serializedName: "textContent", + type: { + name: "String" + } + } + } + } + }; + exports2.MessageActionsPayloadAttachment = { + serializedName: "MessageActionsPayloadAttachment", + type: { + name: "Composite", + className: "MessageActionsPayloadAttachment", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + contentType: { + serializedName: "contentType", + type: { + name: "String" + } + }, + contentUrl: { + serializedName: "contentUrl", + type: { + name: "String" + } + }, + content: { + serializedName: "content", + type: { + name: "Object" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + thumbnailUrl: { + serializedName: "thumbnailUrl", + type: { + name: "String" + } + } + } + } + }; + exports2.MessageActionsPayloadMention = { + serializedName: "MessageActionsPayloadMention", + type: { + name: "Composite", + className: "MessageActionsPayloadMention", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "Number" + } + }, + mentionText: { + serializedName: "mentionText", + type: { + name: "String" + } + }, + mentioned: { + serializedName: "mentioned", + type: { + name: "Composite", + className: "MessageActionsPayloadFrom" + } + } + } + } + }; + exports2.MessageActionsPayloadReaction = { + serializedName: "MessageActionsPayloadReaction", + type: { + name: "Composite", + className: "MessageActionsPayloadReaction", + modelProperties: { + reactionType: { + serializedName: "reactionType", + type: { + name: "String" + } + }, + createdDateTime: { + serializedName: "createdDateTime", + type: { + name: "String" + } + }, + user: { + serializedName: "user", + type: { + name: "Composite", + className: "MessageActionsPayloadFrom" + } + } + } + } + }; + exports2.MessageActionsPayload = { + serializedName: "MessageActionsPayload", + type: { + name: "Composite", + className: "MessageActionsPayload", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + }, + replyToId: { + serializedName: "replyToId", + type: { + name: "String" + } + }, + messageType: { + serializedName: "messageType", + type: { + name: "String" + } + }, + createdDateTime: { + serializedName: "createdDateTime", + type: { + name: "String" + } + }, + lastModifiedDateTime: { + serializedName: "lastModifiedDateTime", + type: { + name: "String" + } + }, + deleted: { + serializedName: "deleted", + type: { + name: "Boolean" + } + }, + subject: { + serializedName: "subject", + type: { + name: "String" + } + }, + summary: { + serializedName: "summary", + type: { + name: "String" + } + }, + importance: { + serializedName: "importance", + type: { + name: "String" + } + }, + locale: { + serializedName: "locale", + type: { + name: "String" + } + }, + from: { + serializedName: "from", + type: { + name: "Composite", + className: "MessageActionsPayloadFrom" + } + }, + body: { + serializedName: "body", + type: { + name: "Composite", + className: "MessageActionsPayloadBody" + } + }, + attachmentLayout: { + serializedName: "attachmentLayout", + type: { + name: "String" + } + }, + attachments: { + serializedName: "attachments", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MessageActionsPayloadAttachment" + } + } + } + }, + mentions: { + serializedName: "mentions", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MessageActionsPayloadMention" + } + } + } + }, + reactions: { + serializedName: "reactions", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MessageActionsPayloadReaction" + } + } + } + }, + linkToMessage: { + serializedName: "linkToMessage", + type: { + name: "String" + } + } + } + } + }; + exports2.TaskModuleRequest = { + serializedName: "TaskModuleRequest", + type: { + name: "Composite", + className: "TaskModuleRequest", + modelProperties: { + data: { + serializedName: "data", + type: { + name: "Object" + } + }, + context: { + serializedName: "context", + type: { + name: "Composite", + className: "TaskModuleRequestContext" + } + } + } + } + }; + exports2.MessagingExtensionAction = { + serializedName: "MessagingExtensionAction", + type: { + name: "Composite", + className: "MessagingExtensionAction", + modelProperties: Object.assign(Object.assign({}, exports2.TaskModuleRequest.type.modelProperties), { commandId: { + serializedName: "commandId", + type: { + name: "String" + } + }, commandContext: { + serializedName: "commandContext", + type: { + name: "String" + } + }, botMessagePreviewAction: { + serializedName: "botMessagePreviewAction", + type: { + name: "String" + } + }, botActivityPreview: { + serializedName: "botActivityPreview", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "Activity" + } + } + } + }, messagePayload: { + serializedName: "messagePayload", + type: { + name: "Composite", + className: "MessageActionsPayload" + } + } }) + } + }; + exports2.TaskModuleResponseBase = { + serializedName: "TaskModuleResponseBase", + type: { + name: "Composite", + className: "TaskModuleResponseBase", + modelProperties: { + type: { + serializedName: "type", + type: { + name: "String" + } + } + } + } + }; + exports2.Attachment = { + serializedName: "Attachment", + type: { + name: "Composite", + className: "Attachment", + modelProperties: { + contentType: { + serializedName: "contentType", + type: { + name: "String" + } + }, + contentUrl: { + serializedName: "contentUrl", + type: { + name: "String" + } + }, + content: { + serializedName: "content", + type: { + name: "Object" + } + }, + name: { + serializedName: "name", + type: { + name: "String" + } + }, + thumbnailUrl: { + serializedName: "thumbnailUrl", + type: { + name: "String" + } + } + } + } + }; + exports2.MessagingExtensionAttachment = { + serializedName: "MessagingExtensionAttachment", + type: { + name: "Composite", + className: "MessagingExtensionAttachment", + modelProperties: Object.assign(Object.assign({}, exports2.Attachment.type.modelProperties), { preview: { + serializedName: "preview", + type: { + name: "Composite", + className: "Attachment" + } + } }) + } + }; + exports2.MessagingExtensionSuggestedAction = { + serializedName: "MessagingExtensionSuggestedAction", + type: { + name: "Composite", + className: "MessagingExtensionSuggestedAction", + modelProperties: { + actions: { + serializedName: "actions", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "CardAction" + } + } + } + } + } + } + }; + exports2.MessagingExtensionResult = { + serializedName: "MessagingExtensionResult", + type: { + name: "Composite", + className: "MessagingExtensionResult", + modelProperties: { + attachmentLayout: { + serializedName: "attachmentLayout", + type: { + name: "String" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + }, + attachments: { + serializedName: "attachments", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "MessagingExtensionAttachment" + } + } + } + }, + suggestedActions: { + serializedName: "suggestedActions", + type: { + name: "Composite", + className: "MessagingExtensionSuggestedAction" + } + }, + text: { + serializedName: "text", + type: { + name: "String" + } + }, + activityPreview: { + serializedName: "activityPreview", + type: { + name: "Composite", + className: "Activity" + } + } + } + } + }; + exports2.CacheInfo = { + serializedName: "cacheInfo", + type: { + name: "Composite", + className: "cacheInfo", + modelProperties: { + cacheType: { + serializedName: "cacheType", + type: { + name: "String" + } + }, + cacheDuration: { + serializedName: "cacheDuration", + type: { + name: "Number" + } + } + } + } + }; + exports2.MessagingExtensionActionResponse = { + serializedName: "MessagingExtensionActionResponse", + type: { + name: "Composite", + className: "MessagingExtensionActionResponse", + modelProperties: { + task: { + serializedName: "task", + type: { + name: "Composite", + className: "TaskModuleResponseBase" + } + }, + composeExtension: { + serializedName: "composeExtension", + type: { + name: "Composite", + className: "MessagingExtensionResult" + } + }, + cacheInfo: { + serializedName: "cacheInfo", + type: { + name: "Composite", + className: "cacheInfo" + } + } + } + } + }; + exports2.MessagingExtensionResponse = { + serializedName: "MessagingExtensionResponse", + type: { + name: "Composite", + className: "MessagingExtensionResponse", + modelProperties: { + composeExtension: { + serializedName: "composeExtension", + type: { + name: "Composite", + className: "MessagingExtensionResult" + } + }, + cacheInfo: { + serializedName: "cacheInfo", + type: { + name: "Composite", + className: "cacheInfo" + } + } + } + } + }; + exports2.FileConsentCard = { + serializedName: "FileConsentCard", + type: { + name: "Composite", + className: "FileConsentCard", + modelProperties: { + description: { + serializedName: "description", + type: { + name: "String" + } + }, + sizeInBytes: { + serializedName: "sizeInBytes", + type: { + name: "Number" + } + }, + acceptContext: { + serializedName: "acceptContext", + type: { + name: "Object" + } + }, + declineContext: { + serializedName: "declineContext", + type: { + name: "Object" + } + } + } + } + }; + exports2.FileDownloadInfo = { + serializedName: "FileDownloadInfo", + type: { + name: "Composite", + className: "FileDownloadInfo", + modelProperties: { + downloadUrl: { + serializedName: "downloadUrl", + type: { + name: "String" + } + }, + uniqueId: { + serializedName: "uniqueId", + type: { + name: "String" + } + }, + fileType: { + serializedName: "fileType", + type: { + name: "String" + } + }, + etag: { + serializedName: "etag", + type: { + name: "Object" + } + } + } + } + }; + exports2.FileInfoCard = { + serializedName: "FileInfoCard", + type: { + name: "Composite", + className: "FileInfoCard", + modelProperties: { + uniqueId: { + serializedName: "uniqueId", + type: { + name: "String" + } + }, + fileType: { + serializedName: "fileType", + type: { + name: "String" + } + }, + etag: { + serializedName: "etag", + type: { + name: "Object" + } + } + } + } + }; + exports2.FileUploadInfo = { + serializedName: "FileUploadInfo", + type: { + name: "Composite", + className: "FileUploadInfo", + modelProperties: { + name: { + serializedName: "name", + type: { + name: "String" + } + }, + uploadUrl: { + serializedName: "uploadUrl", + type: { + name: "String" + } + }, + contentUrl: { + serializedName: "contentUrl", + type: { + name: "String" + } + }, + uniqueId: { + serializedName: "uniqueId", + type: { + name: "String" + } + }, + fileType: { + serializedName: "fileType", + type: { + name: "String" + } + } + } + } + }; + exports2.FileConsentCardResponse = { + serializedName: "FileConsentCardResponse", + type: { + name: "Composite", + className: "FileConsentCardResponse", + modelProperties: { + action: { + serializedName: "action", + type: { + name: "String" + } + }, + context: { + serializedName: "context", + type: { + name: "Object" + } + }, + uploadInfo: { + serializedName: "uploadInfo", + type: { + name: "Composite", + className: "FileUploadInfo" + } + } + } + } + }; + exports2.TaskModuleTaskInfo = { + serializedName: "TaskModuleTaskInfo", + type: { + name: "Composite", + className: "TaskModuleTaskInfo", + modelProperties: { + title: { + serializedName: "title", + type: { + name: "String" + } + }, + height: { + serializedName: "height", + type: { + name: "Object" + } + }, + width: { + serializedName: "width", + type: { + name: "Object" + } + }, + url: { + serializedName: "url", + type: { + name: "String" + } + }, + card: { + serializedName: "card", + type: { + name: "Composite", + className: "Attachment" + } + }, + fallbackUrl: { + serializedName: "fallbackUrl", + type: { + name: "String" + } + }, + completionBotId: { + serializedName: "completionBotId", + type: { + name: "String" + } + } + } + } + }; + exports2.TaskModuleContinueResponse = { + serializedName: "TaskModuleContinueResponse", + type: { + name: "Composite", + className: "TaskModuleContinueResponse", + modelProperties: Object.assign(Object.assign({}, exports2.TaskModuleResponseBase.type.modelProperties), { value: { + serializedName: "value", + type: { + name: "Composite", + className: "TaskModuleTaskInfo" + } + } }) + } + }; + exports2.TaskModuleMessageResponse = { + serializedName: "TaskModuleMessageResponse", + type: { + name: "Composite", + className: "TaskModuleMessageResponse", + modelProperties: Object.assign(Object.assign({}, exports2.TaskModuleResponseBase.type.modelProperties), { value: { + serializedName: "value", + type: { + name: "String" + } + } }) + } + }; + exports2.TaskModuleResponse = { + serializedName: "TaskModuleResponse", + type: { + name: "Composite", + className: "TaskModuleResponse", + modelProperties: { + task: { + serializedName: "task", + type: { + name: "Composite", + className: "TaskModuleResponseBase" + } + }, + cacheInfo: { + serializedName: "cacheInfo", + type: { + name: "Composite", + className: "cacheInfo" + } + } + } + } + }; + exports2.TaskModuleRequestContext = { + serializedName: "TaskModuleRequest_context", + type: { + name: "Composite", + className: "TaskModuleRequestContext", + modelProperties: { + theme: { + serializedName: "theme", + type: { + name: "String" + } + } + } + } + }; + exports2.AppBasedLinkQuery = { + serializedName: "AppBasedLinkQuery", + type: { + name: "Composite", + className: "AppBasedLinkQuery", + modelProperties: { + url: { + serializedName: "url", + type: { + name: "String" + } + }, + state: { + serializedName: "state", + type: { + name: "String" + } + } + } + } + }; + exports2.BatchOperationRequest = { + serializedName: "BatchOperationRequest", + type: { + name: "Composite", + className: "BatchOperationRequest", + modelProperties: { + activity: { + serializedName: "activity", + type: { + name: "Composite", + className: "Activity", + modelProperties: { + text: { + serializedName: "text", + type: { + name: "String" + } + }, + type: { + serializedName: "type", + type: { + name: "String" + } + } + } + } + }, + tenantId: { + serializedName: "tenantId", + type: { + name: "String" + } + }, + teamId: { + serializedName: "teamId", + type: { + name: "String" + } + }, + members: { + serializedName: "members", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "TeamsMember", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + } + } + } + } + } + } + } + } + }; + exports2.BatchOperationResponse = { + serializedName: "BatchOperationResponse", + type: { + name: "Composite", + className: "BatchOperationResponse", + modelProperties: { + operationId: { + serializedName: "operationId", + type: { + name: "String" + } + } + } + } + }; + exports2.GetTeamsOperationStateResponse = { + serializedName: "GetTeamsOperationStateResponse", + type: { + name: "Composite", + className: "GetTeamsOperationStateResponse", + modelProperties: { + state: { + serializedName: "state", + type: { + name: "String" + } + }, + stateMap: { + serializedName: "stateMap", + type: { + name: "Dictionary", + value: { + type: { + name: "Number" + } + } + } + }, + retryAfter: { + serializedName: "retryAfter", + type: { + name: "DateTime" + } + }, + totalEntriesCount: { + serializedName: "totalEntriesCount", + type: { + name: "Number" + } + } + } + } + }; + exports2.GetTeamsFailedEntriesResponse = { + serializedName: "BatchFailedEntriesResponse", + type: { + name: "Composite", + className: "BatchFailedEntriesResponse", + modelProperties: { + continuationToken: { + serializedName: "continuationToken", + type: { + name: "String" + } + }, + failedEntryResponses: { + serializedName: "failedEntryResponses", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "BatchFailedEntry", + modelProperties: { + id: { + serializedName: "Id", + type: { + name: "String" + } + }, + error: { + serializedName: "error", + type: { + name: "String" + } + } + } + } + } + } + } + } + } + }; + exports2.TeamsMember = { + serializedName: "TeamsMember", + type: { + name: "Composite", + className: "TeamsMember", + modelProperties: { + id: { + serializedName: "id", + type: { + name: "String" + } + } + } + } + }; + } +}); + +// node_modules/botframework-connector/lib/teams/models/teamsMappers.js +var require_teamsMappers = __commonJS({ + "node_modules/botframework-connector/lib/teams/models/teamsMappers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TeamsMember = exports2.GetTeamsOperationStateResponse = exports2.GetTeamsFailedEntriesResponse = exports2.BatchOperationResponse = exports2.BatchOperationRequest = exports2.Attachment = exports2.TaskModuleTaskInfo = exports2.TaskModuleContinueResponse = exports2.MeetingNotificationResponse = exports2.MeetingNotificationRecipientFailureInfo = exports2.OnBehalfOf = exports2.MeetingNotificationChannelData = exports2.MeetingNotification = exports2.TeamsMeetingParticipant = exports2.TeamsMeetingInfo = exports2.TeamsMeetingDetails = exports2.TeamsChannelAccount = exports2.TeamDetails = exports2.Meeting = exports2.MessageActionsPayloadConversation = exports2.ChannelInfo = exports2.ConversationList = exports2.Activity = exports2.InnerHttpError = exports2.ErrorModel = exports2.ErrorResponse = void 0; + var mappers_1 = require_mappers(); + Object.defineProperty(exports2, "ErrorResponse", { enumerable: true, get: function() { + return mappers_1.ErrorResponse; + } }); + Object.defineProperty(exports2, "ErrorModel", { enumerable: true, get: function() { + return mappers_1.ErrorModel; + } }); + Object.defineProperty(exports2, "InnerHttpError", { enumerable: true, get: function() { + return mappers_1.InnerHttpError; + } }); + var mappers_2 = require_mappers3(); + Object.defineProperty(exports2, "Activity", { enumerable: true, get: function() { + return mappers_2.Activity; + } }); + Object.defineProperty(exports2, "ConversationList", { enumerable: true, get: function() { + return mappers_2.ConversationList; + } }); + Object.defineProperty(exports2, "ChannelInfo", { enumerable: true, get: function() { + return mappers_2.ChannelInfo; + } }); + Object.defineProperty(exports2, "MessageActionsPayloadConversation", { enumerable: true, get: function() { + return mappers_2.MessageActionsPayloadConversation; + } }); + Object.defineProperty(exports2, "Meeting", { enumerable: true, get: function() { + return mappers_2.Meeting; + } }); + Object.defineProperty(exports2, "TeamDetails", { enumerable: true, get: function() { + return mappers_2.TeamDetails; + } }); + Object.defineProperty(exports2, "TeamsChannelAccount", { enumerable: true, get: function() { + return mappers_2.TeamsChannelAccount; + } }); + Object.defineProperty(exports2, "TeamsMeetingDetails", { enumerable: true, get: function() { + return mappers_2.TeamsMeetingDetails; + } }); + Object.defineProperty(exports2, "TeamsMeetingInfo", { enumerable: true, get: function() { + return mappers_2.TeamsMeetingInfo; + } }); + Object.defineProperty(exports2, "TeamsMeetingParticipant", { enumerable: true, get: function() { + return mappers_2.TeamsMeetingParticipant; + } }); + Object.defineProperty(exports2, "MeetingNotification", { enumerable: true, get: function() { + return mappers_2.MeetingNotification; + } }); + Object.defineProperty(exports2, "MeetingNotificationChannelData", { enumerable: true, get: function() { + return mappers_2.MeetingNotificationChannelData; + } }); + Object.defineProperty(exports2, "OnBehalfOf", { enumerable: true, get: function() { + return mappers_2.OnBehalfOf; + } }); + Object.defineProperty(exports2, "MeetingNotificationRecipientFailureInfo", { enumerable: true, get: function() { + return mappers_2.MeetingNotificationRecipientFailureInfo; + } }); + Object.defineProperty(exports2, "MeetingNotificationResponse", { enumerable: true, get: function() { + return mappers_2.MeetingNotificationResponse; + } }); + Object.defineProperty(exports2, "TaskModuleContinueResponse", { enumerable: true, get: function() { + return mappers_2.TaskModuleContinueResponse; + } }); + Object.defineProperty(exports2, "TaskModuleTaskInfo", { enumerable: true, get: function() { + return mappers_2.TaskModuleTaskInfo; + } }); + Object.defineProperty(exports2, "Attachment", { enumerable: true, get: function() { + return mappers_2.Attachment; + } }); + Object.defineProperty(exports2, "BatchOperationRequest", { enumerable: true, get: function() { + return mappers_2.BatchOperationRequest; + } }); + Object.defineProperty(exports2, "BatchOperationResponse", { enumerable: true, get: function() { + return mappers_2.BatchOperationResponse; + } }); + Object.defineProperty(exports2, "GetTeamsFailedEntriesResponse", { enumerable: true, get: function() { + return mappers_2.GetTeamsFailedEntriesResponse; + } }); + Object.defineProperty(exports2, "GetTeamsOperationStateResponse", { enumerable: true, get: function() { + return mappers_2.GetTeamsOperationStateResponse; + } }); + Object.defineProperty(exports2, "TeamsMember", { enumerable: true, get: function() { + return mappers_2.TeamsMember; + } }); + } +}); + +// node_modules/botframework-connector/lib/teams/models/parameters.js +var require_parameters3 = __commonJS({ + "node_modules/botframework-connector/lib/teams/models/parameters.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.operationId = exports2.tenantId = exports2.participantId = exports2.meetingId = exports2.teamId = void 0; + exports2.teamId = { + parameterPath: "teamId", + mapper: { + required: true, + serializedName: "teamId", + type: { + name: "String" + } + } + }; + exports2.meetingId = { + parameterPath: "meetingId", + mapper: { + required: true, + serializedName: "meetingId", + type: { + name: "String" + } + } + }; + exports2.participantId = { + parameterPath: "participantId", + mapper: { + required: true, + serializedName: "participantId", + type: { + name: "String" + } + } + }; + exports2.tenantId = { + parameterPath: ["options", "tenantId"], + mapper: { + serializedName: "tenantId", + type: { + name: "String" + } + } + }; + exports2.operationId = { + parameterPath: "operationId", + mapper: { + serializedName: "operationId", + type: { + name: "String" + } + } + }; + } +}); + +// node_modules/botframework-connector/lib/teams/operations/teams.js +var require_teams2 = __commonJS({ + "node_modules/botframework-connector/lib/teams/operations/teams.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Teams = void 0; + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var Mappers = __importStar2(require_teamsMappers()); + var Parameters = __importStar2(require_parameters3()); + var __1 = require_teams3(); + var Teams = class { + /** + * Create a Teams. + * + * @param {TeamsConnectorClientContext} client Reference to the service client. + */ + constructor(client) { + this.retryCount = 10; + this.client = client; + } + /** + * Fetches channel list for a given team. + * + * @param teamId Team Id. + * @param options Optional. The options object to be used in every request. + * @param callback The callback. + * @returns A `Promise`. + */ + fetchChannelList(teamId, options, callback) { + return this.client.sendOperationRequest({ + teamId, + options + }, fetchChannelListOperationSpec, callback); + } + /** + * Fetches details related to a team. + * + * @param teamId Team Id. + * @param options Optional. The options object to be used in every request. + * @param callback The callback. + * @returns A `Promise`. + */ + fetchTeamDetails(teamId, options, callback) { + return this.client.sendOperationRequest({ + teamId, + options + }, fetchTeamDetailsOperationSpec, callback); + } + /** + * @param meetingId Meeting Id. + * @param participantId Participant Id. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with TeamsFetchMeetingParticipantResponse. + */ + fetchMeetingParticipant(meetingId, participantId, options, callback) { + return this.client.sendOperationRequest({ + meetingId, + participantId, + options + }, fetchMeetingParticipantOperationSpec, callback); + } + /** + * @param meetingId Meeting Id. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with TeamsFetchMeetingInfoResponse. + */ + fetchMeetingInfo(meetingId, options, callback) { + return this.client.sendOperationRequest({ + meetingId, + options + }, fetchMeetingInfoOperationSpec, callback); + } + /** + * @param meetingId Meeting Id. + * @param notification The content and configuration for the notification to send. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with either MeetingNotificationResponse or an empty object. + */ + sendMeetingNotification(meetingId, notification, options, callback) { + return this.client.sendOperationRequest({ + meetingId, + notification, + options + }, sendMeetingNotificationOperationSpec, callback); + } + //Batch Operations + /** + * Send message to a list of users. + * + * @param activity The activity to send. + * @param tenantId The tenant Id. + * @param members The list of members. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with TeamsBatchOperationResponse. + */ + sendMessageToListOfUsers(activity, tenantId, members, options, callback) { + const content = { + activity, + members, + tenantId + }; + return (0, __1.retryAction)(() => this.client.sendOperationRequest({ + content, + options + }, sendMessageToListOfUsersOperationSpec, callback), this.retryCount); + } + /** + * Send message to all users belonging to a tenant. + * + * @param activity The activity to send. + * @param tenantId The id of the recipient Tenant. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with TeamsBatchOperationResponse. + */ + sendMessageToAllUsersInTenant(activity, tenantId, options, callback) { + const content = { + activity, + tenantId + }; + return (0, __1.retryAction)(() => this.client.sendOperationRequest({ + content, + options + }, sendMessageToAllUsersInTenantOperationSpec, callback), this.retryCount); + } + /** + * Send message to all users belonging to a team. + * + * @param activity The activity to send. + * @param tenantId The tenant Id. + * @param teamId The id of the recipient Team. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with TeamsBatchOperationResponse. + */ + sendMessageToAllUsersInTeam(activity, tenantId, teamId, options, callback) { + const content = { + activity, + tenantId, + teamId + }; + return (0, __1.retryAction)(() => this.client.sendOperationRequest({ + content, + options + }, sendMessageToAllUsersInTeamOperationSpec, callback), this.retryCount); + } + /** + * Send message to a list of channels. + * + * @param activity The activity to send. + * @param tenantId The tenant Id. + * @param members The list of channels. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with TeamsBatchOperationResponse. + */ + sendMessageToListOfChannels(activity, tenantId, members, options, callback) { + const content = { + activity, + tenantId, + members + }; + return (0, __1.retryAction)(() => this.client.sendOperationRequest({ + content, + options + }, sendMessageToListOfChannelsOperationSpec, callback), this.retryCount); + } + /** + * Get the state of an operation. + * + * @param operationId The operationId to get the state of. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with BatchOperationStateResponse. + */ + getOperationState(operationId, options, callback) { + return (0, __1.retryAction)(() => this.client.sendOperationRequest({ + operationId, + options + }, getOperationStateSpec, callback), this.retryCount); + } + /** + * Get the failed entries of an operation. + * + * @param operationId The operationId to get the failed entries of. + * @param options The optional parameters. + * @param callback The callback. + * @returns Promise with BatchFailedEntriesResponse. + */ + getOperationFailedEntries(operationId, options, callback) { + return (0, __1.retryAction)(() => this.client.sendOperationRequest({ + operationId, + options + }, getPagedFailedEntriesSpec, callback), this.retryCount); + } + /** + * Cancel an operation. + * + * @param operationId The id of the operation to cancel. + * @param options The optional parameters. + * @returns Promise with CancelOperationResponse. + */ + cancelOperation(operationId, options) { + return (0, __1.retryAction)(() => this.client.sendOperationRequest({ + operationId, + options + }, cancelOperationSpec), this.retryCount); + } + }; + exports2.Teams = Teams; + var serializer = (0, azureCoreHttpCompat_1.createSerializer)(Mappers); + var fetchChannelListOperationSpec = { + httpMethod: "GET", + path: "v3/teams/{teamId}/conversations", + urlParameters: [Parameters.teamId], + responses: { + 200: { + bodyMapper: Mappers.ConversationList + }, + default: {} + }, + serializer + }; + var fetchTeamDetailsOperationSpec = { + httpMethod: "GET", + path: "v3/teams/{teamId}", + urlParameters: [Parameters.teamId], + responses: { + 200: { + bodyMapper: Mappers.TeamDetails + }, + default: {} + }, + serializer + }; + var fetchMeetingParticipantOperationSpec = { + httpMethod: "GET", + path: "v1/meetings/{meetingId}/participants/{participantId}", + urlParameters: [Parameters.meetingId, Parameters.participantId], + queryParameters: [Parameters.tenantId], + responses: { + 200: { + bodyMapper: Mappers.TeamsMeetingParticipant + }, + default: {} + }, + serializer + }; + var fetchMeetingInfoOperationSpec = { + httpMethod: "GET", + path: "v1/meetings/{meetingId}", + urlParameters: [Parameters.meetingId], + responses: { + 200: { + bodyMapper: Mappers.TeamsMeetingInfo + }, + default: {} + }, + serializer + }; + var sendMeetingNotificationOperationSpec = { + httpMethod: "POST", + path: "v1/meetings/{meetingId}/notification", + urlParameters: [Parameters.meetingId], + requestBody: { + parameterPath: "notification", + mapper: Object.assign(Object.assign({}, Mappers.MeetingNotification), { required: true }) + }, + responses: { + 202: { + bodyMapper: Mappers.MeetingNotificationResponse + }, + 207: { + bodyMapper: Mappers.MeetingNotificationResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var sendMessageToListOfUsersOperationSpec = { + httpMethod: "POST", + path: "v3/batch/conversation/users", + requestBody: { + parameterPath: "content", + mapper: Object.assign(Object.assign({}, Mappers.BatchOperationRequest), { required: true }) + }, + responses: { + 201: { + bodyMapper: Mappers.BatchOperationResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var sendMessageToAllUsersInTenantOperationSpec = { + httpMethod: "POST", + path: "v3/batch/conversation/tenant", + requestBody: { + parameterPath: "content", + mapper: Object.assign(Object.assign({}, Mappers.BatchOperationRequest), { required: true }) + }, + responses: { + 201: { + bodyMapper: Mappers.BatchOperationResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var sendMessageToAllUsersInTeamOperationSpec = { + httpMethod: "POST", + path: "v3/batch/conversation/team", + requestBody: { + parameterPath: "content", + mapper: Object.assign(Object.assign({}, Mappers.BatchOperationRequest), { required: true }) + }, + responses: { + 201: { + bodyMapper: Mappers.BatchOperationResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var sendMessageToListOfChannelsOperationSpec = { + httpMethod: "POST", + path: "v3/batch/conversation/channels", + requestBody: { + parameterPath: "content", + mapper: Object.assign(Object.assign({}, Mappers.BatchOperationRequest), { required: true }) + }, + responses: { + 201: { + bodyMapper: Mappers.BatchOperationResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getOperationStateSpec = { + httpMethod: "GET", + path: "v3/batch/conversation/{operationId}", + urlParameters: [Parameters.operationId], + responses: { + 200: { + bodyMapper: Mappers.GetTeamsOperationStateResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var getPagedFailedEntriesSpec = { + httpMethod: "GET", + path: "v3/batch/conversation/failedentries/{operationId}", + urlParameters: [Parameters.operationId], + responses: { + 200: { + bodyMapper: Mappers.GetTeamsFailedEntriesResponse + }, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + var cancelOperationSpec = { + httpMethod: "DELETE", + path: "v3/batch/conversation/{operationId}", + urlParameters: [Parameters.operationId], + responses: { + 200: {}, + default: { + bodyMapper: Mappers.ErrorResponse + } + }, + serializer + }; + } +}); + +// node_modules/botframework-connector/lib/teams/operations/index.js +var require_operations3 = __commonJS({ + "node_modules/botframework-connector/lib/teams/operations/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_teams2(), exports2); + } +}); + +// node_modules/botframework-connector/lib/teams/teamsConnectorClientContext.js +var require_teamsConnectorClientContext = __commonJS({ + "node_modules/botframework-connector/lib/teams/teamsConnectorClientContext.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TeamsConnectorClientContext = void 0; + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var TeamsConnectorClientContext = class extends azureCoreHttpCompat_1.ServiceClientContext { + /** + * Initializes a new instance of the TeamsConnectorClientContext class. + * + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials, options) { + super(credentials, Object.assign(Object.assign({}, options), { baseUri: (options === null || options === void 0 ? void 0 : options.baseUri) || "https://api.botframework.com" })); + } + }; + exports2.TeamsConnectorClientContext = TeamsConnectorClientContext; + } +}); + +// node_modules/botframework-connector/lib/teams/teamsConnectorClient.js +var require_teamsConnectorClient = __commonJS({ + "node_modules/botframework-connector/lib/teams/teamsConnectorClient.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TeamsConnectorMappers = exports2.TeamsConnectorModels = exports2.TeamsConnectorClient = void 0; + var Models = __importStar2(require_models3()); + exports2.TeamsConnectorModels = Models; + var Mappers = __importStar2(require_mappers3()); + exports2.TeamsConnectorMappers = Mappers; + var operations = __importStar2(require_operations3()); + var teamsConnectorClientContext_1 = require_teamsConnectorClientContext(); + var TeamsConnectorClient = class extends teamsConnectorClientContext_1.TeamsConnectorClientContext { + /** + * Initializes a new instance of the TeamsConnectorClient class. + * + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials, options) { + super(credentials, options); + this.teams = new operations.Teams(this); + } + }; + exports2.TeamsConnectorClient = TeamsConnectorClient; + __exportStar2(require_operations3(), exports2); + } +}); + +// node_modules/botframework-connector/lib/teams/readReceiptInfo.js +var require_readReceiptInfo = __commonJS({ + "node_modules/botframework-connector/lib/teams/readReceiptInfo.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ReadReceiptInfo = void 0; + var ReadReceiptInfo = class _ReadReceiptInfo { + /** + * Initializes a new instance of the ReadReceiptInfo class. + * + * @param lastReadMessageId Optional. The id of the last read message. + */ + constructor(lastReadMessageId) { + this.lastReadMessageId = lastReadMessageId; + } + /** + * Helper method useful for determining if a message has been read. This method + * converts the strings to numbers. If the compareMessageId is less than or equal to + * the lastReadMessageId, then the message has been read. + * + * @param compareMessageId The id of the message to compare. + * @param lastReadMessageId The id of the last message read by the user. + * @returns True if the compareMessageId is less than or equal to the lastReadMessageId. + */ + static isMessageRead(compareMessageId, lastReadMessageId) { + if (compareMessageId && compareMessageId.trim().length > 0 && lastReadMessageId && lastReadMessageId.trim().length > 0) { + const compareMessageIdNum = Number(compareMessageId); + const lastReadMessageIdNum = Number(lastReadMessageId); + if (compareMessageIdNum && lastReadMessageIdNum) { + return compareMessageIdNum <= lastReadMessageIdNum; + } + } + return false; + } + /** + * Helper method useful for determining if a message has been read. + * If the compareMessageId is less than or equal to the lastReadMessageId, then the message has been read. + * + * @param compareMessageId The id of the message to compare. + * @returns True if the compareMessageId is less than or equal to the lastReadMessageId. + */ + isMessageRead(compareMessageId) { + return _ReadReceiptInfo.isMessageRead(compareMessageId, this.lastReadMessageId); + } + }; + exports2.ReadReceiptInfo = ReadReceiptInfo; + } +}); + +// node_modules/botframework-connector/lib/teams/retryAction.js +var require_retryAction = __commonJS({ + "node_modules/botframework-connector/lib/teams/retryAction.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.retryAction = void 0; + function retryAction(promise, maxRetries, initialDelay = 500) { + return __awaiter2(this, void 0, void 0, function* () { + let delay = initialDelay, n = 1; + let errStatusCode; + const errorsArray = []; + maxRetries = Math.max(maxRetries, 1); + do { + try { + return yield promise(n); + } catch (err) { + errorsArray.push(err); + errStatusCode = err.statusCode; + if (err.statusCode == 429) { + yield new Promise((resolve) => setTimeout(resolve, delay)); + delay *= n; + n++; + } + } + } while (n <= maxRetries && errStatusCode === 429); + throw { errors: errorsArray, message: "Failed to perform the required operation." }; + }); + } + exports2.retryAction = retryAction; + } +}); + +// node_modules/botframework-connector/lib/teams/index.js +var require_teams3 = __commonJS({ + "node_modules/botframework-connector/lib/teams/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_teamsConnectorClient(), exports2); + __exportStar2(require_teamsConnectorClientContext(), exports2); + __exportStar2(require_models3(), exports2); + __exportStar2(require_readReceiptInfo(), exports2); + __exportStar2(require_retryAction(), exports2); + } +}); + +// node_modules/cross-fetch/dist/node-ponyfill.js +var require_node_ponyfill = __commonJS({ + "node_modules/cross-fetch/dist/node-ponyfill.js"(exports2, module2) { + var nodeFetch = require_lib7(); + var realFetch = nodeFetch.default || nodeFetch; + var fetch2 = function(url, options) { + if (/^\/\//.test(url)) { + url = "https:" + url; + } + return realFetch.call(this, url, options); + }; + fetch2.ponyfill = true; + module2.exports = exports2 = fetch2; + exports2.fetch = fetch2; + exports2.Headers = nodeFetch.Headers; + exports2.Request = nodeFetch.Request; + exports2.Response = nodeFetch.Response; + exports2.default = fetch2; + } +}); + +// node_modules/botframework-connector/lib/emulatorApiClient.js +var require_emulatorApiClient = __commonJS({ + "node_modules/botframework-connector/lib/emulatorApiClient.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.EmulatorApiClient = void 0; + var cross_fetch_1 = __importDefault2(require_node_ponyfill()); + var EmulatorApiClient = class { + /** + * OAuth card emulation. + * + * @remarks If the emulation fails, an error containing the status code from the server is thrown. + * + * @param credentials [AppCredentials](xref:botframework-connector.AppCredentials) for OAuth. + * @param emulatorUrl The URL of the emulator. + * @param emulate `true` to send an emulated OAuth card to the emulator; or `false` to not send the card. + * @returns `true` on a successful emulation of OAuthCards. + */ + static emulateOAuthCards(credentials, emulatorUrl, emulate) { + return __awaiter2(this, void 0, void 0, function* () { + const token = yield credentials.getToken(); + const requestUrl = emulatorUrl + (emulatorUrl.endsWith("/") ? "" : "/") + `api/usertoken/emulateOAuthCards?emulate=${(!!emulate).toString()}`; + const res = yield (0, cross_fetch_1.default)(requestUrl, { + method: "POST", + headers: { + Authorization: `Bearer ${token}` + } + }); + if (res.ok) { + return true; + } else { + throw new Error(`EmulateOAuthCards failed with status code: ${res.status}`); + } + }); + } + }; + exports2.EmulatorApiClient = EmulatorApiClient; + } +}); + +// node_modules/botframework-connector/lib/index.js +var require_lib9 = __commonJS({ + "node_modules/botframework-connector/lib/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ConversationConstants = exports2.TokenApiModels = exports2.TokenApiClient = exports2.EmulatorApiClient = exports2.ConnectorClient = void 0; + __exportStar2(require_auth(), exports2); + __exportStar2(require_teams3(), exports2); + __exportStar2(require_models2(), exports2); + var connectorClient_1 = require_connectorClient(); + Object.defineProperty(exports2, "ConnectorClient", { enumerable: true, get: function() { + return connectorClient_1.ConnectorClient; + } }); + var emulatorApiClient_1 = require_emulatorApiClient(); + Object.defineProperty(exports2, "EmulatorApiClient", { enumerable: true, get: function() { + return emulatorApiClient_1.EmulatorApiClient; + } }); + var tokenApiClient_1 = require_tokenApiClient(); + Object.defineProperty(exports2, "TokenApiClient", { enumerable: true, get: function() { + return tokenApiClient_1.TokenApiClient; + } }); + Object.defineProperty(exports2, "TokenApiModels", { enumerable: true, get: function() { + return tokenApiClient_1.TokenApiModels; + } }); + exports2.ConversationConstants = __importStar2(require_conversationConstants()); + } +}); + +// node_modules/botbuilder-core/lib/configurationServiceClientCredentialFactory.js +var require_configurationServiceClientCredentialFactory = __commonJS({ + "node_modules/botbuilder-core/lib/configurationServiceClientCredentialFactory.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createServiceClientCredentialFactoryFromConfiguration = exports2.ConfigurationServiceClientCredentialFactory = void 0; + var z = __importStar2(require_zod()); + var assert_1 = require("assert"); + var botframework_connector_1 = require_lib9(); + var MultiTenant = "MultiTenant"; + var SingleTenant = "SingleTenant"; + var UserAssignedMsi = "UserAssignedMsi"; + var TypedConfig = z.object({ + /** + * The ID assigned to your bot in the [Bot Framework Portal](https://dev.botframework.com/). + */ + MicrosoftAppId: z.string(), + /** + * The password assigned to your bot in the [Bot Framework Portal](https://dev.botframework.com/). + */ + MicrosoftAppPassword: z.string(), + /** + * The type of app id assigned to your bot in the [Bot Framework Portal](https://dev.botframework.com/). + */ + MicrosoftAppType: z.string(), + /** + * The tenant id assigned to your bot in the [Bot Framework Portal](https://dev.botframework.com/). + */ + MicrosoftAppTenantId: z.string(), + /** + * Certificate thumbprint to authenticate the appId against AAD. + */ + [botframework_connector_1.AuthenticationConstants.CertificateThumbprint]: z.string(), + /** + * Certificate key to authenticate the appId against AAD. + */ + [botframework_connector_1.AuthenticationConstants.CertificatePrivateKey]: z.string() + }).partial(); + var ConfigurationServiceClientCredentialFactory = class extends botframework_connector_1.PasswordServiceClientCredentialFactory { + /** + * Initializes a new instance of the [ConfigurationServiceClientCredentialFactory](xref:botbuilder-core.ConfigurationServiceClientCredentialFactory) class. + * + * @param factoryOptions A [ConfigurationServiceClientCredentialFactoryOptions](xref:botbuilder-core.ConfigurationServiceClientCredentialFactoryOptions) object. + */ + constructor(factoryOptions = {}) { + var _a; + const { MicrosoftAppId = null, MicrosoftAppPassword = null, MicrosoftAppType = null, MicrosoftAppTenantId = null, [botframework_connector_1.AuthenticationConstants.CertificateThumbprint]: CertificateThumbprint = null, [botframework_connector_1.AuthenticationConstants.CertificatePrivateKey]: CertificatePrivateKey = null } = TypedConfig.nonstrict().parse(factoryOptions); + super(MicrosoftAppId, MicrosoftAppPassword, MicrosoftAppTenantId); + const appType = (_a = MicrosoftAppType === null || MicrosoftAppType === void 0 ? void 0 : MicrosoftAppType.trim()) !== null && _a !== void 0 ? _a : MultiTenant; + const withCertificate = CertificateThumbprint || CertificatePrivateKey; + if (withCertificate) { + (0, assert_1.ok)(CertificateThumbprint === null || CertificateThumbprint === void 0 ? void 0 : CertificateThumbprint.trim(), "CertificateThumbprint is required when using a Certificate in configuration."); + (0, assert_1.ok)(CertificatePrivateKey === null || CertificatePrivateKey === void 0 ? void 0 : CertificatePrivateKey.trim(), "CertificatePrivateKey is required when using a Certificate in configuration."); + } + switch (appType.toLocaleLowerCase()) { + case UserAssignedMsi.toLocaleLowerCase(): + (0, assert_1.ok)(MicrosoftAppId === null || MicrosoftAppId === void 0 ? void 0 : MicrosoftAppId.trim(), "MicrosoftAppId is required for MSI in configuration."); + (0, assert_1.ok)(MicrosoftAppTenantId === null || MicrosoftAppTenantId === void 0 ? void 0 : MicrosoftAppTenantId.trim(), "MicrosoftAppTenantId is required for MSI in configuration."); + (0, assert_1.ok)(!(MicrosoftAppPassword === null || MicrosoftAppPassword === void 0 ? void 0 : MicrosoftAppPassword.trim()), "MicrosoftAppPassword must not be set for MSI in configuration."); + this.inner = new botframework_connector_1.ManagedIdentityServiceClientCredentialsFactory(MicrosoftAppId, new botframework_connector_1.JwtTokenProviderFactory()); + break; + case SingleTenant.toLocaleLowerCase(): + (0, assert_1.ok)(MicrosoftAppId === null || MicrosoftAppId === void 0 ? void 0 : MicrosoftAppId.trim(), "MicrosoftAppId is required for SingleTenant in configuration."); + (0, assert_1.ok)(MicrosoftAppTenantId === null || MicrosoftAppTenantId === void 0 ? void 0 : MicrosoftAppTenantId.trim(), "MicrosoftAppTenantId is required for SingleTenant in configuration."); + if (withCertificate) { + this.inner = new botframework_connector_1.CertificateServiceClientCredentialsFactory(MicrosoftAppId, CertificateThumbprint, CertificatePrivateKey, MicrosoftAppTenantId); + } else { + (0, assert_1.ok)(MicrosoftAppPassword === null || MicrosoftAppPassword === void 0 ? void 0 : MicrosoftAppPassword.trim(), "MicrosoftAppPassword is required for SingleTenant in configuration."); + this.inner = new botframework_connector_1.PasswordServiceClientCredentialFactory(MicrosoftAppId, MicrosoftAppPassword, MicrosoftAppTenantId); + } + break; + default: + if (withCertificate) { + (0, assert_1.ok)(MicrosoftAppId === null || MicrosoftAppId === void 0 ? void 0 : MicrosoftAppId.trim(), "MicrosoftAppId is required for MultiTenant when using a Certificate in configuration."); + this.inner = new botframework_connector_1.CertificateServiceClientCredentialsFactory(MicrosoftAppId, CertificateThumbprint, CertificatePrivateKey); + } else { + this.inner = new botframework_connector_1.PasswordServiceClientCredentialFactory(MicrosoftAppId, MicrosoftAppPassword, ""); + } + break; + } + } + /** + * @inheritdoc + */ + isValidAppId(microsoftAppId) { + return this.inner.isValidAppId(microsoftAppId); + } + /** + * @inheritdoc + */ + isAuthenticationDisabled() { + return this.inner.isAuthenticationDisabled(); + } + /** + * @inheritdoc + */ + createCredentials(microsoftAppId, audience, loginEndpoint, validateAuthority) { + return this.inner.createCredentials(microsoftAppId, audience, loginEndpoint, validateAuthority); + } + }; + exports2.ConfigurationServiceClientCredentialFactory = ConfigurationServiceClientCredentialFactory; + function createServiceClientCredentialFactoryFromConfiguration(configuration) { + const factoryOptions = configuration.get(); + return new ConfigurationServiceClientCredentialFactory(factoryOptions); + } + exports2.createServiceClientCredentialFactoryFromConfiguration = createServiceClientCredentialFactoryFromConfiguration; + } +}); + +// node_modules/botbuilder-core/lib/configurationBotFrameworkAuthentication.js +var require_configurationBotFrameworkAuthentication = __commonJS({ + "node_modules/botbuilder-core/lib/configurationBotFrameworkAuthentication.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createBotFrameworkAuthenticationFromConfiguration = exports2.ConfigurationBotFrameworkAuthentication = void 0; + var z = __importStar2(require_zod()); + var botframework_connector_1 = require_lib9(); + var configurationServiceClientCredentialFactory_1 = require_configurationServiceClientCredentialFactory(); + var TypedOptions = z.object({ + /** + * The ID assigned to your bot in the [Bot Framework Portal](https://dev.botframework.com/). + */ + MicrosoftAppId: z.string(), + /** + * The tenant id assigned to your bot in the [Bot Framework Portal](https://dev.botframework.com/). + */ + MicrosoftAppTenantId: z.string(), + /** + * (Optional) The OAuth URL used to get a token from OAuthApiClient. The "OAuthUrl" member takes precedence over this value. + */ + [botframework_connector_1.AuthenticationConstants.OAuthUrlKey]: z.string(), + /** + * (Optional) The OpenID metadata document used for authenticating tokens coming from the channel. The "ToBotFromChannelOpenIdMetadataUrl" member takes precedence over this value. + */ + [botframework_connector_1.AuthenticationConstants.BotOpenIdMetadataKey]: z.string().nullable(), + /** + * A string used to indicate if which cloud the bot is operating in (e.g. Public Azure or US Government). + * + * @remarks + * A `null` or `''` value indicates Public Azure, whereas [GovernmentConstants.ChannelService](xref:botframework-connector.GovernmentConstants.ChannelService) indicates the bot is operating in the US Government cloud. + * + * Other values result in a custom authentication configuration derived from the values passed in on the [ConfigurationBotFrameworkAuthenticationOptions](xef:botbuilder-core.ConfigurationBotFrameworkAuthenticationOptions) instance. + */ + [botframework_connector_1.AuthenticationConstants.ChannelService]: z.string(), + /** + * Flag indicating whether or not to validate the address. + */ + ValidateAuthority: z.union([z.string(), z.boolean()]), + /** + * The Login URL used to specify the tenant from which the bot should obtain access tokens from. + */ + ToChannelFromBotLoginUrl: z.string(), + /** + * The Oauth scope to request. + * + * @remarks + * This value is used when fetching a token to indicate the ultimate recipient or `audience` of an activity sent using these credentials. + */ + ToChannelFromBotOAuthScope: z.string(), + /** + * The Token issuer for signed requests to the channel. + */ + ToBotFromChannelTokenIssuer: z.string(), + /** + * The OAuth URL used to get a token from OAuthApiClient. + */ + OAuthUrl: z.string(), + /** + * The OpenID metadata document used for authenticating tokens coming from the channel. + */ + ToBotFromChannelOpenIdMetadataUrl: z.string(), + /** + * The The OpenID metadata document used for authenticating tokens coming from the Emulator. + */ + ToBotFromEmulatorOpenIdMetadataUrl: z.string(), + /** + * A value for the CallerId. + */ + CallerId: z.string(), + /** + * Certificate thumbprint to authenticate the appId against AAD. + */ + [botframework_connector_1.AuthenticationConstants.CertificateThumbprint]: z.string(), + /** + * Certificate key to authenticate the appId against AAD. + */ + [botframework_connector_1.AuthenticationConstants.CertificatePrivateKey]: z.string() + }).partial(); + var ConfigurationBotFrameworkAuthentication = class extends botframework_connector_1.BotFrameworkAuthentication { + /** + * Initializes a new instance of the [ConfigurationBotFrameworkAuthentication](xref:botbuilder-core.ConfigurationBotFrameworkAuthentication) class. + * + * @param botFrameworkAuthConfig A [ConfigurationBotFrameworkAuthenticationOptions](xref:botbuilder-core.ConfigurationBotFrameworkAuthenticationOptions) object. + * @param credentialsFactory A [ServiceClientCredentialsFactory](xref:botframework-connector.ServiceClientCredentialsFactory) instance. + * @param authConfiguration A [Configuration](xref:botframework-connector.AuthenticationConfiguration) object. + * @param botFrameworkClientFetch A custom Fetch implementation to be used in the [BotFrameworkClient](xref:botframework-connector.BotFrameworkClient). + * @param connectorClientOptions A [ConnectorClientOptions](xref:botframework-connector.ConnectorClientOptions) object. + */ + constructor(botFrameworkAuthConfig = {}, credentialsFactory, authConfiguration, botFrameworkClientFetch, connectorClientOptions = {}) { + var _a; + super(); + try { + botframework_connector_1.AseChannelValidation.init(botFrameworkAuthConfig); + const typedBotFrameworkAuthConfig = TypedOptions.nonstrict().parse(botFrameworkAuthConfig); + const { CallerId, ChannelService, OAuthUrl = typedBotFrameworkAuthConfig[botframework_connector_1.AuthenticationConstants.OAuthUrlKey], ToBotFromChannelOpenIdMetadataUrl = typedBotFrameworkAuthConfig[botframework_connector_1.AuthenticationConstants.BotOpenIdMetadataKey], ToBotFromChannelTokenIssuer, ToBotFromEmulatorOpenIdMetadataUrl, ToChannelFromBotLoginUrl, ToChannelFromBotOAuthScope } = typedBotFrameworkAuthConfig; + let ValidateAuthority = true; + try { + ValidateAuthority = Boolean(JSON.parse(`${(_a = typedBotFrameworkAuthConfig.ValidateAuthority) !== null && _a !== void 0 ? _a : true}`)); + } catch (_err) { + } + this.inner = botframework_connector_1.BotFrameworkAuthenticationFactory.create(ChannelService, ValidateAuthority, ToChannelFromBotLoginUrl, ToChannelFromBotOAuthScope, ToBotFromChannelTokenIssuer, OAuthUrl, ToBotFromChannelOpenIdMetadataUrl, ToBotFromEmulatorOpenIdMetadataUrl, CallerId, credentialsFactory !== null && credentialsFactory !== void 0 ? credentialsFactory : new configurationServiceClientCredentialFactory_1.ConfigurationServiceClientCredentialFactory(typedBotFrameworkAuthConfig), authConfiguration !== null && authConfiguration !== void 0 ? authConfiguration : { requiredEndorsements: [] }, botFrameworkClientFetch, connectorClientOptions); + } catch (err) { + if (z.instanceof(z.ZodError).safeParse(err).success) { + throw new Error(JSON.stringify(err.errors, null, 2)); + } + throw err; + } + } + /** + * Authenticate Bot Framework Protocol requests to Skills. + * + * @param authHeader The http auth header received in the skill request. + * @returns {Promise} A [ClaimsIdentity](xref:botframework-connector.ClaimsIdentity). + */ + authenticateChannelRequest(authHeader) { + return this.inner.authenticateChannelRequest(authHeader); + } + /** + * Validate Bot Framework Protocol requests. + * + * @param activity The inbound Activity. + * @param authHeader The HTTP auth header. + * @returns {Promise} An [AuthenticateRequestResult](xref:botframework-connector.AuthenticateRequestResult). + */ + authenticateRequest(activity, authHeader) { + return this.inner.authenticateRequest(activity, authHeader); + } + /** + * Validate Bot Framework Protocol requests. + * + * @param authHeader The HTTP auth header. + * @param channelIdHeader The channel ID HTTP header. + * @returns {Promise} An [AuthenticateRequestResult](xref:botframework-connector.AuthenticateRequestResult). + */ + authenticateStreamingRequest(authHeader, channelIdHeader) { + return this.inner.authenticateStreamingRequest(authHeader, channelIdHeader); + } + /** + * Creates a BotFrameworkClient for calling Skills. + * + * @returns A [BotFrameworkClient](xref:botframework-connector.BotFrameworkClient). + */ + createBotFrameworkClient() { + return this.inner.createBotFrameworkClient(); + } + /** + * Creates a ConnectorFactory that can be used to create ConnectorClients that can use credentials from this particular Cloud Environment. + * + * @param claimsIdentity The inbound Activity's ClaimsIdentity. + * @returns A [ConnectorFactory](xref:botframework-connector.ConnectorFactory). + */ + createConnectorFactory(claimsIdentity) { + return this.inner.createConnectorFactory(claimsIdentity); + } + /** + * Creates the appropriate UserTokenClient instance. + * + * @param claimsIdentity The inbound Activity's ClaimsIdentity. + * @returns {Promise} An [UserTokenClient](xref:botframework-connector.UserTokenClient). + */ + createUserTokenClient(claimsIdentity) { + return this.inner.createUserTokenClient(claimsIdentity); + } + }; + exports2.ConfigurationBotFrameworkAuthentication = ConfigurationBotFrameworkAuthentication; + function createBotFrameworkAuthenticationFromConfiguration(configuration, credentialsFactory, authConfiguration, botFrameworkClientFetch, connectorClientOptions = {}) { + const botFrameworkAuthConfig = configuration === null || configuration === void 0 ? void 0 : configuration.get(); + return new ConfigurationBotFrameworkAuthentication(botFrameworkAuthConfig, credentialsFactory, authConfiguration, botFrameworkClientFetch, connectorClientOptions); + } + exports2.createBotFrameworkAuthenticationFromConfiguration = createBotFrameworkAuthenticationFromConfiguration; + } +}); + +// node_modules/botbuilder-core/lib/conversationState.js +var require_conversationState = __commonJS({ + "node_modules/botbuilder-core/lib/conversationState.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ConversationState = void 0; + var botState_1 = require_botState(); + var NO_KEY = "ConversationState: overridden getStorageKey method did not return a key."; + var ConversationState = class extends botState_1.BotState { + /** + * Creates a new ConversationState instance. + * + * @param storage Storage provider to persist conversation state to. + * @param namespace (Optional) namespace to append to storage keys. Defaults to an empty string. + */ + constructor(storage, namespace = "") { + super(storage, (context) => { + const key = this.getStorageKey(context); + return key ? Promise.resolve(key) : Promise.reject(new Error(NO_KEY)); + }); + this.namespace = namespace; + } + /** + * Returns the storage key for the current conversation state. + * + * @param context Context for current turn of conversation with the user. + * @returns The storage key for the current conversation state. + */ + getStorageKey(context) { + const activity = context.activity; + const channelId = activity.channelId; + const conversationId = activity && activity.conversation && activity.conversation.id ? activity.conversation.id : void 0; + if (!channelId) { + throw new Error("missing activity.channelId"); + } + if (!conversationId) { + throw new Error("missing activity.conversation.id"); + } + return `${channelId}/conversations/${conversationId}/${this.namespace}`; + } + }; + exports2.ConversationState = ConversationState; + } +}); + +// node_modules/botbuilder-core/lib/coreAppCredentials.js +var require_coreAppCredentials = __commonJS({ + "node_modules/botbuilder-core/lib/coreAppCredentials.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botbuilder-core/lib/extendedUserTokenProvider.js +var require_extendedUserTokenProvider = __commonJS({ + "node_modules/botbuilder-core/lib/extendedUserTokenProvider.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botbuilder-core/lib/intentScore.js +var require_intentScore = __commonJS({ + "node_modules/botbuilder-core/lib/intentScore.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botbuilder-core/lib/invokeResponse.js +var require_invokeResponse = __commonJS({ + "node_modules/botbuilder-core/lib/invokeResponse.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botbuilder-core/lib/memoryTranscriptStore.js +var require_memoryTranscriptStore = __commonJS({ + "node_modules/botbuilder-core/lib/memoryTranscriptStore.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MemoryTranscriptStore = void 0; + var MemoryTranscriptStore = class _MemoryTranscriptStore { + constructor() { + this.channels = /* @__PURE__ */ new Map(); + } + /** + * Log an activity to the transcript. + * + * @param activity Activity to log. + * @returns {Promise} A promise representing the async operation. + */ + logActivity(activity) { + if (!activity) { + throw new Error("activity cannot be null for logActivity()"); + } + let channel; + if (!this.channels.has(activity.channelId)) { + channel = /* @__PURE__ */ new Map(); + this.channels.set(activity.channelId, channel); + } else { + channel = this.channels.get(activity.channelId); + } + let transcript; + if (!channel.has(activity.conversation.id)) { + transcript = []; + channel.set(activity.conversation.id, transcript); + } else { + transcript = channel.get(activity.conversation.id); + } + transcript.push(activity); + return Promise.resolve(); + } + /** + * Get activities from the memory transcript store. + * + * @param channelId Channel Id. + * @param conversationId Conversation Id. + * @param continuationToken Continuation token to page through results. + * @param startDate Earliest time to include. + * @returns {Promise>} A page of matching activities. + */ + getTranscriptActivities(channelId, conversationId, continuationToken, startDate) { + if (!channelId) { + throw new Error("Missing channelId"); + } + if (!conversationId) { + throw new Error("Missing conversationId"); + } + const pagedResult = { items: [], continuationToken: void 0 }; + if (this.channels.has(channelId)) { + const channel = this.channels.get(channelId); + if (channel.has(conversationId)) { + const transcript = channel.get(conversationId); + if (continuationToken) { + pagedResult.items = transcript.sort(timestampSorter).filter((a) => !startDate || a.timestamp >= startDate).filter(skipWhileExpression((a) => a.id !== continuationToken)).slice(1, _MemoryTranscriptStore.pageSize + 1); + } else { + pagedResult.items = transcript.sort(timestampSorter).filter((a) => !startDate || a.timestamp >= startDate).slice(0, _MemoryTranscriptStore.pageSize); + } + if (pagedResult.items.length === _MemoryTranscriptStore.pageSize) { + pagedResult.continuationToken = pagedResult.items[pagedResult.items.length - 1].id; + } + } + } + return Promise.resolve(pagedResult); + } + /** + * List conversations in the channelId. + * + * @param channelId Channel Id. + * @param continuationToken Continuation token to page through results. + * @returns {Promise>} A page of conversations for a channel from the store. + */ + listTranscripts(channelId, continuationToken) { + if (!channelId) { + throw new Error("Missing channelId"); + } + const pagedResult = { items: [], continuationToken: void 0 }; + if (this.channels.has(channelId)) { + const channel = this.channels.get(channelId); + if (continuationToken) { + pagedResult.items = Array.from(channel.entries()).map((kv) => ({ + channelId, + id: kv[0], + created: getDate(kv[1]) + })).sort(createdSorter).filter(skipWhileExpression((a) => a.id !== continuationToken)).slice(1, _MemoryTranscriptStore.pageSize + 1); + } else { + pagedResult.items = Array.from(channel.entries()).map((kv) => ({ + channelId, + id: kv[0], + created: getDate(kv[1]) + })).sort(createdSorter).slice(0, _MemoryTranscriptStore.pageSize); + } + if (pagedResult.items.length === _MemoryTranscriptStore.pageSize) { + pagedResult.continuationToken = pagedResult.items[pagedResult.items.length - 1].id; + } + } + return Promise.resolve(pagedResult); + } + /** + * Delete a specific conversation and all of it's activities. + * + * @param channelId Channel Id where conversation took place. + * @param conversationId Id of the conversation to delete. + * @returns {Promise} A promise representing the async operation. + */ + deleteTranscript(channelId, conversationId) { + if (!channelId) { + throw new Error("Missing channelId"); + } + if (!conversationId) { + throw new Error("Missing conversationId"); + } + if (this.channels.has(channelId)) { + const channel = this.channels.get(channelId); + if (channel.has(conversationId)) { + channel.delete(conversationId); + } + } + return Promise.resolve(); + } + }; + exports2.MemoryTranscriptStore = MemoryTranscriptStore; + MemoryTranscriptStore.pageSize = 20; + var createdSorter = (a, b) => a.created.getTime() - b.created.getTime(); + var timestampSorter = (a, b) => a.timestamp.getTime() - b.timestamp.getTime(); + var skipWhileExpression = (expression) => { + let skipping = true; + return (item) => { + if (!skipping) { + return true; + } + if (!expression(item)) { + skipping = false; + } + return !skipping; + }; + }; + var getDate = (activities) => { + if (activities && activities.length > 0) { + return activities[0].timestamp || /* @__PURE__ */ new Date(0); + } + return /* @__PURE__ */ new Date(0); + }; + } +}); + +// node_modules/botbuilder-core/lib/privateConversationState.js +var require_privateConversationState = __commonJS({ + "node_modules/botbuilder-core/lib/privateConversationState.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PrivateConversationState = void 0; + var botState_1 = require_botState(); + var NO_KEY = "PrivateConversationState: overridden getStorageKey method did not return a key."; + var PrivateConversationState = class extends botState_1.BotState { + /** + * Creates a new PrivateConversationState instance. + * + * @param storage Storage provider to persist PrivateConversation state to. + * @param namespace (Optional) namespace to append to storage keys. Defaults to an empty string. + */ + constructor(storage, namespace = "") { + super(storage, (context) => { + const key = this.getStorageKey(context); + return key ? Promise.resolve(key) : Promise.reject(new Error(NO_KEY)); + }); + this.namespace = namespace; + } + /** + * Returns the storage key for the current PrivateConversation state. + * + * @param context Context for current turn of PrivateConversation with the user. + * @returns The storage key for the current PrivateConversation state. + */ + getStorageKey(context) { + const activity = context.activity; + const channelId = activity.channelId; + const conversationId = activity && activity.conversation && activity.conversation.id ? activity.conversation.id : void 0; + const userId = activity && activity.from && activity.from.id ? activity.from.id : void 0; + if (!channelId) { + throw new Error("missing activity.channelId"); + } + if (!conversationId) { + throw new Error("missing activity.conversation.id"); + } + if (!userId) { + throw new Error("missing activity.from.id"); + } + return `${channelId}/conversations/${conversationId}/users/${userId}/${this.namespace}`; + } + }; + exports2.PrivateConversationState = PrivateConversationState; + } +}); + +// node_modules/botbuilder-core/lib/propertyManager.js +var require_propertyManager = __commonJS({ + "node_modules/botbuilder-core/lib/propertyManager.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botbuilder-core/lib/queueStorage.js +var require_queueStorage = __commonJS({ + "node_modules/botbuilder-core/lib/queueStorage.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.QueueStorage = void 0; + var QueueStorage = class { + }; + exports2.QueueStorage = QueueStorage; + } +}); + +// node_modules/botbuilder-core/lib/recognizerResult.js +var require_recognizerResult = __commonJS({ + "node_modules/botbuilder-core/lib/recognizerResult.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getTopScoringIntent = void 0; + var getTopScoringIntent = (result) => { + var _a; + if (!result || !result.intents) { + throw new Error("result is empty"); + } + let topIntent = ""; + let topScore = -1; + for (const [intentName, intent] of Object.entries(result.intents)) { + const score = (_a = intent.score) !== null && _a !== void 0 ? _a : -1; + if (!topIntent || score > topScore) { + topIntent = intentName; + topScore = score; + } + } + return { + intent: topIntent, + score: topScore + }; + }; + exports2.getTopScoringIntent = getTopScoringIntent; + } +}); + +// node_modules/botbuilder-core/lib/turnContextStateCollection.js +var require_turnContextStateCollection = __commonJS({ + "node_modules/botbuilder-core/lib/turnContextStateCollection.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TurnContextStateCollection = void 0; + var TURN_STATE_SCOPE_CACHE = Symbol("turnStateScopeCache"); + var TurnContextStateCollection = class extends Map { + /** + * Gets a value from the [TurnContextStateCollection](xref:botbuilder-core.TurnContextStateCollection). + * + * @param key The values key. + * @returns The object; or null if no service is registered by the key. + */ + get(key) { + return super.get(key); + } + /** + * Push a value by key to the turn's context. + * + * @remarks + * The keys current value (if any) will be saved and can be restored by calling [pop()](#pop). + * @param key The values key. + * @param value The new value. + */ + push(key, value) { + const current = this.get(key); + const cache = this.get(TURN_STATE_SCOPE_CACHE) || /* @__PURE__ */ new Map(); + if (cache.has(key)) { + cache.get(key).push(current); + } else { + cache.set(key, [current]); + } + if (value == void 0) { + value = current; + } + this.set(key, value); + this.set(TURN_STATE_SCOPE_CACHE, cache); + } + /** + * Restores a keys previous value, and returns the value that was removed. + * + * @param key The values key. + * @returns The removed value. + */ + pop(key) { + const current = this.get(key); + let previous; + const cache = this.get(TURN_STATE_SCOPE_CACHE) || /* @__PURE__ */ new Map(); + if (cache.has(key)) { + previous = cache.get(key).pop(); + } + this.set(key, previous); + this.set(TURN_STATE_SCOPE_CACHE, cache); + return current; + } + }; + exports2.TurnContextStateCollection = TurnContextStateCollection; + } +}); + +// node_modules/botbuilder-core/lib/turnContext.js +var require_turnContext = __commonJS({ + "node_modules/botbuilder-core/lib/turnContext.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TurnContext = exports2.BotCallbackHandlerKey = void 0; + var _1 = require_lib10(); + var internal_1 = require_internal2(); + var turnContextStateCollection_1 = require_turnContextStateCollection(); + var botframework_schema_1 = require_lib4(); + exports2.BotCallbackHandlerKey = "botCallbackHandler"; + function getAppropriateReplyToId(source) { + if (source.type !== botframework_schema_1.ActivityTypes.ConversationUpdate || source.channelId !== botframework_schema_1.Channels.Directline && source.channelId !== botframework_schema_1.Channels.Webchat) { + return source.id; + } + return void 0; + } + var TurnContext = class _TurnContext { + /** + * Creates an new instance of the [TurnContext](xref:xref:botbuilder-core.TurnContext) class. + * + * @param adapterOrContext The adapter creating the context or the context object to clone. + * @param request Optional. The incoming activity for the turn. + */ + constructor(adapterOrContext, request) { + this._respondedRef = { responded: false }; + this._turnState = new turnContextStateCollection_1.TurnContextStateCollection(); + this._onSendActivities = []; + this._onUpdateActivity = []; + this._onDeleteActivity = []; + this._turn = "turn"; + this._locale = "locale"; + this.bufferedReplyActivities = []; + if (adapterOrContext instanceof _TurnContext) { + adapterOrContext.copyTo(this); + } else { + this._adapter = adapterOrContext; + this._activity = request; + } + } + /** + * Removes at mentions for the activity's [recipient](xref:botframework-schema.Activity.recipient) + * from the text of an activity and returns the updated text. + * Use with caution; this function alters the activity's [text](xref:botframework-schema.Activity.text) property. + * + * @param activity The activity to remove at mentions from. + * @returns The updated activity's text. + * @remarks + * Some channels, for example Microsoft Teams, add at-mention details to the text of a message activity. + * + * Use this helper method to modify the activity's [text](xref:botframework-schema.Activity.text) property. + * It removes all at mentions of the activity's [recipient](xref:botframework-schema.Activity.recipient) + * and then returns the updated property value. + * + * For example: + * ```JavaScript + * const updatedText = TurnContext.removeRecipientMention(turnContext.request); + * ``` + * **See also** + * - [removeMentionText](xref:botbuilder-core.TurnContext.removeMentionText) + */ + static removeRecipientMention(activity) { + return _TurnContext.removeMentionText(activity, activity.recipient.id); + } + /** + * Removes at mentions for a given ID from the text of an activity and returns the updated text. + * Use with caution; this function alters the activity's [text](xref:botframework-schema.Activity.text) property. + * + * @param activity The activity to remove at mentions from. + * @param id The ID of the user or bot to remove at mentions for. + * @returns The updated activity's text. + * @remarks + * Some channels, for example Microsoft Teams, add at mentions to the text of a message activity. + * + * Use this helper method to modify the activity's [text](xref:botframework-schema.Activity.text) property. + * It removes all at mentions for the given bot or user ID and then returns the updated property value. + * + * For example, when you remove mentions of **echoBot** from an activity containing the text "@echoBot Hi Bot", + * the activity text is updated, and the method returns "Hi Bot". + * + * The format of a mention [entity](xref:botframework-schema.Entity) is channel-dependent. + * However, the mention's [text](xref:botframework-schema.Mention.text) property should contain + * the exact text for the user as it appears in the activity text. + * + * For example, whether the channel uses "username" or "@username", this string is in + * the activity's text, and this method will remove all occurrences of that string from the text. + * + * For example: + * ```JavaScript + * const updatedText = TurnContext.removeMentionText(activity, activity.recipient.id); + * ``` + * **See also** + * - [removeRecipientMention](xref:botbuilder-core.TurnContext.removeRecipientMention) + */ + static removeMentionText(activity, id) { + const mentions = _TurnContext.getMentions(activity); + const mentionsFiltered = mentions.filter((mention) => mention.mentioned.id === id); + if (mentionsFiltered.length) { + activity.text = activity.text.replace(mentionsFiltered[0].text, "").trim(); + } + return activity.text; + } + /** + * Gets all at-mention entities included in an activity. + * + * @param activity The activity. + * @returns All the at-mention entities included in an activity. + * @remarks + * The activity's [entities](xref:botframework-schema.Activity.entities) property contains a flat + * list of metadata objects pertaining to this activity and can contain + * [mention](xref:botframework-schema.Mention) entities. This method returns all such entities + * for a given activity. + * + * For example: + * ```JavaScript + * const mentions = TurnContext.getMentions(turnContext.request); + * ``` + */ + static getMentions(activity) { + const result = []; + if (activity.entities !== void 0) { + for (let i = 0; i < activity.entities.length; i++) { + if (activity.entities[i].type.toLowerCase() === "mention") { + result.push(activity.entities[i]); + } + } + } + return result; + } + /** + * Copies conversation reference information from an activity. + * + * @param activity The activity to get the information from. + * @returns A conversation reference for the conversation that contains this activity. + * @remarks + * You can save the conversation reference as a JSON object and use it later to proactively message the user. + * + * For example: + * ```JavaScript + * const reference = TurnContext.getConversationReference(context.request); + * ``` + * + * **See also** + * + * - [BotAdapter.continueConversation](xref:botbuilder-core.BotAdapter.continueConversation) + */ + static getConversationReference(activity) { + return { + activityId: getAppropriateReplyToId(activity), + user: (0, internal_1.shallowCopy)(activity.from), + bot: (0, internal_1.shallowCopy)(activity.recipient), + conversation: (0, internal_1.shallowCopy)(activity.conversation), + channelId: activity.channelId, + locale: activity.locale, + serviceUrl: activity.serviceUrl + }; + } + /** + * Updates an activity with the delivery information from an existing conversation reference. + * + * @param activity The activity to update. + * @param reference The conversation reference to copy delivery information from. + * @param isIncoming Optional. `true` to treat the activity as an incoming activity, where the + * bot is the recipient; otherwise, `false`. Default is `false`, and the activity will show + * the bot as the sender. + * @returns This activity, updated with the delivery information. + * @remarks + * Call the [getConversationReference](xref:botbuilder-core.TurnContext.getConversationReference) + * method on an incoming activity to get a conversation reference that you can then use + * to update an outgoing activity with the correct delivery information. + */ + static applyConversationReference(activity, reference, isIncoming = false) { + var _a; + activity.channelId = reference.channelId; + (_a = activity.locale) !== null && _a !== void 0 ? _a : activity.locale = reference.locale; + activity.serviceUrl = reference.serviceUrl; + activity.conversation = reference.conversation; + if (isIncoming) { + activity.from = reference.user; + activity.recipient = reference.bot; + if (reference.activityId) { + activity.id = reference.activityId; + } + } else { + activity.from = reference.bot; + activity.recipient = reference.user; + if (reference.activityId) { + activity.replyToId = reference.activityId; + } + } + return activity; + } + /** + * Copies conversation reference information from a resource response for a sent activity. + * + * @param activity The sent activity. + * @param reply The resource response for the activity, returned by the + * [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) or + * [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) method. + * @returns A ConversationReference that can be stored and used later to delete or update the activity. + * @remarks + * You can save the conversation reference as a JSON object and use it later to update or delete the message. + * + * For example: + * ```javascript + * var reply = await context.sendActivity('Hi'); + * var reference = TurnContext.getReplyConversationReference(context.activity, reply); + * ``` + * + * **See also** + * + * - [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity) + * - [updateActivity](xref:botbuilder-core.TurnContext.updateActivity) + */ + static getReplyConversationReference(activity, reply) { + const reference = _TurnContext.getConversationReference(activity); + reference.activityId = reply.id; + return reference; + } + /** + * Asynchronously sends an activity to the sender of the incoming activity. + * + * @param name The activity or text to send. + * @param value Optional. The text to be spoken by your bot on a speech-enabled channel. + * @param valueType Optional. Indicates whether your bot is accepting, expecting, or ignoring user + * @param label Optional. Indicates whether your bot is accepting, expecting, or ignoring user + * @returns A promise with a ResourceResponse. + * @remarks + * Creates and sends a Trace activity. Trace activities are only sent when the channel is the emulator. + * + * For example: + * ```JavaScript + * await context.sendTraceActivity(`The following exception was thrown ${msg}`); + * ``` + * + * **See also** + * + * - [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) + */ + sendTraceActivity(name, value, valueType, label) { + const traceActivity = { + type: botframework_schema_1.ActivityTypes.Trace, + timestamp: /* @__PURE__ */ new Date(), + name, + value, + valueType, + label + }; + return this.sendActivity(traceActivity); + } + /** + * Asynchronously sends an activity to the sender of the incoming activity. + * + * @param activityOrText The activity or text to send. + * @param speak Optional. The text to be spoken by your bot on a speech-enabled channel. + * @param inputHint Optional. Indicates whether your bot is accepting, expecting, or ignoring user + * input after the message is delivered to the client. One of: 'acceptingInput', 'ignoringInput', + * or 'expectingInput'. Default is 'acceptingInput'. + * @returns A promise with a ResourceResponse. + * @remarks + * If the activity is successfully sent, results in a + * [ResourceResponse](xref:botframework-schema.ResourceResponse) object containing the ID that the + * receiving channel assigned to the activity. + * + * See the channel's documentation for limits imposed upon the contents of the **activityOrText** parameter. + * + * To control various characteristics of your bot's speech such as voice, rate, volume, pronunciation, + * and pitch, specify **speak** in Speech Synthesis Markup Language (SSML) format. + * + * For example: + * ```JavaScript + * await context.sendActivity(`Hello World`); + * ``` + * + * **See also** + * + * - [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) + * - [updateActivity](xref:botbuilder-core.TurnContext.updateActivity) + * - [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity) + */ + sendActivity(activityOrText, speak, inputHint) { + return __awaiter2(this, void 0, void 0, function* () { + let a; + if (typeof activityOrText === "string") { + a = { text: activityOrText, inputHint: inputHint || botframework_schema_1.InputHints.AcceptingInput }; + if (speak) { + a.speak = speak; + } + } else { + a = activityOrText; + } + const responses = (yield this.sendActivities([a])) || []; + return responses[0]; + }); + } + /** + * Asynchronously sends a set of activities to the sender of the incoming activity. + * + * @param activities The activities to send. + * @returns A promise with a ResourceResponse. + * @remarks + * If the activities are successfully sent, results in an array of + * [ResourceResponse](xref:botframework-schema.ResourceResponse) objects containing the IDs that + * the receiving channel assigned to the activities. + * + * Before they are sent, the delivery information of each outbound activity is updated based on the + * delivery information of the inbound inbound activity. + * + * For example: + * ```JavaScript + * await context.sendActivities([ + * { type: 'typing' }, + * { type: 'delay', value: 2000 }, + * { type: 'message', text: 'Hello... How are you?' } + * ]); + * ``` + * + * **See also** + * + * - [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) + * - [updateActivity](xref:botbuilder-core.TurnContext.updateActivity) + * - [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity) + */ + sendActivities(activities) { + let sentNonTraceActivity = false; + const ref = _TurnContext.getConversationReference(this.activity); + const output = activities.map((activity) => { + const result = _TurnContext.applyConversationReference(Object.assign({}, activity), ref); + if (!result.type) { + result.type = botframework_schema_1.ActivityTypes.Message; + } + if (result.type !== botframework_schema_1.ActivityTypes.Trace) { + sentNonTraceActivity = true; + } + if (result.id) { + delete result.id; + } + return result; + }); + return this.emit(this._onSendActivities, output, () => __awaiter2(this, void 0, void 0, function* () { + if (this.activity.deliveryMode === botframework_schema_1.DeliveryModes.ExpectReplies) { + const responses = []; + output.forEach((a) => { + this.bufferedReplyActivities.push(a); + if (a.type === botframework_schema_1.ActivityTypes.InvokeResponse) { + this.turnState.set(_1.INVOKE_RESPONSE_KEY, a); + } + responses.push({ id: void 0 }); + }); + if (sentNonTraceActivity) { + this.responded = true; + } + return responses; + } else { + const responses = yield this.adapter.sendActivities(this, output); + for (let index = 0; index < (responses === null || responses === void 0 ? void 0 : responses.length); index++) { + const activity = output[index]; + activity.id = responses[index].id; + } + if (sentNonTraceActivity) { + this.responded = true; + } + return responses; + } + })); + } + /** + * Asynchronously updates a previously sent activity. + * + * @param activity The replacement for the original activity. + * @returns A promise with a ResourceResponse. + * @remarks + * The [id](xref:botframework-schema.Activity.id) of the replacement activity indicates the activity + * in the conversation to replace. + * + * For example: + * ```JavaScript + * const matched = /approve (.*)/i.exec(context.activity.text); + * if (matched) { + * const update = await approveExpenseReport(matched[1]); + * await context.updateActivity(update); + * } + * ``` + * + * **See also** + * + * - [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) + * - [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity) + * - [getReplyConversationReference](xref:botbuilder-core.TurnContext.getReplyConversationReference) + */ + updateActivity(activity) { + const ref = _TurnContext.getConversationReference(this.activity); + const a = _TurnContext.applyConversationReference(activity, ref); + return this.emit(this._onUpdateActivity, a, () => this.adapter.updateActivity(this, a)); + } + /** + * Asynchronously deletes a previously sent activity. + * + * @param idOrReference ID or conversation reference for the activity to delete. + * @returns A promise representing the async operation. + * @remarks + * If an ID is specified, the conversation reference for the current request is used + * to get the rest of the information needed. + * + * For example: + * ```JavaScript + * const matched = /approve (.*)/i.exec(context.activity.text); + * if (matched) { + * const savedId = await approveExpenseReport(matched[1]); + * await context.deleteActivity(savedId); + * } + * ``` + * + * **See also** + * + * - [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) + * - [updateActivity](xref:botbuilder-core.TurnContext.updateActivity) + * - [getReplyConversationReference](xref:botbuilder-core.TurnContext.getReplyConversationReference) + */ + deleteActivity(idOrReference) { + let reference; + if (typeof idOrReference === "string") { + reference = _TurnContext.getConversationReference(this.activity); + reference.activityId = idOrReference; + } else { + reference = idOrReference; + } + return this.emit(this._onDeleteActivity, reference, () => this.adapter.deleteActivity(this, reference)); + } + /** + * Adds a response handler for send activity operations. + * + * @param handler The handler to add to the context object. + * @returns The updated context object. + * @remarks + * This method returns a reference to the turn context object. + * + * When the [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) or + * [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) method is called, + * the registered handlers are called in the order in which they were added to the context object + * before the activities are sent. + * + * This example shows how to listen for and log outgoing `message` activities. + * + * ```JavaScript + * context.onSendActivities(async (ctx, activities, next) => { + * // Log activities before sending them. + * activities.filter(a => a.type === 'message').forEach(a => logSend(a)); + * + * // Allow the send process to continue. + * next(); + * }); + * ``` + */ + onSendActivities(handler) { + this._onSendActivities.push(handler); + return this; + } + /** + * Adds a response handler for update activity operations. + * + * @param handler The handler to add to the context object. + * @returns The updated context object. + * @remarks + * This method returns a reference to the turn context object. + * + * When the [updateActivity](xref:botbuilder-core.TurnContext.updateActivity) method is called, + * the registered handlers are called in the order in which they were added to the context object + * before the activity is updated. + * + * This example shows how to listen for and log activity updates. + * + * ```JavaScript + * context.onUpdateActivity(async (ctx, activity, next) => { + * // Replace activity + * await next(); + * + * // Log update + * logUpdate(activity); + * }); + * ``` + */ + onUpdateActivity(handler) { + this._onUpdateActivity.push(handler); + return this; + } + /** + * Adds a response handler for delete activity operations. + * + * @param handler The handler to add to the context object. + * @returns The updated context object. + * @remarks + * This method returns a reference to the turn context object. + * + * When the [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity) method is called, + * the registered handlers are called in the order in which they were added to the context object + * before the activity is deleted. + * + * This example shows how to listen for and log activity deletions. + * + * ```JavaScript + * context.onDeleteActivity(async (ctx, reference, next) => { + * // Delete activity + * await next(); + * + * // Log delete + * logDelete(activity); + * }); + * ``` + */ + onDeleteActivity(handler) { + this._onDeleteActivity.push(handler); + return this; + } + /** + * Called when this turn context object is passed into the constructor for a new turn context. + * + * @param context The new turn context object. + * @remarks + * This copies private members from this object to the new object. + * All property values are copied by reference. + * + * Override this in a derived class to copy any additional members, as necessary. + */ + copyTo(context) { + [ + "_adapter", + "_activity", + "_respondedRef", + "_services", + "_onSendActivities", + "_onUpdateActivity", + "_onDeleteActivity" + ].forEach((prop) => context[prop] = this[prop]); + } + /** + * Gets the bot adapter that created this context object. + * + * @returns The bot adapter that created this context object. + */ + get adapter() { + return this._adapter; + } + /** + * Gets the activity associated with this turn. + * + * @returns The activity associated with this turn. + * @remarks + * This example shows how to get the users trimmed utterance from the activity: + * + * ```JavaScript + * const utterance = (context.activity.text || '').trim(); + * ``` + */ + get activity() { + return this._activity; + } + /** + * Indicates whether the bot has replied to the user this turn. + * + * @returns True if at least one response was sent for the current turn; otherwise, false. + * @remarks + * **true** if at least one response was sent for the current turn; otherwise, **false**. + * Use this to determine if your bot needs to run fallback logic after other normal processing. + * + * Trace activities do not set this flag. + * + * for example: + * ```JavaScript + * await routeActivity(context); + * if (!context.responded) { + * await context.sendActivity(`I'm sorry. I didn't understand.`); + * } + * ``` + */ + get responded() { + return this._respondedRef.responded; + } + /** + * Sets the response flag on the current turn context. + * + * @remarks + * The [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) and + * [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) methods call this method to + * update the responded flag. You can call this method directly to indicate that your bot has + * responded appropriately to the incoming activity. + */ + set responded(value) { + if (!value) { + throw new Error("TurnContext: cannot set 'responded' to a value of 'false'."); + } + this._respondedRef.responded = true; + } + /** + * Gets the locale stored in the turnState. + * + * @returns The locale stored in the turnState. + */ + get locale() { + const turnObj = this._turnState[this._turn]; + const locale = turnObj[this._locale]; + if (typeof locale === "string") { + return locale; + } + return void 0; + } + /** + * Sets the locale stored in the turnState. + */ + set locale(value) { + const turnObj = this._turnState[this._turn]; + if (turnObj) { + turnObj[this._locale] = value; + } else { + this._turnState[this._turn] = { locale: value }; + } + } + /** + * Gets the services registered on this context object. + * + * @returns The services registered on this context object. + * @remarks + * Middleware, other components, and services will typically use this to cache information + * that could be asked for by a bot multiple times during a turn. You can use this cache to + * pass information between components of your bot. + * + * For example: + * ```JavaScript + * const cartKey = Symbol(); + * const cart = await loadUsersShoppingCart(context); + * context.turnState.set(cartKey, cart); + * ``` + * + * > [!TIP] + * > When creating middleware or a third-party component, use a unique symbol for your cache key + * > to avoid state naming collisions with the bot or other middleware or components. + */ + get turnState() { + return this._turnState; + } + /** + * @private + * Executes `handlers` as a chain, returning a promise that resolves to the final result. + */ + emit(handlers, arg, next) { + const runHandlers = ([handler, ...remaining]) => { + try { + return handler ? handler(this, arg, () => runHandlers(remaining)) : Promise.resolve(next()); + } catch (err) { + return Promise.reject(err); + } + }; + return runHandlers(handlers); + } + }; + exports2.TurnContext = TurnContext; + } +}); + +// node_modules/botbuilder-core/lib/showTypingMiddleware.js +var require_showTypingMiddleware = __commonJS({ + "node_modules/botbuilder-core/lib/showTypingMiddleware.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ShowTypingMiddleware = void 0; + var botframework_schema_1 = require_lib4(); + var botframework_connector_1 = require_lib9(); + var turnContext_1 = require_turnContext(); + var ShowTypingMiddleware = class { + /** + * Create the SendTypingIndicator middleware + * + * @param delay {number} Number of milliseconds to wait before sending the first typing indicator. + * @param period {number} Number of milliseconds to wait before sending each following indicator. + */ + constructor(delay = 500, period = 2e3) { + this.delay = delay; + this.period = period; + if (delay < 0) { + throw new Error("Delay must be greater than or equal to zero"); + } + if (period <= 0) { + throw new Error("Repeat period must be greater than zero"); + } + } + /** + * Processes an incoming activity. + * + * @param context {TurnContext} An incoming TurnContext object. + * @param next {function} The next delegate function. + */ + onTurn(context, next) { + return __awaiter2(this, void 0, void 0, function* () { + let finished = false; + let timeout; + const scheduleIndicator = (delay = this.delay) => { + timeout = setTimeout(() => __awaiter2(this, void 0, void 0, function* () { + if (!finished) { + try { + yield this.sendTypingActivity(context); + } catch (err) { + if (context.adapter && context.adapter.onTurnError) { + yield context.adapter.onTurnError(context, err); + } else { + throw err; + } + } + scheduleIndicator(this.period); + } + }), delay); + }; + if (!this.isSkillBot(context) && context.activity.type === botframework_schema_1.ActivityTypes.Message) { + finished = false; + scheduleIndicator(); + } + try { + yield next(); + } finally { + finished = true; + if (timeout) + clearTimeout(timeout); + } + }); + } + isSkillBot(context) { + const identity = context.turnState.get(context.adapter.BotIdentityKey); + return identity && botframework_connector_1.SkillValidation.isSkillClaim(identity.claims); + } + /** + * @private + */ + sendTypingActivity(context) { + return __awaiter2(this, void 0, void 0, function* () { + const conversationReference = turnContext_1.TurnContext.getConversationReference(context.activity); + const typingActivity = turnContext_1.TurnContext.applyConversationReference({ + type: botframework_schema_1.ActivityTypes.Typing, + relatesTo: context.activity.relatesTo + }, conversationReference); + yield context.adapter.sendActivities(context, [typingActivity]); + }); + } + }; + exports2.ShowTypingMiddleware = ShowTypingMiddleware; + } +}); + +// node_modules/botbuilder-core/lib/skypeMentionNormalizeMiddleware.js +var require_skypeMentionNormalizeMiddleware = __commonJS({ + "node_modules/botbuilder-core/lib/skypeMentionNormalizeMiddleware.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkypeMentionNormalizeMiddleware = void 0; + var SkypeMentionNormalizeMiddleware = class _SkypeMentionNormalizeMiddleware { + /** + * Performs the normalization of Skype mention Entities. + * + * @param activity [Activity](xref:botframework-schema.Activity) containing the mentions to normalize. + */ + static normalizeSkypeMentionText(activity) { + if (activity.channelId === "skype" && activity.type === "message") { + activity.entities.map((element) => { + if (element.type === "mention") { + const text = element["text"]; + const end = text.indexOf(">"); + if (end > -1) { + const start = text.indexOf("<", end); + if (start > -1) + element["text"] = text.substring(end + 1, start); + } + } + }); + } + } + /** + * Middleware implementation which corrects the Entity text of type [Mention](xref:botframework-schema.Mention) to a value that [removeMentionText](xref:botbuilder-core.TurnContext.removeMentionText) can work with. + * + * @param turnContext [TurnContext](xref:botbuilder-core.TurnContext) for the current turn of conversation. + * @param next Delegate to call to continue the bot middleware pipeline. + */ + onTurn(turnContext, next) { + return __awaiter2(this, void 0, void 0, function* () { + _SkypeMentionNormalizeMiddleware.normalizeSkypeMentionText(turnContext.activity); + yield next(); + }); + } + }; + exports2.SkypeMentionNormalizeMiddleware = SkypeMentionNormalizeMiddleware; + } +}); + +// node_modules/botbuilder-core/lib/stringUtils.js +var require_stringUtils = __commonJS({ + "node_modules/botbuilder-core/lib/stringUtils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.StringUtils = void 0; + var StringUtils = class { + /** + * Truncate string with ... + * + * @param text Text. + * @param length Length to truncate text. + * @returns Original string modified. + */ + static ellipsis(text, length) { + text = text || ""; + if (text.length <= length) { + return text; + } + return `${text.substr(0, length)}...`; + } + /** + * UniqueHash - create a unique hash from a string. + * + * @remarks + * The source for this function was derived from the following article: + * + * https://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ + * @param text Text to hash. + * @returns A string which is an unique hash. + */ + static hash(text) { + const length = text.length; + let hash = 0; + for (let i = 0; i < length; i++) { + const chr = text.charCodeAt(i); + hash = (hash << 5) - hash + chr; + hash |= 0; + } + return hash.toString(); + } + /** + * EllipsisHash - create truncated string with unique hash for the truncated part. + * + * @param text Text to truncate. + * @param length Length to truncate at. + * @returns The truncated string with unique hash for the truncated part. + */ + static ellipsisHash(text, length) { + text = text || ""; + if (text.length <= length) { + return text; + } + return `${this.ellipsis(text, length)}${this.hash(text)}`; + } + }; + exports2.StringUtils = StringUtils; + } +}); + +// node_modules/botbuilder-core/lib/telemetryConstants.js +var require_telemetryConstants = __commonJS({ + "node_modules/botbuilder-core/lib/telemetryConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TelemetryConstants = void 0; + var TelemetryConstants = class { + }; + exports2.TelemetryConstants = TelemetryConstants; + TelemetryConstants.channelIdProperty = "channelId"; + TelemetryConstants.conversationIdProperty = "conversationId"; + TelemetryConstants.conversationNameProperty = "conversationName"; + TelemetryConstants.dialogIdProperty = "dialogId"; + TelemetryConstants.fromIdProperty = "fromId"; + TelemetryConstants.fromNameProperty = "fromName"; + TelemetryConstants.localeProperty = "locale"; + TelemetryConstants.recipientIdProperty = "recipientId"; + TelemetryConstants.recipientNameProperty = "recipientName"; + TelemetryConstants.replyActivityIdProperty = "replyActivityId"; + TelemetryConstants.textProperty = "text"; + TelemetryConstants.speakProperty = "speak"; + TelemetryConstants.userIdProperty = "userId"; + TelemetryConstants.attachmentsProperty = "attachments"; + TelemetryConstants.activityTypeProperty = "type"; + TelemetryConstants.activityIdProperty = "activityId"; + } +}); + +// node_modules/botbuilder-core/lib/telemetryLoggerMiddleware.js +var require_telemetryLoggerMiddleware = __commonJS({ + "node_modules/botbuilder-core/lib/telemetryLoggerMiddleware.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TelemetryLoggerMiddleware = void 0; + var botTelemetryClient_1 = require_botTelemetryClient(); + var telemetryConstants_1 = require_telemetryConstants(); + var turnContext_1 = require_turnContext(); + var botframework_schema_1 = require_lib4(); + function isTeamsChannelData(channelData) { + return typeof channelData === "object"; + } + var TelemetryLoggerMiddleware = class _TelemetryLoggerMiddleware { + /** + * Initializes a new instance of the TelemetryLoggerMiddleware class. + * + * @param telemetryClient The BotTelemetryClient used for logging. + * @param logPersonalInformation (Optional) Enable/Disable logging original message name within Application Insights. + */ + constructor(telemetryClient, logPersonalInformation = false) { + this._telemetryClient = telemetryClient || new botTelemetryClient_1.NullTelemetryClient(); + this._logPersonalInformation = logPersonalInformation; + } + /** + * Gets a value indicating whether to log personal information that came from the user. + * + * @returns A value indicating whether to log personal information or not. + */ + get logPersonalInformation() { + return this._logPersonalInformation; + } + /** + * Gets the currently configured botTelemetryClient that logs the events. + * + * @returns The currently configured [BotTelemetryClient](xref:botbuilder-core.BotTelemetryClient) that logs the events. + */ + get telemetryClient() { + return this._telemetryClient; + } + /** + * Logs events based on incoming and outgoing activities using the botTelemetryClient class. + * + * @param context The context object for this turn. + * @param next The delegate to call to continue the bot middleware pipeline + */ + onTurn(context, next) { + return __awaiter2(this, void 0, void 0, function* () { + if (context === null) { + throw new Error("context is null"); + } + context.turnState.set("telemetryClient", this.telemetryClient); + if (context.activity !== null) { + const activity = context.activity; + yield this.onReceiveActivity(activity); + } + context.onSendActivities((ctx, activities, nextSend) => __awaiter2(this, void 0, void 0, function* () { + const responses = yield nextSend(); + activities.forEach((act) => __awaiter2(this, void 0, void 0, function* () { + yield this.onSendActivity(act); + })); + return responses; + })); + context.onUpdateActivity((ctx, activity, nextUpdate) => __awaiter2(this, void 0, void 0, function* () { + const response = yield nextUpdate(); + yield this.onUpdateActivity(activity); + return response; + })); + context.onDeleteActivity((ctx, reference, nextDelete) => __awaiter2(this, void 0, void 0, function* () { + yield nextDelete(); + const deletedActivity = turnContext_1.TurnContext.applyConversationReference({ + type: botframework_schema_1.ActivityTypes.MessageDelete, + id: reference.activityId + }, reference, false); + yield this.onDeleteActivity(deletedActivity); + })); + if (next !== null) { + yield next(); + } + }); + } + /** + * Invoked when a message is received from the user. + * Performs logging of telemetry data using the IBotTelemetryClient.TrackEvent() method. + * The event name logged is "BotMessageReceived". + * + * @param activity Current activity sent from user. + */ + onReceiveActivity(activity) { + return __awaiter2(this, void 0, void 0, function* () { + this.telemetryClient.trackEvent({ + name: _TelemetryLoggerMiddleware.botMsgReceiveEvent, + properties: yield this.fillReceiveEventProperties(activity) + }); + }); + } + /** + * Invoked when the bot sends a message to the user. + * Performs logging of telemetry data using the botTelemetryClient.trackEvent() method. + * The event name logged is "BotMessageSend". + * + * @param activity Last activity sent from user. + */ + onSendActivity(activity) { + return __awaiter2(this, void 0, void 0, function* () { + this.telemetryClient.trackEvent({ + name: _TelemetryLoggerMiddleware.botMsgSendEvent, + properties: yield this.fillSendEventProperties(activity) + }); + }); + } + /** + * Invoked when the bot updates a message. + * Performs logging of telemetry data using the botTelemetryClient.trackEvent() method. + * The event name used is "BotMessageUpdate". + * + * @param activity Current activity sent from user. + */ + onUpdateActivity(activity) { + return __awaiter2(this, void 0, void 0, function* () { + this.telemetryClient.trackEvent({ + name: _TelemetryLoggerMiddleware.botMsgUpdateEvent, + properties: yield this.fillUpdateEventProperties(activity) + }); + }); + } + /** + * Invoked when the bot deletes a message. + * Performs logging of telemetry data using the botTelemetryClient.trackEvent() method. + * The event name used is "BotMessageDelete". + * + * @param activity Current activity sent from user. + */ + onDeleteActivity(activity) { + return __awaiter2(this, void 0, void 0, function* () { + this.telemetryClient.trackEvent({ + name: _TelemetryLoggerMiddleware.botMsgDeleteEvent, + properties: yield this.fillDeleteEventProperties(activity) + }); + }); + } + /** + * Fills the Application Insights Custom Event properties for BotMessageReceived. + * These properties are logged in the custom event when a new message is received from the user. + * + * @param activity Last activity sent from user. + * @param telemetryProperties Additional properties to add to the event. + * @returns A dictionary that is sent as "Properties" to botTelemetryClient.trackEvent method. + */ + fillReceiveEventProperties(activity, telemetryProperties) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; + return __awaiter2(this, void 0, void 0, function* () { + const properties = {}; + if (activity) { + properties[telemetryConstants_1.TelemetryConstants.fromIdProperty] = (_b = (_a = activity.from) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : ""; + properties[telemetryConstants_1.TelemetryConstants.conversationIdProperty] = (_d = (_c = activity.conversation) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : ""; + properties[telemetryConstants_1.TelemetryConstants.conversationNameProperty] = (_f = (_e = activity.conversation) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : ""; + properties[telemetryConstants_1.TelemetryConstants.localeProperty] = (_g = activity.locale) !== null && _g !== void 0 ? _g : ""; + properties[telemetryConstants_1.TelemetryConstants.recipientIdProperty] = (_j = (_h = activity.recipient) === null || _h === void 0 ? void 0 : _h.id) !== null && _j !== void 0 ? _j : ""; + properties[telemetryConstants_1.TelemetryConstants.recipientNameProperty] = (_l = (_k = activity.recipient) === null || _k === void 0 ? void 0 : _k.name) !== null && _l !== void 0 ? _l : ""; + properties[telemetryConstants_1.TelemetryConstants.activityTypeProperty] = (_m = activity.type) !== null && _m !== void 0 ? _m : ""; + properties[telemetryConstants_1.TelemetryConstants.activityIdProperty] = (_o = activity.id) !== null && _o !== void 0 ? _o : ""; + if (this.logPersonalInformation) { + const fromName = (_q = (_p = activity.from) === null || _p === void 0 ? void 0 : _p.name) === null || _q === void 0 ? void 0 : _q.trim(); + if (fromName) { + properties[telemetryConstants_1.TelemetryConstants.fromNameProperty] = fromName; + } + const activityText = (_r = activity.text) === null || _r === void 0 ? void 0 : _r.trim(); + if (activityText) { + properties[telemetryConstants_1.TelemetryConstants.textProperty] = activityText; + } + const activitySpeak = (_s = activity.speak) === null || _s === void 0 ? void 0 : _s.trim(); + if (activitySpeak) { + properties[telemetryConstants_1.TelemetryConstants.speakProperty] = activitySpeak; + } + } + if (telemetryProperties) { + return Object.assign({}, properties, telemetryProperties); + } + } + this.populateAdditionalChannelProperties(activity, properties); + if (telemetryProperties) { + return Object.assign({}, properties, telemetryProperties); + } + return properties; + }); + } + /** + * Fills the Application Insights Custom Event properties for BotMessageSend. + * These properties are logged in the custom event when a response message is sent by the Bot to the user. + * + * @param activity - Last activity sent from user. + * @param telemetryProperties Additional properties to add to the event. + * @returns A dictionary that is sent as "Properties" to botTelemetryClient.trackEvent method. + */ + fillSendEventProperties(activity, telemetryProperties) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; + return __awaiter2(this, void 0, void 0, function* () { + const properties = {}; + if (activity) { + properties[telemetryConstants_1.TelemetryConstants.replyActivityIdProperty] = (_a = activity.replyToId) !== null && _a !== void 0 ? _a : ""; + properties[telemetryConstants_1.TelemetryConstants.recipientIdProperty] = (_c = (_b = activity.recipient) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : ""; + properties[telemetryConstants_1.TelemetryConstants.conversationIdProperty] = (_e = (_d = activity.conversation) === null || _d === void 0 ? void 0 : _d.id) !== null && _e !== void 0 ? _e : ""; + properties[telemetryConstants_1.TelemetryConstants.conversationNameProperty] = (_g = (_f = activity.conversation) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : ""; + properties[telemetryConstants_1.TelemetryConstants.localeProperty] = (_h = activity.locale) !== null && _h !== void 0 ? _h : ""; + properties[telemetryConstants_1.TelemetryConstants.activityTypeProperty] = (_j = activity.type) !== null && _j !== void 0 ? _j : ""; + properties[telemetryConstants_1.TelemetryConstants.activityIdProperty] = (_k = activity.id) !== null && _k !== void 0 ? _k : ""; + if (this.logPersonalInformation) { + const recipientName = (_m = (_l = activity.recipient) === null || _l === void 0 ? void 0 : _l.name) === null || _m === void 0 ? void 0 : _m.trim(); + if (recipientName) { + properties[telemetryConstants_1.TelemetryConstants.recipientNameProperty] = recipientName; + } + const activityText = (_o = activity.text) === null || _o === void 0 ? void 0 : _o.trim(); + if (activityText) { + properties[telemetryConstants_1.TelemetryConstants.textProperty] = activityText; + } + const activitySpeak = (_p = activity.speak) === null || _p === void 0 ? void 0 : _p.trim(); + if (activitySpeak) { + properties[telemetryConstants_1.TelemetryConstants.speakProperty] = activitySpeak; + } + if ((_q = activity.attachments) === null || _q === void 0 ? void 0 : _q.length) { + properties[telemetryConstants_1.TelemetryConstants.attachmentsProperty] = JSON.stringify(activity.attachments); + } + } + if (telemetryProperties) { + return Object.assign({}, properties, telemetryProperties); + } + } + return properties; + }); + } + /** + * Fills the event properties for BotMessageUpdate. + * These properties are logged when an activity message is updated by the Bot. + * For example, if a card is interacted with by the use, and the card needs to be updated to reflect + * some interaction. + * + * @param activity - Last activity sent from user. + * @param telemetryProperties Additional properties to add to the event. + * @returns A dictionary that is sent as "Properties" to botTelemetryClient.trackEvent method. + */ + fillUpdateEventProperties(activity, telemetryProperties) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; + return __awaiter2(this, void 0, void 0, function* () { + const properties = {}; + if (activity) { + properties[telemetryConstants_1.TelemetryConstants.recipientIdProperty] = (_b = (_a = activity.recipient) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : ""; + properties[telemetryConstants_1.TelemetryConstants.conversationIdProperty] = (_d = (_c = activity.conversation) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : ""; + properties[telemetryConstants_1.TelemetryConstants.conversationNameProperty] = (_f = (_e = activity.conversation) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : ""; + properties[telemetryConstants_1.TelemetryConstants.localeProperty] = (_g = activity.locale) !== null && _g !== void 0 ? _g : ""; + properties[telemetryConstants_1.TelemetryConstants.activityTypeProperty] = (_h = activity.type) !== null && _h !== void 0 ? _h : ""; + properties[telemetryConstants_1.TelemetryConstants.activityIdProperty] = (_j = activity.id) !== null && _j !== void 0 ? _j : ""; + if (this.logPersonalInformation) { + const activityText = (_k = activity.text) === null || _k === void 0 ? void 0 : _k.trim(); + if (activityText) { + properties[telemetryConstants_1.TelemetryConstants.textProperty] = activityText; + } + } + if (telemetryProperties) { + return Object.assign({}, properties, telemetryProperties); + } + } + return properties; + }); + } + /** + * Fills the Application Insights Custom Event properties for BotMessageDelete. + * These properties are logged in the custom event when an activity message is deleted by the Bot. This is a relatively rare case. + * + * @param activity - Last activity sent from user. + * @param telemetryProperties Additional properties to add to the event. + * @returns A dictionary that is sent as "Properties" to botTelemetryClient.trackEvent method. + */ + fillDeleteEventProperties(activity, telemetryProperties) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j; + return __awaiter2(this, void 0, void 0, function* () { + const properties = {}; + if (activity) { + properties[telemetryConstants_1.TelemetryConstants.channelIdProperty] = (_a = activity.channelId) !== null && _a !== void 0 ? _a : ""; + properties[telemetryConstants_1.TelemetryConstants.recipientIdProperty] = (_c = (_b = activity.recipient) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : ""; + properties[telemetryConstants_1.TelemetryConstants.conversationIdProperty] = (_e = (_d = activity.conversation) === null || _d === void 0 ? void 0 : _d.id) !== null && _e !== void 0 ? _e : ""; + properties[telemetryConstants_1.TelemetryConstants.conversationNameProperty] = (_g = (_f = activity.conversation) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : ""; + properties[telemetryConstants_1.TelemetryConstants.activityTypeProperty] = (_h = activity.type) !== null && _h !== void 0 ? _h : ""; + properties[telemetryConstants_1.TelemetryConstants.activityIdProperty] = (_j = activity.id) !== null && _j !== void 0 ? _j : ""; + if (telemetryProperties) { + return Object.assign({}, properties, telemetryProperties); + } + } + return properties; + }); + } + populateAdditionalChannelProperties(activity, properties) { + var _a, _b, _c, _d; + if (activity) { + const channelData = activity.channelData; + switch (activity.channelId) { + case "msteams": + properties.TeamsUserAadObjectId = (_b = (_a = activity.from) === null || _a === void 0 ? void 0 : _a.aadObjectId) !== null && _b !== void 0 ? _b : ""; + if (isTeamsChannelData(channelData)) { + properties.TeamsTenantId = (_d = (_c = channelData.tenant) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : ""; + if (channelData.team) { + properties.TeamsTeamInfo = JSON.stringify(channelData.team); + } + } + break; + default: + break; + } + } + } + }; + exports2.TelemetryLoggerMiddleware = TelemetryLoggerMiddleware; + TelemetryLoggerMiddleware.botMsgReceiveEvent = "BotMessageReceived"; + TelemetryLoggerMiddleware.botMsgSendEvent = "BotMessageSend"; + TelemetryLoggerMiddleware.botMsgUpdateEvent = "BotMessageUpdate"; + TelemetryLoggerMiddleware.botMsgDeleteEvent = "BotMessageDelete"; + } +}); + +// node_modules/botbuilder-core/lib/testAdapter.js +var require_testAdapter = __commonJS({ + "node_modules/botbuilder-core/lib/testAdapter.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TestFlow = exports2.TestAdapter = void 0; + var assert_1 = __importDefault2(require("assert")); + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + var botframework_schema_1 = require_lib4(); + var botAdapter_1 = require_botAdapter(); + var turnContext_1 = require_turnContext(); + var TestAdapter = class _TestAdapter extends botAdapter_1.BotAdapter { + /** + * Creates a new TestAdapter instance. + * + * @param logicOrConversation The bots logic that's under test. + * @param template (Optional) activity containing default values to assign to all test messages received. + * @param sendTraceActivity Indicates whether the adapter should add to its queue any trace activities generated by the bot. + */ + constructor(logicOrConversation, template, sendTraceActivity = false) { + super(); + this.locale = "en-us"; + this.activeQueue = []; + this._sendTraceActivity = false; + this._nextId = 0; + this.ExceptionExpected = "ExceptionExpected"; + this._userTokens = []; + this._magicCodes = []; + this.exchangeableTokens = {}; + this._sendTraceActivity = sendTraceActivity; + this.template = template || {}; + if (logicOrConversation) { + if (typeof logicOrConversation === "function") { + this._logic = logicOrConversation; + this.conversation = _TestAdapter.createConversation("Convo1"); + } else { + this.conversation = logicOrConversation; + } + } else { + this.conversation = _TestAdapter.createConversation("Convo1"); + } + Object.assign(this.conversation, { + locale: this.template.locale || this.conversation.locale || this.locale, + serviceUrl: this.template.serviceUrl || this.conversation.serviceUrl, + channelId: this.template.channelId || this.conversation.channelId, + bot: this.template.recipient || this.conversation.bot, + user: this.template.from || this.conversation.user + }); + } + /** + * @private + * INTERNAL: used to drive the promise chain forward when running tests. + */ + get activityBuffer() { + return this.activeQueue; + } + /** + * Gets a value indicating whether to send trace activities. + * + * @returns A value indicating whether to send trace activities. + */ + get enableTrace() { + return this._sendTraceActivity; + } + /** + * Sets a value inidicating whether to send trace activities. + */ + set enableTrace(value) { + this._sendTraceActivity = value; + } + /** + * Create a ConversationReference. + * + * @param name name of the conversation (also id). + * @param user name of the user (also id) default: User1. + * @param bot name of the bot (also id) default: Bot. + * @returns The [ConversationReference](xref:botframework-schema.ConversationReference). + */ + static createConversation(name, user = "User1", bot = "Bot") { + const conversationReference = { + channelId: botframework_schema_1.Channels.Test, + serviceUrl: "https://test.com", + conversation: { isGroup: false, id: name, name }, + user: { id: user.toLowerCase(), name: user }, + bot: { id: bot.toLowerCase(), name: bot }, + locale: "en-us" + }; + return conversationReference; + } + /** + * Dequeues and returns the next bot response from the activeQueue. + * + * @returns The next activity in the queue; or undefined, if the queue is empty. + */ + getNextReply() { + if (this.activeQueue.length > 0) { + return this.activeQueue.shift(); + } + return void 0; + } + /** + * Creates a message activity from text and the current conversational context. + * + * @param text The message text. + * @returns An appropriate message activity. + */ + makeActivity(text) { + const activity = { + type: botframework_schema_1.ActivityTypes.Message, + locale: this.locale, + from: this.conversation.user, + recipient: this.conversation.bot, + conversation: this.conversation.conversation, + serviceUrl: this.conversation.serviceUrl, + id: (this._nextId++).toString(), + text + }; + return activity; + } + /** + * Processes a message activity from a user. + * + * @param userSays The text of the user's message. + * @param callback The bot logic to invoke. + * @returns {Promise} A promise representing the async operation. + */ + sendTextToBot(userSays, callback) { + return this.processActivity(this.makeActivity(userSays), callback); + } + /** + * Receives an activity and runs it through the middleware pipeline. + * + * @param activity The activity to process. + * @param callback The bot logic to invoke. + * @returns {Promise} A promise representing the async operation. + */ + processActivity(activity, callback) { + return __awaiter2(this, void 0, void 0, function* () { + const request = typeof activity === "string" ? { type: botframework_schema_1.ActivityTypes.Message, text: activity } : activity; + request.type = request.type || botframework_schema_1.ActivityTypes.Message; + request.channelId = request.channelId || this.conversation.channelId; + if (!request.from || request.from.id === "unknown" || request.from.role === botframework_schema_1.RoleTypes.Bot) { + request.from = this.conversation.user; + } + request.recipient = request.recipient || this.conversation.bot; + request.conversation = request.conversation || this.conversation.conversation; + request.serviceUrl = request.serviceUrl || this.conversation.serviceUrl; + request.id = request.id || (this._nextId++).toString(); + request.timestamp = request.timestamp || /* @__PURE__ */ new Date(); + Object.assign(request, this.template); + const context = this.createContext(request); + if (callback) { + return yield this.runMiddleware(context, callback); + } else if (this._logic) { + return yield this.runMiddleware(context, this._logic); + } + }); + } + /** + * @private + * Sends activities to the conversation. + * @param context Context object for the current turn of conversation with the user. + * @param activities Set of activities sent by logic under test. + */ + sendActivities(context, activities) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context) { + throw new Error("TurnContext cannot be null."); + } + if (!activities) { + throw new Error("Activities cannot be null."); + } + if (activities.length == 0) { + throw new Error("Expecting one or more activities, but the array was empty."); + } + const responses = []; + for (let i = 0; i < activities.length; i++) { + const activity = activities[i]; + if (!activity.id) { + activity.id = (0, uuid_1.v4)(); + } + if (!activity.timestamp) { + activity.timestamp = /* @__PURE__ */ new Date(); + } + if (activity.type === "delay") { + const delayMs = parseInt(activity.value); + yield new Promise((resolve) => setTimeout(resolve, delayMs)); + } else if (activity.type === botframework_schema_1.ActivityTypes.Trace) { + if (this._sendTraceActivity) { + this.activeQueue.push(activity); + } + } else { + this.activeQueue.push(activity); + } + responses.push({ id: activity.id }); + } + return responses; + }); + } + /** + * @private + * Replaces an existing activity in the activeQueue. + * @param context Context object for the current turn of conversation with the user. + * @param activity Activity being updated. + * @returns promise representing async operation + */ + updateActivity(context, activity) { + if (activity.id) { + const idx = this.activeQueue.findIndex((a) => a.id === activity.id); + if (idx !== -1) { + this.activeQueue.splice(idx, 1, activity); + } + return Promise.resolve({ id: activity.id }); + } + return Promise.resolve(); + } + /** + * @private + * Deletes an existing activity in the activeQueue. + * @param context Context object for the current turn of conversation with the user. + * @param reference `ConversationReference` for activity being deleted. + */ + deleteActivity(context, reference) { + if (reference.activityId) { + const idx = this.activeQueue.findIndex((a) => a.id === reference.activityId); + if (idx !== -1) { + this.activeQueue.splice(idx, 1); + } + } + return Promise.resolve(); + } + /** + * @private + * INTERNAL: called by a `TestFlow` instance to simulate a user sending a message to the bot. + * This will cause the adapters middleware pipe to be run and it's logic to be called. + * @param activity Text or activity from user. The current conversation reference [template](#template) will be merged the passed in activity to properly address the activity. Fields specified in the activity override fields in the template. + */ + receiveActivity(activity) { + return this.processActivity(activity); + } + /** + * The `TestAdapter` doesn't implement `continueConversation()` and will return an error if it's + * called. + * + * @param _reference A reference to the conversation to continue. + * @param _logic The asynchronous method to call after the adapter middleware runs. + * @returns {Promise} A promise representing the async operation. + */ + continueConversation(_reference, _logic) { + return Promise.reject(new Error("not implemented")); + } + /** + * Creates a turn context. + * + * @param request An incoming request body. + * @returns The created [TurnContext](xref:botbuilder-core.TurnContext). + * @remarks + * Override this in a derived class to modify how the adapter creates a turn context. + */ + createContext(request) { + return new turnContext_1.TurnContext(this, request); + } + /** + * Sends something to the bot. This returns a new `TestFlow` instance which can be used to add + * additional steps for inspecting the bots reply and then sending additional activities. + * + * @remarks + * This example shows how to send a message and then verify that the response was as expected: + * + * ```JavaScript + * adapter.send('hi') + * .assertReply('Hello World') + * .then(() => done()); + * ``` + * @param userSays Text or activity simulating user input. + * @returns a new [TestFlow](xref:botbuilder-core.TestFlow) instance which can be used to add additional steps + * for inspecting the bots reply and then sending additional activities. + */ + send(userSays) { + return new TestFlow(this.processActivity(userSays), this); + } + /** + * Send something to the bot and expects the bot to return with a given reply. + * + * @remarks + * This is simply a wrapper around calls to `send()` and `assertReply()`. This is such a + * common pattern that a helper is provided. + * + * ```JavaScript + * adapter.test('hi', 'Hello World') + * .then(() => done()); + * ``` + * @param userSays Text or activity simulating user input. + * @param expected Expected text or activity of the reply sent by the bot. + * @param description (Optional) Description of the test case. If not provided one will be generated. + * @param _timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + test(userSays, expected, description, _timeout) { + return this.send(userSays).assertReply(expected, description); + } + /** + * Test a list of activities. + * + * @remarks + * Each activity with the "bot" role will be processed with assertReply() and every other + * activity will be processed as a user message with send(). + * @param activities Array of activities. + * @param description (Optional) Description of the test case. If not provided one will be generated. + * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + testActivities(activities, description, timeout) { + if (!activities) { + throw new Error("Missing array of activities"); + } + const activityInspector = (expected) => (actual, description2) => validateTranscriptActivity(actual, expected, description2); + return activities.reduce((flow, activity) => { + const assertDescription = `reply ${description ? " from " + description : ""}`; + return this.isReply(activity) ? flow.assertReply(activityInspector(activity, description), assertDescription, timeout) : flow.send(activity); + }, new TestFlow(Promise.resolve(), this)); + } + /** + * Adds a fake user token so it can later be retrieved. + * + * @param connectionName The connection name. + * @param channelId The channel id. + * @param userId The user id. + * @param token The token to store. + * @param magicCode (Optional) The optional magic code to associate with this token. + */ + addUserToken(connectionName, channelId, userId, token, magicCode) { + const key = new UserToken(); + key.channelId = channelId; + key.connectionName = connectionName; + key.userId = userId; + key.token = token; + if (!magicCode) { + this._userTokens.push(key); + } else { + const mc = new TokenMagicCode(); + mc.key = key; + mc.magicCode = magicCode; + this._magicCodes.push(mc); + } + } + /** + * Asynchronously retrieves the token status for each configured connection for the given user. + * In testAdapter, retrieves tokens which were previously added via addUserToken. + * + * @param context The context object for the turn. + * @param userId The ID of the user to retrieve the token status for. + * @param includeFilter Optional. A comma-separated list of connection's to include. If present, + * the `includeFilter` parameter limits the tokens this method returns. + * @param _oAuthAppCredentials AppCredentials for OAuth. + * @returns The [TokenStatus](xref:botframework-connector.TokenStatus) objects retrieved. + */ + getTokenStatus(context, userId, includeFilter, _oAuthAppCredentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context || !context.activity) { + throw new Error("testAdapter.getTokenStatus(): context with activity is required"); + } + if (!userId && (!context.activity.from || !context.activity.from.id)) { + throw new Error("testAdapter.getTokenStatus(): missing userId, from or from.id"); + } + const filter = includeFilter ? includeFilter.split(",") : void 0; + if (!userId) { + userId = context.activity.from.id; + } + return this._userTokens.filter((x) => x.channelId === context.activity.channelId && x.userId === userId && (!filter || filter.includes(x.connectionName))).map((token) => ({ + ConnectionName: token.connectionName, + HasToken: true, + ServiceProviderDisplayName: token.connectionName + })); + }); + } + /** + * Retrieves the OAuth token for a user that is in a sign-in flow. + * + * @param context Context for the current turn of conversation with the user. + * @param connectionName Name of the auth connection to use. + * @param magicCode (Optional) Optional user entered code to validate. + * @returns The OAuth token for a user that is in a sign-in flow. + */ + getUserToken(context, connectionName, magicCode) { + return __awaiter2(this, void 0, void 0, function* () { + const key = new UserToken(); + key.channelId = context.activity.channelId; + key.connectionName = connectionName; + key.userId = context.activity.from.id; + if (magicCode) { + const magicCodeRecord = this._magicCodes.find((item) => key.equalsKey(item.key) && item.magicCode === magicCode); + if (magicCodeRecord) { + this.addUserToken(connectionName, key.channelId, key.userId, magicCodeRecord.key.token); + const idx = this._magicCodes.indexOf(magicCodeRecord); + this._magicCodes.splice(idx, 1); + } + } + const userToken = this._userTokens.find((token) => key.equalsKey(token)); + return userToken && Object.assign({ expiration: void 0 }, userToken); + }); + } + /** + * Signs the user out with the token server. + * + * @param context Context for the current turn of conversation with the user. + * @param connectionName Name of the auth connection to use. + * @param userId User ID to sign out. + */ + signOutUser(context, connectionName, userId) { + return __awaiter2(this, void 0, void 0, function* () { + const channelId = context.activity.channelId; + userId = userId || context.activity.from.id; + this._userTokens = this._userTokens.filter((token) => connectionName && (connectionName !== token.connectionName || channelId !== token.channelId || userId !== token.userId)); + }); + } + /** + * Gets a signin link from the token server that can be sent as part of a SigninCard. + * + * @param context Context for the current turn of conversation with the user. + * @param connectionName Name of the auth connection to use. + * @returns A signin link from the token server that can be sent as part of a SigninCard. + */ + getSignInLink(context, connectionName) { + return __awaiter2(this, void 0, void 0, function* () { + return `https://fake.com/oauthsignin/${connectionName}/${context.activity.channelId}/${context.activity.from.id}`; + }); + } + /** + * Signs the user out with the token server. + * + * @param _context Context for the current turn of conversation with the user. + * @param _connectionName Name of the auth connection to use. + * @param _resourceUrls The list of resource URLs to retrieve tokens for. + * @returns A Dictionary of resourceUrl to the corresponding TokenResponse. + */ + getAadTokens(_context, _connectionName, _resourceUrls) { + return __awaiter2(this, void 0, void 0, function* () { + return void 0; + }); + } + /** + * Adds a fake exchangeable token so it can be exchanged later. + * + * @param connectionName Name of the auth connection to use. + * @param channelId Channel ID. + * @param userId User ID. + * @param exchangeableItem Exchangeable token or resource URI. + * @param token Token to store. + */ + addExchangeableToken(connectionName, channelId, userId, exchangeableItem, token) { + const key = new ExchangeableToken(); + key.channelId = channelId; + key.connectionName = connectionName; + key.userId = userId; + key.exchangeableItem = exchangeableItem; + key.token = token; + this.exchangeableTokens[key.toKey()] = key; + } + /** + * Gets a sign-in resource. + * + * @param context [TurnContext](xref:botbuilder-core.TurnContext) for the current turn of conversation with the user. + * @param connectionName Name of the auth connection to use. + * @param userId User ID + * @param _finalRedirect Final redirect URL. + * @returns A `Promise` with a new [SignInUrlResponse](xref:botframework-schema.SignInUrlResponse) object. + */ + getSignInResource(context, connectionName, userId, _finalRedirect) { + return __awaiter2(this, void 0, void 0, function* () { + return { + signInLink: `https://botframeworktestadapter.com/oauthsignin/${connectionName}/${context.activity.channelId}/${userId}`, + tokenExchangeResource: { + id: String(Math.random()), + providerId: null, + uri: `api://${connectionName}/resource` + } + }; + }); + } + /** + * Performs a token exchange operation such as for single sign-on. + * + * @param context [TurnContext](xref:botbuilder-core.TurnContext) for the current turn of conversation with the user. + * @param connectionName Name of the auth connection to use. + * @param userId User id associated with the token. + * @param tokenExchangeRequest Exchange request details, either a token to exchange or a uri to exchange. + * @returns If the promise completes, the exchanged token is returned. + */ + exchangeToken(context, connectionName, userId, tokenExchangeRequest) { + return __awaiter2(this, void 0, void 0, function* () { + const exchangeableValue = tokenExchangeRequest.token ? tokenExchangeRequest.token : tokenExchangeRequest.uri; + const key = new ExchangeableToken(); + key.channelId = context.activity.channelId; + key.connectionName = connectionName; + key.exchangeableItem = exchangeableValue; + key.userId = userId; + const tokenExchangeResponse = this.exchangeableTokens[key.toKey()]; + if (tokenExchangeResponse && tokenExchangeResponse.token === this.ExceptionExpected) { + throw new Error("Exception occurred during exchanging tokens"); + } + return tokenExchangeResponse ? { + channelId: key.channelId, + connectionName: key.connectionName, + token: tokenExchangeResponse.token, + expiration: null + } : null; + }); + } + /** + * Adds an instruction to throw an exception during exchange requests. + * + * @param connectionName The connection name. + * @param channelId The channel id. + * @param userId The user id. + * @param exchangeableItem The exchangeable token or resource URI. + */ + throwOnExchangeRequest(connectionName, channelId, userId, exchangeableItem) { + const token = new ExchangeableToken(); + token.channelId = channelId; + token.connectionName = connectionName; + token.userId = userId; + token.exchangeableItem = exchangeableItem; + const key = token.toKey(); + token.token = this.ExceptionExpected; + this.exchangeableTokens[key] = token; + } + /** + * Indicates if the activity is a reply from the bot (role == 'bot') + * + * @remarks + * Checks to see if the from property and if from.role exists on the Activity before + * checking to see who the activity is from. Otherwise returns false by default. + * @param activity Activity to check. + * @returns True if the activity is a reply from the bot, otherwise, false. + */ + isReply(activity) { + if (activity.from && activity.from.role) { + return activity.from.role && activity.from.role.toLocaleLowerCase() === "bot"; + } else { + return false; + } + } + }; + exports2.TestAdapter = TestAdapter; + var UserToken = class { + equalsKey(rhs) { + return rhs && this.connectionName === rhs.connectionName && this.userId === rhs.userId && this.channelId === rhs.channelId; + } + }; + var TokenMagicCode = class { + }; + var ExchangeableToken = class extends UserToken { + equalsKey(rhs) { + return rhs != null && this.exchangeableItem === rhs.exchangeableItem && super.equalsKey(rhs); + } + toKey() { + return this.exchangeableItem; + } + }; + var TestFlow = class _TestFlow { + /** + * @private + * INTERNAL: creates a new TestFlow instance. + * @param previous Promise chain for the current test sequence. + * @param adapter Adapter under tested. + * @param callback The bot turn processing logic to test. + */ + constructor(previous, adapter, callback) { + this.previous = previous; + this.adapter = adapter; + this.callback = callback; + } + /** + * Send something to the bot and expects the bot to return with a given reply. This is simply a + * wrapper around calls to `send()` and `assertReply()`. This is such a common pattern that a + * helper is provided. + * + * @param userSays Text or activity simulating user input. + * @param expected Expected text or activity of the reply sent by the bot. + * @param description (Optional) Description of the test case. If not provided one will be generated. + * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + test(userSays, expected, description, timeout) { + return this.send(userSays).assertReply(expected, description || `test("${userSays}", "${expected}")`, timeout); + } + /** + * Sends something to the bot. + * + * @param userSays Text or activity simulating user input. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + send(userSays) { + return new _TestFlow(this.previous.then(() => this.adapter.processActivity(userSays, this.callback)), this.adapter, this.callback); + } + /** + * Creates a conversation update activity and process the activity. + * + * @returns {TestFlow} A new TestFlow object. + */ + sendConversationUpdate() { + return new _TestFlow(this.previous.then(() => { + var _a; + const cu = botframework_schema_1.ActivityEx.createConversationUpdateActivity(); + (_a = cu.membersAdded) !== null && _a !== void 0 ? _a : cu.membersAdded = []; + cu.membersAdded.push(this.adapter.conversation.user); + return this.adapter.processActivity(cu, this.callback); + }), this.adapter, this.callback); + } + /** + * Generates an assertion if the bots response doesn't match the expected text/activity. + * + * @param expected Expected text or activity from the bot. Can be a callback to inspect the response using custom logic. + * @param description (Optional) Description of the test case. If not provided one will be generated. + * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + assertReply(expected, description, timeout) { + function defaultInspector(reply, description2) { + if (typeof expected === "object") { + validateActivity(reply, expected); + } else { + assert_1.default.equal(reply.type, botframework_schema_1.ActivityTypes.Message, `${description2} type === '${reply.type}'. `); + assert_1.default.equal(reply.text, expected, `${description2} text === "${reply.text}"`); + } + } + if (!description) { + description = ""; + } + const inspector = typeof expected === "function" ? expected : defaultInspector; + return new _TestFlow(this.previous.then(() => { + return new Promise((resolve, reject) => { + if (!timeout) { + timeout = 3e3; + } + const start = (/* @__PURE__ */ new Date()).getTime(); + const adapter = this.adapter; + function waitForActivity() { + const current = (/* @__PURE__ */ new Date()).getTime(); + if (current - start > timeout) { + let expecting; + switch (typeof expected) { + case "string": + default: + expecting = `"${expected.toString()}"`; + break; + case "object": + expecting = `"${expected.text}`; + break; + case "function": + expecting = expected.toString(); + break; + } + reject(new Error(`TestAdapter.assertReply(${expecting}): ${description} Timed out after ${current - start}ms.`)); + } else if (adapter.activeQueue.length > 0) { + const reply = adapter.activeQueue.shift(); + try { + inspector(reply, description); + } catch (err) { + reject(err); + } + resolve(); + } else { + setTimeout(waitForActivity, 5); + } + } + waitForActivity(); + }); + }), this.adapter, this.callback); + } + /** + * Generates an assertion that the turn processing logic did not generate a reply from the bot, as expected. + * + * @param description (Optional) Description of the test case. If not provided one will be generated. + * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + assertNoReply(description, timeout) { + return new _TestFlow(this.previous.then(() => { + return new Promise((resolve) => { + if (!timeout) { + timeout = 3e3; + } + const start = (/* @__PURE__ */ new Date()).getTime(); + const adapter = this.adapter; + function waitForActivity() { + const current = (/* @__PURE__ */ new Date()).getTime(); + if (current - start > timeout) { + resolve(); + } else if (adapter.activeQueue.length > 0) { + const reply = adapter.activeQueue.shift(); + assert_1.default.strictEqual(reply, void 0, `${JSON.stringify(reply)} is responded when waiting for no reply: '${description}'`); + resolve(); + } else { + setTimeout(waitForActivity, 5); + } + } + waitForActivity(); + }); + }), this.adapter, this.callback); + } + /** + * Generates an assertion if the bots response is not one of the candidate strings. + * + * @param candidates List of candidate responses. + * @param description (Optional) Description of the test case. If not provided one will be generated. + * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + assertReplyOneOf(candidates, description, timeout) { + return this.assertReply((activity, description2) => { + for (const candidate of candidates) { + if (activity.text === candidate) { + return; + } + } + assert_1.default.fail(`TestAdapter.assertReplyOneOf(): ${description2 || ""} FAILED, Expected one of :${JSON.stringify(candidates)}`); + }, description, timeout); + } + /** + * Inserts a delay before continuing. + * + * @param ms ms to wait. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + delay(ms) { + return new _TestFlow(this.previous.then(() => { + return new Promise((resolve, _reject) => { + setTimeout(resolve, ms); + }); + }), this.adapter, this.callback); + } + /** + * Adds a `then()` step to the tests promise chain. + * + * @param onFulfilled Code to run if the test is currently passing. + * @param onRejected Code to run if the test has thrown an error. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + then(onFulfilled, onRejected) { + return new _TestFlow(this.previous.then(onFulfilled, onRejected), this.adapter, this.callback); + } + /** + * Adds a finally clause. Note that you can't keep chaining afterwards. + * + * @param onFinally Code to run after the test chain. + * @returns {Promise} A promise representing the async operation. + */ + finally(onFinally) { + return Promise.resolve(this.previous.finally(onFinally)); + } + /** + * Adds a `catch()` clause to the tests promise chain. + * + * @param onRejected Code to run if the test has thrown an error. + * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. + */ + catch(onRejected) { + return new _TestFlow(this.previous.catch(onRejected), this.adapter, this.callback); + } + /** + * Start the test sequence, returning a promise to await. + * + * @returns {Promise} A promise representing the async operation. + */ + startTest() { + return this.previous; + } + }; + exports2.TestFlow = TestFlow; + function validateActivity(activity, expected) { + Object.keys(expected).forEach((prop) => { + assert_1.default.equal(activity[prop], expected[prop]); + }); + } + function validateTranscriptActivity(activity, expected, description) { + assert_1.default.equal(activity.type, expected.type, `failed "type" assert on ${description}`); + assert_1.default.equal(activity.text, expected.text, `failed "text" assert on ${description}`); + assert_1.default.equal(activity.speak, expected.speak, `failed "speak" assert on ${description}`); + assert_1.default.deepEqual(activity.suggestedActions, expected.suggestedActions, `failed "suggestedActions" assert on ${description}`); + } + } +}); + +// node_modules/botbuilder-core/lib/transcriptLogger.js +var require_transcriptLogger = __commonJS({ + "node_modules/botbuilder-core/lib/transcriptLogger.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ConsoleTranscriptLogger = exports2.TranscriptLoggerMiddleware = void 0; + var botframework_schema_1 = require_lib4(); + var turnContext_1 = require_turnContext(); + var TranscriptLoggerMiddleware = class { + /** + * Middleware for logging incoming and outgoing activities to a transcript store. + * + * @param logger Transcript logger + */ + constructor(logger) { + if (!logger) { + throw new Error("TranscriptLoggerMiddleware requires a TranscriptLogger instance."); + } + this.logger = logger; + } + /** + * Initialization for middleware turn. + * + * @param context Context for the current turn of conversation with the user. + * @param next Function to call at the end of the middleware chain. + */ + onTurn(context, next) { + return __awaiter2(this, void 0, void 0, function* () { + const transcript = []; + if (context.activity) { + if (!context.activity.from.role) { + context.activity.from.role = botframework_schema_1.RoleTypes.User; + } + this.logActivity(transcript, this.cloneActivity(context.activity)); + } + context.onSendActivities((ctx, activities, next2) => __awaiter2(this, void 0, void 0, function* () { + const responses = yield next2(); + activities.forEach((activity, index) => { + const clonedActivity = this.cloneActivity(activity); + clonedActivity.id = responses && responses[index] ? responses[index].id : clonedActivity.id; + if (!clonedActivity.id) { + const prefix = `g_${Math.random().toString(36).slice(2, 8)}`; + if (clonedActivity.timestamp) { + clonedActivity.id = `${prefix}${new Date(clonedActivity.timestamp).getTime().toString()}`; + } else { + clonedActivity.id = `${prefix}${(/* @__PURE__ */ new Date()).getTime().toString()}`; + } + } + this.logActivity(transcript, clonedActivity); + }); + return responses; + })); + context.onUpdateActivity((ctx, activity, next2) => __awaiter2(this, void 0, void 0, function* () { + const response = yield next2(); + const updateActivity = this.cloneActivity(activity); + updateActivity.type = botframework_schema_1.ActivityTypes.MessageUpdate; + this.logActivity(transcript, updateActivity); + return response; + })); + context.onDeleteActivity((ctx, reference, next2) => __awaiter2(this, void 0, void 0, function* () { + yield next2(); + const deleteActivity = turnContext_1.TurnContext.applyConversationReference({ + type: botframework_schema_1.ActivityTypes.MessageDelete, + id: reference.activityId + }, reference, false); + this.logActivity(transcript, this.cloneActivity(deleteActivity)); + })); + yield next(); + while (transcript.length) { + try { + const maybePromise = this.logger.logActivity(transcript.shift()); + if (maybePromise instanceof Promise) { + maybePromise.catch((err) => { + this.transcriptLoggerErrorHandler(err); + }); + } + } catch (err) { + this.transcriptLoggerErrorHandler(err); + } + } + }); + } + /** + * Logs the Activity. + * + * @param transcript Array where the activity will be pushed. + * @param activity Activity to log. + */ + logActivity(transcript, activity) { + if (!activity.timestamp) { + activity.timestamp = /* @__PURE__ */ new Date(); + } + if (!(activity.type === botframework_schema_1.ActivityTypes.Event && activity.name === botframework_schema_1.ActivityEventNames.ContinueConversation)) { + transcript.push(activity); + } + } + /** + * Clones the Activity entity. + * + * @param activity Activity to clone. + * @returns The cloned activity. + */ + cloneActivity(activity) { + return Object.assign({}, activity); + } + /** + * Error logging helper function. + * + * @param err Error or object to console.error out. + */ + transcriptLoggerErrorHandler(err) { + if (err instanceof Error) { + console.error(`TranscriptLoggerMiddleware logActivity failed: "${err.message}"`); + console.error(err.stack); + } else { + console.error(`TranscriptLoggerMiddleware logActivity failed: "${JSON.stringify(err)}"`); + } + } + }; + exports2.TranscriptLoggerMiddleware = TranscriptLoggerMiddleware; + var ConsoleTranscriptLogger = class { + /** + * Log an activity to the transcript. + * + * @param activity Activity being logged. + */ + logActivity(activity) { + if (!activity) { + throw new Error("Activity is required."); + } + console.log("Activity Log:", activity); + } + }; + exports2.ConsoleTranscriptLogger = ConsoleTranscriptLogger; + } +}); + +// node_modules/botbuilder-core/lib/userState.js +var require_userState = __commonJS({ + "node_modules/botbuilder-core/lib/userState.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.UserState = void 0; + var botState_1 = require_botState(); + var NO_KEY = "UserState: overridden getStorageKey method did not return a key."; + var UserState = class extends botState_1.BotState { + /** + * Creates a new UserState instance. + * + * @param storage Storage provider to persist user state to. + * @param namespace (Optional) namespace to append to storage keys. Defaults to an empty string. + */ + constructor(storage, namespace = "") { + super(storage, (context) => { + const key = this.getStorageKey(context); + return key ? Promise.resolve(key) : Promise.reject(new Error(NO_KEY)); + }); + this.namespace = namespace; + } + /** + * Returns the storage key for the current user state. + * + * @param context Context for current turn of conversation with the user. + * @returns The storage key for the current user state. + */ + getStorageKey(context) { + const activity = context.activity; + const channelId = activity.channelId; + const userId = activity && activity.from && activity.from.id ? activity.from.id : void 0; + if (!channelId) { + throw new Error("missing activity.channelId"); + } + if (!userId) { + throw new Error("missing activity.from.id"); + } + return `${channelId}/users/${userId}/${this.namespace}`; + } + }; + exports2.UserState = UserState; + } +}); + +// node_modules/botbuilder-core/lib/userTokenProvider.js +var require_userTokenProvider = __commonJS({ + "node_modules/botbuilder-core/lib/userTokenProvider.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botbuilder-core/lib/userTokenSettings.js +var require_userTokenSettings = __commonJS({ + "node_modules/botbuilder-core/lib/userTokenSettings.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.OAuthLoginTimeoutMsValue = exports2.TokenPollingSettingsKey = exports2.OAuthLoginTimeoutKey = void 0; + exports2.OAuthLoginTimeoutKey = "loginTimeout"; + exports2.TokenPollingSettingsKey = "tokenPollingSettings"; + exports2.OAuthLoginTimeoutMsValue = 9e5; + } +}); + +// node_modules/botbuilder-core/lib/skills/skillConversationIdFactoryBase.js +var require_skillConversationIdFactoryBase = __commonJS({ + "node_modules/botbuilder-core/lib/skills/skillConversationIdFactoryBase.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkillConversationIdFactoryBase = void 0; + var SkillConversationIdFactoryBase = class { + /** + * Creates a conversation ID for a skill conversation based on the caller's ConversationReference. + * + * @param _options The [SkillConversationIdFactoryOptions](xref:botbuilder-core.SkillConversationIdFactoryOptions) to use. + * @remarks It should be possible to use the returned string on a request URL and it should not contain special characters. + * Returns A unique conversation ID used to communicate with the skill. + */ + createSkillConversationIdWithOptions(_options) { + throw new Error("Not Implemented"); + } + /** + * Creates a conversation ID for a skill conversation based on the caller's ConversationReference. + * + * @deprecated Method is deprecated, please use createSkillConversationIdWithOptions() with SkillConversationIdFactoryOptions instead. + * @param _conversationReference The skill's caller ConversationReference. + * @remarks It should be possible to use the returned string on a request URL and it should not contain special characters. + * Returns A unique conversation ID used to communicate with the skill. + */ + createSkillConversationId(_conversationReference) { + throw new Error("Not Implemented"); + } + /** + * Gets the ConversationReference created using createSkillConversationId() for a skillConversationId. + * + * @deprecated Method is deprecated, please use getSkillConversationReference() instead. + * @param _skillConversationId A skill conversationId created using createSkillConversationId(). + * @remarks Returns The caller's ConversationReference for a skillConversationId. null if not found. + */ + getConversationReference(_skillConversationId) { + throw new Error("Not Implemented"); + } + /** + * Gets the SkillConversationReference created using createSkillConversationId() for a skillConversationId. + * + * @param _skillConversationId Gets the SkillConversationReference used during createSkillConversationId for a skillConversationId. + */ + getSkillConversationReference(_skillConversationId) { + throw new Error("Not Implemented"); + } + }; + exports2.SkillConversationIdFactoryBase = SkillConversationIdFactoryBase; + } +}); + +// node_modules/botbuilder-core/lib/skills/skillConversationIdFactory.js +var require_skillConversationIdFactory = __commonJS({ + "node_modules/botbuilder-core/lib/skills/skillConversationIdFactory.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkillConversationIdFactory = void 0; + var skillConversationIdFactoryBase_1 = require_skillConversationIdFactoryBase(); + var turnContext_1 = require_turnContext(); + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + var SkillConversationIdFactory = class extends skillConversationIdFactoryBase_1.SkillConversationIdFactoryBase { + /** + * Creates a new instance of the SkillConversationIdFactory class. + * + * @param storage The storage for the [ConversationReference](xref:botframework-schema:ConversationReference) instances. + */ + constructor(storage) { + super(); + this.storage = storage; + } + /** + * Creates a conversation ID for a skill conversation based on the caller's [ConversationReference](xref:botframework-schema:ConversationReference). + * + * @param options The [SkillConversationIdFactoryOptions](xref:botbuilder-core.SkillConversationIdFactoryOptions) to use. + * @returns {Promise} A unique conversation ID used to communicate with the skill. + */ + createSkillConversationIdWithOptions(options) { + return __awaiter2(this, void 0, void 0, function* () { + const conversationReference = turnContext_1.TurnContext.getConversationReference(options.activity); + const skillConversationId = (0, uuid_1.v4)(); + const skillConversationReference = { + conversationReference, + oAuthScope: options.fromBotOAuthScope + }; + yield this.storage.write({ [skillConversationId]: skillConversationReference }); + return skillConversationId; + }); + } + /** + * Gets the ConversationReference created using createSkillConversationId() for a skillConversationId. + * + * @param skillConversationId A skill conversationId created using createSkillConversationId(). + * @returns {Promise} The caller's ConversationReference for a skillConversationId. Null if not found. + */ + getSkillConversationReference(skillConversationId) { + return __awaiter2(this, void 0, void 0, function* () { + const skillConversationInfo = yield this.storage.read([skillConversationId]); + if (!skillConversationInfo) { + return void 0; + } + const skillConversationReference = skillConversationInfo[skillConversationId]; + if (!skillConversationReference) { + return void 0; + } + return skillConversationReference; + }); + } + /** + * Deletes the [SkillConversationReference](xref:botbuilder-core.SkillConversationReference) from the storage. + * + * @param skillConversationId The skill conversation id to use as key for the delete. + * @returns {Promise} A promise representing the asynchronous operation. + */ + deleteConversationReference(skillConversationId) { + return this.storage.delete([skillConversationId]); + } + }; + exports2.SkillConversationIdFactory = SkillConversationIdFactory; + } +}); + +// node_modules/botbuilder-core/lib/skills/constants.js +var require_constants5 = __commonJS({ + "node_modules/botbuilder-core/lib/skills/constants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkillConversationReferenceKey = void 0; + exports2.SkillConversationReferenceKey = Symbol("SkillConversationReference"); + } +}); + +// node_modules/botbuilder-core/lib/skills/index.js +var require_skills = __commonJS({ + "node_modules/botbuilder-core/lib/skills/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkillConversationReferenceKey = exports2.SkillConversationIdFactoryBase = exports2.SkillConversationIdFactory = void 0; + var skillConversationIdFactory_1 = require_skillConversationIdFactory(); + Object.defineProperty(exports2, "SkillConversationIdFactory", { enumerable: true, get: function() { + return skillConversationIdFactory_1.SkillConversationIdFactory; + } }); + var skillConversationIdFactoryBase_1 = require_skillConversationIdFactoryBase(); + Object.defineProperty(exports2, "SkillConversationIdFactoryBase", { enumerable: true, get: function() { + return skillConversationIdFactoryBase_1.SkillConversationIdFactoryBase; + } }); + var constants_1 = require_constants5(); + Object.defineProperty(exports2, "SkillConversationReferenceKey", { enumerable: true, get: function() { + return constants_1.SkillConversationReferenceKey; + } }); + } +}); + +// node_modules/botbuilder-core/lib/cloudAdapterBase.js +var require_cloudAdapterBase = __commonJS({ + "node_modules/botbuilder-core/lib/cloudAdapterBase.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CloudAdapterBase = void 0; + var botAdapter_1 = require_botAdapter(); + var turnContext_1 = require_turnContext(); + var activityHandlerBase_1 = require_activityHandlerBase(); + var botbuilder_stdlib_1 = require_lib5(); + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + var botframework_connector_1 = require_lib9(); + var botframework_schema_1 = require_lib4(); + var CloudAdapterBase = class extends botAdapter_1.BotAdapter { + /** + * Create a new [CloudAdapterBase](xref:botbuilder.CloudAdapterBase) instance. + * + * @param botFrameworkAuthentication A [BotFrameworkAuthentication](xref:botframework-connector.BotFrameworkAuthentication) used for validating and creating tokens. + */ + constructor(botFrameworkAuthentication) { + super(); + this.botFrameworkAuthentication = botFrameworkAuthentication; + this.ConnectorFactoryKey = Symbol("ConnectorFactory"); + this.UserTokenClientKey = Symbol("UserTokenClient"); + if (!botFrameworkAuthentication) { + throw new TypeError("`botFrameworkAuthentication` parameter required"); + } + } + /** + * @inheritdoc + */ + sendActivities(context, activities) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + if (!context) { + throw new TypeError("`context` parameter required"); + } + if (!activities) { + throw new TypeError("`activities` parameter required"); + } + if (!activities.length) { + throw new Error("Expecting one or more activities, but the array was empty."); + } + const responses = []; + for (const activity of activities) { + delete activity.id; + let response; + if (activity.type === "delay") { + yield (0, botbuilder_stdlib_1.delay)(typeof activity.value === "number" ? activity.value : 1e3); + } else if (activity.type === botframework_schema_1.ActivityTypes.InvokeResponse) { + context.turnState.set(activityHandlerBase_1.INVOKE_RESPONSE_KEY, activity); + } else if (activity.type === botframework_schema_1.ActivityTypes.Trace && activity.channelId !== botframework_schema_1.Channels.Emulator) { + } else { + const connectorClient = context.turnState.get(this.ConnectorClientKey); + if (!connectorClient) { + throw new Error("Unable to extract ConnectorClient from turn context."); + } + if (activity.replyToId) { + response = yield connectorClient.conversations.replyToActivity(activity.conversation.id, activity.replyToId, activity); + } else { + response = yield connectorClient.conversations.sendToConversation(activity.conversation.id, activity); + } + } + if (!response) { + response = { id: (_a = activity.id) !== null && _a !== void 0 ? _a : "" }; + } + responses.push(response); + } + return responses; + }); + } + /** + * @inheritdoc + */ + updateActivity(context, activity) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context) { + throw new TypeError("`context` parameter required"); + } + if (!activity) { + throw new TypeError("`activity` parameter required"); + } + const connectorClient = context.turnState.get(this.ConnectorClientKey); + if (!connectorClient) { + throw new Error("Unable to extract ConnectorClient from turn context."); + } + const response = yield connectorClient.conversations.updateActivity(activity.conversation.id, activity.id, activity); + return (response === null || response === void 0 ? void 0 : response.id) ? { id: response.id } : void 0; + }); + } + /** + * @inheritdoc + */ + deleteActivity(context, reference) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context) { + throw new TypeError("`context` parameter required"); + } + if (!reference) { + throw new TypeError("`reference` parameter required"); + } + const connectorClient = context.turnState.get(this.ConnectorClientKey); + if (!connectorClient) { + throw new Error("Unable to extract ConnectorClient from turn context."); + } + yield connectorClient.conversations.deleteActivity(reference.conversation.id, reference.activityId); + }); + } + /** + * @inheritdoc + * @deprecated + */ + continueConversation(_reference, _logic) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("`CloudAdapterBase.continueConversation` is deprecated, please use `CloudAdapterBase.continueConversationAsync`"); + }); + } + /** + * @internal + */ + continueConversationAsync(botAppIdOrClaimsIdentity, reference, logicOrAudience, maybeLogic) { + return __awaiter2(this, void 0, void 0, function* () { + const botAppId = typeof botAppIdOrClaimsIdentity === "string" ? botAppIdOrClaimsIdentity : void 0; + const claimsIdentity = typeof botAppIdOrClaimsIdentity !== "string" ? botAppIdOrClaimsIdentity : this.createClaimsIdentity(botAppId); + const audience = typeof logicOrAudience === "string" ? logicOrAudience : void 0; + const logic = typeof logicOrAudience === "function" ? logicOrAudience : maybeLogic; + return this.processProactive(claimsIdentity, botframework_schema_1.ActivityEx.getContinuationActivity(reference), audience, logic); + }); + } + /** + * @inheritdoc + */ + createConversationAsync(botAppId, channelId, serviceUrl, audience, conversationParameters, logic) { + return __awaiter2(this, void 0, void 0, function* () { + if (typeof serviceUrl !== "string" || !serviceUrl) { + throw new TypeError("`serviceUrl` must be a non-empty string"); + } + if (!conversationParameters) + throw new TypeError("`conversationParameters` must be defined"); + if (!logic) + throw new TypeError("`logic` must be defined"); + const claimsIdentity = this.createClaimsIdentity(botAppId); + claimsIdentity.claims.push({ type: botframework_connector_1.AuthenticationConstants.ServiceUrlClaim, value: serviceUrl }); + const connectorFactory = this.botFrameworkAuthentication.createConnectorFactory(claimsIdentity); + const connectorClient = yield connectorFactory.create(serviceUrl, audience); + const createConversationResult = yield connectorClient.conversations.createConversation(conversationParameters); + const createActivity = this.createCreateActivity(createConversationResult.id, channelId, serviceUrl, conversationParameters); + const userTokenClient = yield this.botFrameworkAuthentication.createUserTokenClient(claimsIdentity); + const context = this.createTurnContext(createActivity, claimsIdentity, void 0, connectorClient, userTokenClient, logic, connectorFactory); + yield this.runMiddleware(context, logic); + }); + } + createCreateActivity(createdConversationId, channelId, serviceUrl, conversationParameters) { + const activity = botframework_schema_1.ActivityEx.createEventActivity(); + activity.name = botframework_schema_1.ActivityEventNames.CreateConversation; + activity.channelId = channelId; + activity.serviceUrl = serviceUrl; + activity.id = createdConversationId !== null && createdConversationId !== void 0 ? createdConversationId : (0, uuid_1.v4)(); + activity.conversation = { + conversationType: void 0, + id: createdConversationId, + isGroup: conversationParameters.isGroup, + name: void 0, + tenantId: conversationParameters.tenantId + }; + activity.channelData = conversationParameters.channelData; + activity.recipient = conversationParameters.bot; + return activity; + } + /** + * The implementation for continue conversation. + * + * @param claimsIdentity The [ClaimsIdentity](xref:botframework-connector.ClaimsIdentity) for the conversation. + * @param continuationActivity The continuation [Activity](xref:botframework-schema.Activity) used to create the [TurnContext](xref:botbuilder-core.TurnContext). + * @param audience The audience for the call. + * @param logic The function to call for the resulting bot turn. + * @returns a Promise representing the async operation + */ + processProactive(claimsIdentity, continuationActivity, audience, logic) { + return __awaiter2(this, void 0, void 0, function* () { + const connectorFactory = this.botFrameworkAuthentication.createConnectorFactory(claimsIdentity); + const connectorClient = yield connectorFactory.create(continuationActivity.serviceUrl, audience); + const userTokenClient = yield this.botFrameworkAuthentication.createUserTokenClient(claimsIdentity); + const context = this.createTurnContext(continuationActivity, claimsIdentity, audience, connectorClient, userTokenClient, logic, connectorFactory); + yield this.runMiddleware(context, logic); + }); + } + /** + * @internal + */ + processActivity(authHeaderOrAuthenticateRequestResult, activity, logic) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + const authenticateRequestResult = typeof authHeaderOrAuthenticateRequestResult === "string" ? yield this.botFrameworkAuthentication.authenticateRequest(activity, authHeaderOrAuthenticateRequestResult) : authHeaderOrAuthenticateRequestResult; + activity.callerId = authenticateRequestResult.callerId; + const connectorClient = yield (_a = authenticateRequestResult.connectorFactory) === null || _a === void 0 ? void 0 : _a.create(activity.serviceUrl, authenticateRequestResult.audience); + if (!connectorClient) { + throw new Error("Unable to extract ConnectorClient from turn context."); + } + const userTokenClient = yield this.botFrameworkAuthentication.createUserTokenClient(authenticateRequestResult.claimsIdentity); + const context = this.createTurnContext(activity, authenticateRequestResult.claimsIdentity, authenticateRequestResult.audience, connectorClient, userTokenClient, logic, authenticateRequestResult.connectorFactory); + yield this.runMiddleware(context, logic); + return this.processTurnResults(context); + }); + } + /** + * This is a helper to create the ClaimsIdentity structure from an appId that will be added to the TurnContext. + * It is intended for use in proactive and named-pipe scenarios. + * + * @param botAppId The bot's application id. + * @returns a [ClaimsIdentity](xref:botframework-connector.ClaimsIdentity) with the audience and appId claims set to the botAppId. + */ + createClaimsIdentity(botAppId = "") { + return new botframework_connector_1.ClaimsIdentity([ + { + type: botframework_connector_1.AuthenticationConstants.AudienceClaim, + value: botAppId + }, + { + type: botframework_connector_1.AuthenticationConstants.AppIdClaim, + value: botAppId + } + ]); + } + createTurnContext(activity, claimsIdentity, oauthScope, connectorClient, userTokenClient, logic, connectorFactory) { + const context = new turnContext_1.TurnContext(this, activity); + context.turnState.set(this.BotIdentityKey, claimsIdentity); + context.turnState.set(this.ConnectorClientKey, connectorClient); + context.turnState.set(this.UserTokenClientKey, userTokenClient); + context.turnState.set(turnContext_1.BotCallbackHandlerKey, logic); + context.turnState.set(this.ConnectorFactoryKey, connectorFactory); + context.turnState.set(this.OAuthScopeKey, oauthScope); + return context; + } + processTurnResults(context) { + if (context.activity.deliveryMode === botframework_schema_1.DeliveryModes.ExpectReplies) { + return { + status: botframework_schema_1.StatusCodes.OK, + body: { + activities: context.bufferedReplyActivities + } + }; + } + if (context.activity.type === botframework_schema_1.ActivityTypes.Invoke) { + const activityInvokeResponse = context.turnState.get(activityHandlerBase_1.INVOKE_RESPONSE_KEY); + if (!activityInvokeResponse) { + return { status: botframework_schema_1.StatusCodes.NOT_IMPLEMENTED }; + } + return activityInvokeResponse.value; + } + return void 0; + } + }; + exports2.CloudAdapterBase = CloudAdapterBase; + } +}); + +// node_modules/botbuilder-core/lib/index.js +var require_lib10 = __commonJS({ + "node_modules/botbuilder-core/lib/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CloudAdapterBase = exports2.SkillConversationReferenceKey = exports2.SkillConversationIdFactoryBase = exports2.SkillConversationIdFactory = void 0; + __exportStar2(require_activityFactory(), exports2); + __exportStar2(require_activityHandler(), exports2); + __exportStar2(require_activityHandlerBase(), exports2); + __exportStar2(require_adapterExtensions(), exports2); + __exportStar2(require_autoSaveStateMiddleware(), exports2); + __exportStar2(require_botAdapter(), exports2); + __exportStar2(require_botComponent(), exports2); + __exportStar2(require_botState(), exports2); + __exportStar2(require_botStatePropertyAccessor(), exports2); + __exportStar2(require_botStateSet(), exports2); + __exportStar2(require_botTelemetryClient(), exports2); + __exportStar2(require_browserStorage(), exports2); + __exportStar2(require_cardFactory(), exports2); + __exportStar2(require_componentRegistration(), exports2); + __exportStar2(require_configurationBotFrameworkAuthentication(), exports2); + __exportStar2(require_configurationServiceClientCredentialFactory(), exports2); + __exportStar2(require_conversationState(), exports2); + __exportStar2(require_coreAppCredentials(), exports2); + __exportStar2(require_extendedUserTokenProvider(), exports2); + __exportStar2(require_intentScore(), exports2); + __exportStar2(require_invokeException(), exports2); + __exportStar2(require_invokeResponse(), exports2); + __exportStar2(require_memoryStorage(), exports2); + __exportStar2(require_memoryTranscriptStore(), exports2); + __exportStar2(require_messageFactory(), exports2); + __exportStar2(require_middlewareSet(), exports2); + __exportStar2(require_privateConversationState(), exports2); + __exportStar2(require_propertyManager(), exports2); + __exportStar2(require_queueStorage(), exports2); + __exportStar2(require_recognizerResult(), exports2); + __exportStar2(require_registerClassMiddleware(), exports2); + __exportStar2(require_showTypingMiddleware(), exports2); + __exportStar2(require_signInConstants(), exports2); + __exportStar2(require_skypeMentionNormalizeMiddleware(), exports2); + __exportStar2(require_storage(), exports2); + __exportStar2(require_stringUtils(), exports2); + __exportStar2(require_telemetryLoggerMiddleware(), exports2); + __exportStar2(require_testAdapter(), exports2); + __exportStar2(require_transcriptLogger(), exports2); + __exportStar2(require_turnContext(), exports2); + __exportStar2(require_turnContextStateCollection(), exports2); + __exportStar2(require_userState(), exports2); + __exportStar2(require_userTokenProvider(), exports2); + __exportStar2(require_userTokenSettings(), exports2); + __exportStar2(require_lib4(), exports2); + var skills_1 = require_skills(); + Object.defineProperty(exports2, "SkillConversationIdFactory", { enumerable: true, get: function() { + return skills_1.SkillConversationIdFactory; + } }); + Object.defineProperty(exports2, "SkillConversationIdFactoryBase", { enumerable: true, get: function() { + return skills_1.SkillConversationIdFactoryBase; + } }); + Object.defineProperty(exports2, "SkillConversationReferenceKey", { enumerable: true, get: function() { + return skills_1.SkillConversationReferenceKey; + } }); + var cloudAdapterBase_1 = require_cloudAdapterBase(); + Object.defineProperty(exports2, "CloudAdapterBase", { enumerable: true, get: function() { + return cloudAdapterBase_1.CloudAdapterBase; + } }); + } +}); + +// node_modules/universalify/index.js +var require_universalify = __commonJS({ + "node_modules/universalify/index.js"(exports2) { + "use strict"; + exports2.fromCallback = function(fn) { + return Object.defineProperty(function(...args) { + if (typeof args[args.length - 1] === "function") fn.apply(this, args); + else { + return new Promise((resolve, reject) => { + args.push((err, res) => err != null ? reject(err) : resolve(res)); + fn.apply(this, args); + }); + } + }, "name", { value: fn.name }); + }; + exports2.fromPromise = function(fn) { + return Object.defineProperty(function(...args) { + const cb = args[args.length - 1]; + if (typeof cb !== "function") return fn.apply(this, args); + else { + args.pop(); + fn.apply(this, args).then((r) => cb(null, r), cb); + } + }, "name", { value: fn.name }); + }; + } +}); + +// node_modules/graceful-fs/polyfills.js +var require_polyfills = __commonJS({ + "node_modules/graceful-fs/polyfills.js"(exports2, module2) { + var constants = require("constants"); + var origCwd = process.cwd; + var cwd = null; + var platform2 = process.env.GRACEFUL_FS_PLATFORM || process.platform; + process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process); + return cwd; + }; + try { + process.cwd(); + } catch (er) { + } + if (typeof process.chdir === "function") { + chdir = process.chdir; + process.chdir = function(d) { + cwd = null; + chdir.call(process, d); + }; + if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir); + } + var chdir; + module2.exports = patch; + function patch(fs6) { + if (constants.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs6); + } + if (!fs6.lutimes) { + patchLutimes(fs6); + } + fs6.chown = chownFix(fs6.chown); + fs6.fchown = chownFix(fs6.fchown); + fs6.lchown = chownFix(fs6.lchown); + fs6.chmod = chmodFix(fs6.chmod); + fs6.fchmod = chmodFix(fs6.fchmod); + fs6.lchmod = chmodFix(fs6.lchmod); + fs6.chownSync = chownFixSync(fs6.chownSync); + fs6.fchownSync = chownFixSync(fs6.fchownSync); + fs6.lchownSync = chownFixSync(fs6.lchownSync); + fs6.chmodSync = chmodFixSync(fs6.chmodSync); + fs6.fchmodSync = chmodFixSync(fs6.fchmodSync); + fs6.lchmodSync = chmodFixSync(fs6.lchmodSync); + fs6.stat = statFix(fs6.stat); + fs6.fstat = statFix(fs6.fstat); + fs6.lstat = statFix(fs6.lstat); + fs6.statSync = statFixSync(fs6.statSync); + fs6.fstatSync = statFixSync(fs6.fstatSync); + fs6.lstatSync = statFixSync(fs6.lstatSync); + if (fs6.chmod && !fs6.lchmod) { + fs6.lchmod = function(path3, mode, cb) { + if (cb) process.nextTick(cb); + }; + fs6.lchmodSync = function() { + }; + } + if (fs6.chown && !fs6.lchown) { + fs6.lchown = function(path3, uid, gid, cb) { + if (cb) process.nextTick(cb); + }; + fs6.lchownSync = function() { + }; + } + if (platform2 === "win32") { + fs6.rename = typeof fs6.rename !== "function" ? fs6.rename : (function(fs$rename) { + function rename(from, to, cb) { + var start = Date.now(); + var backoff = 0; + fs$rename(from, to, function CB(er) { + if (er && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 6e4) { + setTimeout(function() { + fs6.stat(to, function(stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er); + }); + }, backoff); + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er); + }); + } + if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename); + return rename; + })(fs6.rename); + } + fs6.read = typeof fs6.read !== "function" ? fs6.read : (function(fs$read) { + function read(fd, buffer, offset, length, position, callback_) { + var callback; + if (callback_ && typeof callback_ === "function") { + var eagCounter = 0; + callback = function(er, _, __) { + if (er && er.code === "EAGAIN" && eagCounter < 10) { + eagCounter++; + return fs$read.call(fs6, fd, buffer, offset, length, position, callback); + } + callback_.apply(this, arguments); + }; + } + return fs$read.call(fs6, fd, buffer, offset, length, position, callback); + } + if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read); + return read; + })(fs6.read); + fs6.readSync = typeof fs6.readSync !== "function" ? fs6.readSync : /* @__PURE__ */ (function(fs$readSync) { + return function(fd, buffer, offset, length, position) { + var eagCounter = 0; + while (true) { + try { + return fs$readSync.call(fs6, fd, buffer, offset, length, position); + } catch (er) { + if (er.code === "EAGAIN" && eagCounter < 10) { + eagCounter++; + continue; + } + throw er; + } + } + }; + })(fs6.readSync); + function patchLchmod(fs7) { + fs7.lchmod = function(path3, mode, callback) { + fs7.open( + path3, + constants.O_WRONLY | constants.O_SYMLINK, + mode, + function(err, fd) { + if (err) { + if (callback) callback(err); + return; + } + fs7.fchmod(fd, mode, function(err2) { + fs7.close(fd, function(err22) { + if (callback) callback(err2 || err22); + }); + }); + } + ); + }; + fs7.lchmodSync = function(path3, mode) { + var fd = fs7.openSync(path3, constants.O_WRONLY | constants.O_SYMLINK, mode); + var threw = true; + var ret; + try { + ret = fs7.fchmodSync(fd, mode); + threw = false; + } finally { + if (threw) { + try { + fs7.closeSync(fd); + } catch (er) { + } + } else { + fs7.closeSync(fd); + } + } + return ret; + }; + } + function patchLutimes(fs7) { + if (constants.hasOwnProperty("O_SYMLINK") && fs7.futimes) { + fs7.lutimes = function(path3, at, mt, cb) { + fs7.open(path3, constants.O_SYMLINK, function(er, fd) { + if (er) { + if (cb) cb(er); + return; + } + fs7.futimes(fd, at, mt, function(er2) { + fs7.close(fd, function(er22) { + if (cb) cb(er2 || er22); + }); + }); + }); + }; + fs7.lutimesSync = function(path3, at, mt) { + var fd = fs7.openSync(path3, constants.O_SYMLINK); + var ret; + var threw = true; + try { + ret = fs7.futimesSync(fd, at, mt); + threw = false; + } finally { + if (threw) { + try { + fs7.closeSync(fd); + } catch (er) { + } + } else { + fs7.closeSync(fd); + } + } + return ret; + }; + } else if (fs7.futimes) { + fs7.lutimes = function(_a, _b, _c, cb) { + if (cb) process.nextTick(cb); + }; + fs7.lutimesSync = function() { + }; + } + } + function chmodFix(orig) { + if (!orig) return orig; + return function(target, mode, cb) { + return orig.call(fs6, target, mode, function(er) { + if (chownErOk(er)) er = null; + if (cb) cb.apply(this, arguments); + }); + }; + } + function chmodFixSync(orig) { + if (!orig) return orig; + return function(target, mode) { + try { + return orig.call(fs6, target, mode); + } catch (er) { + if (!chownErOk(er)) throw er; + } + }; + } + function chownFix(orig) { + if (!orig) return orig; + return function(target, uid, gid, cb) { + return orig.call(fs6, target, uid, gid, function(er) { + if (chownErOk(er)) er = null; + if (cb) cb.apply(this, arguments); + }); + }; + } + function chownFixSync(orig) { + if (!orig) return orig; + return function(target, uid, gid) { + try { + return orig.call(fs6, target, uid, gid); + } catch (er) { + if (!chownErOk(er)) throw er; + } + }; + } + function statFix(orig) { + if (!orig) return orig; + return function(target, options, cb) { + if (typeof options === "function") { + cb = options; + options = null; + } + function callback(er, stats) { + if (stats) { + if (stats.uid < 0) stats.uid += 4294967296; + if (stats.gid < 0) stats.gid += 4294967296; + } + if (cb) cb.apply(this, arguments); + } + return options ? orig.call(fs6, target, options, callback) : orig.call(fs6, target, callback); + }; + } + function statFixSync(orig) { + if (!orig) return orig; + return function(target, options) { + var stats = options ? orig.call(fs6, target, options) : orig.call(fs6, target); + if (stats) { + if (stats.uid < 0) stats.uid += 4294967296; + if (stats.gid < 0) stats.gid += 4294967296; + } + return stats; + }; + } + function chownErOk(er) { + if (!er) + return true; + if (er.code === "ENOSYS") + return true; + var nonroot = !process.getuid || process.getuid() !== 0; + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true; + } + return false; + } + } + } +}); + +// node_modules/graceful-fs/legacy-streams.js +var require_legacy_streams = __commonJS({ + "node_modules/graceful-fs/legacy-streams.js"(exports2, module2) { + var Stream = require("stream").Stream; + module2.exports = legacy; + function legacy(fs6) { + return { + ReadStream, + WriteStream + }; + function ReadStream(path3, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path3, options); + Stream.call(this); + var self2 = this; + this.path = path3; + this.fd = null; + this.readable = true; + this.paused = false; + this.flags = "r"; + this.mode = 438; + this.bufferSize = 64 * 1024; + options = options || {}; + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + if (this.encoding) this.setEncoding(this.encoding); + if (this.start !== void 0) { + if ("number" !== typeof this.start) { + throw TypeError("start must be a Number"); + } + if (this.end === void 0) { + this.end = Infinity; + } else if ("number" !== typeof this.end) { + throw TypeError("end must be a Number"); + } + if (this.start > this.end) { + throw new Error("start must be <= end"); + } + this.pos = this.start; + } + if (this.fd !== null) { + process.nextTick(function() { + self2._read(); + }); + return; + } + fs6.open(this.path, this.flags, this.mode, function(err, fd) { + if (err) { + self2.emit("error", err); + self2.readable = false; + return; + } + self2.fd = fd; + self2.emit("open", fd); + self2._read(); + }); + } + function WriteStream(path3, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path3, options); + Stream.call(this); + this.path = path3; + this.fd = null; + this.writable = true; + this.flags = "w"; + this.encoding = "binary"; + this.mode = 438; + this.bytesWritten = 0; + options = options || {}; + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + if (this.start !== void 0) { + if ("number" !== typeof this.start) { + throw TypeError("start must be a Number"); + } + if (this.start < 0) { + throw new Error("start must be >= zero"); + } + this.pos = this.start; + } + this.busy = false; + this._queue = []; + if (this.fd === null) { + this._open = fs6.open; + this._queue.push([this._open, this.path, this.flags, this.mode, void 0]); + this.flush(); + } + } + } + } +}); + +// node_modules/graceful-fs/clone.js +var require_clone = __commonJS({ + "node_modules/graceful-fs/clone.js"(exports2, module2) { + "use strict"; + module2.exports = clone; + var getPrototypeOf = Object.getPrototypeOf || function(obj) { + return obj.__proto__; + }; + function clone(obj) { + if (obj === null || typeof obj !== "object") + return obj; + if (obj instanceof Object) + var copy = { __proto__: getPrototypeOf(obj) }; + else + var copy = /* @__PURE__ */ Object.create(null); + Object.getOwnPropertyNames(obj).forEach(function(key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)); + }); + return copy; + } + } +}); + +// node_modules/graceful-fs/graceful-fs.js +var require_graceful_fs = __commonJS({ + "node_modules/graceful-fs/graceful-fs.js"(exports2, module2) { + var fs6 = require("fs"); + var polyfills = require_polyfills(); + var legacy = require_legacy_streams(); + var clone = require_clone(); + var util = require("util"); + var gracefulQueue; + var previousSymbol; + if (typeof Symbol === "function" && typeof Symbol.for === "function") { + gracefulQueue = Symbol.for("graceful-fs.queue"); + previousSymbol = Symbol.for("graceful-fs.previous"); + } else { + gracefulQueue = "___graceful-fs.queue"; + previousSymbol = "___graceful-fs.previous"; + } + function noop() { + } + function publishQueue(context, queue2) { + Object.defineProperty(context, gracefulQueue, { + get: function() { + return queue2; + } + }); + } + var debug = noop; + if (util.debuglog) + debug = util.debuglog("gfs4"); + else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) + debug = function() { + var m = util.format.apply(util, arguments); + m = "GFS4: " + m.split(/\n/).join("\nGFS4: "); + console.error(m); + }; + if (!fs6[gracefulQueue]) { + queue = global[gracefulQueue] || []; + publishQueue(fs6, queue); + fs6.close = (function(fs$close) { + function close(fd, cb) { + return fs$close.call(fs6, fd, function(err) { + if (!err) { + resetQueue(); + } + if (typeof cb === "function") + cb.apply(this, arguments); + }); + } + Object.defineProperty(close, previousSymbol, { + value: fs$close + }); + return close; + })(fs6.close); + fs6.closeSync = (function(fs$closeSync) { + function closeSync(fd) { + fs$closeSync.apply(fs6, arguments); + resetQueue(); + } + Object.defineProperty(closeSync, previousSymbol, { + value: fs$closeSync + }); + return closeSync; + })(fs6.closeSync); + if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) { + process.on("exit", function() { + debug(fs6[gracefulQueue]); + require("assert").equal(fs6[gracefulQueue].length, 0); + }); + } + } + var queue; + if (!global[gracefulQueue]) { + publishQueue(global, fs6[gracefulQueue]); + } + module2.exports = patch(clone(fs6)); + if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs6.__patched) { + module2.exports = patch(fs6); + fs6.__patched = true; + } + function patch(fs7) { + polyfills(fs7); + fs7.gracefulify = patch; + fs7.createReadStream = createReadStream; + fs7.createWriteStream = createWriteStream; + var fs$readFile = fs7.readFile; + fs7.readFile = readFile; + function readFile(path3, options, cb) { + if (typeof options === "function") + cb = options, options = null; + return go$readFile(path3, options, cb); + function go$readFile(path4, options2, cb2, startTime) { + return fs$readFile(path4, options2, function(err) { + if (err && (err.code === "EMFILE" || err.code === "ENFILE")) + enqueue([go$readFile, [path4, options2, cb2], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb2 === "function") + cb2.apply(this, arguments); + } + }); + } + } + var fs$writeFile = fs7.writeFile; + fs7.writeFile = writeFile; + function writeFile(path3, data, options, cb) { + if (typeof options === "function") + cb = options, options = null; + return go$writeFile(path3, data, options, cb); + function go$writeFile(path4, data2, options2, cb2, startTime) { + return fs$writeFile(path4, data2, options2, function(err) { + if (err && (err.code === "EMFILE" || err.code === "ENFILE")) + enqueue([go$writeFile, [path4, data2, options2, cb2], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb2 === "function") + cb2.apply(this, arguments); + } + }); + } + } + var fs$appendFile = fs7.appendFile; + if (fs$appendFile) + fs7.appendFile = appendFile; + function appendFile(path3, data, options, cb) { + if (typeof options === "function") + cb = options, options = null; + return go$appendFile(path3, data, options, cb); + function go$appendFile(path4, data2, options2, cb2, startTime) { + return fs$appendFile(path4, data2, options2, function(err) { + if (err && (err.code === "EMFILE" || err.code === "ENFILE")) + enqueue([go$appendFile, [path4, data2, options2, cb2], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb2 === "function") + cb2.apply(this, arguments); + } + }); + } + } + var fs$copyFile = fs7.copyFile; + if (fs$copyFile) + fs7.copyFile = copyFile; + function copyFile(src, dest, flags, cb) { + if (typeof flags === "function") { + cb = flags; + flags = 0; + } + return go$copyFile(src, dest, flags, cb); + function go$copyFile(src2, dest2, flags2, cb2, startTime) { + return fs$copyFile(src2, dest2, flags2, function(err) { + if (err && (err.code === "EMFILE" || err.code === "ENFILE")) + enqueue([go$copyFile, [src2, dest2, flags2, cb2], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb2 === "function") + cb2.apply(this, arguments); + } + }); + } + } + var fs$readdir = fs7.readdir; + fs7.readdir = readdir; + var noReaddirOptionVersions = /^v[0-5]\./; + function readdir(path3, options, cb) { + if (typeof options === "function") + cb = options, options = null; + var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path4, options2, cb2, startTime) { + return fs$readdir(path4, fs$readdirCallback( + path4, + options2, + cb2, + startTime + )); + } : function go$readdir2(path4, options2, cb2, startTime) { + return fs$readdir(path4, options2, fs$readdirCallback( + path4, + options2, + cb2, + startTime + )); + }; + return go$readdir(path3, options, cb); + function fs$readdirCallback(path4, options2, cb2, startTime) { + return function(err, files) { + if (err && (err.code === "EMFILE" || err.code === "ENFILE")) + enqueue([ + go$readdir, + [path4, options2, cb2], + err, + startTime || Date.now(), + Date.now() + ]); + else { + if (files && files.sort) + files.sort(); + if (typeof cb2 === "function") + cb2.call(this, err, files); + } + }; + } + } + if (process.version.substr(0, 4) === "v0.8") { + var legStreams = legacy(fs7); + ReadStream = legStreams.ReadStream; + WriteStream = legStreams.WriteStream; + } + var fs$ReadStream = fs7.ReadStream; + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype); + ReadStream.prototype.open = ReadStream$open; + } + var fs$WriteStream = fs7.WriteStream; + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype); + WriteStream.prototype.open = WriteStream$open; + } + Object.defineProperty(fs7, "ReadStream", { + get: function() { + return ReadStream; + }, + set: function(val) { + ReadStream = val; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(fs7, "WriteStream", { + get: function() { + return WriteStream; + }, + set: function(val) { + WriteStream = val; + }, + enumerable: true, + configurable: true + }); + var FileReadStream = ReadStream; + Object.defineProperty(fs7, "FileReadStream", { + get: function() { + return FileReadStream; + }, + set: function(val) { + FileReadStream = val; + }, + enumerable: true, + configurable: true + }); + var FileWriteStream = WriteStream; + Object.defineProperty(fs7, "FileWriteStream", { + get: function() { + return FileWriteStream; + }, + set: function(val) { + FileWriteStream = val; + }, + enumerable: true, + configurable: true + }); + function ReadStream(path3, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this; + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments); + } + function ReadStream$open() { + var that = this; + open2(that.path, that.flags, that.mode, function(err, fd) { + if (err) { + if (that.autoClose) + that.destroy(); + that.emit("error", err); + } else { + that.fd = fd; + that.emit("open", fd); + that.read(); + } + }); + } + function WriteStream(path3, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this; + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments); + } + function WriteStream$open() { + var that = this; + open2(that.path, that.flags, that.mode, function(err, fd) { + if (err) { + that.destroy(); + that.emit("error", err); + } else { + that.fd = fd; + that.emit("open", fd); + } + }); + } + function createReadStream(path3, options) { + return new fs7.ReadStream(path3, options); + } + function createWriteStream(path3, options) { + return new fs7.WriteStream(path3, options); + } + var fs$open = fs7.open; + fs7.open = open2; + function open2(path3, flags, mode, cb) { + if (typeof mode === "function") + cb = mode, mode = null; + return go$open(path3, flags, mode, cb); + function go$open(path4, flags2, mode2, cb2, startTime) { + return fs$open(path4, flags2, mode2, function(err, fd) { + if (err && (err.code === "EMFILE" || err.code === "ENFILE")) + enqueue([go$open, [path4, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb2 === "function") + cb2.apply(this, arguments); + } + }); + } + } + return fs7; + } + function enqueue(elem) { + debug("ENQUEUE", elem[0].name, elem[1]); + fs6[gracefulQueue].push(elem); + retry(); + } + var retryTimer; + function resetQueue() { + var now = Date.now(); + for (var i = 0; i < fs6[gracefulQueue].length; ++i) { + if (fs6[gracefulQueue][i].length > 2) { + fs6[gracefulQueue][i][3] = now; + fs6[gracefulQueue][i][4] = now; + } + } + retry(); + } + function retry() { + clearTimeout(retryTimer); + retryTimer = void 0; + if (fs6[gracefulQueue].length === 0) + return; + var elem = fs6[gracefulQueue].shift(); + var fn = elem[0]; + var args = elem[1]; + var err = elem[2]; + var startTime = elem[3]; + var lastTime = elem[4]; + if (startTime === void 0) { + debug("RETRY", fn.name, args); + fn.apply(null, args); + } else if (Date.now() - startTime >= 6e4) { + debug("TIMEOUT", fn.name, args); + var cb = args.pop(); + if (typeof cb === "function") + cb.call(null, err); + } else { + var sinceAttempt = Date.now() - lastTime; + var sinceStart = Math.max(lastTime - startTime, 1); + var desiredDelay = Math.min(sinceStart * 1.2, 100); + if (sinceAttempt >= desiredDelay) { + debug("RETRY", fn.name, args); + fn.apply(null, args.concat([startTime])); + } else { + fs6[gracefulQueue].push(elem); + } + } + if (retryTimer === void 0) { + retryTimer = setTimeout(retry, 0); + } + } + } +}); + +// node_modules/fs-extra/lib/fs/index.js +var require_fs = __commonJS({ + "node_modules/fs-extra/lib/fs/index.js"(exports2) { + "use strict"; + var u = require_universalify().fromCallback; + var fs6 = require_graceful_fs(); + var api = [ + "access", + "appendFile", + "chmod", + "chown", + "close", + "copyFile", + "cp", + "fchmod", + "fchown", + "fdatasync", + "fstat", + "fsync", + "ftruncate", + "futimes", + "glob", + "lchmod", + "lchown", + "lutimes", + "link", + "lstat", + "mkdir", + "mkdtemp", + "open", + "opendir", + "readdir", + "readFile", + "readlink", + "realpath", + "rename", + "rm", + "rmdir", + "stat", + "statfs", + "symlink", + "truncate", + "unlink", + "utimes", + "writeFile" + ].filter((key) => { + return typeof fs6[key] === "function"; + }); + Object.assign(exports2, fs6); + api.forEach((method) => { + exports2[method] = u(fs6[method]); + }); + exports2.exists = function(filename, callback) { + if (typeof callback === "function") { + return fs6.exists(filename, callback); + } + return new Promise((resolve) => { + return fs6.exists(filename, resolve); + }); + }; + exports2.read = function(fd, buffer, offset, length, position, callback) { + if (typeof callback === "function") { + return fs6.read(fd, buffer, offset, length, position, callback); + } + return new Promise((resolve, reject) => { + fs6.read(fd, buffer, offset, length, position, (err, bytesRead, buffer2) => { + if (err) return reject(err); + resolve({ bytesRead, buffer: buffer2 }); + }); + }); + }; + exports2.write = function(fd, buffer, ...args) { + if (typeof args[args.length - 1] === "function") { + return fs6.write(fd, buffer, ...args); + } + return new Promise((resolve, reject) => { + fs6.write(fd, buffer, ...args, (err, bytesWritten, buffer2) => { + if (err) return reject(err); + resolve({ bytesWritten, buffer: buffer2 }); + }); + }); + }; + exports2.readv = function(fd, buffers, ...args) { + if (typeof args[args.length - 1] === "function") { + return fs6.readv(fd, buffers, ...args); + } + return new Promise((resolve, reject) => { + fs6.readv(fd, buffers, ...args, (err, bytesRead, buffers2) => { + if (err) return reject(err); + resolve({ bytesRead, buffers: buffers2 }); + }); + }); + }; + exports2.writev = function(fd, buffers, ...args) { + if (typeof args[args.length - 1] === "function") { + return fs6.writev(fd, buffers, ...args); + } + return new Promise((resolve, reject) => { + fs6.writev(fd, buffers, ...args, (err, bytesWritten, buffers2) => { + if (err) return reject(err); + resolve({ bytesWritten, buffers: buffers2 }); + }); + }); + }; + if (typeof fs6.realpath.native === "function") { + exports2.realpath.native = u(fs6.realpath.native); + } else { + process.emitWarning( + "fs.realpath.native is not a function. Is fs being monkey-patched?", + "Warning", + "fs-extra-WARN0003" + ); + } + } +}); + +// node_modules/fs-extra/lib/mkdirs/utils.js +var require_utils8 = __commonJS({ + "node_modules/fs-extra/lib/mkdirs/utils.js"(exports2, module2) { + "use strict"; + var path3 = require("path"); + module2.exports.checkPath = function checkPath(pth) { + if (process.platform === "win32") { + const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path3.parse(pth).root, "")); + if (pathHasInvalidWinCharacters) { + const error = new Error(`Path contains invalid characters: ${pth}`); + error.code = "EINVAL"; + throw error; + } + } + }; + } +}); + +// node_modules/fs-extra/lib/mkdirs/make-dir.js +var require_make_dir = __commonJS({ + "node_modules/fs-extra/lib/mkdirs/make-dir.js"(exports2, module2) { + "use strict"; + var fs6 = require_fs(); + var { checkPath } = require_utils8(); + var getMode = (options) => { + const defaults = { mode: 511 }; + if (typeof options === "number") return options; + return { ...defaults, ...options }.mode; + }; + module2.exports.makeDir = async (dir, options) => { + checkPath(dir); + return fs6.mkdir(dir, { + mode: getMode(options), + recursive: true + }); + }; + module2.exports.makeDirSync = (dir, options) => { + checkPath(dir); + return fs6.mkdirSync(dir, { + mode: getMode(options), + recursive: true + }); + }; + } +}); + +// node_modules/fs-extra/lib/mkdirs/index.js +var require_mkdirs = __commonJS({ + "node_modules/fs-extra/lib/mkdirs/index.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + var { makeDir: _makeDir, makeDirSync } = require_make_dir(); + var makeDir = u(_makeDir); + module2.exports = { + mkdirs: makeDir, + mkdirsSync: makeDirSync, + // alias + mkdirp: makeDir, + mkdirpSync: makeDirSync, + ensureDir: makeDir, + ensureDirSync: makeDirSync + }; + } +}); + +// node_modules/fs-extra/lib/path-exists/index.js +var require_path_exists = __commonJS({ + "node_modules/fs-extra/lib/path-exists/index.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + var fs6 = require_fs(); + function pathExists(path3) { + return fs6.access(path3).then(() => true).catch(() => false); + } + module2.exports = { + pathExists: u(pathExists), + pathExistsSync: fs6.existsSync + }; + } +}); + +// node_modules/fs-extra/lib/util/utimes.js +var require_utimes = __commonJS({ + "node_modules/fs-extra/lib/util/utimes.js"(exports2, module2) { + "use strict"; + var fs6 = require_fs(); + var u = require_universalify().fromPromise; + async function utimesMillis(path3, atime, mtime) { + const fd = await fs6.open(path3, "r+"); + let closeErr = null; + try { + await fs6.futimes(fd, atime, mtime); + } finally { + try { + await fs6.close(fd); + } catch (e) { + closeErr = e; + } + } + if (closeErr) { + throw closeErr; + } + } + function utimesMillisSync(path3, atime, mtime) { + const fd = fs6.openSync(path3, "r+"); + fs6.futimesSync(fd, atime, mtime); + return fs6.closeSync(fd); + } + module2.exports = { + utimesMillis: u(utimesMillis), + utimesMillisSync + }; + } +}); + +// node_modules/fs-extra/lib/util/stat.js +var require_stat = __commonJS({ + "node_modules/fs-extra/lib/util/stat.js"(exports2, module2) { + "use strict"; + var fs6 = require_fs(); + var path3 = require("path"); + var u = require_universalify().fromPromise; + function getStats(src, dest, opts) { + const statFunc = opts.dereference ? (file) => fs6.stat(file, { bigint: true }) : (file) => fs6.lstat(file, { bigint: true }); + return Promise.all([ + statFunc(src), + statFunc(dest).catch((err) => { + if (err.code === "ENOENT") return null; + throw err; + }) + ]).then(([srcStat, destStat]) => ({ srcStat, destStat })); + } + function getStatsSync(src, dest, opts) { + let destStat; + const statFunc = opts.dereference ? (file) => fs6.statSync(file, { bigint: true }) : (file) => fs6.lstatSync(file, { bigint: true }); + const srcStat = statFunc(src); + try { + destStat = statFunc(dest); + } catch (err) { + if (err.code === "ENOENT") return { srcStat, destStat: null }; + throw err; + } + return { srcStat, destStat }; + } + async function checkPaths(src, dest, funcName, opts) { + const { srcStat, destStat } = await getStats(src, dest, opts); + if (destStat) { + if (areIdentical(srcStat, destStat)) { + const srcBaseName = path3.basename(src); + const destBaseName = path3.basename(dest); + if (funcName === "move" && srcBaseName !== destBaseName && srcBaseName.toLowerCase() === destBaseName.toLowerCase()) { + return { srcStat, destStat, isChangingCase: true }; + } + throw new Error("Source and destination must not be the same."); + } + if (srcStat.isDirectory() && !destStat.isDirectory()) { + throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`); + } + if (!srcStat.isDirectory() && destStat.isDirectory()) { + throw new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`); + } + } + if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + throw new Error(errMsg(src, dest, funcName)); + } + return { srcStat, destStat }; + } + function checkPathsSync(src, dest, funcName, opts) { + const { srcStat, destStat } = getStatsSync(src, dest, opts); + if (destStat) { + if (areIdentical(srcStat, destStat)) { + const srcBaseName = path3.basename(src); + const destBaseName = path3.basename(dest); + if (funcName === "move" && srcBaseName !== destBaseName && srcBaseName.toLowerCase() === destBaseName.toLowerCase()) { + return { srcStat, destStat, isChangingCase: true }; + } + throw new Error("Source and destination must not be the same."); + } + if (srcStat.isDirectory() && !destStat.isDirectory()) { + throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`); + } + if (!srcStat.isDirectory() && destStat.isDirectory()) { + throw new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`); + } + } + if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + throw new Error(errMsg(src, dest, funcName)); + } + return { srcStat, destStat }; + } + async function checkParentPaths(src, srcStat, dest, funcName) { + const srcParent = path3.resolve(path3.dirname(src)); + const destParent = path3.resolve(path3.dirname(dest)); + if (destParent === srcParent || destParent === path3.parse(destParent).root) return; + let destStat; + try { + destStat = await fs6.stat(destParent, { bigint: true }); + } catch (err) { + if (err.code === "ENOENT") return; + throw err; + } + if (areIdentical(srcStat, destStat)) { + throw new Error(errMsg(src, dest, funcName)); + } + return checkParentPaths(src, srcStat, destParent, funcName); + } + function checkParentPathsSync(src, srcStat, dest, funcName) { + const srcParent = path3.resolve(path3.dirname(src)); + const destParent = path3.resolve(path3.dirname(dest)); + if (destParent === srcParent || destParent === path3.parse(destParent).root) return; + let destStat; + try { + destStat = fs6.statSync(destParent, { bigint: true }); + } catch (err) { + if (err.code === "ENOENT") return; + throw err; + } + if (areIdentical(srcStat, destStat)) { + throw new Error(errMsg(src, dest, funcName)); + } + return checkParentPathsSync(src, srcStat, destParent, funcName); + } + function areIdentical(srcStat, destStat) { + return destStat.ino !== void 0 && destStat.dev !== void 0 && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev; + } + function isSrcSubdir(src, dest) { + const srcArr = path3.resolve(src).split(path3.sep).filter((i) => i); + const destArr = path3.resolve(dest).split(path3.sep).filter((i) => i); + return srcArr.every((cur, i) => destArr[i] === cur); + } + function errMsg(src, dest, funcName) { + return `Cannot ${funcName} '${src}' to a subdirectory of itself, '${dest}'.`; + } + module2.exports = { + // checkPaths + checkPaths: u(checkPaths), + checkPathsSync, + // checkParent + checkParentPaths: u(checkParentPaths), + checkParentPathsSync, + // Misc + isSrcSubdir, + areIdentical + }; + } +}); + +// node_modules/fs-extra/lib/util/async.js +var require_async2 = __commonJS({ + "node_modules/fs-extra/lib/util/async.js"(exports2, module2) { + "use strict"; + async function asyncIteratorConcurrentProcess(iterator, fn) { + const promises = []; + for await (const item of iterator) { + promises.push( + fn(item).then( + () => null, + (err) => err ?? new Error("unknown error") + ) + ); + } + await Promise.all( + promises.map( + (promise) => promise.then((possibleErr) => { + if (possibleErr !== null) throw possibleErr; + }) + ) + ); + } + module2.exports = { + asyncIteratorConcurrentProcess + }; + } +}); + +// node_modules/fs-extra/lib/copy/copy.js +var require_copy = __commonJS({ + "node_modules/fs-extra/lib/copy/copy.js"(exports2, module2) { + "use strict"; + var fs6 = require_fs(); + var path3 = require("path"); + var { mkdirs } = require_mkdirs(); + var { pathExists } = require_path_exists(); + var { utimesMillis } = require_utimes(); + var stat = require_stat(); + var { asyncIteratorConcurrentProcess } = require_async2(); + async function copy(src, dest, opts = {}) { + if (typeof opts === "function") { + opts = { filter: opts }; + } + opts.clobber = "clobber" in opts ? !!opts.clobber : true; + opts.overwrite = "overwrite" in opts ? !!opts.overwrite : opts.clobber; + if (opts.preserveTimestamps && process.arch === "ia32") { + process.emitWarning( + "Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269", + "Warning", + "fs-extra-WARN0001" + ); + } + const { srcStat, destStat } = await stat.checkPaths(src, dest, "copy", opts); + await stat.checkParentPaths(src, srcStat, dest, "copy"); + const include = await runFilter(src, dest, opts); + if (!include) return; + const destParent = path3.dirname(dest); + const dirExists = await pathExists(destParent); + if (!dirExists) { + await mkdirs(destParent); + } + await getStatsAndPerformCopy(destStat, src, dest, opts); + } + async function runFilter(src, dest, opts) { + if (!opts.filter) return true; + return opts.filter(src, dest); + } + async function getStatsAndPerformCopy(destStat, src, dest, opts) { + const statFn = opts.dereference ? fs6.stat : fs6.lstat; + const srcStat = await statFn(src); + if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts); + if (srcStat.isFile() || srcStat.isCharacterDevice() || srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts); + if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts); + if (srcStat.isSocket()) throw new Error(`Cannot copy a socket file: ${src}`); + if (srcStat.isFIFO()) throw new Error(`Cannot copy a FIFO pipe: ${src}`); + throw new Error(`Unknown file: ${src}`); + } + async function onFile(srcStat, destStat, src, dest, opts) { + if (!destStat) return copyFile(srcStat, src, dest, opts); + if (opts.overwrite) { + await fs6.unlink(dest); + return copyFile(srcStat, src, dest, opts); + } + if (opts.errorOnExist) { + throw new Error(`'${dest}' already exists`); + } + } + async function copyFile(srcStat, src, dest, opts) { + await fs6.copyFile(src, dest); + if (opts.preserveTimestamps) { + if (fileIsNotWritable(srcStat.mode)) { + await makeFileWritable(dest, srcStat.mode); + } + const updatedSrcStat = await fs6.stat(src); + await utimesMillis(dest, updatedSrcStat.atime, updatedSrcStat.mtime); + } + return fs6.chmod(dest, srcStat.mode); + } + function fileIsNotWritable(srcMode) { + return (srcMode & 128) === 0; + } + function makeFileWritable(dest, srcMode) { + return fs6.chmod(dest, srcMode | 128); + } + async function onDir(srcStat, destStat, src, dest, opts) { + if (!destStat) { + await fs6.mkdir(dest); + } + await asyncIteratorConcurrentProcess(await fs6.opendir(src), async (item) => { + const srcItem = path3.join(src, item.name); + const destItem = path3.join(dest, item.name); + const include = await runFilter(srcItem, destItem, opts); + if (include) { + const { destStat: destStat2 } = await stat.checkPaths(srcItem, destItem, "copy", opts); + await getStatsAndPerformCopy(destStat2, srcItem, destItem, opts); + } + }); + if (!destStat) { + await fs6.chmod(dest, srcStat.mode); + } + } + async function onLink(destStat, src, dest, opts) { + let resolvedSrc = await fs6.readlink(src); + if (opts.dereference) { + resolvedSrc = path3.resolve(process.cwd(), resolvedSrc); + } + if (!destStat) { + return fs6.symlink(resolvedSrc, dest); + } + let resolvedDest = null; + try { + resolvedDest = await fs6.readlink(dest); + } catch (e) { + if (e.code === "EINVAL" || e.code === "UNKNOWN") return fs6.symlink(resolvedSrc, dest); + throw e; + } + if (opts.dereference) { + resolvedDest = path3.resolve(process.cwd(), resolvedDest); + } + if (resolvedSrc !== resolvedDest) { + if (stat.isSrcSubdir(resolvedSrc, resolvedDest)) { + throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`); + } + if (stat.isSrcSubdir(resolvedDest, resolvedSrc)) { + throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`); + } + } + await fs6.unlink(dest); + return fs6.symlink(resolvedSrc, dest); + } + module2.exports = copy; + } +}); + +// node_modules/fs-extra/lib/copy/copy-sync.js +var require_copy_sync = __commonJS({ + "node_modules/fs-extra/lib/copy/copy-sync.js"(exports2, module2) { + "use strict"; + var fs6 = require_graceful_fs(); + var path3 = require("path"); + var mkdirsSync = require_mkdirs().mkdirsSync; + var utimesMillisSync = require_utimes().utimesMillisSync; + var stat = require_stat(); + function copySync(src, dest, opts) { + if (typeof opts === "function") { + opts = { filter: opts }; + } + opts = opts || {}; + opts.clobber = "clobber" in opts ? !!opts.clobber : true; + opts.overwrite = "overwrite" in opts ? !!opts.overwrite : opts.clobber; + if (opts.preserveTimestamps && process.arch === "ia32") { + process.emitWarning( + "Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269", + "Warning", + "fs-extra-WARN0002" + ); + } + const { srcStat, destStat } = stat.checkPathsSync(src, dest, "copy", opts); + stat.checkParentPathsSync(src, srcStat, dest, "copy"); + if (opts.filter && !opts.filter(src, dest)) return; + const destParent = path3.dirname(dest); + if (!fs6.existsSync(destParent)) mkdirsSync(destParent); + return getStats(destStat, src, dest, opts); + } + function getStats(destStat, src, dest, opts) { + const statSync = opts.dereference ? fs6.statSync : fs6.lstatSync; + const srcStat = statSync(src); + if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts); + else if (srcStat.isFile() || srcStat.isCharacterDevice() || srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts); + else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts); + else if (srcStat.isSocket()) throw new Error(`Cannot copy a socket file: ${src}`); + else if (srcStat.isFIFO()) throw new Error(`Cannot copy a FIFO pipe: ${src}`); + throw new Error(`Unknown file: ${src}`); + } + function onFile(srcStat, destStat, src, dest, opts) { + if (!destStat) return copyFile(srcStat, src, dest, opts); + return mayCopyFile(srcStat, src, dest, opts); + } + function mayCopyFile(srcStat, src, dest, opts) { + if (opts.overwrite) { + fs6.unlinkSync(dest); + return copyFile(srcStat, src, dest, opts); + } else if (opts.errorOnExist) { + throw new Error(`'${dest}' already exists`); + } + } + function copyFile(srcStat, src, dest, opts) { + fs6.copyFileSync(src, dest); + if (opts.preserveTimestamps) handleTimestamps(srcStat.mode, src, dest); + return setDestMode(dest, srcStat.mode); + } + function handleTimestamps(srcMode, src, dest) { + if (fileIsNotWritable(srcMode)) makeFileWritable(dest, srcMode); + return setDestTimestamps(src, dest); + } + function fileIsNotWritable(srcMode) { + return (srcMode & 128) === 0; + } + function makeFileWritable(dest, srcMode) { + return setDestMode(dest, srcMode | 128); + } + function setDestMode(dest, srcMode) { + return fs6.chmodSync(dest, srcMode); + } + function setDestTimestamps(src, dest) { + const updatedSrcStat = fs6.statSync(src); + return utimesMillisSync(dest, updatedSrcStat.atime, updatedSrcStat.mtime); + } + function onDir(srcStat, destStat, src, dest, opts) { + if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts); + return copyDir(src, dest, opts); + } + function mkDirAndCopy(srcMode, src, dest, opts) { + fs6.mkdirSync(dest); + copyDir(src, dest, opts); + return setDestMode(dest, srcMode); + } + function copyDir(src, dest, opts) { + const dir = fs6.opendirSync(src); + try { + let dirent; + while ((dirent = dir.readSync()) !== null) { + copyDirItem(dirent.name, src, dest, opts); + } + } finally { + dir.closeSync(); + } + } + function copyDirItem(item, src, dest, opts) { + const srcItem = path3.join(src, item); + const destItem = path3.join(dest, item); + if (opts.filter && !opts.filter(srcItem, destItem)) return; + const { destStat } = stat.checkPathsSync(srcItem, destItem, "copy", opts); + return getStats(destStat, srcItem, destItem, opts); + } + function onLink(destStat, src, dest, opts) { + let resolvedSrc = fs6.readlinkSync(src); + if (opts.dereference) { + resolvedSrc = path3.resolve(process.cwd(), resolvedSrc); + } + if (!destStat) { + return fs6.symlinkSync(resolvedSrc, dest); + } else { + let resolvedDest; + try { + resolvedDest = fs6.readlinkSync(dest); + } catch (err) { + if (err.code === "EINVAL" || err.code === "UNKNOWN") return fs6.symlinkSync(resolvedSrc, dest); + throw err; + } + if (opts.dereference) { + resolvedDest = path3.resolve(process.cwd(), resolvedDest); + } + if (resolvedSrc !== resolvedDest) { + if (stat.isSrcSubdir(resolvedSrc, resolvedDest)) { + throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`); + } + if (stat.isSrcSubdir(resolvedDest, resolvedSrc)) { + throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`); + } + } + return copyLink(resolvedSrc, dest); + } + } + function copyLink(resolvedSrc, dest) { + fs6.unlinkSync(dest); + return fs6.symlinkSync(resolvedSrc, dest); + } + module2.exports = copySync; + } +}); + +// node_modules/fs-extra/lib/copy/index.js +var require_copy2 = __commonJS({ + "node_modules/fs-extra/lib/copy/index.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + module2.exports = { + copy: u(require_copy()), + copySync: require_copy_sync() + }; + } +}); + +// node_modules/fs-extra/lib/remove/index.js +var require_remove = __commonJS({ + "node_modules/fs-extra/lib/remove/index.js"(exports2, module2) { + "use strict"; + var fs6 = require_graceful_fs(); + var u = require_universalify().fromCallback; + function remove(path3, callback) { + fs6.rm(path3, { recursive: true, force: true }, callback); + } + function removeSync(path3) { + fs6.rmSync(path3, { recursive: true, force: true }); + } + module2.exports = { + remove: u(remove), + removeSync + }; + } +}); + +// node_modules/fs-extra/lib/empty/index.js +var require_empty = __commonJS({ + "node_modules/fs-extra/lib/empty/index.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + var fs6 = require_fs(); + var path3 = require("path"); + var mkdir = require_mkdirs(); + var remove = require_remove(); + var emptyDir = u(async function emptyDir2(dir) { + let items; + try { + items = await fs6.readdir(dir); + } catch { + return mkdir.mkdirs(dir); + } + return Promise.all(items.map((item) => remove.remove(path3.join(dir, item)))); + }); + function emptyDirSync(dir) { + let items; + try { + items = fs6.readdirSync(dir); + } catch { + return mkdir.mkdirsSync(dir); + } + items.forEach((item) => { + item = path3.join(dir, item); + remove.removeSync(item); + }); + } + module2.exports = { + emptyDirSync, + emptydirSync: emptyDirSync, + emptyDir, + emptydir: emptyDir + }; + } +}); + +// node_modules/fs-extra/lib/ensure/file.js +var require_file2 = __commonJS({ + "node_modules/fs-extra/lib/ensure/file.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + var path3 = require("path"); + var fs6 = require_fs(); + var mkdir = require_mkdirs(); + async function createFile2(file) { + let stats; + try { + stats = await fs6.stat(file); + } catch { + } + if (stats && stats.isFile()) return; + const dir = path3.dirname(file); + let dirStats = null; + try { + dirStats = await fs6.stat(dir); + } catch (err) { + if (err.code === "ENOENT") { + await mkdir.mkdirs(dir); + await fs6.writeFile(file, ""); + return; + } else { + throw err; + } + } + if (dirStats.isDirectory()) { + await fs6.writeFile(file, ""); + } else { + await fs6.readdir(dir); + } + } + function createFileSync(file) { + let stats; + try { + stats = fs6.statSync(file); + } catch { + } + if (stats && stats.isFile()) return; + const dir = path3.dirname(file); + try { + if (!fs6.statSync(dir).isDirectory()) { + fs6.readdirSync(dir); + } + } catch (err) { + if (err && err.code === "ENOENT") mkdir.mkdirsSync(dir); + else throw err; + } + fs6.writeFileSync(file, ""); + } + module2.exports = { + createFile: u(createFile2), + createFileSync + }; + } +}); + +// node_modules/fs-extra/lib/ensure/link.js +var require_link = __commonJS({ + "node_modules/fs-extra/lib/ensure/link.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + var path3 = require("path"); + var fs6 = require_fs(); + var mkdir = require_mkdirs(); + var { pathExists } = require_path_exists(); + var { areIdentical } = require_stat(); + async function createLink(srcpath, dstpath) { + let dstStat; + try { + dstStat = await fs6.lstat(dstpath); + } catch { + } + let srcStat; + try { + srcStat = await fs6.lstat(srcpath); + } catch (err) { + err.message = err.message.replace("lstat", "ensureLink"); + throw err; + } + if (dstStat && areIdentical(srcStat, dstStat)) return; + const dir = path3.dirname(dstpath); + const dirExists = await pathExists(dir); + if (!dirExists) { + await mkdir.mkdirs(dir); + } + await fs6.link(srcpath, dstpath); + } + function createLinkSync(srcpath, dstpath) { + let dstStat; + try { + dstStat = fs6.lstatSync(dstpath); + } catch { + } + try { + const srcStat = fs6.lstatSync(srcpath); + if (dstStat && areIdentical(srcStat, dstStat)) return; + } catch (err) { + err.message = err.message.replace("lstat", "ensureLink"); + throw err; + } + const dir = path3.dirname(dstpath); + const dirExists = fs6.existsSync(dir); + if (dirExists) return fs6.linkSync(srcpath, dstpath); + mkdir.mkdirsSync(dir); + return fs6.linkSync(srcpath, dstpath); + } + module2.exports = { + createLink: u(createLink), + createLinkSync + }; + } +}); + +// node_modules/fs-extra/lib/ensure/symlink-paths.js +var require_symlink_paths = __commonJS({ + "node_modules/fs-extra/lib/ensure/symlink-paths.js"(exports2, module2) { + "use strict"; + var path3 = require("path"); + var fs6 = require_fs(); + var { pathExists } = require_path_exists(); + var u = require_universalify().fromPromise; + async function symlinkPaths(srcpath, dstpath) { + if (path3.isAbsolute(srcpath)) { + try { + await fs6.lstat(srcpath); + } catch (err) { + err.message = err.message.replace("lstat", "ensureSymlink"); + throw err; + } + return { + toCwd: srcpath, + toDst: srcpath + }; + } + const dstdir = path3.dirname(dstpath); + const relativeToDst = path3.join(dstdir, srcpath); + const exists = await pathExists(relativeToDst); + if (exists) { + return { + toCwd: relativeToDst, + toDst: srcpath + }; + } + try { + await fs6.lstat(srcpath); + } catch (err) { + err.message = err.message.replace("lstat", "ensureSymlink"); + throw err; + } + return { + toCwd: srcpath, + toDst: path3.relative(dstdir, srcpath) + }; + } + function symlinkPathsSync(srcpath, dstpath) { + if (path3.isAbsolute(srcpath)) { + const exists2 = fs6.existsSync(srcpath); + if (!exists2) throw new Error("absolute srcpath does not exist"); + return { + toCwd: srcpath, + toDst: srcpath + }; + } + const dstdir = path3.dirname(dstpath); + const relativeToDst = path3.join(dstdir, srcpath); + const exists = fs6.existsSync(relativeToDst); + if (exists) { + return { + toCwd: relativeToDst, + toDst: srcpath + }; + } + const srcExists = fs6.existsSync(srcpath); + if (!srcExists) throw new Error("relative srcpath does not exist"); + return { + toCwd: srcpath, + toDst: path3.relative(dstdir, srcpath) + }; + } + module2.exports = { + symlinkPaths: u(symlinkPaths), + symlinkPathsSync + }; + } +}); + +// node_modules/fs-extra/lib/ensure/symlink-type.js +var require_symlink_type = __commonJS({ + "node_modules/fs-extra/lib/ensure/symlink-type.js"(exports2, module2) { + "use strict"; + var fs6 = require_fs(); + var u = require_universalify().fromPromise; + async function symlinkType(srcpath, type) { + if (type) return type; + let stats; + try { + stats = await fs6.lstat(srcpath); + } catch { + return "file"; + } + return stats && stats.isDirectory() ? "dir" : "file"; + } + function symlinkTypeSync(srcpath, type) { + if (type) return type; + let stats; + try { + stats = fs6.lstatSync(srcpath); + } catch { + return "file"; + } + return stats && stats.isDirectory() ? "dir" : "file"; + } + module2.exports = { + symlinkType: u(symlinkType), + symlinkTypeSync + }; + } +}); + +// node_modules/fs-extra/lib/ensure/symlink.js +var require_symlink = __commonJS({ + "node_modules/fs-extra/lib/ensure/symlink.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + var path3 = require("path"); + var fs6 = require_fs(); + var { mkdirs, mkdirsSync } = require_mkdirs(); + var { symlinkPaths, symlinkPathsSync } = require_symlink_paths(); + var { symlinkType, symlinkTypeSync } = require_symlink_type(); + var { pathExists } = require_path_exists(); + var { areIdentical } = require_stat(); + async function createSymlink(srcpath, dstpath, type) { + let stats; + try { + stats = await fs6.lstat(dstpath); + } catch { + } + if (stats && stats.isSymbolicLink()) { + let srcStat; + if (path3.isAbsolute(srcpath)) { + srcStat = await fs6.stat(srcpath); + } else { + const dstdir = path3.dirname(dstpath); + const relativeToDst = path3.join(dstdir, srcpath); + try { + srcStat = await fs6.stat(relativeToDst); + } catch { + srcStat = await fs6.stat(srcpath); + } + } + const dstStat = await fs6.stat(dstpath); + if (areIdentical(srcStat, dstStat)) return; + } + const relative = await symlinkPaths(srcpath, dstpath); + srcpath = relative.toDst; + const toType = await symlinkType(relative.toCwd, type); + const dir = path3.dirname(dstpath); + if (!await pathExists(dir)) { + await mkdirs(dir); + } + return fs6.symlink(srcpath, dstpath, toType); + } + function createSymlinkSync(srcpath, dstpath, type) { + let stats; + try { + stats = fs6.lstatSync(dstpath); + } catch { + } + if (stats && stats.isSymbolicLink()) { + let srcStat; + if (path3.isAbsolute(srcpath)) { + srcStat = fs6.statSync(srcpath); + } else { + const dstdir = path3.dirname(dstpath); + const relativeToDst = path3.join(dstdir, srcpath); + try { + srcStat = fs6.statSync(relativeToDst); + } catch { + srcStat = fs6.statSync(srcpath); + } + } + const dstStat = fs6.statSync(dstpath); + if (areIdentical(srcStat, dstStat)) return; + } + const relative = symlinkPathsSync(srcpath, dstpath); + srcpath = relative.toDst; + type = symlinkTypeSync(relative.toCwd, type); + const dir = path3.dirname(dstpath); + const exists = fs6.existsSync(dir); + if (exists) return fs6.symlinkSync(srcpath, dstpath, type); + mkdirsSync(dir); + return fs6.symlinkSync(srcpath, dstpath, type); + } + module2.exports = { + createSymlink: u(createSymlink), + createSymlinkSync + }; + } +}); + +// node_modules/fs-extra/lib/ensure/index.js +var require_ensure = __commonJS({ + "node_modules/fs-extra/lib/ensure/index.js"(exports2, module2) { + "use strict"; + var { createFile: createFile2, createFileSync } = require_file2(); + var { createLink, createLinkSync } = require_link(); + var { createSymlink, createSymlinkSync } = require_symlink(); + module2.exports = { + // file + createFile: createFile2, + createFileSync, + ensureFile: createFile2, + ensureFileSync: createFileSync, + // link + createLink, + createLinkSync, + ensureLink: createLink, + ensureLinkSync: createLinkSync, + // symlink + createSymlink, + createSymlinkSync, + ensureSymlink: createSymlink, + ensureSymlinkSync: createSymlinkSync + }; + } +}); + +// node_modules/jsonfile/utils.js +var require_utils9 = __commonJS({ + "node_modules/jsonfile/utils.js"(exports2, module2) { + function stringify4(obj, { EOL = "\n", finalEOL = true, replacer = null, spaces } = {}) { + const EOF = finalEOL ? EOL : ""; + const str = JSON.stringify(obj, replacer, spaces); + return str.replace(/\n/g, EOL) + EOF; + } + function stripBom(content) { + if (Buffer.isBuffer(content)) content = content.toString("utf8"); + return content.replace(/^\uFEFF/, ""); + } + module2.exports = { stringify: stringify4, stripBom }; + } +}); + +// node_modules/jsonfile/index.js +var require_jsonfile = __commonJS({ + "node_modules/jsonfile/index.js"(exports2, module2) { + var _fs; + try { + _fs = require_graceful_fs(); + } catch (_) { + _fs = require("fs"); + } + var universalify = require_universalify(); + var { stringify: stringify4, stripBom } = require_utils9(); + async function _readFile(file, options = {}) { + if (typeof options === "string") { + options = { encoding: options }; + } + const fs6 = options.fs || _fs; + const shouldThrow = "throws" in options ? options.throws : true; + let data = await universalify.fromCallback(fs6.readFile)(file, options); + data = stripBom(data); + let obj; + try { + obj = JSON.parse(data, options ? options.reviver : null); + } catch (err) { + if (shouldThrow) { + err.message = `${file}: ${err.message}`; + throw err; + } else { + return null; + } + } + return obj; + } + var readFile = universalify.fromPromise(_readFile); + function readFileSync(file, options = {}) { + if (typeof options === "string") { + options = { encoding: options }; + } + const fs6 = options.fs || _fs; + const shouldThrow = "throws" in options ? options.throws : true; + try { + let content = fs6.readFileSync(file, options); + content = stripBom(content); + return JSON.parse(content, options.reviver); + } catch (err) { + if (shouldThrow) { + err.message = `${file}: ${err.message}`; + throw err; + } else { + return null; + } + } + } + async function _writeFile(file, obj, options = {}) { + const fs6 = options.fs || _fs; + const str = stringify4(obj, options); + await universalify.fromCallback(fs6.writeFile)(file, str, options); + } + var writeFile = universalify.fromPromise(_writeFile); + function writeFileSync(file, obj, options = {}) { + const fs6 = options.fs || _fs; + const str = stringify4(obj, options); + return fs6.writeFileSync(file, str, options); + } + module2.exports = { + readFile, + readFileSync, + writeFile, + writeFileSync + }; + } +}); + +// node_modules/fs-extra/lib/json/jsonfile.js +var require_jsonfile2 = __commonJS({ + "node_modules/fs-extra/lib/json/jsonfile.js"(exports2, module2) { + "use strict"; + var jsonFile = require_jsonfile(); + module2.exports = { + // jsonfile exports + readJson: jsonFile.readFile, + readJsonSync: jsonFile.readFileSync, + writeJson: jsonFile.writeFile, + writeJsonSync: jsonFile.writeFileSync + }; + } +}); + +// node_modules/fs-extra/lib/output-file/index.js +var require_output_file = __commonJS({ + "node_modules/fs-extra/lib/output-file/index.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + var fs6 = require_fs(); + var path3 = require("path"); + var mkdir = require_mkdirs(); + var pathExists = require_path_exists().pathExists; + async function outputFile(file, data, encoding = "utf-8") { + const dir = path3.dirname(file); + if (!await pathExists(dir)) { + await mkdir.mkdirs(dir); + } + return fs6.writeFile(file, data, encoding); + } + function outputFileSync(file, ...args) { + const dir = path3.dirname(file); + if (!fs6.existsSync(dir)) { + mkdir.mkdirsSync(dir); + } + fs6.writeFileSync(file, ...args); + } + module2.exports = { + outputFile: u(outputFile), + outputFileSync + }; + } +}); + +// node_modules/fs-extra/lib/json/output-json.js +var require_output_json = __commonJS({ + "node_modules/fs-extra/lib/json/output-json.js"(exports2, module2) { + "use strict"; + var { stringify: stringify4 } = require_utils9(); + var { outputFile } = require_output_file(); + async function outputJson(file, data, options = {}) { + const str = stringify4(data, options); + await outputFile(file, str, options); + } + module2.exports = outputJson; + } +}); + +// node_modules/fs-extra/lib/json/output-json-sync.js +var require_output_json_sync = __commonJS({ + "node_modules/fs-extra/lib/json/output-json-sync.js"(exports2, module2) { + "use strict"; + var { stringify: stringify4 } = require_utils9(); + var { outputFileSync } = require_output_file(); + function outputJsonSync(file, data, options) { + const str = stringify4(data, options); + outputFileSync(file, str, options); + } + module2.exports = outputJsonSync; + } +}); + +// node_modules/fs-extra/lib/json/index.js +var require_json2 = __commonJS({ + "node_modules/fs-extra/lib/json/index.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + var jsonFile = require_jsonfile2(); + jsonFile.outputJson = u(require_output_json()); + jsonFile.outputJsonSync = require_output_json_sync(); + jsonFile.outputJSON = jsonFile.outputJson; + jsonFile.outputJSONSync = jsonFile.outputJsonSync; + jsonFile.writeJSON = jsonFile.writeJson; + jsonFile.writeJSONSync = jsonFile.writeJsonSync; + jsonFile.readJSON = jsonFile.readJson; + jsonFile.readJSONSync = jsonFile.readJsonSync; + module2.exports = jsonFile; + } +}); + +// node_modules/fs-extra/lib/move/move.js +var require_move = __commonJS({ + "node_modules/fs-extra/lib/move/move.js"(exports2, module2) { + "use strict"; + var fs6 = require_fs(); + var path3 = require("path"); + var { copy } = require_copy2(); + var { remove } = require_remove(); + var { mkdirp } = require_mkdirs(); + var { pathExists } = require_path_exists(); + var stat = require_stat(); + async function move(src, dest, opts = {}) { + const overwrite = opts.overwrite || opts.clobber || false; + const { srcStat, isChangingCase = false } = await stat.checkPaths(src, dest, "move", opts); + await stat.checkParentPaths(src, srcStat, dest, "move"); + const destParent = path3.dirname(dest); + const parsedParentPath = path3.parse(destParent); + if (parsedParentPath.root !== destParent) { + await mkdirp(destParent); + } + return doRename(src, dest, overwrite, isChangingCase); + } + async function doRename(src, dest, overwrite, isChangingCase) { + if (!isChangingCase) { + if (overwrite) { + await remove(dest); + } else if (await pathExists(dest)) { + throw new Error("dest already exists."); + } + } + try { + await fs6.rename(src, dest); + } catch (err) { + if (err.code !== "EXDEV") { + throw err; + } + await moveAcrossDevice(src, dest, overwrite); + } + } + async function moveAcrossDevice(src, dest, overwrite) { + const opts = { + overwrite, + errorOnExist: true, + preserveTimestamps: true + }; + await copy(src, dest, opts); + return remove(src); + } + module2.exports = move; + } +}); + +// node_modules/fs-extra/lib/move/move-sync.js +var require_move_sync = __commonJS({ + "node_modules/fs-extra/lib/move/move-sync.js"(exports2, module2) { + "use strict"; + var fs6 = require_graceful_fs(); + var path3 = require("path"); + var copySync = require_copy2().copySync; + var removeSync = require_remove().removeSync; + var mkdirpSync = require_mkdirs().mkdirpSync; + var stat = require_stat(); + function moveSync(src, dest, opts) { + opts = opts || {}; + const overwrite = opts.overwrite || opts.clobber || false; + const { srcStat, isChangingCase = false } = stat.checkPathsSync(src, dest, "move", opts); + stat.checkParentPathsSync(src, srcStat, dest, "move"); + if (!isParentRoot(dest)) mkdirpSync(path3.dirname(dest)); + return doRename(src, dest, overwrite, isChangingCase); + } + function isParentRoot(dest) { + const parent = path3.dirname(dest); + const parsedPath = path3.parse(parent); + return parsedPath.root === parent; + } + function doRename(src, dest, overwrite, isChangingCase) { + if (isChangingCase) return rename(src, dest, overwrite); + if (overwrite) { + removeSync(dest); + return rename(src, dest, overwrite); + } + if (fs6.existsSync(dest)) throw new Error("dest already exists."); + return rename(src, dest, overwrite); + } + function rename(src, dest, overwrite) { + try { + fs6.renameSync(src, dest); + } catch (err) { + if (err.code !== "EXDEV") throw err; + return moveAcrossDevice(src, dest, overwrite); + } + } + function moveAcrossDevice(src, dest, overwrite) { + const opts = { + overwrite, + errorOnExist: true, + preserveTimestamps: true + }; + copySync(src, dest, opts); + return removeSync(src); + } + module2.exports = moveSync; + } +}); + +// node_modules/fs-extra/lib/move/index.js +var require_move2 = __commonJS({ + "node_modules/fs-extra/lib/move/index.js"(exports2, module2) { + "use strict"; + var u = require_universalify().fromPromise; + module2.exports = { + move: u(require_move()), + moveSync: require_move_sync() + }; + } +}); + +// node_modules/fs-extra/lib/index.js +var require_lib11 = __commonJS({ + "node_modules/fs-extra/lib/index.js"(exports2, module2) { + "use strict"; + module2.exports = { + // Export promiseified graceful-fs: + ...require_fs(), + // Export extra methods: + ...require_copy2(), + ...require_empty(), + ...require_ensure(), + ...require_json2(), + ...require_mkdirs(), + ...require_move2(), + ...require_output_file(), + ...require_path_exists(), + ...require_remove() + }; + } +}); + +// node_modules/botbuilder/vendors/filenamify/index.js +var require_filenamify = __commonJS({ + "node_modules/botbuilder/vendors/filenamify/index.js"(exports2, module2) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var index_exports = {}; + __export2(index_exports, { + default: () => filenamify, + filenamifyPath: () => filenamifyPath + }); + module2.exports = __toCommonJS2(index_exports); + function filenameReservedRegex() { + return /[<>:"/\\|?*\u0000-\u001F]/g; + } + function windowsReservedNameRegex() { + return /^(con|prn|aux|nul|com\d|lpt\d)$/i; + } + var MAX_FILENAME_LENGTH = 100; + var reRelativePath = /^\.+(\\|\/)|^\.+$/; + var reTrailingPeriods = /\.+$/; + function filenamify(string, options = {}) { + const reControlChars = /[\u0000-\u001F\u0080-\u009F]/g; + const reRepeatedReservedCharacters = /([<>:"/\\|?*\u0000-\u001F]){2,}/g; + if (typeof string !== "string") { + throw new TypeError("Expected a string"); + } + const replacement = options.replacement === void 0 ? "!" : options.replacement; + if (filenameReservedRegex().test(replacement) && reControlChars.test(replacement)) { + throw new Error("Replacement string cannot contain reserved filename characters"); + } + if (replacement.length > 0) { + string = string.replace(reRepeatedReservedCharacters, "$1"); + } + string = string.normalize("NFD"); + string = string.replace(reRelativePath, replacement); + string = string.replace(filenameReservedRegex(), replacement); + string = string.replace(reControlChars, replacement); + string = string.replace(reTrailingPeriods, ""); + if (replacement.length > 0) { + const startedWithDot = string[0] === "."; + if (!startedWithDot && string[0] === ".") { + string = replacement + string; + } + if (string[string.length - 1] === ".") { + string += replacement; + } + } + string = windowsReservedNameRegex().test(string) ? string + replacement : string; + const allowedLength = typeof options.maxLength === "number" ? options.maxLength : MAX_FILENAME_LENGTH; + if (string.length > allowedLength) { + const extensionIndex = string.lastIndexOf("."); + if (extensionIndex === -1) { + string = string.slice(0, allowedLength); + } else { + const filename = string.slice(0, extensionIndex); + const extension = string.slice(extensionIndex); + string = filename.slice(0, Math.max(1, allowedLength - extension.length)) + extension; + } + } + return string; + } + var import_node_path2 = __toESM2(require("path"), 1); + function filenamifyPath(filePath, options) { + filePath = import_node_path2.default.resolve(filePath); + return import_node_path2.default.join(import_node_path2.default.dirname(filePath), filenamify(import_node_path2.default.basename(filePath), options)); + } + } +}); + +// node_modules/botbuilder/lib/fileTranscriptStore.js +var require_fileTranscriptStore = __commonJS({ + "node_modules/botbuilder/lib/fileTranscriptStore.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.FileTranscriptStore = void 0; + var path_1 = require("path"); + var fs_extra_1 = require_lib11(); + var index_1 = __importDefault2(require_filenamify()); + var epochTicks = 621355968e9; + var ticksPerMillisecond = 1e4; + function getTicks(timestamp) { + const ticks = epochTicks + timestamp.getTime() * ticksPerMillisecond; + return ticks.toString(16); + } + function readDate(ticks) { + const t = Math.round((parseInt(ticks, 16) - epochTicks) / ticksPerMillisecond); + return new Date(t); + } + function withDateFilter(date, fileName) { + if (!date) { + return true; + } + const ticks = fileName.split("-")[0]; + return readDate(ticks) >= date; + } + function includeWhen(expression) { + let shouldInclude = false; + return (item) => { + return shouldInclude || (shouldInclude = expression(item)); + }; + } + function parseActivity(json) { + const activity = JSON.parse(json); + activity.timestamp = new Date(activity.timestamp); + return activity; + } + var FileTranscriptStore = class _FileTranscriptStore { + /** + * Creates an instance of FileTranscriptStore. + * + * @param folder Root folder where transcript will be stored. + */ + constructor(folder) { + if (!folder) { + throw new Error("Missing folder."); + } + this.rootFolder = folder; + } + /** + * Log an activity to the transcript. + * + * @param activity Activity being logged. + * @returns {Promise} a promise representing the asynchronous operation. + */ + logActivity(activity) { + return __awaiter2(this, void 0, void 0, function* () { + if (!activity) { + throw new Error("activity cannot be null for logActivity()"); + } + const conversationFolder = this.getTranscriptFolder(activity.channelId, activity.conversation.id); + const activityFileName = this.getActivityFilename(activity); + return this.saveActivity(activity, conversationFolder, activityFileName); + }); + } + /** + * Get all activities associated with a conversation id (aka get the transcript). + * + * @param channelId Channel Id. + * @param conversationId Conversation Id. + * @param continuationToken (Optional) Continuation token to page through results. + * @param startDate (Optional) Earliest time to include. + * @returns {Promise>} PagedResult of activities. + */ + getTranscriptActivities(channelId, conversationId, continuationToken, startDate) { + return __awaiter2(this, void 0, void 0, function* () { + if (!channelId) { + throw new Error("Missing channelId"); + } + if (!conversationId) { + throw new Error("Missing conversationId"); + } + const pagedResult = { items: [], continuationToken: void 0 }; + const transcriptFolder = this.getTranscriptFolder(channelId, conversationId); + const exists = yield (0, fs_extra_1.pathExists)(transcriptFolder); + if (!exists) { + return pagedResult; + } + const transcriptFolderContents = yield (0, fs_extra_1.readdir)(transcriptFolder); + const include = includeWhen((fileName) => !continuationToken || (0, path_1.parse)(fileName).name === continuationToken); + const items = transcriptFolderContents.filter((transcript) => transcript.endsWith(".json") && withDateFilter(startDate, transcript) && include(transcript)); + pagedResult.items = yield Promise.all(items.slice(0, _FileTranscriptStore.PageSize).sort().map((activityFilename) => __awaiter2(this, void 0, void 0, function* () { + const json = yield (0, fs_extra_1.readFile)((0, path_1.join)(transcriptFolder, activityFilename), "utf8"); + return parseActivity(json); + }))); + const { length } = pagedResult.items; + if (length === _FileTranscriptStore.PageSize && items[length]) { + pagedResult.continuationToken = (0, path_1.parse)(items[length]).name; + } + return pagedResult; + }); + } + /** + * List all the logged conversations for a given channelId. + * + * @param channelId Channel Id. + * @param continuationToken (Optional) Continuation token to page through results. + * @returns {Promise>} PagedResult of transcripts. + */ + listTranscripts(channelId, continuationToken) { + return __awaiter2(this, void 0, void 0, function* () { + if (!channelId) { + throw new Error("Missing channelId"); + } + const pagedResult = { items: [], continuationToken: void 0 }; + const channelFolder = this.getChannelFolder(channelId); + const exists = yield (0, fs_extra_1.pathExists)(channelFolder); + if (!exists) { + return pagedResult; + } + const channels = yield (0, fs_extra_1.readdir)(channelFolder); + const items = channels.filter(includeWhen((di) => !continuationToken || di === continuationToken)); + pagedResult.items = items.slice(0, _FileTranscriptStore.PageSize).map((i) => ({ channelId, id: i, created: null })); + const { length } = pagedResult.items; + if (length === _FileTranscriptStore.PageSize && items[length]) { + pagedResult.continuationToken = items[length]; + } + return pagedResult; + }); + } + /** + * Delete a conversation and all of it's activities. + * + * @param channelId Channel Id where conversation took place. + * @param conversationId Id of the conversation to delete. + * @returns {Promise} A promise representing the asynchronous operation. + */ + deleteTranscript(channelId, conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!channelId) { + throw new Error("Missing channelId"); + } + if (!conversationId) { + throw new Error("Missing conversationId"); + } + const transcriptFolder = this.getTranscriptFolder(channelId, conversationId); + return (0, fs_extra_1.remove)(transcriptFolder); + }); + } + /** + * Saves the [Activity](xref:botframework-schema.Activity) as a JSON file. + * + * @param activity The [Activity](xref:botframework-schema.Activity) to transcript. + * @param transcriptPath The path where the transcript will be saved. + * @param activityFilename The name for the file. + * @returns {Promise} A promise representing the asynchronous operation. + */ + saveActivity(activity, transcriptPath, activityFilename) { + return __awaiter2(this, void 0, void 0, function* () { + const json = JSON.stringify(activity, null, " "); + const exists = yield (0, fs_extra_1.pathExists)(transcriptPath); + if (!exists) { + yield (0, fs_extra_1.mkdirp)(transcriptPath); + } + return (0, fs_extra_1.writeFile)((0, path_1.join)(transcriptPath, activityFilename), json, "utf8"); + }); + } + /** + * @private + */ + getActivityFilename(activity) { + return `${getTicks(activity.timestamp)}-${this.sanitizeKey(activity.id)}.json`; + } + /** + * @private + */ + getChannelFolder(channelId) { + return (0, path_1.join)(this.rootFolder, this.sanitizeKey(channelId)); + } + /** + * @private + */ + getTranscriptFolder(channelId, conversationId) { + return (0, path_1.join)(this.rootFolder, this.sanitizeKey(channelId), this.sanitizeKey(conversationId)); + } + /** + * @private + */ + sanitizeKey(key) { + return (0, index_1.default)(key); + } + }; + exports2.FileTranscriptStore = FileTranscriptStore; + FileTranscriptStore.PageSize = 20; + } +}); + +// node_modules/botbuilder/lib/teamsActivityHelpers.js +var require_teamsActivityHelpers = __commonJS({ + "node_modules/botbuilder/lib/teamsActivityHelpers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.teamsGetTeamOnBehalfOf = exports2.teamsNotifyUser = exports2.teamsGetChannelId = exports2.teamsGetTeamId = exports2.teamsGetTeamInfo = exports2.teamsGetTenant = exports2.teamsGetTeamMeetingInfo = exports2.teamsGetSelectedChannelId = void 0; + function isTeamsChannelData(channelData) { + return typeof channelData === "object"; + } + function validateActivity(activity) { + if (!activity) { + throw new Error("Missing activity parameter"); + } + } + function teamsGetSelectedChannelId(activity) { + var _a, _b, _c, _d; + validateActivity(activity); + return (_d = (_c = (_b = (_a = activity.channelData) === null || _a === void 0 ? void 0 : _a.settings) === null || _b === void 0 ? void 0 : _b.selectedChannel) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : ""; + } + exports2.teamsGetSelectedChannelId = teamsGetSelectedChannelId; + function teamsGetTeamMeetingInfo(activity) { + validateActivity(activity); + if (isTeamsChannelData(activity.channelData)) { + return activity.channelData.meeting || null; + } + return null; + } + exports2.teamsGetTeamMeetingInfo = teamsGetTeamMeetingInfo; + function teamsGetTenant(activity) { + validateActivity(activity); + if (isTeamsChannelData(activity.channelData)) { + return activity.channelData.tenant || null; + } + return null; + } + exports2.teamsGetTenant = teamsGetTenant; + function teamsGetTeamInfo(activity) { + validateActivity(activity); + const channelData = activity.channelData; + if (isTeamsChannelData(channelData)) { + const team = channelData.team; + return team || null; + } + return null; + } + exports2.teamsGetTeamInfo = teamsGetTeamInfo; + function teamsGetTeamId(activity) { + const team = teamsGetTeamInfo(activity); + return team && team.id ? team.id : null; + } + exports2.teamsGetTeamId = teamsGetTeamId; + function teamsGetChannelId(activity) { + validateActivity(activity); + const channelData = activity.channelData; + if (isTeamsChannelData(channelData)) { + const channel = channelData.channel; + return channel && channel.id ? channel.id : null; + } + return null; + } + exports2.teamsGetChannelId = teamsGetChannelId; + function teamsNotifyUser(activity, alertInMeeting = false, externalResourceUrl) { + validateActivity(activity); + if (!isTeamsChannelData(activity.channelData)) { + activity.channelData = {}; + } + if (isTeamsChannelData(activity.channelData)) { + activity.channelData.notification = { alert: !alertInMeeting, alertInMeeting, externalResourceUrl }; + } + } + exports2.teamsNotifyUser = teamsNotifyUser; + function teamsGetTeamOnBehalfOf(activity) { + validateActivity(activity); + if (isTeamsChannelData(activity.channelData)) { + return activity.channelData.onBehalfOf || null; + } + return null; + } + exports2.teamsGetTeamOnBehalfOf = teamsGetTeamOnBehalfOf; + } +}); + +// node_modules/botbuilder/lib/inspectionMiddleware.js +var require_inspectionMiddleware = __commonJS({ + "node_modules/botbuilder/lib/inspectionMiddleware.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.InspectionState = exports2.InspectionMiddleware = void 0; + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + var botframework_connector_1 = require_lib9(); + var botbuilder_core_1 = require_lib10(); + var teamsActivityHelpers_1 = require_teamsActivityHelpers(); + var TraceActivity = class { + static makeCommandActivity(command) { + return { + type: botbuilder_core_1.ActivityTypes.Trace, + timestamp: /* @__PURE__ */ new Date(), + name: "Command", + label: "Command", + value: command, + valueType: "https://www.botframework.com/schemas/command" + }; + } + static fromActivity(activity, name, label) { + return { + type: botbuilder_core_1.ActivityTypes.Trace, + timestamp: /* @__PURE__ */ new Date(), + name, + label, + value: activity, + valueType: "https://www.botframework.com/schemas/activity" + }; + } + static fromState(botState) { + return { + type: botbuilder_core_1.ActivityTypes.Trace, + timestamp: /* @__PURE__ */ new Date(), + name: "BotState", + label: "Bot State", + value: botState, + valueType: "https://www.botframework.com/schemas/botState" + }; + } + static fromConversationReference(conversationReference) { + return { + type: botbuilder_core_1.ActivityTypes.Trace, + timestamp: /* @__PURE__ */ new Date(), + name: "Deleted Message", + label: "MessageDelete", + value: conversationReference, + valueType: "https://www.botframework.com/schemas/conversationReference" + }; + } + static fromError(errorMessage) { + return { + type: botbuilder_core_1.ActivityTypes.Trace, + timestamp: /* @__PURE__ */ new Date(), + name: "Turn Error", + label: "TurnError", + value: errorMessage, + valueType: "https://www.botframework.com/schemas/error" + }; + } + }; + var InterceptionMiddleware = class { + /** + * Implement middleware signature + * + * @param turnContext {TurnContext} An incoming TurnContext object. + * @param next {function} The next delegate function. + */ + onTurn(turnContext, next) { + return __awaiter2(this, void 0, void 0, function* () { + const { shouldForwardToApplication, shouldIntercept } = yield this.invokeInbound(turnContext, TraceActivity.fromActivity(turnContext.activity, "ReceivedActivity", "Received Activity")); + if (shouldIntercept) { + turnContext.onSendActivities((ctx, activities, nextSend) => __awaiter2(this, void 0, void 0, function* () { + const traceActivities = []; + activities.forEach((activity) => { + traceActivities.push(TraceActivity.fromActivity(activity, "SentActivity", "Sent Activity")); + }); + yield this.invokeOutbound(ctx, traceActivities); + return yield nextSend(); + })); + turnContext.onUpdateActivity((ctx, activity, nextUpdate) => __awaiter2(this, void 0, void 0, function* () { + const traceActivity = TraceActivity.fromActivity(activity, "MessageUpdate", "Updated Message"); + yield this.invokeOutbound(ctx, [traceActivity]); + return yield nextUpdate(); + })); + turnContext.onDeleteActivity((ctx, reference, nextDelete) => __awaiter2(this, void 0, void 0, function* () { + const traceActivity = TraceActivity.fromConversationReference(reference); + yield this.invokeOutbound(ctx, [traceActivity]); + return yield nextDelete(); + })); + } + if (shouldForwardToApplication) { + try { + yield next(); + } catch (err) { + const traceActivity = TraceActivity.fromError(err.toString()); + yield this.invokeOutbound(turnContext, [traceActivity]); + throw err; + } + } + if (shouldIntercept) { + yield this.invokeTraceState(turnContext); + } + }); + } + invokeInbound(turnContext, traceActivity) { + return __awaiter2(this, void 0, void 0, function* () { + try { + return yield this.inbound(turnContext, traceActivity); + } catch (err) { + console.warn(`Exception in inbound interception ${err}`); + return { shouldForwardToApplication: true, shouldIntercept: false }; + } + }); + } + invokeOutbound(turnContext, traceActivities) { + return __awaiter2(this, void 0, void 0, function* () { + try { + yield this.outbound(turnContext, traceActivities); + } catch (err) { + console.warn(`Exception in outbound interception ${err}`); + } + }); + } + invokeTraceState(turnContext) { + return __awaiter2(this, void 0, void 0, function* () { + try { + yield this.traceState(turnContext); + } catch (err) { + console.warn(`Exception in state interception ${err}`); + } + }); + } + }; + var InspectionMiddleware = class _InspectionMiddleware extends InterceptionMiddleware { + /** + * Create the Inspection middleware for sending trace activities out to an emulator session + * + * @param inspectionState A state management object for inspection state. + * @param userState A state management object for user state. + * @param conversationState A state management object for conversation state. + * @param credentials The authentication credentials. + */ + constructor(inspectionState, userState, conversationState, credentials) { + super(); + this.inspectionState = inspectionState; + this.inspectionStateAccessor = inspectionState.createProperty("InspectionSessionByStatus"); + this.userState = userState; + this.conversationState = conversationState; + credentials = Object.assign({ appId: "", appPassword: "" }, credentials); + this.credentials = new botframework_connector_1.MicrosoftAppCredentials(credentials.appId, credentials.appPassword); + } + /** + * Indentifies open and attach commands and calls the appropriate method. + * + * @param turnContext The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @returns True if the command is open or attached, otherwise false. + */ + processCommand(turnContext) { + return __awaiter2(this, void 0, void 0, function* () { + if (turnContext.activity.type == botbuilder_core_1.ActivityTypes.Message && turnContext.activity.text !== void 0) { + const originalText = turnContext.activity.text; + botbuilder_core_1.TurnContext.removeRecipientMention(turnContext.activity); + const command = turnContext.activity.text.trim().split(" "); + if (command.length > 1 && command[0] === _InspectionMiddleware.command) { + if (command.length === 2 && command[1] === "open") { + yield this.processOpenCommand(turnContext); + return true; + } + if (command.length === 3 && command[1] === "attach") { + yield this.processAttachCommand(turnContext, command[2]); + return true; + } + } + turnContext.activity.text = originalText; + } + return false; + }); + } + /** + * Processes inbound activities. + * + * @param turnContext The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param traceActivity The trace activity. + * @returns {Promise} A promise representing the asynchronous operation. + */ + inbound(turnContext, traceActivity) { + return __awaiter2(this, void 0, void 0, function* () { + if (yield this.processCommand(turnContext)) { + return { shouldForwardToApplication: false, shouldIntercept: false }; + } + const session = yield this.findSession(turnContext); + if (session !== void 0) { + if (yield this.invokeSend(turnContext, session, traceActivity)) { + return { shouldForwardToApplication: true, shouldIntercept: true }; + } else { + return { shouldForwardToApplication: true, shouldIntercept: false }; + } + } else { + return { shouldForwardToApplication: true, shouldIntercept: false }; + } + }); + } + /** + * Processes outbound activities. + * + * @param turnContext The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param traceActivities A collection of trace activities. + */ + outbound(turnContext, traceActivities) { + return __awaiter2(this, void 0, void 0, function* () { + const session = yield this.findSession(turnContext); + if (session !== void 0) { + for (let i = 0; i < traceActivities.length; i++) { + const traceActivity = traceActivities[i]; + if (!(yield this.invokeSend(turnContext, session, traceActivity))) { + break; + } + } + } + }); + } + /** + * Processes the state management object. + * + * @param turnContext The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + */ + traceState(turnContext) { + return __awaiter2(this, void 0, void 0, function* () { + const session = yield this.findSession(turnContext); + if (session !== void 0) { + if (this.userState !== void 0) { + yield this.userState.load(turnContext, false); + } + if (this.conversationState != void 0) { + yield this.conversationState.load(turnContext, false); + } + const botState = {}; + if (this.userState !== void 0) { + botState.userState = this.userState.get(turnContext); + } + if (this.conversationState !== void 0) { + botState.conversationState = this.conversationState.get(turnContext); + } + yield this.invokeSend(turnContext, session, TraceActivity.fromState(botState)); + } + }); + } + /** + * @private + */ + processOpenCommand(turnContext) { + return __awaiter2(this, void 0, void 0, function* () { + const sessions = yield this.inspectionStateAccessor.get(turnContext, InspectionSessionsByStatus.DefaultValue); + const sessionId = this.openCommand(sessions, botbuilder_core_1.TurnContext.getConversationReference(turnContext.activity)); + yield turnContext.sendActivity(TraceActivity.makeCommandActivity(`${_InspectionMiddleware.command} attach ${sessionId}`)); + yield this.inspectionState.saveChanges(turnContext, false); + }); + } + /** + * @private + */ + processAttachCommand(turnContext, sessionId) { + return __awaiter2(this, void 0, void 0, function* () { + const sessions = yield this.inspectionStateAccessor.get(turnContext, InspectionSessionsByStatus.DefaultValue); + if (this.attachCommand(this.getAttachId(turnContext.activity), sessions, sessionId)) { + yield turnContext.sendActivity("Attached to session, all traffic is being replicated for inspection."); + } else { + yield turnContext.sendActivity(`Open session with id ${sessionId} does not exist.`); + } + yield this.inspectionState.saveChanges(turnContext, false); + }); + } + /** + * @private + */ + openCommand(sessions, conversationReference) { + const sessionId = (0, uuid_1.v4)(); + sessions.openedSessions[sessionId] = conversationReference; + return sessionId; + } + /** + * @private + */ + attachCommand(attachId, sessions, sessionId) { + const inspectionSessionState = sessions.openedSessions[sessionId]; + if (inspectionSessionState !== void 0) { + sessions.attachedSessions[attachId] = inspectionSessionState; + delete sessions.openedSessions[sessionId]; + return true; + } + return false; + } + /** + * @private + */ + findSession(turnContext) { + return __awaiter2(this, void 0, void 0, function* () { + const sessions = yield this.inspectionStateAccessor.get(turnContext, InspectionSessionsByStatus.DefaultValue); + const conversationReference = sessions.attachedSessions[this.getAttachId(turnContext.activity)]; + if (conversationReference !== void 0) { + return new InspectionSession(conversationReference, this.credentials); + } + return void 0; + }); + } + /** + * @private + */ + invokeSend(turnContext, session, activity) { + return __awaiter2(this, void 0, void 0, function* () { + if (yield session.send(activity)) { + return true; + } else { + yield this.cleanUpSession(turnContext); + return false; + } + }); + } + /** + * @private + */ + cleanUpSession(turnContext) { + return __awaiter2(this, void 0, void 0, function* () { + const sessions = yield this.inspectionStateAccessor.get(turnContext, InspectionSessionsByStatus.DefaultValue); + delete sessions.attachedSessions[this.getAttachId(turnContext.activity)]; + yield this.inspectionState.saveChanges(turnContext, false); + }); + } + /** + * @private + */ + getAttachId(activity) { + const teamId = (0, teamsActivityHelpers_1.teamsGetTeamId)(activity); + return teamId ? teamId : activity.conversation.id; + } + }; + exports2.InspectionMiddleware = InspectionMiddleware; + InspectionMiddleware.command = "/INSPECT"; + var InspectionSession = class { + constructor(conversationReference, credentials) { + this.conversationReference = conversationReference; + this.connectorClient = new botframework_connector_1.ConnectorClient(credentials, { baseUri: conversationReference.serviceUrl }); + } + send(activity) { + return __awaiter2(this, void 0, void 0, function* () { + botbuilder_core_1.TurnContext.applyConversationReference(activity, this.conversationReference); + try { + yield this.connectorClient.conversations.sendToConversation(activity.conversation.id, activity); + } catch (_a) { + return false; + } + return true; + }); + } + }; + var InspectionSessionsByStatus = class { + constructor() { + this.openedSessions = {}; + this.attachedSessions = {}; + } + }; + InspectionSessionsByStatus.DefaultValue = new InspectionSessionsByStatus(); + var InspectionState = class extends botbuilder_core_1.BotState { + /** + * Creates a new instance of the [InspectionState](xref:botbuilder.InspectionState) class. + * + * @param storage The [Storage](xref:botbuilder-core.Storage) layer this state management object will use to store and retrieve state. + */ + constructor(storage) { + super(storage, (context) => { + return Promise.resolve(this.getStorageKey(context)); + }); + } + /** + * Gets the key to use when reading and writing state to and from storage. + * + * @param _turnContext The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @returns The storage key. + */ + getStorageKey(_turnContext) { + return "InspectionState"; + } + }; + exports2.InspectionState = InspectionState; + } +}); + +// node_modules/entities/lib/generated/decode-data-html.js +var require_decode_data_html = __commonJS({ + "node_modules/entities/lib/generated/decode-data-html.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.default = new Uint16Array( + // prettier-ignore + '\u1D41<\xD5\u0131\u028A\u049D\u057B\u05D0\u0675\u06DE\u07A2\u07D6\u080F\u0A4A\u0A91\u0DA1\u0E6D\u0F09\u0F26\u10CA\u1228\u12E1\u1415\u149D\u14C3\u14DF\u1525\0\0\0\0\0\0\u156B\u16CD\u198D\u1C12\u1DDD\u1F7E\u2060\u21B0\u228D\u23C0\u23FB\u2442\u2824\u2912\u2D08\u2E48\u2FCE\u3016\u32BA\u3639\u37AC\u38FE\u3A28\u3A71\u3AE0\u3B2E\u0800EMabcfglmnoprstu\\bfms\x7F\x84\x8B\x90\x95\x98\xA6\xB3\xB9\xC8\xCFlig\u803B\xC6\u40C6P\u803B&\u4026cute\u803B\xC1\u40C1reve;\u4102\u0100iyx}rc\u803B\xC2\u40C2;\u4410r;\uC000\u{1D504}rave\u803B\xC0\u40C0pha;\u4391acr;\u4100d;\u6A53\u0100gp\x9D\xA1on;\u4104f;\uC000\u{1D538}plyFunction;\u6061ing\u803B\xC5\u40C5\u0100cs\xBE\xC3r;\uC000\u{1D49C}ign;\u6254ilde\u803B\xC3\u40C3ml\u803B\xC4\u40C4\u0400aceforsu\xE5\xFB\xFE\u0117\u011C\u0122\u0127\u012A\u0100cr\xEA\xF2kslash;\u6216\u0176\xF6\xF8;\u6AE7ed;\u6306y;\u4411\u0180crt\u0105\u010B\u0114ause;\u6235noullis;\u612Ca;\u4392r;\uC000\u{1D505}pf;\uC000\u{1D539}eve;\u42D8c\xF2\u0113mpeq;\u624E\u0700HOacdefhilorsu\u014D\u0151\u0156\u0180\u019E\u01A2\u01B5\u01B7\u01BA\u01DC\u0215\u0273\u0278\u027Ecy;\u4427PY\u803B\xA9\u40A9\u0180cpy\u015D\u0162\u017Aute;\u4106\u0100;i\u0167\u0168\u62D2talDifferentialD;\u6145leys;\u612D\u0200aeio\u0189\u018E\u0194\u0198ron;\u410Cdil\u803B\xC7\u40C7rc;\u4108nint;\u6230ot;\u410A\u0100dn\u01A7\u01ADilla;\u40B8terDot;\u40B7\xF2\u017Fi;\u43A7rcle\u0200DMPT\u01C7\u01CB\u01D1\u01D6ot;\u6299inus;\u6296lus;\u6295imes;\u6297o\u0100cs\u01E2\u01F8kwiseContourIntegral;\u6232eCurly\u0100DQ\u0203\u020FoubleQuote;\u601Duote;\u6019\u0200lnpu\u021E\u0228\u0247\u0255on\u0100;e\u0225\u0226\u6237;\u6A74\u0180git\u022F\u0236\u023Aruent;\u6261nt;\u622FourIntegral;\u622E\u0100fr\u024C\u024E;\u6102oduct;\u6210nterClockwiseContourIntegral;\u6233oss;\u6A2Fcr;\uC000\u{1D49E}p\u0100;C\u0284\u0285\u62D3ap;\u624D\u0580DJSZacefios\u02A0\u02AC\u02B0\u02B4\u02B8\u02CB\u02D7\u02E1\u02E6\u0333\u048D\u0100;o\u0179\u02A5trahd;\u6911cy;\u4402cy;\u4405cy;\u440F\u0180grs\u02BF\u02C4\u02C7ger;\u6021r;\u61A1hv;\u6AE4\u0100ay\u02D0\u02D5ron;\u410E;\u4414l\u0100;t\u02DD\u02DE\u6207a;\u4394r;\uC000\u{1D507}\u0100af\u02EB\u0327\u0100cm\u02F0\u0322ritical\u0200ADGT\u0300\u0306\u0316\u031Ccute;\u40B4o\u0174\u030B\u030D;\u42D9bleAcute;\u42DDrave;\u4060ilde;\u42DCond;\u62C4ferentialD;\u6146\u0470\u033D\0\0\0\u0342\u0354\0\u0405f;\uC000\u{1D53B}\u0180;DE\u0348\u0349\u034D\u40A8ot;\u60DCqual;\u6250ble\u0300CDLRUV\u0363\u0372\u0382\u03CF\u03E2\u03F8ontourIntegra\xEC\u0239o\u0274\u0379\0\0\u037B\xBB\u0349nArrow;\u61D3\u0100eo\u0387\u03A4ft\u0180ART\u0390\u0396\u03A1rrow;\u61D0ightArrow;\u61D4e\xE5\u02CAng\u0100LR\u03AB\u03C4eft\u0100AR\u03B3\u03B9rrow;\u67F8ightArrow;\u67FAightArrow;\u67F9ight\u0100AT\u03D8\u03DErrow;\u61D2ee;\u62A8p\u0241\u03E9\0\0\u03EFrrow;\u61D1ownArrow;\u61D5erticalBar;\u6225n\u0300ABLRTa\u0412\u042A\u0430\u045E\u047F\u037Crrow\u0180;BU\u041D\u041E\u0422\u6193ar;\u6913pArrow;\u61F5reve;\u4311eft\u02D2\u043A\0\u0446\0\u0450ightVector;\u6950eeVector;\u695Eector\u0100;B\u0459\u045A\u61BDar;\u6956ight\u01D4\u0467\0\u0471eeVector;\u695Fector\u0100;B\u047A\u047B\u61C1ar;\u6957ee\u0100;A\u0486\u0487\u62A4rrow;\u61A7\u0100ct\u0492\u0497r;\uC000\u{1D49F}rok;\u4110\u0800NTacdfglmopqstux\u04BD\u04C0\u04C4\u04CB\u04DE\u04E2\u04E7\u04EE\u04F5\u0521\u052F\u0536\u0552\u055D\u0560\u0565G;\u414AH\u803B\xD0\u40D0cute\u803B\xC9\u40C9\u0180aiy\u04D2\u04D7\u04DCron;\u411Arc\u803B\xCA\u40CA;\u442Dot;\u4116r;\uC000\u{1D508}rave\u803B\xC8\u40C8ement;\u6208\u0100ap\u04FA\u04FEcr;\u4112ty\u0253\u0506\0\0\u0512mallSquare;\u65FBerySmallSquare;\u65AB\u0100gp\u0526\u052Aon;\u4118f;\uC000\u{1D53C}silon;\u4395u\u0100ai\u053C\u0549l\u0100;T\u0542\u0543\u6A75ilde;\u6242librium;\u61CC\u0100ci\u0557\u055Ar;\u6130m;\u6A73a;\u4397ml\u803B\xCB\u40CB\u0100ip\u056A\u056Fsts;\u6203onentialE;\u6147\u0280cfios\u0585\u0588\u058D\u05B2\u05CCy;\u4424r;\uC000\u{1D509}lled\u0253\u0597\0\0\u05A3mallSquare;\u65FCerySmallSquare;\u65AA\u0370\u05BA\0\u05BF\0\0\u05C4f;\uC000\u{1D53D}All;\u6200riertrf;\u6131c\xF2\u05CB\u0600JTabcdfgorst\u05E8\u05EC\u05EF\u05FA\u0600\u0612\u0616\u061B\u061D\u0623\u066C\u0672cy;\u4403\u803B>\u403Emma\u0100;d\u05F7\u05F8\u4393;\u43DCreve;\u411E\u0180eiy\u0607\u060C\u0610dil;\u4122rc;\u411C;\u4413ot;\u4120r;\uC000\u{1D50A};\u62D9pf;\uC000\u{1D53E}eater\u0300EFGLST\u0635\u0644\u064E\u0656\u065B\u0666qual\u0100;L\u063E\u063F\u6265ess;\u62DBullEqual;\u6267reater;\u6AA2ess;\u6277lantEqual;\u6A7Eilde;\u6273cr;\uC000\u{1D4A2};\u626B\u0400Aacfiosu\u0685\u068B\u0696\u069B\u069E\u06AA\u06BE\u06CARDcy;\u442A\u0100ct\u0690\u0694ek;\u42C7;\u405Eirc;\u4124r;\u610ClbertSpace;\u610B\u01F0\u06AF\0\u06B2f;\u610DizontalLine;\u6500\u0100ct\u06C3\u06C5\xF2\u06A9rok;\u4126mp\u0144\u06D0\u06D8ownHum\xF0\u012Fqual;\u624F\u0700EJOacdfgmnostu\u06FA\u06FE\u0703\u0707\u070E\u071A\u071E\u0721\u0728\u0744\u0778\u078B\u078F\u0795cy;\u4415lig;\u4132cy;\u4401cute\u803B\xCD\u40CD\u0100iy\u0713\u0718rc\u803B\xCE\u40CE;\u4418ot;\u4130r;\u6111rave\u803B\xCC\u40CC\u0180;ap\u0720\u072F\u073F\u0100cg\u0734\u0737r;\u412AinaryI;\u6148lie\xF3\u03DD\u01F4\u0749\0\u0762\u0100;e\u074D\u074E\u622C\u0100gr\u0753\u0758ral;\u622Bsection;\u62C2isible\u0100CT\u076C\u0772omma;\u6063imes;\u6062\u0180gpt\u077F\u0783\u0788on;\u412Ef;\uC000\u{1D540}a;\u4399cr;\u6110ilde;\u4128\u01EB\u079A\0\u079Ecy;\u4406l\u803B\xCF\u40CF\u0280cfosu\u07AC\u07B7\u07BC\u07C2\u07D0\u0100iy\u07B1\u07B5rc;\u4134;\u4419r;\uC000\u{1D50D}pf;\uC000\u{1D541}\u01E3\u07C7\0\u07CCr;\uC000\u{1D4A5}rcy;\u4408kcy;\u4404\u0380HJacfos\u07E4\u07E8\u07EC\u07F1\u07FD\u0802\u0808cy;\u4425cy;\u440Cppa;\u439A\u0100ey\u07F6\u07FBdil;\u4136;\u441Ar;\uC000\u{1D50E}pf;\uC000\u{1D542}cr;\uC000\u{1D4A6}\u0580JTaceflmost\u0825\u0829\u082C\u0850\u0863\u09B3\u09B8\u09C7\u09CD\u0A37\u0A47cy;\u4409\u803B<\u403C\u0280cmnpr\u0837\u083C\u0841\u0844\u084Dute;\u4139bda;\u439Bg;\u67EAlacetrf;\u6112r;\u619E\u0180aey\u0857\u085C\u0861ron;\u413Ddil;\u413B;\u441B\u0100fs\u0868\u0970t\u0500ACDFRTUVar\u087E\u08A9\u08B1\u08E0\u08E6\u08FC\u092F\u095B\u0390\u096A\u0100nr\u0883\u088FgleBracket;\u67E8row\u0180;BR\u0899\u089A\u089E\u6190ar;\u61E4ightArrow;\u61C6eiling;\u6308o\u01F5\u08B7\0\u08C3bleBracket;\u67E6n\u01D4\u08C8\0\u08D2eeVector;\u6961ector\u0100;B\u08DB\u08DC\u61C3ar;\u6959loor;\u630Aight\u0100AV\u08EF\u08F5rrow;\u6194ector;\u694E\u0100er\u0901\u0917e\u0180;AV\u0909\u090A\u0910\u62A3rrow;\u61A4ector;\u695Aiangle\u0180;BE\u0924\u0925\u0929\u62B2ar;\u69CFqual;\u62B4p\u0180DTV\u0937\u0942\u094CownVector;\u6951eeVector;\u6960ector\u0100;B\u0956\u0957\u61BFar;\u6958ector\u0100;B\u0965\u0966\u61BCar;\u6952ight\xE1\u039Cs\u0300EFGLST\u097E\u098B\u0995\u099D\u09A2\u09ADqualGreater;\u62DAullEqual;\u6266reater;\u6276ess;\u6AA1lantEqual;\u6A7Dilde;\u6272r;\uC000\u{1D50F}\u0100;e\u09BD\u09BE\u62D8ftarrow;\u61DAidot;\u413F\u0180npw\u09D4\u0A16\u0A1Bg\u0200LRlr\u09DE\u09F7\u0A02\u0A10eft\u0100AR\u09E6\u09ECrrow;\u67F5ightArrow;\u67F7ightArrow;\u67F6eft\u0100ar\u03B3\u0A0Aight\xE1\u03BFight\xE1\u03CAf;\uC000\u{1D543}er\u0100LR\u0A22\u0A2CeftArrow;\u6199ightArrow;\u6198\u0180cht\u0A3E\u0A40\u0A42\xF2\u084C;\u61B0rok;\u4141;\u626A\u0400acefiosu\u0A5A\u0A5D\u0A60\u0A77\u0A7C\u0A85\u0A8B\u0A8Ep;\u6905y;\u441C\u0100dl\u0A65\u0A6FiumSpace;\u605Flintrf;\u6133r;\uC000\u{1D510}nusPlus;\u6213pf;\uC000\u{1D544}c\xF2\u0A76;\u439C\u0480Jacefostu\u0AA3\u0AA7\u0AAD\u0AC0\u0B14\u0B19\u0D91\u0D97\u0D9Ecy;\u440Acute;\u4143\u0180aey\u0AB4\u0AB9\u0ABEron;\u4147dil;\u4145;\u441D\u0180gsw\u0AC7\u0AF0\u0B0Eative\u0180MTV\u0AD3\u0ADF\u0AE8ediumSpace;\u600Bhi\u0100cn\u0AE6\u0AD8\xEB\u0AD9eryThi\xEE\u0AD9ted\u0100GL\u0AF8\u0B06reaterGreate\xF2\u0673essLes\xF3\u0A48Line;\u400Ar;\uC000\u{1D511}\u0200Bnpt\u0B22\u0B28\u0B37\u0B3Areak;\u6060BreakingSpace;\u40A0f;\u6115\u0680;CDEGHLNPRSTV\u0B55\u0B56\u0B6A\u0B7C\u0BA1\u0BEB\u0C04\u0C5E\u0C84\u0CA6\u0CD8\u0D61\u0D85\u6AEC\u0100ou\u0B5B\u0B64ngruent;\u6262pCap;\u626DoubleVerticalBar;\u6226\u0180lqx\u0B83\u0B8A\u0B9Bement;\u6209ual\u0100;T\u0B92\u0B93\u6260ilde;\uC000\u2242\u0338ists;\u6204reater\u0380;EFGLST\u0BB6\u0BB7\u0BBD\u0BC9\u0BD3\u0BD8\u0BE5\u626Fqual;\u6271ullEqual;\uC000\u2267\u0338reater;\uC000\u226B\u0338ess;\u6279lantEqual;\uC000\u2A7E\u0338ilde;\u6275ump\u0144\u0BF2\u0BFDownHump;\uC000\u224E\u0338qual;\uC000\u224F\u0338e\u0100fs\u0C0A\u0C27tTriangle\u0180;BE\u0C1A\u0C1B\u0C21\u62EAar;\uC000\u29CF\u0338qual;\u62ECs\u0300;EGLST\u0C35\u0C36\u0C3C\u0C44\u0C4B\u0C58\u626Equal;\u6270reater;\u6278ess;\uC000\u226A\u0338lantEqual;\uC000\u2A7D\u0338ilde;\u6274ested\u0100GL\u0C68\u0C79reaterGreater;\uC000\u2AA2\u0338essLess;\uC000\u2AA1\u0338recedes\u0180;ES\u0C92\u0C93\u0C9B\u6280qual;\uC000\u2AAF\u0338lantEqual;\u62E0\u0100ei\u0CAB\u0CB9verseElement;\u620CghtTriangle\u0180;BE\u0CCB\u0CCC\u0CD2\u62EBar;\uC000\u29D0\u0338qual;\u62ED\u0100qu\u0CDD\u0D0CuareSu\u0100bp\u0CE8\u0CF9set\u0100;E\u0CF0\u0CF3\uC000\u228F\u0338qual;\u62E2erset\u0100;E\u0D03\u0D06\uC000\u2290\u0338qual;\u62E3\u0180bcp\u0D13\u0D24\u0D4Eset\u0100;E\u0D1B\u0D1E\uC000\u2282\u20D2qual;\u6288ceeds\u0200;EST\u0D32\u0D33\u0D3B\u0D46\u6281qual;\uC000\u2AB0\u0338lantEqual;\u62E1ilde;\uC000\u227F\u0338erset\u0100;E\u0D58\u0D5B\uC000\u2283\u20D2qual;\u6289ilde\u0200;EFT\u0D6E\u0D6F\u0D75\u0D7F\u6241qual;\u6244ullEqual;\u6247ilde;\u6249erticalBar;\u6224cr;\uC000\u{1D4A9}ilde\u803B\xD1\u40D1;\u439D\u0700Eacdfgmoprstuv\u0DBD\u0DC2\u0DC9\u0DD5\u0DDB\u0DE0\u0DE7\u0DFC\u0E02\u0E20\u0E22\u0E32\u0E3F\u0E44lig;\u4152cute\u803B\xD3\u40D3\u0100iy\u0DCE\u0DD3rc\u803B\xD4\u40D4;\u441Eblac;\u4150r;\uC000\u{1D512}rave\u803B\xD2\u40D2\u0180aei\u0DEE\u0DF2\u0DF6cr;\u414Cga;\u43A9cron;\u439Fpf;\uC000\u{1D546}enCurly\u0100DQ\u0E0E\u0E1AoubleQuote;\u601Cuote;\u6018;\u6A54\u0100cl\u0E27\u0E2Cr;\uC000\u{1D4AA}ash\u803B\xD8\u40D8i\u016C\u0E37\u0E3Cde\u803B\xD5\u40D5es;\u6A37ml\u803B\xD6\u40D6er\u0100BP\u0E4B\u0E60\u0100ar\u0E50\u0E53r;\u603Eac\u0100ek\u0E5A\u0E5C;\u63DEet;\u63B4arenthesis;\u63DC\u0480acfhilors\u0E7F\u0E87\u0E8A\u0E8F\u0E92\u0E94\u0E9D\u0EB0\u0EFCrtialD;\u6202y;\u441Fr;\uC000\u{1D513}i;\u43A6;\u43A0usMinus;\u40B1\u0100ip\u0EA2\u0EADncareplan\xE5\u069Df;\u6119\u0200;eio\u0EB9\u0EBA\u0EE0\u0EE4\u6ABBcedes\u0200;EST\u0EC8\u0EC9\u0ECF\u0EDA\u627Aqual;\u6AAFlantEqual;\u627Cilde;\u627Eme;\u6033\u0100dp\u0EE9\u0EEEuct;\u620Fortion\u0100;a\u0225\u0EF9l;\u621D\u0100ci\u0F01\u0F06r;\uC000\u{1D4AB};\u43A8\u0200Ufos\u0F11\u0F16\u0F1B\u0F1FOT\u803B"\u4022r;\uC000\u{1D514}pf;\u611Acr;\uC000\u{1D4AC}\u0600BEacefhiorsu\u0F3E\u0F43\u0F47\u0F60\u0F73\u0FA7\u0FAA\u0FAD\u1096\u10A9\u10B4\u10BEarr;\u6910G\u803B\xAE\u40AE\u0180cnr\u0F4E\u0F53\u0F56ute;\u4154g;\u67EBr\u0100;t\u0F5C\u0F5D\u61A0l;\u6916\u0180aey\u0F67\u0F6C\u0F71ron;\u4158dil;\u4156;\u4420\u0100;v\u0F78\u0F79\u611Cerse\u0100EU\u0F82\u0F99\u0100lq\u0F87\u0F8Eement;\u620Builibrium;\u61CBpEquilibrium;\u696Fr\xBB\u0F79o;\u43A1ght\u0400ACDFTUVa\u0FC1\u0FEB\u0FF3\u1022\u1028\u105B\u1087\u03D8\u0100nr\u0FC6\u0FD2gleBracket;\u67E9row\u0180;BL\u0FDC\u0FDD\u0FE1\u6192ar;\u61E5eftArrow;\u61C4eiling;\u6309o\u01F5\u0FF9\0\u1005bleBracket;\u67E7n\u01D4\u100A\0\u1014eeVector;\u695Dector\u0100;B\u101D\u101E\u61C2ar;\u6955loor;\u630B\u0100er\u102D\u1043e\u0180;AV\u1035\u1036\u103C\u62A2rrow;\u61A6ector;\u695Biangle\u0180;BE\u1050\u1051\u1055\u62B3ar;\u69D0qual;\u62B5p\u0180DTV\u1063\u106E\u1078ownVector;\u694FeeVector;\u695Cector\u0100;B\u1082\u1083\u61BEar;\u6954ector\u0100;B\u1091\u1092\u61C0ar;\u6953\u0100pu\u109B\u109Ef;\u611DndImplies;\u6970ightarrow;\u61DB\u0100ch\u10B9\u10BCr;\u611B;\u61B1leDelayed;\u69F4\u0680HOacfhimoqstu\u10E4\u10F1\u10F7\u10FD\u1119\u111E\u1151\u1156\u1161\u1167\u11B5\u11BB\u11BF\u0100Cc\u10E9\u10EEHcy;\u4429y;\u4428FTcy;\u442Ccute;\u415A\u0280;aeiy\u1108\u1109\u110E\u1113\u1117\u6ABCron;\u4160dil;\u415Erc;\u415C;\u4421r;\uC000\u{1D516}ort\u0200DLRU\u112A\u1134\u113E\u1149ownArrow\xBB\u041EeftArrow\xBB\u089AightArrow\xBB\u0FDDpArrow;\u6191gma;\u43A3allCircle;\u6218pf;\uC000\u{1D54A}\u0272\u116D\0\0\u1170t;\u621Aare\u0200;ISU\u117B\u117C\u1189\u11AF\u65A1ntersection;\u6293u\u0100bp\u118F\u119Eset\u0100;E\u1197\u1198\u628Fqual;\u6291erset\u0100;E\u11A8\u11A9\u6290qual;\u6292nion;\u6294cr;\uC000\u{1D4AE}ar;\u62C6\u0200bcmp\u11C8\u11DB\u1209\u120B\u0100;s\u11CD\u11CE\u62D0et\u0100;E\u11CD\u11D5qual;\u6286\u0100ch\u11E0\u1205eeds\u0200;EST\u11ED\u11EE\u11F4\u11FF\u627Bqual;\u6AB0lantEqual;\u627Dilde;\u627FTh\xE1\u0F8C;\u6211\u0180;es\u1212\u1213\u1223\u62D1rset\u0100;E\u121C\u121D\u6283qual;\u6287et\xBB\u1213\u0580HRSacfhiors\u123E\u1244\u1249\u1255\u125E\u1271\u1276\u129F\u12C2\u12C8\u12D1ORN\u803B\xDE\u40DEADE;\u6122\u0100Hc\u124E\u1252cy;\u440By;\u4426\u0100bu\u125A\u125C;\u4009;\u43A4\u0180aey\u1265\u126A\u126Fron;\u4164dil;\u4162;\u4422r;\uC000\u{1D517}\u0100ei\u127B\u1289\u01F2\u1280\0\u1287efore;\u6234a;\u4398\u0100cn\u128E\u1298kSpace;\uC000\u205F\u200ASpace;\u6009lde\u0200;EFT\u12AB\u12AC\u12B2\u12BC\u623Cqual;\u6243ullEqual;\u6245ilde;\u6248pf;\uC000\u{1D54B}ipleDot;\u60DB\u0100ct\u12D6\u12DBr;\uC000\u{1D4AF}rok;\u4166\u0AE1\u12F7\u130E\u131A\u1326\0\u132C\u1331\0\0\0\0\0\u1338\u133D\u1377\u1385\0\u13FF\u1404\u140A\u1410\u0100cr\u12FB\u1301ute\u803B\xDA\u40DAr\u0100;o\u1307\u1308\u619Fcir;\u6949r\u01E3\u1313\0\u1316y;\u440Eve;\u416C\u0100iy\u131E\u1323rc\u803B\xDB\u40DB;\u4423blac;\u4170r;\uC000\u{1D518}rave\u803B\xD9\u40D9acr;\u416A\u0100di\u1341\u1369er\u0100BP\u1348\u135D\u0100ar\u134D\u1350r;\u405Fac\u0100ek\u1357\u1359;\u63DFet;\u63B5arenthesis;\u63DDon\u0100;P\u1370\u1371\u62C3lus;\u628E\u0100gp\u137B\u137Fon;\u4172f;\uC000\u{1D54C}\u0400ADETadps\u1395\u13AE\u13B8\u13C4\u03E8\u13D2\u13D7\u13F3rrow\u0180;BD\u1150\u13A0\u13A4ar;\u6912ownArrow;\u61C5ownArrow;\u6195quilibrium;\u696Eee\u0100;A\u13CB\u13CC\u62A5rrow;\u61A5own\xE1\u03F3er\u0100LR\u13DE\u13E8eftArrow;\u6196ightArrow;\u6197i\u0100;l\u13F9\u13FA\u43D2on;\u43A5ing;\u416Ecr;\uC000\u{1D4B0}ilde;\u4168ml\u803B\xDC\u40DC\u0480Dbcdefosv\u1427\u142C\u1430\u1433\u143E\u1485\u148A\u1490\u1496ash;\u62ABar;\u6AEBy;\u4412ash\u0100;l\u143B\u143C\u62A9;\u6AE6\u0100er\u1443\u1445;\u62C1\u0180bty\u144C\u1450\u147Aar;\u6016\u0100;i\u144F\u1455cal\u0200BLST\u1461\u1465\u146A\u1474ar;\u6223ine;\u407Ceparator;\u6758ilde;\u6240ThinSpace;\u600Ar;\uC000\u{1D519}pf;\uC000\u{1D54D}cr;\uC000\u{1D4B1}dash;\u62AA\u0280cefos\u14A7\u14AC\u14B1\u14B6\u14BCirc;\u4174dge;\u62C0r;\uC000\u{1D51A}pf;\uC000\u{1D54E}cr;\uC000\u{1D4B2}\u0200fios\u14CB\u14D0\u14D2\u14D8r;\uC000\u{1D51B};\u439Epf;\uC000\u{1D54F}cr;\uC000\u{1D4B3}\u0480AIUacfosu\u14F1\u14F5\u14F9\u14FD\u1504\u150F\u1514\u151A\u1520cy;\u442Fcy;\u4407cy;\u442Ecute\u803B\xDD\u40DD\u0100iy\u1509\u150Drc;\u4176;\u442Br;\uC000\u{1D51C}pf;\uC000\u{1D550}cr;\uC000\u{1D4B4}ml;\u4178\u0400Hacdefos\u1535\u1539\u153F\u154B\u154F\u155D\u1560\u1564cy;\u4416cute;\u4179\u0100ay\u1544\u1549ron;\u417D;\u4417ot;\u417B\u01F2\u1554\0\u155BoWidt\xE8\u0AD9a;\u4396r;\u6128pf;\u6124cr;\uC000\u{1D4B5}\u0BE1\u1583\u158A\u1590\0\u15B0\u15B6\u15BF\0\0\0\0\u15C6\u15DB\u15EB\u165F\u166D\0\u1695\u169B\u16B2\u16B9\0\u16BEcute\u803B\xE1\u40E1reve;\u4103\u0300;Ediuy\u159C\u159D\u15A1\u15A3\u15A8\u15AD\u623E;\uC000\u223E\u0333;\u623Frc\u803B\xE2\u40E2te\u80BB\xB4\u0306;\u4430lig\u803B\xE6\u40E6\u0100;r\xB2\u15BA;\uC000\u{1D51E}rave\u803B\xE0\u40E0\u0100ep\u15CA\u15D6\u0100fp\u15CF\u15D4sym;\u6135\xE8\u15D3ha;\u43B1\u0100ap\u15DFc\u0100cl\u15E4\u15E7r;\u4101g;\u6A3F\u0264\u15F0\0\0\u160A\u0280;adsv\u15FA\u15FB\u15FF\u1601\u1607\u6227nd;\u6A55;\u6A5Clope;\u6A58;\u6A5A\u0380;elmrsz\u1618\u1619\u161B\u161E\u163F\u164F\u1659\u6220;\u69A4e\xBB\u1619sd\u0100;a\u1625\u1626\u6221\u0461\u1630\u1632\u1634\u1636\u1638\u163A\u163C\u163E;\u69A8;\u69A9;\u69AA;\u69AB;\u69AC;\u69AD;\u69AE;\u69AFt\u0100;v\u1645\u1646\u621Fb\u0100;d\u164C\u164D\u62BE;\u699D\u0100pt\u1654\u1657h;\u6222\xBB\xB9arr;\u637C\u0100gp\u1663\u1667on;\u4105f;\uC000\u{1D552}\u0380;Eaeiop\u12C1\u167B\u167D\u1682\u1684\u1687\u168A;\u6A70cir;\u6A6F;\u624Ad;\u624Bs;\u4027rox\u0100;e\u12C1\u1692\xF1\u1683ing\u803B\xE5\u40E5\u0180cty\u16A1\u16A6\u16A8r;\uC000\u{1D4B6};\u402Amp\u0100;e\u12C1\u16AF\xF1\u0288ilde\u803B\xE3\u40E3ml\u803B\xE4\u40E4\u0100ci\u16C2\u16C8onin\xF4\u0272nt;\u6A11\u0800Nabcdefiklnoprsu\u16ED\u16F1\u1730\u173C\u1743\u1748\u1778\u177D\u17E0\u17E6\u1839\u1850\u170D\u193D\u1948\u1970ot;\u6AED\u0100cr\u16F6\u171Ek\u0200ceps\u1700\u1705\u170D\u1713ong;\u624Cpsilon;\u43F6rime;\u6035im\u0100;e\u171A\u171B\u623Dq;\u62CD\u0176\u1722\u1726ee;\u62BDed\u0100;g\u172C\u172D\u6305e\xBB\u172Drk\u0100;t\u135C\u1737brk;\u63B6\u0100oy\u1701\u1741;\u4431quo;\u601E\u0280cmprt\u1753\u175B\u1761\u1764\u1768aus\u0100;e\u010A\u0109ptyv;\u69B0s\xE9\u170Cno\xF5\u0113\u0180ahw\u176F\u1771\u1773;\u43B2;\u6136een;\u626Cr;\uC000\u{1D51F}g\u0380costuvw\u178D\u179D\u17B3\u17C1\u17D5\u17DB\u17DE\u0180aiu\u1794\u1796\u179A\xF0\u0760rc;\u65EFp\xBB\u1371\u0180dpt\u17A4\u17A8\u17ADot;\u6A00lus;\u6A01imes;\u6A02\u0271\u17B9\0\0\u17BEcup;\u6A06ar;\u6605riangle\u0100du\u17CD\u17D2own;\u65BDp;\u65B3plus;\u6A04e\xE5\u1444\xE5\u14ADarow;\u690D\u0180ako\u17ED\u1826\u1835\u0100cn\u17F2\u1823k\u0180lst\u17FA\u05AB\u1802ozenge;\u69EBriangle\u0200;dlr\u1812\u1813\u1818\u181D\u65B4own;\u65BEeft;\u65C2ight;\u65B8k;\u6423\u01B1\u182B\0\u1833\u01B2\u182F\0\u1831;\u6592;\u65914;\u6593ck;\u6588\u0100eo\u183E\u184D\u0100;q\u1843\u1846\uC000=\u20E5uiv;\uC000\u2261\u20E5t;\u6310\u0200ptwx\u1859\u185E\u1867\u186Cf;\uC000\u{1D553}\u0100;t\u13CB\u1863om\xBB\u13CCtie;\u62C8\u0600DHUVbdhmptuv\u1885\u1896\u18AA\u18BB\u18D7\u18DB\u18EC\u18FF\u1905\u190A\u1910\u1921\u0200LRlr\u188E\u1890\u1892\u1894;\u6557;\u6554;\u6556;\u6553\u0280;DUdu\u18A1\u18A2\u18A4\u18A6\u18A8\u6550;\u6566;\u6569;\u6564;\u6567\u0200LRlr\u18B3\u18B5\u18B7\u18B9;\u655D;\u655A;\u655C;\u6559\u0380;HLRhlr\u18CA\u18CB\u18CD\u18CF\u18D1\u18D3\u18D5\u6551;\u656C;\u6563;\u6560;\u656B;\u6562;\u655Fox;\u69C9\u0200LRlr\u18E4\u18E6\u18E8\u18EA;\u6555;\u6552;\u6510;\u650C\u0280;DUdu\u06BD\u18F7\u18F9\u18FB\u18FD;\u6565;\u6568;\u652C;\u6534inus;\u629Flus;\u629Eimes;\u62A0\u0200LRlr\u1919\u191B\u191D\u191F;\u655B;\u6558;\u6518;\u6514\u0380;HLRhlr\u1930\u1931\u1933\u1935\u1937\u1939\u193B\u6502;\u656A;\u6561;\u655E;\u653C;\u6524;\u651C\u0100ev\u0123\u1942bar\u803B\xA6\u40A6\u0200ceio\u1951\u1956\u195A\u1960r;\uC000\u{1D4B7}mi;\u604Fm\u0100;e\u171A\u171Cl\u0180;bh\u1968\u1969\u196B\u405C;\u69C5sub;\u67C8\u016C\u1974\u197El\u0100;e\u1979\u197A\u6022t\xBB\u197Ap\u0180;Ee\u012F\u1985\u1987;\u6AAE\u0100;q\u06DC\u06DB\u0CE1\u19A7\0\u19E8\u1A11\u1A15\u1A32\0\u1A37\u1A50\0\0\u1AB4\0\0\u1AC1\0\0\u1B21\u1B2E\u1B4D\u1B52\0\u1BFD\0\u1C0C\u0180cpr\u19AD\u19B2\u19DDute;\u4107\u0300;abcds\u19BF\u19C0\u19C4\u19CA\u19D5\u19D9\u6229nd;\u6A44rcup;\u6A49\u0100au\u19CF\u19D2p;\u6A4Bp;\u6A47ot;\u6A40;\uC000\u2229\uFE00\u0100eo\u19E2\u19E5t;\u6041\xEE\u0693\u0200aeiu\u19F0\u19FB\u1A01\u1A05\u01F0\u19F5\0\u19F8s;\u6A4Don;\u410Ddil\u803B\xE7\u40E7rc;\u4109ps\u0100;s\u1A0C\u1A0D\u6A4Cm;\u6A50ot;\u410B\u0180dmn\u1A1B\u1A20\u1A26il\u80BB\xB8\u01ADptyv;\u69B2t\u8100\xA2;e\u1A2D\u1A2E\u40A2r\xE4\u01B2r;\uC000\u{1D520}\u0180cei\u1A3D\u1A40\u1A4Dy;\u4447ck\u0100;m\u1A47\u1A48\u6713ark\xBB\u1A48;\u43C7r\u0380;Ecefms\u1A5F\u1A60\u1A62\u1A6B\u1AA4\u1AAA\u1AAE\u65CB;\u69C3\u0180;el\u1A69\u1A6A\u1A6D\u42C6q;\u6257e\u0261\u1A74\0\0\u1A88rrow\u0100lr\u1A7C\u1A81eft;\u61BAight;\u61BB\u0280RSacd\u1A92\u1A94\u1A96\u1A9A\u1A9F\xBB\u0F47;\u64C8st;\u629Birc;\u629Aash;\u629Dnint;\u6A10id;\u6AEFcir;\u69C2ubs\u0100;u\u1ABB\u1ABC\u6663it\xBB\u1ABC\u02EC\u1AC7\u1AD4\u1AFA\0\u1B0Aon\u0100;e\u1ACD\u1ACE\u403A\u0100;q\xC7\xC6\u026D\u1AD9\0\0\u1AE2a\u0100;t\u1ADE\u1ADF\u402C;\u4040\u0180;fl\u1AE8\u1AE9\u1AEB\u6201\xEE\u1160e\u0100mx\u1AF1\u1AF6ent\xBB\u1AE9e\xF3\u024D\u01E7\u1AFE\0\u1B07\u0100;d\u12BB\u1B02ot;\u6A6Dn\xF4\u0246\u0180fry\u1B10\u1B14\u1B17;\uC000\u{1D554}o\xE4\u0254\u8100\xA9;s\u0155\u1B1Dr;\u6117\u0100ao\u1B25\u1B29rr;\u61B5ss;\u6717\u0100cu\u1B32\u1B37r;\uC000\u{1D4B8}\u0100bp\u1B3C\u1B44\u0100;e\u1B41\u1B42\u6ACF;\u6AD1\u0100;e\u1B49\u1B4A\u6AD0;\u6AD2dot;\u62EF\u0380delprvw\u1B60\u1B6C\u1B77\u1B82\u1BAC\u1BD4\u1BF9arr\u0100lr\u1B68\u1B6A;\u6938;\u6935\u0270\u1B72\0\0\u1B75r;\u62DEc;\u62DFarr\u0100;p\u1B7F\u1B80\u61B6;\u693D\u0300;bcdos\u1B8F\u1B90\u1B96\u1BA1\u1BA5\u1BA8\u622Arcap;\u6A48\u0100au\u1B9B\u1B9Ep;\u6A46p;\u6A4Aot;\u628Dr;\u6A45;\uC000\u222A\uFE00\u0200alrv\u1BB5\u1BBF\u1BDE\u1BE3rr\u0100;m\u1BBC\u1BBD\u61B7;\u693Cy\u0180evw\u1BC7\u1BD4\u1BD8q\u0270\u1BCE\0\0\u1BD2re\xE3\u1B73u\xE3\u1B75ee;\u62CEedge;\u62CFen\u803B\xA4\u40A4earrow\u0100lr\u1BEE\u1BF3eft\xBB\u1B80ight\xBB\u1BBDe\xE4\u1BDD\u0100ci\u1C01\u1C07onin\xF4\u01F7nt;\u6231lcty;\u632D\u0980AHabcdefhijlorstuwz\u1C38\u1C3B\u1C3F\u1C5D\u1C69\u1C75\u1C8A\u1C9E\u1CAC\u1CB7\u1CFB\u1CFF\u1D0D\u1D7B\u1D91\u1DAB\u1DBB\u1DC6\u1DCDr\xF2\u0381ar;\u6965\u0200glrs\u1C48\u1C4D\u1C52\u1C54ger;\u6020eth;\u6138\xF2\u1133h\u0100;v\u1C5A\u1C5B\u6010\xBB\u090A\u016B\u1C61\u1C67arow;\u690Fa\xE3\u0315\u0100ay\u1C6E\u1C73ron;\u410F;\u4434\u0180;ao\u0332\u1C7C\u1C84\u0100gr\u02BF\u1C81r;\u61CAtseq;\u6A77\u0180glm\u1C91\u1C94\u1C98\u803B\xB0\u40B0ta;\u43B4ptyv;\u69B1\u0100ir\u1CA3\u1CA8sht;\u697F;\uC000\u{1D521}ar\u0100lr\u1CB3\u1CB5\xBB\u08DC\xBB\u101E\u0280aegsv\u1CC2\u0378\u1CD6\u1CDC\u1CE0m\u0180;os\u0326\u1CCA\u1CD4nd\u0100;s\u0326\u1CD1uit;\u6666amma;\u43DDin;\u62F2\u0180;io\u1CE7\u1CE8\u1CF8\u40F7de\u8100\xF7;o\u1CE7\u1CF0ntimes;\u62C7n\xF8\u1CF7cy;\u4452c\u026F\u1D06\0\0\u1D0Arn;\u631Eop;\u630D\u0280lptuw\u1D18\u1D1D\u1D22\u1D49\u1D55lar;\u4024f;\uC000\u{1D555}\u0280;emps\u030B\u1D2D\u1D37\u1D3D\u1D42q\u0100;d\u0352\u1D33ot;\u6251inus;\u6238lus;\u6214quare;\u62A1blebarwedg\xE5\xFAn\u0180adh\u112E\u1D5D\u1D67ownarrow\xF3\u1C83arpoon\u0100lr\u1D72\u1D76ef\xF4\u1CB4igh\xF4\u1CB6\u0162\u1D7F\u1D85karo\xF7\u0F42\u026F\u1D8A\0\0\u1D8Ern;\u631Fop;\u630C\u0180cot\u1D98\u1DA3\u1DA6\u0100ry\u1D9D\u1DA1;\uC000\u{1D4B9};\u4455l;\u69F6rok;\u4111\u0100dr\u1DB0\u1DB4ot;\u62F1i\u0100;f\u1DBA\u1816\u65BF\u0100ah\u1DC0\u1DC3r\xF2\u0429a\xF2\u0FA6angle;\u69A6\u0100ci\u1DD2\u1DD5y;\u445Fgrarr;\u67FF\u0900Dacdefglmnopqrstux\u1E01\u1E09\u1E19\u1E38\u0578\u1E3C\u1E49\u1E61\u1E7E\u1EA5\u1EAF\u1EBD\u1EE1\u1F2A\u1F37\u1F44\u1F4E\u1F5A\u0100Do\u1E06\u1D34o\xF4\u1C89\u0100cs\u1E0E\u1E14ute\u803B\xE9\u40E9ter;\u6A6E\u0200aioy\u1E22\u1E27\u1E31\u1E36ron;\u411Br\u0100;c\u1E2D\u1E2E\u6256\u803B\xEA\u40EAlon;\u6255;\u444Dot;\u4117\u0100Dr\u1E41\u1E45ot;\u6252;\uC000\u{1D522}\u0180;rs\u1E50\u1E51\u1E57\u6A9Aave\u803B\xE8\u40E8\u0100;d\u1E5C\u1E5D\u6A96ot;\u6A98\u0200;ils\u1E6A\u1E6B\u1E72\u1E74\u6A99nters;\u63E7;\u6113\u0100;d\u1E79\u1E7A\u6A95ot;\u6A97\u0180aps\u1E85\u1E89\u1E97cr;\u4113ty\u0180;sv\u1E92\u1E93\u1E95\u6205et\xBB\u1E93p\u01001;\u1E9D\u1EA4\u0133\u1EA1\u1EA3;\u6004;\u6005\u6003\u0100gs\u1EAA\u1EAC;\u414Bp;\u6002\u0100gp\u1EB4\u1EB8on;\u4119f;\uC000\u{1D556}\u0180als\u1EC4\u1ECE\u1ED2r\u0100;s\u1ECA\u1ECB\u62D5l;\u69E3us;\u6A71i\u0180;lv\u1EDA\u1EDB\u1EDF\u43B5on\xBB\u1EDB;\u43F5\u0200csuv\u1EEA\u1EF3\u1F0B\u1F23\u0100io\u1EEF\u1E31rc\xBB\u1E2E\u0269\u1EF9\0\0\u1EFB\xED\u0548ant\u0100gl\u1F02\u1F06tr\xBB\u1E5Dess\xBB\u1E7A\u0180aei\u1F12\u1F16\u1F1Als;\u403Dst;\u625Fv\u0100;D\u0235\u1F20D;\u6A78parsl;\u69E5\u0100Da\u1F2F\u1F33ot;\u6253rr;\u6971\u0180cdi\u1F3E\u1F41\u1EF8r;\u612Fo\xF4\u0352\u0100ah\u1F49\u1F4B;\u43B7\u803B\xF0\u40F0\u0100mr\u1F53\u1F57l\u803B\xEB\u40EBo;\u60AC\u0180cip\u1F61\u1F64\u1F67l;\u4021s\xF4\u056E\u0100eo\u1F6C\u1F74ctatio\xEE\u0559nential\xE5\u0579\u09E1\u1F92\0\u1F9E\0\u1FA1\u1FA7\0\0\u1FC6\u1FCC\0\u1FD3\0\u1FE6\u1FEA\u2000\0\u2008\u205Allingdotse\xF1\u1E44y;\u4444male;\u6640\u0180ilr\u1FAD\u1FB3\u1FC1lig;\u8000\uFB03\u0269\u1FB9\0\0\u1FBDg;\u8000\uFB00ig;\u8000\uFB04;\uC000\u{1D523}lig;\u8000\uFB01lig;\uC000fj\u0180alt\u1FD9\u1FDC\u1FE1t;\u666Dig;\u8000\uFB02ns;\u65B1of;\u4192\u01F0\u1FEE\0\u1FF3f;\uC000\u{1D557}\u0100ak\u05BF\u1FF7\u0100;v\u1FFC\u1FFD\u62D4;\u6AD9artint;\u6A0D\u0100ao\u200C\u2055\u0100cs\u2011\u2052\u03B1\u201A\u2030\u2038\u2045\u2048\0\u2050\u03B2\u2022\u2025\u2027\u202A\u202C\0\u202E\u803B\xBD\u40BD;\u6153\u803B\xBC\u40BC;\u6155;\u6159;\u615B\u01B3\u2034\0\u2036;\u6154;\u6156\u02B4\u203E\u2041\0\0\u2043\u803B\xBE\u40BE;\u6157;\u615C5;\u6158\u01B6\u204C\0\u204E;\u615A;\u615D8;\u615El;\u6044wn;\u6322cr;\uC000\u{1D4BB}\u0880Eabcdefgijlnorstv\u2082\u2089\u209F\u20A5\u20B0\u20B4\u20F0\u20F5\u20FA\u20FF\u2103\u2112\u2138\u0317\u213E\u2152\u219E\u0100;l\u064D\u2087;\u6A8C\u0180cmp\u2090\u2095\u209Dute;\u41F5ma\u0100;d\u209C\u1CDA\u43B3;\u6A86reve;\u411F\u0100iy\u20AA\u20AErc;\u411D;\u4433ot;\u4121\u0200;lqs\u063E\u0642\u20BD\u20C9\u0180;qs\u063E\u064C\u20C4lan\xF4\u0665\u0200;cdl\u0665\u20D2\u20D5\u20E5c;\u6AA9ot\u0100;o\u20DC\u20DD\u6A80\u0100;l\u20E2\u20E3\u6A82;\u6A84\u0100;e\u20EA\u20ED\uC000\u22DB\uFE00s;\u6A94r;\uC000\u{1D524}\u0100;g\u0673\u061Bmel;\u6137cy;\u4453\u0200;Eaj\u065A\u210C\u210E\u2110;\u6A92;\u6AA5;\u6AA4\u0200Eaes\u211B\u211D\u2129\u2134;\u6269p\u0100;p\u2123\u2124\u6A8Arox\xBB\u2124\u0100;q\u212E\u212F\u6A88\u0100;q\u212E\u211Bim;\u62E7pf;\uC000\u{1D558}\u0100ci\u2143\u2146r;\u610Am\u0180;el\u066B\u214E\u2150;\u6A8E;\u6A90\u8300>;cdlqr\u05EE\u2160\u216A\u216E\u2173\u2179\u0100ci\u2165\u2167;\u6AA7r;\u6A7Aot;\u62D7Par;\u6995uest;\u6A7C\u0280adels\u2184\u216A\u2190\u0656\u219B\u01F0\u2189\0\u218Epro\xF8\u209Er;\u6978q\u0100lq\u063F\u2196les\xF3\u2088i\xED\u066B\u0100en\u21A3\u21ADrtneqq;\uC000\u2269\uFE00\xC5\u21AA\u0500Aabcefkosy\u21C4\u21C7\u21F1\u21F5\u21FA\u2218\u221D\u222F\u2268\u227Dr\xF2\u03A0\u0200ilmr\u21D0\u21D4\u21D7\u21DBrs\xF0\u1484f\xBB\u2024il\xF4\u06A9\u0100dr\u21E0\u21E4cy;\u444A\u0180;cw\u08F4\u21EB\u21EFir;\u6948;\u61ADar;\u610Firc;\u4125\u0180alr\u2201\u220E\u2213rts\u0100;u\u2209\u220A\u6665it\xBB\u220Alip;\u6026con;\u62B9r;\uC000\u{1D525}s\u0100ew\u2223\u2229arow;\u6925arow;\u6926\u0280amopr\u223A\u223E\u2243\u225E\u2263rr;\u61FFtht;\u623Bk\u0100lr\u2249\u2253eftarrow;\u61A9ightarrow;\u61AAf;\uC000\u{1D559}bar;\u6015\u0180clt\u226F\u2274\u2278r;\uC000\u{1D4BD}as\xE8\u21F4rok;\u4127\u0100bp\u2282\u2287ull;\u6043hen\xBB\u1C5B\u0AE1\u22A3\0\u22AA\0\u22B8\u22C5\u22CE\0\u22D5\u22F3\0\0\u22F8\u2322\u2367\u2362\u237F\0\u2386\u23AA\u23B4cute\u803B\xED\u40ED\u0180;iy\u0771\u22B0\u22B5rc\u803B\xEE\u40EE;\u4438\u0100cx\u22BC\u22BFy;\u4435cl\u803B\xA1\u40A1\u0100fr\u039F\u22C9;\uC000\u{1D526}rave\u803B\xEC\u40EC\u0200;ino\u073E\u22DD\u22E9\u22EE\u0100in\u22E2\u22E6nt;\u6A0Ct;\u622Dfin;\u69DCta;\u6129lig;\u4133\u0180aop\u22FE\u231A\u231D\u0180cgt\u2305\u2308\u2317r;\u412B\u0180elp\u071F\u230F\u2313in\xE5\u078Ear\xF4\u0720h;\u4131f;\u62B7ed;\u41B5\u0280;cfot\u04F4\u232C\u2331\u233D\u2341are;\u6105in\u0100;t\u2338\u2339\u621Eie;\u69DDdo\xF4\u2319\u0280;celp\u0757\u234C\u2350\u235B\u2361al;\u62BA\u0100gr\u2355\u2359er\xF3\u1563\xE3\u234Darhk;\u6A17rod;\u6A3C\u0200cgpt\u236F\u2372\u2376\u237By;\u4451on;\u412Ff;\uC000\u{1D55A}a;\u43B9uest\u803B\xBF\u40BF\u0100ci\u238A\u238Fr;\uC000\u{1D4BE}n\u0280;Edsv\u04F4\u239B\u239D\u23A1\u04F3;\u62F9ot;\u62F5\u0100;v\u23A6\u23A7\u62F4;\u62F3\u0100;i\u0777\u23AElde;\u4129\u01EB\u23B8\0\u23BCcy;\u4456l\u803B\xEF\u40EF\u0300cfmosu\u23CC\u23D7\u23DC\u23E1\u23E7\u23F5\u0100iy\u23D1\u23D5rc;\u4135;\u4439r;\uC000\u{1D527}ath;\u4237pf;\uC000\u{1D55B}\u01E3\u23EC\0\u23F1r;\uC000\u{1D4BF}rcy;\u4458kcy;\u4454\u0400acfghjos\u240B\u2416\u2422\u2427\u242D\u2431\u2435\u243Bppa\u0100;v\u2413\u2414\u43BA;\u43F0\u0100ey\u241B\u2420dil;\u4137;\u443Ar;\uC000\u{1D528}reen;\u4138cy;\u4445cy;\u445Cpf;\uC000\u{1D55C}cr;\uC000\u{1D4C0}\u0B80ABEHabcdefghjlmnoprstuv\u2470\u2481\u2486\u248D\u2491\u250E\u253D\u255A\u2580\u264E\u265E\u2665\u2679\u267D\u269A\u26B2\u26D8\u275D\u2768\u278B\u27C0\u2801\u2812\u0180art\u2477\u247A\u247Cr\xF2\u09C6\xF2\u0395ail;\u691Barr;\u690E\u0100;g\u0994\u248B;\u6A8Bar;\u6962\u0963\u24A5\0\u24AA\0\u24B1\0\0\0\0\0\u24B5\u24BA\0\u24C6\u24C8\u24CD\0\u24F9ute;\u413Amptyv;\u69B4ra\xEE\u084Cbda;\u43BBg\u0180;dl\u088E\u24C1\u24C3;\u6991\xE5\u088E;\u6A85uo\u803B\xAB\u40ABr\u0400;bfhlpst\u0899\u24DE\u24E6\u24E9\u24EB\u24EE\u24F1\u24F5\u0100;f\u089D\u24E3s;\u691Fs;\u691D\xEB\u2252p;\u61ABl;\u6939im;\u6973l;\u61A2\u0180;ae\u24FF\u2500\u2504\u6AABil;\u6919\u0100;s\u2509\u250A\u6AAD;\uC000\u2AAD\uFE00\u0180abr\u2515\u2519\u251Drr;\u690Crk;\u6772\u0100ak\u2522\u252Cc\u0100ek\u2528\u252A;\u407B;\u405B\u0100es\u2531\u2533;\u698Bl\u0100du\u2539\u253B;\u698F;\u698D\u0200aeuy\u2546\u254B\u2556\u2558ron;\u413E\u0100di\u2550\u2554il;\u413C\xEC\u08B0\xE2\u2529;\u443B\u0200cqrs\u2563\u2566\u256D\u257Da;\u6936uo\u0100;r\u0E19\u1746\u0100du\u2572\u2577har;\u6967shar;\u694Bh;\u61B2\u0280;fgqs\u258B\u258C\u0989\u25F3\u25FF\u6264t\u0280ahlrt\u2598\u25A4\u25B7\u25C2\u25E8rrow\u0100;t\u0899\u25A1a\xE9\u24F6arpoon\u0100du\u25AF\u25B4own\xBB\u045Ap\xBB\u0966eftarrows;\u61C7ight\u0180ahs\u25CD\u25D6\u25DErrow\u0100;s\u08F4\u08A7arpoon\xF3\u0F98quigarro\xF7\u21F0hreetimes;\u62CB\u0180;qs\u258B\u0993\u25FAlan\xF4\u09AC\u0280;cdgs\u09AC\u260A\u260D\u261D\u2628c;\u6AA8ot\u0100;o\u2614\u2615\u6A7F\u0100;r\u261A\u261B\u6A81;\u6A83\u0100;e\u2622\u2625\uC000\u22DA\uFE00s;\u6A93\u0280adegs\u2633\u2639\u263D\u2649\u264Bppro\xF8\u24C6ot;\u62D6q\u0100gq\u2643\u2645\xF4\u0989gt\xF2\u248C\xF4\u099Bi\xED\u09B2\u0180ilr\u2655\u08E1\u265Asht;\u697C;\uC000\u{1D529}\u0100;E\u099C\u2663;\u6A91\u0161\u2669\u2676r\u0100du\u25B2\u266E\u0100;l\u0965\u2673;\u696Alk;\u6584cy;\u4459\u0280;acht\u0A48\u2688\u268B\u2691\u2696r\xF2\u25C1orne\xF2\u1D08ard;\u696Bri;\u65FA\u0100io\u269F\u26A4dot;\u4140ust\u0100;a\u26AC\u26AD\u63B0che\xBB\u26AD\u0200Eaes\u26BB\u26BD\u26C9\u26D4;\u6268p\u0100;p\u26C3\u26C4\u6A89rox\xBB\u26C4\u0100;q\u26CE\u26CF\u6A87\u0100;q\u26CE\u26BBim;\u62E6\u0400abnoptwz\u26E9\u26F4\u26F7\u271A\u272F\u2741\u2747\u2750\u0100nr\u26EE\u26F1g;\u67ECr;\u61FDr\xEB\u08C1g\u0180lmr\u26FF\u270D\u2714eft\u0100ar\u09E6\u2707ight\xE1\u09F2apsto;\u67FCight\xE1\u09FDparrow\u0100lr\u2725\u2729ef\xF4\u24EDight;\u61AC\u0180afl\u2736\u2739\u273Dr;\u6985;\uC000\u{1D55D}us;\u6A2Dimes;\u6A34\u0161\u274B\u274Fst;\u6217\xE1\u134E\u0180;ef\u2757\u2758\u1800\u65CAnge\xBB\u2758ar\u0100;l\u2764\u2765\u4028t;\u6993\u0280achmt\u2773\u2776\u277C\u2785\u2787r\xF2\u08A8orne\xF2\u1D8Car\u0100;d\u0F98\u2783;\u696D;\u600Eri;\u62BF\u0300achiqt\u2798\u279D\u0A40\u27A2\u27AE\u27BBquo;\u6039r;\uC000\u{1D4C1}m\u0180;eg\u09B2\u27AA\u27AC;\u6A8D;\u6A8F\u0100bu\u252A\u27B3o\u0100;r\u0E1F\u27B9;\u601Arok;\u4142\u8400<;cdhilqr\u082B\u27D2\u2639\u27DC\u27E0\u27E5\u27EA\u27F0\u0100ci\u27D7\u27D9;\u6AA6r;\u6A79re\xE5\u25F2mes;\u62C9arr;\u6976uest;\u6A7B\u0100Pi\u27F5\u27F9ar;\u6996\u0180;ef\u2800\u092D\u181B\u65C3r\u0100du\u2807\u280Dshar;\u694Ahar;\u6966\u0100en\u2817\u2821rtneqq;\uC000\u2268\uFE00\xC5\u281E\u0700Dacdefhilnopsu\u2840\u2845\u2882\u288E\u2893\u28A0\u28A5\u28A8\u28DA\u28E2\u28E4\u0A83\u28F3\u2902Dot;\u623A\u0200clpr\u284E\u2852\u2863\u287Dr\u803B\xAF\u40AF\u0100et\u2857\u2859;\u6642\u0100;e\u285E\u285F\u6720se\xBB\u285F\u0100;s\u103B\u2868to\u0200;dlu\u103B\u2873\u2877\u287Bow\xEE\u048Cef\xF4\u090F\xF0\u13D1ker;\u65AE\u0100oy\u2887\u288Cmma;\u6A29;\u443Cash;\u6014asuredangle\xBB\u1626r;\uC000\u{1D52A}o;\u6127\u0180cdn\u28AF\u28B4\u28C9ro\u803B\xB5\u40B5\u0200;acd\u1464\u28BD\u28C0\u28C4s\xF4\u16A7ir;\u6AF0ot\u80BB\xB7\u01B5us\u0180;bd\u28D2\u1903\u28D3\u6212\u0100;u\u1D3C\u28D8;\u6A2A\u0163\u28DE\u28E1p;\u6ADB\xF2\u2212\xF0\u0A81\u0100dp\u28E9\u28EEels;\u62A7f;\uC000\u{1D55E}\u0100ct\u28F8\u28FDr;\uC000\u{1D4C2}pos\xBB\u159D\u0180;lm\u2909\u290A\u290D\u43BCtimap;\u62B8\u0C00GLRVabcdefghijlmoprstuvw\u2942\u2953\u297E\u2989\u2998\u29DA\u29E9\u2A15\u2A1A\u2A58\u2A5D\u2A83\u2A95\u2AA4\u2AA8\u2B04\u2B07\u2B44\u2B7F\u2BAE\u2C34\u2C67\u2C7C\u2CE9\u0100gt\u2947\u294B;\uC000\u22D9\u0338\u0100;v\u2950\u0BCF\uC000\u226B\u20D2\u0180elt\u295A\u2972\u2976ft\u0100ar\u2961\u2967rrow;\u61CDightarrow;\u61CE;\uC000\u22D8\u0338\u0100;v\u297B\u0C47\uC000\u226A\u20D2ightarrow;\u61CF\u0100Dd\u298E\u2993ash;\u62AFash;\u62AE\u0280bcnpt\u29A3\u29A7\u29AC\u29B1\u29CCla\xBB\u02DEute;\u4144g;\uC000\u2220\u20D2\u0280;Eiop\u0D84\u29BC\u29C0\u29C5\u29C8;\uC000\u2A70\u0338d;\uC000\u224B\u0338s;\u4149ro\xF8\u0D84ur\u0100;a\u29D3\u29D4\u666El\u0100;s\u29D3\u0B38\u01F3\u29DF\0\u29E3p\u80BB\xA0\u0B37mp\u0100;e\u0BF9\u0C00\u0280aeouy\u29F4\u29FE\u2A03\u2A10\u2A13\u01F0\u29F9\0\u29FB;\u6A43on;\u4148dil;\u4146ng\u0100;d\u0D7E\u2A0Aot;\uC000\u2A6D\u0338p;\u6A42;\u443Dash;\u6013\u0380;Aadqsx\u0B92\u2A29\u2A2D\u2A3B\u2A41\u2A45\u2A50rr;\u61D7r\u0100hr\u2A33\u2A36k;\u6924\u0100;o\u13F2\u13F0ot;\uC000\u2250\u0338ui\xF6\u0B63\u0100ei\u2A4A\u2A4Ear;\u6928\xED\u0B98ist\u0100;s\u0BA0\u0B9Fr;\uC000\u{1D52B}\u0200Eest\u0BC5\u2A66\u2A79\u2A7C\u0180;qs\u0BBC\u2A6D\u0BE1\u0180;qs\u0BBC\u0BC5\u2A74lan\xF4\u0BE2i\xED\u0BEA\u0100;r\u0BB6\u2A81\xBB\u0BB7\u0180Aap\u2A8A\u2A8D\u2A91r\xF2\u2971rr;\u61AEar;\u6AF2\u0180;sv\u0F8D\u2A9C\u0F8C\u0100;d\u2AA1\u2AA2\u62FC;\u62FAcy;\u445A\u0380AEadest\u2AB7\u2ABA\u2ABE\u2AC2\u2AC5\u2AF6\u2AF9r\xF2\u2966;\uC000\u2266\u0338rr;\u619Ar;\u6025\u0200;fqs\u0C3B\u2ACE\u2AE3\u2AEFt\u0100ar\u2AD4\u2AD9rro\xF7\u2AC1ightarro\xF7\u2A90\u0180;qs\u0C3B\u2ABA\u2AEAlan\xF4\u0C55\u0100;s\u0C55\u2AF4\xBB\u0C36i\xED\u0C5D\u0100;r\u0C35\u2AFEi\u0100;e\u0C1A\u0C25i\xE4\u0D90\u0100pt\u2B0C\u2B11f;\uC000\u{1D55F}\u8180\xAC;in\u2B19\u2B1A\u2B36\u40ACn\u0200;Edv\u0B89\u2B24\u2B28\u2B2E;\uC000\u22F9\u0338ot;\uC000\u22F5\u0338\u01E1\u0B89\u2B33\u2B35;\u62F7;\u62F6i\u0100;v\u0CB8\u2B3C\u01E1\u0CB8\u2B41\u2B43;\u62FE;\u62FD\u0180aor\u2B4B\u2B63\u2B69r\u0200;ast\u0B7B\u2B55\u2B5A\u2B5Flle\xEC\u0B7Bl;\uC000\u2AFD\u20E5;\uC000\u2202\u0338lint;\u6A14\u0180;ce\u0C92\u2B70\u2B73u\xE5\u0CA5\u0100;c\u0C98\u2B78\u0100;e\u0C92\u2B7D\xF1\u0C98\u0200Aait\u2B88\u2B8B\u2B9D\u2BA7r\xF2\u2988rr\u0180;cw\u2B94\u2B95\u2B99\u619B;\uC000\u2933\u0338;\uC000\u219D\u0338ghtarrow\xBB\u2B95ri\u0100;e\u0CCB\u0CD6\u0380chimpqu\u2BBD\u2BCD\u2BD9\u2B04\u0B78\u2BE4\u2BEF\u0200;cer\u0D32\u2BC6\u0D37\u2BC9u\xE5\u0D45;\uC000\u{1D4C3}ort\u026D\u2B05\0\0\u2BD6ar\xE1\u2B56m\u0100;e\u0D6E\u2BDF\u0100;q\u0D74\u0D73su\u0100bp\u2BEB\u2BED\xE5\u0CF8\xE5\u0D0B\u0180bcp\u2BF6\u2C11\u2C19\u0200;Ees\u2BFF\u2C00\u0D22\u2C04\u6284;\uC000\u2AC5\u0338et\u0100;e\u0D1B\u2C0Bq\u0100;q\u0D23\u2C00c\u0100;e\u0D32\u2C17\xF1\u0D38\u0200;Ees\u2C22\u2C23\u0D5F\u2C27\u6285;\uC000\u2AC6\u0338et\u0100;e\u0D58\u2C2Eq\u0100;q\u0D60\u2C23\u0200gilr\u2C3D\u2C3F\u2C45\u2C47\xEC\u0BD7lde\u803B\xF1\u40F1\xE7\u0C43iangle\u0100lr\u2C52\u2C5Ceft\u0100;e\u0C1A\u2C5A\xF1\u0C26ight\u0100;e\u0CCB\u2C65\xF1\u0CD7\u0100;m\u2C6C\u2C6D\u43BD\u0180;es\u2C74\u2C75\u2C79\u4023ro;\u6116p;\u6007\u0480DHadgilrs\u2C8F\u2C94\u2C99\u2C9E\u2CA3\u2CB0\u2CB6\u2CD3\u2CE3ash;\u62ADarr;\u6904p;\uC000\u224D\u20D2ash;\u62AC\u0100et\u2CA8\u2CAC;\uC000\u2265\u20D2;\uC000>\u20D2nfin;\u69DE\u0180Aet\u2CBD\u2CC1\u2CC5rr;\u6902;\uC000\u2264\u20D2\u0100;r\u2CCA\u2CCD\uC000<\u20D2ie;\uC000\u22B4\u20D2\u0100At\u2CD8\u2CDCrr;\u6903rie;\uC000\u22B5\u20D2im;\uC000\u223C\u20D2\u0180Aan\u2CF0\u2CF4\u2D02rr;\u61D6r\u0100hr\u2CFA\u2CFDk;\u6923\u0100;o\u13E7\u13E5ear;\u6927\u1253\u1A95\0\0\0\0\0\0\0\0\0\0\0\0\0\u2D2D\0\u2D38\u2D48\u2D60\u2D65\u2D72\u2D84\u1B07\0\0\u2D8D\u2DAB\0\u2DC8\u2DCE\0\u2DDC\u2E19\u2E2B\u2E3E\u2E43\u0100cs\u2D31\u1A97ute\u803B\xF3\u40F3\u0100iy\u2D3C\u2D45r\u0100;c\u1A9E\u2D42\u803B\xF4\u40F4;\u443E\u0280abios\u1AA0\u2D52\u2D57\u01C8\u2D5Alac;\u4151v;\u6A38old;\u69BClig;\u4153\u0100cr\u2D69\u2D6Dir;\u69BF;\uC000\u{1D52C}\u036F\u2D79\0\0\u2D7C\0\u2D82n;\u42DBave\u803B\xF2\u40F2;\u69C1\u0100bm\u2D88\u0DF4ar;\u69B5\u0200acit\u2D95\u2D98\u2DA5\u2DA8r\xF2\u1A80\u0100ir\u2D9D\u2DA0r;\u69BEoss;\u69BBn\xE5\u0E52;\u69C0\u0180aei\u2DB1\u2DB5\u2DB9cr;\u414Dga;\u43C9\u0180cdn\u2DC0\u2DC5\u01CDron;\u43BF;\u69B6pf;\uC000\u{1D560}\u0180ael\u2DD4\u2DD7\u01D2r;\u69B7rp;\u69B9\u0380;adiosv\u2DEA\u2DEB\u2DEE\u2E08\u2E0D\u2E10\u2E16\u6228r\xF2\u1A86\u0200;efm\u2DF7\u2DF8\u2E02\u2E05\u6A5Dr\u0100;o\u2DFE\u2DFF\u6134f\xBB\u2DFF\u803B\xAA\u40AA\u803B\xBA\u40BAgof;\u62B6r;\u6A56lope;\u6A57;\u6A5B\u0180clo\u2E1F\u2E21\u2E27\xF2\u2E01ash\u803B\xF8\u40F8l;\u6298i\u016C\u2E2F\u2E34de\u803B\xF5\u40F5es\u0100;a\u01DB\u2E3As;\u6A36ml\u803B\xF6\u40F6bar;\u633D\u0AE1\u2E5E\0\u2E7D\0\u2E80\u2E9D\0\u2EA2\u2EB9\0\0\u2ECB\u0E9C\0\u2F13\0\0\u2F2B\u2FBC\0\u2FC8r\u0200;ast\u0403\u2E67\u2E72\u0E85\u8100\xB6;l\u2E6D\u2E6E\u40B6le\xEC\u0403\u0269\u2E78\0\0\u2E7Bm;\u6AF3;\u6AFDy;\u443Fr\u0280cimpt\u2E8B\u2E8F\u2E93\u1865\u2E97nt;\u4025od;\u402Eil;\u6030enk;\u6031r;\uC000\u{1D52D}\u0180imo\u2EA8\u2EB0\u2EB4\u0100;v\u2EAD\u2EAE\u43C6;\u43D5ma\xF4\u0A76ne;\u660E\u0180;tv\u2EBF\u2EC0\u2EC8\u43C0chfork\xBB\u1FFD;\u43D6\u0100au\u2ECF\u2EDFn\u0100ck\u2ED5\u2EDDk\u0100;h\u21F4\u2EDB;\u610E\xF6\u21F4s\u0480;abcdemst\u2EF3\u2EF4\u1908\u2EF9\u2EFD\u2F04\u2F06\u2F0A\u2F0E\u402Bcir;\u6A23ir;\u6A22\u0100ou\u1D40\u2F02;\u6A25;\u6A72n\u80BB\xB1\u0E9Dim;\u6A26wo;\u6A27\u0180ipu\u2F19\u2F20\u2F25ntint;\u6A15f;\uC000\u{1D561}nd\u803B\xA3\u40A3\u0500;Eaceinosu\u0EC8\u2F3F\u2F41\u2F44\u2F47\u2F81\u2F89\u2F92\u2F7E\u2FB6;\u6AB3p;\u6AB7u\xE5\u0ED9\u0100;c\u0ECE\u2F4C\u0300;acens\u0EC8\u2F59\u2F5F\u2F66\u2F68\u2F7Eppro\xF8\u2F43urlye\xF1\u0ED9\xF1\u0ECE\u0180aes\u2F6F\u2F76\u2F7Approx;\u6AB9qq;\u6AB5im;\u62E8i\xED\u0EDFme\u0100;s\u2F88\u0EAE\u6032\u0180Eas\u2F78\u2F90\u2F7A\xF0\u2F75\u0180dfp\u0EEC\u2F99\u2FAF\u0180als\u2FA0\u2FA5\u2FAAlar;\u632Eine;\u6312urf;\u6313\u0100;t\u0EFB\u2FB4\xEF\u0EFBrel;\u62B0\u0100ci\u2FC0\u2FC5r;\uC000\u{1D4C5};\u43C8ncsp;\u6008\u0300fiopsu\u2FDA\u22E2\u2FDF\u2FE5\u2FEB\u2FF1r;\uC000\u{1D52E}pf;\uC000\u{1D562}rime;\u6057cr;\uC000\u{1D4C6}\u0180aeo\u2FF8\u3009\u3013t\u0100ei\u2FFE\u3005rnion\xF3\u06B0nt;\u6A16st\u0100;e\u3010\u3011\u403F\xF1\u1F19\xF4\u0F14\u0A80ABHabcdefhilmnoprstux\u3040\u3051\u3055\u3059\u30E0\u310E\u312B\u3147\u3162\u3172\u318E\u3206\u3215\u3224\u3229\u3258\u326E\u3272\u3290\u32B0\u32B7\u0180art\u3047\u304A\u304Cr\xF2\u10B3\xF2\u03DDail;\u691Car\xF2\u1C65ar;\u6964\u0380cdenqrt\u3068\u3075\u3078\u307F\u308F\u3094\u30CC\u0100eu\u306D\u3071;\uC000\u223D\u0331te;\u4155i\xE3\u116Emptyv;\u69B3g\u0200;del\u0FD1\u3089\u308B\u308D;\u6992;\u69A5\xE5\u0FD1uo\u803B\xBB\u40BBr\u0580;abcfhlpstw\u0FDC\u30AC\u30AF\u30B7\u30B9\u30BC\u30BE\u30C0\u30C3\u30C7\u30CAp;\u6975\u0100;f\u0FE0\u30B4s;\u6920;\u6933s;\u691E\xEB\u225D\xF0\u272El;\u6945im;\u6974l;\u61A3;\u619D\u0100ai\u30D1\u30D5il;\u691Ao\u0100;n\u30DB\u30DC\u6236al\xF3\u0F1E\u0180abr\u30E7\u30EA\u30EEr\xF2\u17E5rk;\u6773\u0100ak\u30F3\u30FDc\u0100ek\u30F9\u30FB;\u407D;\u405D\u0100es\u3102\u3104;\u698Cl\u0100du\u310A\u310C;\u698E;\u6990\u0200aeuy\u3117\u311C\u3127\u3129ron;\u4159\u0100di\u3121\u3125il;\u4157\xEC\u0FF2\xE2\u30FA;\u4440\u0200clqs\u3134\u3137\u313D\u3144a;\u6937dhar;\u6969uo\u0100;r\u020E\u020Dh;\u61B3\u0180acg\u314E\u315F\u0F44l\u0200;ips\u0F78\u3158\u315B\u109Cn\xE5\u10BBar\xF4\u0FA9t;\u65AD\u0180ilr\u3169\u1023\u316Esht;\u697D;\uC000\u{1D52F}\u0100ao\u3177\u3186r\u0100du\u317D\u317F\xBB\u047B\u0100;l\u1091\u3184;\u696C\u0100;v\u318B\u318C\u43C1;\u43F1\u0180gns\u3195\u31F9\u31FCht\u0300ahlrst\u31A4\u31B0\u31C2\u31D8\u31E4\u31EErrow\u0100;t\u0FDC\u31ADa\xE9\u30C8arpoon\u0100du\u31BB\u31BFow\xEE\u317Ep\xBB\u1092eft\u0100ah\u31CA\u31D0rrow\xF3\u0FEAarpoon\xF3\u0551ightarrows;\u61C9quigarro\xF7\u30CBhreetimes;\u62CCg;\u42DAingdotse\xF1\u1F32\u0180ahm\u320D\u3210\u3213r\xF2\u0FEAa\xF2\u0551;\u600Foust\u0100;a\u321E\u321F\u63B1che\xBB\u321Fmid;\u6AEE\u0200abpt\u3232\u323D\u3240\u3252\u0100nr\u3237\u323Ag;\u67EDr;\u61FEr\xEB\u1003\u0180afl\u3247\u324A\u324Er;\u6986;\uC000\u{1D563}us;\u6A2Eimes;\u6A35\u0100ap\u325D\u3267r\u0100;g\u3263\u3264\u4029t;\u6994olint;\u6A12ar\xF2\u31E3\u0200achq\u327B\u3280\u10BC\u3285quo;\u603Ar;\uC000\u{1D4C7}\u0100bu\u30FB\u328Ao\u0100;r\u0214\u0213\u0180hir\u3297\u329B\u32A0re\xE5\u31F8mes;\u62CAi\u0200;efl\u32AA\u1059\u1821\u32AB\u65B9tri;\u69CEluhar;\u6968;\u611E\u0D61\u32D5\u32DB\u32DF\u332C\u3338\u3371\0\u337A\u33A4\0\0\u33EC\u33F0\0\u3428\u3448\u345A\u34AD\u34B1\u34CA\u34F1\0\u3616\0\0\u3633cute;\u415Bqu\xEF\u27BA\u0500;Eaceinpsy\u11ED\u32F3\u32F5\u32FF\u3302\u330B\u330F\u331F\u3326\u3329;\u6AB4\u01F0\u32FA\0\u32FC;\u6AB8on;\u4161u\xE5\u11FE\u0100;d\u11F3\u3307il;\u415Frc;\u415D\u0180Eas\u3316\u3318\u331B;\u6AB6p;\u6ABAim;\u62E9olint;\u6A13i\xED\u1204;\u4441ot\u0180;be\u3334\u1D47\u3335\u62C5;\u6A66\u0380Aacmstx\u3346\u334A\u3357\u335B\u335E\u3363\u336Drr;\u61D8r\u0100hr\u3350\u3352\xEB\u2228\u0100;o\u0A36\u0A34t\u803B\xA7\u40A7i;\u403Bwar;\u6929m\u0100in\u3369\xF0nu\xF3\xF1t;\u6736r\u0100;o\u3376\u2055\uC000\u{1D530}\u0200acoy\u3382\u3386\u3391\u33A0rp;\u666F\u0100hy\u338B\u338Fcy;\u4449;\u4448rt\u026D\u3399\0\0\u339Ci\xE4\u1464ara\xEC\u2E6F\u803B\xAD\u40AD\u0100gm\u33A8\u33B4ma\u0180;fv\u33B1\u33B2\u33B2\u43C3;\u43C2\u0400;deglnpr\u12AB\u33C5\u33C9\u33CE\u33D6\u33DE\u33E1\u33E6ot;\u6A6A\u0100;q\u12B1\u12B0\u0100;E\u33D3\u33D4\u6A9E;\u6AA0\u0100;E\u33DB\u33DC\u6A9D;\u6A9Fe;\u6246lus;\u6A24arr;\u6972ar\xF2\u113D\u0200aeit\u33F8\u3408\u340F\u3417\u0100ls\u33FD\u3404lsetm\xE9\u336Ahp;\u6A33parsl;\u69E4\u0100dl\u1463\u3414e;\u6323\u0100;e\u341C\u341D\u6AAA\u0100;s\u3422\u3423\u6AAC;\uC000\u2AAC\uFE00\u0180flp\u342E\u3433\u3442tcy;\u444C\u0100;b\u3438\u3439\u402F\u0100;a\u343E\u343F\u69C4r;\u633Ff;\uC000\u{1D564}a\u0100dr\u344D\u0402es\u0100;u\u3454\u3455\u6660it\xBB\u3455\u0180csu\u3460\u3479\u349F\u0100au\u3465\u346Fp\u0100;s\u1188\u346B;\uC000\u2293\uFE00p\u0100;s\u11B4\u3475;\uC000\u2294\uFE00u\u0100bp\u347F\u348F\u0180;es\u1197\u119C\u3486et\u0100;e\u1197\u348D\xF1\u119D\u0180;es\u11A8\u11AD\u3496et\u0100;e\u11A8\u349D\xF1\u11AE\u0180;af\u117B\u34A6\u05B0r\u0165\u34AB\u05B1\xBB\u117Car\xF2\u1148\u0200cemt\u34B9\u34BE\u34C2\u34C5r;\uC000\u{1D4C8}tm\xEE\xF1i\xEC\u3415ar\xE6\u11BE\u0100ar\u34CE\u34D5r\u0100;f\u34D4\u17BF\u6606\u0100an\u34DA\u34EDight\u0100ep\u34E3\u34EApsilo\xEE\u1EE0h\xE9\u2EAFs\xBB\u2852\u0280bcmnp\u34FB\u355E\u1209\u358B\u358E\u0480;Edemnprs\u350E\u350F\u3511\u3515\u351E\u3523\u352C\u3531\u3536\u6282;\u6AC5ot;\u6ABD\u0100;d\u11DA\u351Aot;\u6AC3ult;\u6AC1\u0100Ee\u3528\u352A;\u6ACB;\u628Alus;\u6ABFarr;\u6979\u0180eiu\u353D\u3552\u3555t\u0180;en\u350E\u3545\u354Bq\u0100;q\u11DA\u350Feq\u0100;q\u352B\u3528m;\u6AC7\u0100bp\u355A\u355C;\u6AD5;\u6AD3c\u0300;acens\u11ED\u356C\u3572\u3579\u357B\u3326ppro\xF8\u32FAurlye\xF1\u11FE\xF1\u11F3\u0180aes\u3582\u3588\u331Bppro\xF8\u331Aq\xF1\u3317g;\u666A\u0680123;Edehlmnps\u35A9\u35AC\u35AF\u121C\u35B2\u35B4\u35C0\u35C9\u35D5\u35DA\u35DF\u35E8\u35ED\u803B\xB9\u40B9\u803B\xB2\u40B2\u803B\xB3\u40B3;\u6AC6\u0100os\u35B9\u35BCt;\u6ABEub;\u6AD8\u0100;d\u1222\u35C5ot;\u6AC4s\u0100ou\u35CF\u35D2l;\u67C9b;\u6AD7arr;\u697Bult;\u6AC2\u0100Ee\u35E4\u35E6;\u6ACC;\u628Blus;\u6AC0\u0180eiu\u35F4\u3609\u360Ct\u0180;en\u121C\u35FC\u3602q\u0100;q\u1222\u35B2eq\u0100;q\u35E7\u35E4m;\u6AC8\u0100bp\u3611\u3613;\u6AD4;\u6AD6\u0180Aan\u361C\u3620\u362Drr;\u61D9r\u0100hr\u3626\u3628\xEB\u222E\u0100;o\u0A2B\u0A29war;\u692Alig\u803B\xDF\u40DF\u0BE1\u3651\u365D\u3660\u12CE\u3673\u3679\0\u367E\u36C2\0\0\0\0\0\u36DB\u3703\0\u3709\u376C\0\0\0\u3787\u0272\u3656\0\0\u365Bget;\u6316;\u43C4r\xEB\u0E5F\u0180aey\u3666\u366B\u3670ron;\u4165dil;\u4163;\u4442lrec;\u6315r;\uC000\u{1D531}\u0200eiko\u3686\u369D\u36B5\u36BC\u01F2\u368B\0\u3691e\u01004f\u1284\u1281a\u0180;sv\u3698\u3699\u369B\u43B8ym;\u43D1\u0100cn\u36A2\u36B2k\u0100as\u36A8\u36AEppro\xF8\u12C1im\xBB\u12ACs\xF0\u129E\u0100as\u36BA\u36AE\xF0\u12C1rn\u803B\xFE\u40FE\u01EC\u031F\u36C6\u22E7es\u8180\xD7;bd\u36CF\u36D0\u36D8\u40D7\u0100;a\u190F\u36D5r;\u6A31;\u6A30\u0180eps\u36E1\u36E3\u3700\xE1\u2A4D\u0200;bcf\u0486\u36EC\u36F0\u36F4ot;\u6336ir;\u6AF1\u0100;o\u36F9\u36FC\uC000\u{1D565}rk;\u6ADA\xE1\u3362rime;\u6034\u0180aip\u370F\u3712\u3764d\xE5\u1248\u0380adempst\u3721\u374D\u3740\u3751\u3757\u375C\u375Fngle\u0280;dlqr\u3730\u3731\u3736\u3740\u3742\u65B5own\xBB\u1DBBeft\u0100;e\u2800\u373E\xF1\u092E;\u625Cight\u0100;e\u32AA\u374B\xF1\u105Aot;\u65ECinus;\u6A3Alus;\u6A39b;\u69CDime;\u6A3Bezium;\u63E2\u0180cht\u3772\u377D\u3781\u0100ry\u3777\u377B;\uC000\u{1D4C9};\u4446cy;\u445Brok;\u4167\u0100io\u378B\u378Ex\xF4\u1777head\u0100lr\u3797\u37A0eftarro\xF7\u084Fightarrow\xBB\u0F5D\u0900AHabcdfghlmoprstuw\u37D0\u37D3\u37D7\u37E4\u37F0\u37FC\u380E\u381C\u3823\u3834\u3851\u385D\u386B\u38A9\u38CC\u38D2\u38EA\u38F6r\xF2\u03EDar;\u6963\u0100cr\u37DC\u37E2ute\u803B\xFA\u40FA\xF2\u1150r\u01E3\u37EA\0\u37EDy;\u445Eve;\u416D\u0100iy\u37F5\u37FArc\u803B\xFB\u40FB;\u4443\u0180abh\u3803\u3806\u380Br\xF2\u13ADlac;\u4171a\xF2\u13C3\u0100ir\u3813\u3818sht;\u697E;\uC000\u{1D532}rave\u803B\xF9\u40F9\u0161\u3827\u3831r\u0100lr\u382C\u382E\xBB\u0957\xBB\u1083lk;\u6580\u0100ct\u3839\u384D\u026F\u383F\0\0\u384Arn\u0100;e\u3845\u3846\u631Cr\xBB\u3846op;\u630Fri;\u65F8\u0100al\u3856\u385Acr;\u416B\u80BB\xA8\u0349\u0100gp\u3862\u3866on;\u4173f;\uC000\u{1D566}\u0300adhlsu\u114B\u3878\u387D\u1372\u3891\u38A0own\xE1\u13B3arpoon\u0100lr\u3888\u388Cef\xF4\u382Digh\xF4\u382Fi\u0180;hl\u3899\u389A\u389C\u43C5\xBB\u13FAon\xBB\u389Aparrows;\u61C8\u0180cit\u38B0\u38C4\u38C8\u026F\u38B6\0\0\u38C1rn\u0100;e\u38BC\u38BD\u631Dr\xBB\u38BDop;\u630Eng;\u416Fri;\u65F9cr;\uC000\u{1D4CA}\u0180dir\u38D9\u38DD\u38E2ot;\u62F0lde;\u4169i\u0100;f\u3730\u38E8\xBB\u1813\u0100am\u38EF\u38F2r\xF2\u38A8l\u803B\xFC\u40FCangle;\u69A7\u0780ABDacdeflnoprsz\u391C\u391F\u3929\u392D\u39B5\u39B8\u39BD\u39DF\u39E4\u39E8\u39F3\u39F9\u39FD\u3A01\u3A20r\xF2\u03F7ar\u0100;v\u3926\u3927\u6AE8;\u6AE9as\xE8\u03E1\u0100nr\u3932\u3937grt;\u699C\u0380eknprst\u34E3\u3946\u394B\u3952\u395D\u3964\u3996app\xE1\u2415othin\xE7\u1E96\u0180hir\u34EB\u2EC8\u3959op\xF4\u2FB5\u0100;h\u13B7\u3962\xEF\u318D\u0100iu\u3969\u396Dgm\xE1\u33B3\u0100bp\u3972\u3984setneq\u0100;q\u397D\u3980\uC000\u228A\uFE00;\uC000\u2ACB\uFE00setneq\u0100;q\u398F\u3992\uC000\u228B\uFE00;\uC000\u2ACC\uFE00\u0100hr\u399B\u399Fet\xE1\u369Ciangle\u0100lr\u39AA\u39AFeft\xBB\u0925ight\xBB\u1051y;\u4432ash\xBB\u1036\u0180elr\u39C4\u39D2\u39D7\u0180;be\u2DEA\u39CB\u39CFar;\u62BBq;\u625Alip;\u62EE\u0100bt\u39DC\u1468a\xF2\u1469r;\uC000\u{1D533}tr\xE9\u39AEsu\u0100bp\u39EF\u39F1\xBB\u0D1C\xBB\u0D59pf;\uC000\u{1D567}ro\xF0\u0EFBtr\xE9\u39B4\u0100cu\u3A06\u3A0Br;\uC000\u{1D4CB}\u0100bp\u3A10\u3A18n\u0100Ee\u3980\u3A16\xBB\u397En\u0100Ee\u3992\u3A1E\xBB\u3990igzag;\u699A\u0380cefoprs\u3A36\u3A3B\u3A56\u3A5B\u3A54\u3A61\u3A6Airc;\u4175\u0100di\u3A40\u3A51\u0100bg\u3A45\u3A49ar;\u6A5Fe\u0100;q\u15FA\u3A4F;\u6259erp;\u6118r;\uC000\u{1D534}pf;\uC000\u{1D568}\u0100;e\u1479\u3A66at\xE8\u1479cr;\uC000\u{1D4CC}\u0AE3\u178E\u3A87\0\u3A8B\0\u3A90\u3A9B\0\0\u3A9D\u3AA8\u3AAB\u3AAF\0\0\u3AC3\u3ACE\0\u3AD8\u17DC\u17DFtr\xE9\u17D1r;\uC000\u{1D535}\u0100Aa\u3A94\u3A97r\xF2\u03C3r\xF2\u09F6;\u43BE\u0100Aa\u3AA1\u3AA4r\xF2\u03B8r\xF2\u09EBa\xF0\u2713is;\u62FB\u0180dpt\u17A4\u3AB5\u3ABE\u0100fl\u3ABA\u17A9;\uC000\u{1D569}im\xE5\u17B2\u0100Aa\u3AC7\u3ACAr\xF2\u03CEr\xF2\u0A01\u0100cq\u3AD2\u17B8r;\uC000\u{1D4CD}\u0100pt\u17D6\u3ADCr\xE9\u17D4\u0400acefiosu\u3AF0\u3AFD\u3B08\u3B0C\u3B11\u3B15\u3B1B\u3B21c\u0100uy\u3AF6\u3AFBte\u803B\xFD\u40FD;\u444F\u0100iy\u3B02\u3B06rc;\u4177;\u444Bn\u803B\xA5\u40A5r;\uC000\u{1D536}cy;\u4457pf;\uC000\u{1D56A}cr;\uC000\u{1D4CE}\u0100cm\u3B26\u3B29y;\u444El\u803B\xFF\u40FF\u0500acdefhiosw\u3B42\u3B48\u3B54\u3B58\u3B64\u3B69\u3B6D\u3B74\u3B7A\u3B80cute;\u417A\u0100ay\u3B4D\u3B52ron;\u417E;\u4437ot;\u417C\u0100et\u3B5D\u3B61tr\xE6\u155Fa;\u43B6r;\uC000\u{1D537}cy;\u4436grarr;\u61DDpf;\uC000\u{1D56B}cr;\uC000\u{1D4CF}\u0100jn\u3B85\u3B87;\u600Dj;\u600C'.split("").map(function(c) { + return c.charCodeAt(0); + }) + ); + } +}); + +// node_modules/entities/lib/generated/decode-data-xml.js +var require_decode_data_xml = __commonJS({ + "node_modules/entities/lib/generated/decode-data-xml.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.default = new Uint16Array( + // prettier-ignore + "\u0200aglq \x1B\u026D\0\0p;\u4026os;\u4027t;\u403Et;\u403Cuot;\u4022".split("").map(function(c) { + return c.charCodeAt(0); + }) + ); + } +}); + +// node_modules/entities/lib/decode_codepoint.js +var require_decode_codepoint = __commonJS({ + "node_modules/entities/lib/decode_codepoint.js"(exports2) { + "use strict"; + var _a; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.replaceCodePoint = exports2.fromCodePoint = void 0; + var decodeMap = /* @__PURE__ */ new Map([ + [0, 65533], + // C1 Unicode control character reference replacements + [128, 8364], + [130, 8218], + [131, 402], + [132, 8222], + [133, 8230], + [134, 8224], + [135, 8225], + [136, 710], + [137, 8240], + [138, 352], + [139, 8249], + [140, 338], + [142, 381], + [145, 8216], + [146, 8217], + [147, 8220], + [148, 8221], + [149, 8226], + [150, 8211], + [151, 8212], + [152, 732], + [153, 8482], + [154, 353], + [155, 8250], + [156, 339], + [158, 382], + [159, 376] + ]); + exports2.fromCodePoint = // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins + (_a = String.fromCodePoint) !== null && _a !== void 0 ? _a : function(codePoint) { + var output = ""; + if (codePoint > 65535) { + codePoint -= 65536; + output += String.fromCharCode(codePoint >>> 10 & 1023 | 55296); + codePoint = 56320 | codePoint & 1023; + } + output += String.fromCharCode(codePoint); + return output; + }; + function replaceCodePoint(codePoint) { + var _a2; + if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) { + return 65533; + } + return (_a2 = decodeMap.get(codePoint)) !== null && _a2 !== void 0 ? _a2 : codePoint; + } + exports2.replaceCodePoint = replaceCodePoint; + function decodeCodePoint(codePoint) { + return (0, exports2.fromCodePoint)(replaceCodePoint(codePoint)); + } + exports2.default = decodeCodePoint; + } +}); + +// node_modules/entities/lib/decode.js +var require_decode2 = __commonJS({ + "node_modules/entities/lib/decode.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.decodeXML = exports2.decodeHTMLStrict = exports2.decodeHTMLAttribute = exports2.decodeHTML = exports2.determineBranch = exports2.EntityDecoder = exports2.DecodingMode = exports2.BinTrieFlags = exports2.fromCodePoint = exports2.replaceCodePoint = exports2.decodeCodePoint = exports2.xmlDecodeTree = exports2.htmlDecodeTree = void 0; + var decode_data_html_js_1 = __importDefault2(require_decode_data_html()); + exports2.htmlDecodeTree = decode_data_html_js_1.default; + var decode_data_xml_js_1 = __importDefault2(require_decode_data_xml()); + exports2.xmlDecodeTree = decode_data_xml_js_1.default; + var decode_codepoint_js_1 = __importStar2(require_decode_codepoint()); + exports2.decodeCodePoint = decode_codepoint_js_1.default; + var decode_codepoint_js_2 = require_decode_codepoint(); + Object.defineProperty(exports2, "replaceCodePoint", { enumerable: true, get: function() { + return decode_codepoint_js_2.replaceCodePoint; + } }); + Object.defineProperty(exports2, "fromCodePoint", { enumerable: true, get: function() { + return decode_codepoint_js_2.fromCodePoint; + } }); + var CharCodes; + (function(CharCodes2) { + CharCodes2[CharCodes2["NUM"] = 35] = "NUM"; + CharCodes2[CharCodes2["SEMI"] = 59] = "SEMI"; + CharCodes2[CharCodes2["EQUALS"] = 61] = "EQUALS"; + CharCodes2[CharCodes2["ZERO"] = 48] = "ZERO"; + CharCodes2[CharCodes2["NINE"] = 57] = "NINE"; + CharCodes2[CharCodes2["LOWER_A"] = 97] = "LOWER_A"; + CharCodes2[CharCodes2["LOWER_F"] = 102] = "LOWER_F"; + CharCodes2[CharCodes2["LOWER_X"] = 120] = "LOWER_X"; + CharCodes2[CharCodes2["LOWER_Z"] = 122] = "LOWER_Z"; + CharCodes2[CharCodes2["UPPER_A"] = 65] = "UPPER_A"; + CharCodes2[CharCodes2["UPPER_F"] = 70] = "UPPER_F"; + CharCodes2[CharCodes2["UPPER_Z"] = 90] = "UPPER_Z"; + })(CharCodes || (CharCodes = {})); + var TO_LOWER_BIT = 32; + var BinTrieFlags; + (function(BinTrieFlags2) { + BinTrieFlags2[BinTrieFlags2["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH"; + BinTrieFlags2[BinTrieFlags2["BRANCH_LENGTH"] = 16256] = "BRANCH_LENGTH"; + BinTrieFlags2[BinTrieFlags2["JUMP_TABLE"] = 127] = "JUMP_TABLE"; + })(BinTrieFlags = exports2.BinTrieFlags || (exports2.BinTrieFlags = {})); + function isNumber(code) { + return code >= CharCodes.ZERO && code <= CharCodes.NINE; + } + function isHexadecimalCharacter(code) { + return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_F || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_F; + } + function isAsciiAlphaNumeric(code) { + return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z || isNumber(code); + } + function isEntityInAttributeInvalidEnd(code) { + return code === CharCodes.EQUALS || isAsciiAlphaNumeric(code); + } + var EntityDecoderState; + (function(EntityDecoderState2) { + EntityDecoderState2[EntityDecoderState2["EntityStart"] = 0] = "EntityStart"; + EntityDecoderState2[EntityDecoderState2["NumericStart"] = 1] = "NumericStart"; + EntityDecoderState2[EntityDecoderState2["NumericDecimal"] = 2] = "NumericDecimal"; + EntityDecoderState2[EntityDecoderState2["NumericHex"] = 3] = "NumericHex"; + EntityDecoderState2[EntityDecoderState2["NamedEntity"] = 4] = "NamedEntity"; + })(EntityDecoderState || (EntityDecoderState = {})); + var DecodingMode; + (function(DecodingMode2) { + DecodingMode2[DecodingMode2["Legacy"] = 0] = "Legacy"; + DecodingMode2[DecodingMode2["Strict"] = 1] = "Strict"; + DecodingMode2[DecodingMode2["Attribute"] = 2] = "Attribute"; + })(DecodingMode = exports2.DecodingMode || (exports2.DecodingMode = {})); + var EntityDecoder = ( + /** @class */ + (function() { + function EntityDecoder2(decodeTree, emitCodePoint, errors) { + this.decodeTree = decodeTree; + this.emitCodePoint = emitCodePoint; + this.errors = errors; + this.state = EntityDecoderState.EntityStart; + this.consumed = 1; + this.result = 0; + this.treeIndex = 0; + this.excess = 1; + this.decodeMode = DecodingMode.Strict; + } + EntityDecoder2.prototype.startEntity = function(decodeMode) { + this.decodeMode = decodeMode; + this.state = EntityDecoderState.EntityStart; + this.result = 0; + this.treeIndex = 0; + this.excess = 1; + this.consumed = 1; + }; + EntityDecoder2.prototype.write = function(str, offset) { + switch (this.state) { + case EntityDecoderState.EntityStart: { + if (str.charCodeAt(offset) === CharCodes.NUM) { + this.state = EntityDecoderState.NumericStart; + this.consumed += 1; + return this.stateNumericStart(str, offset + 1); + } + this.state = EntityDecoderState.NamedEntity; + return this.stateNamedEntity(str, offset); + } + case EntityDecoderState.NumericStart: { + return this.stateNumericStart(str, offset); + } + case EntityDecoderState.NumericDecimal: { + return this.stateNumericDecimal(str, offset); + } + case EntityDecoderState.NumericHex: { + return this.stateNumericHex(str, offset); + } + case EntityDecoderState.NamedEntity: { + return this.stateNamedEntity(str, offset); + } + } + }; + EntityDecoder2.prototype.stateNumericStart = function(str, offset) { + if (offset >= str.length) { + return -1; + } + if ((str.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) { + this.state = EntityDecoderState.NumericHex; + this.consumed += 1; + return this.stateNumericHex(str, offset + 1); + } + this.state = EntityDecoderState.NumericDecimal; + return this.stateNumericDecimal(str, offset); + }; + EntityDecoder2.prototype.addToNumericResult = function(str, start, end, base) { + if (start !== end) { + var digitCount = end - start; + this.result = this.result * Math.pow(base, digitCount) + parseInt(str.substr(start, digitCount), base); + this.consumed += digitCount; + } + }; + EntityDecoder2.prototype.stateNumericHex = function(str, offset) { + var startIdx = offset; + while (offset < str.length) { + var char = str.charCodeAt(offset); + if (isNumber(char) || isHexadecimalCharacter(char)) { + offset += 1; + } else { + this.addToNumericResult(str, startIdx, offset, 16); + return this.emitNumericEntity(char, 3); + } + } + this.addToNumericResult(str, startIdx, offset, 16); + return -1; + }; + EntityDecoder2.prototype.stateNumericDecimal = function(str, offset) { + var startIdx = offset; + while (offset < str.length) { + var char = str.charCodeAt(offset); + if (isNumber(char)) { + offset += 1; + } else { + this.addToNumericResult(str, startIdx, offset, 10); + return this.emitNumericEntity(char, 2); + } + } + this.addToNumericResult(str, startIdx, offset, 10); + return -1; + }; + EntityDecoder2.prototype.emitNumericEntity = function(lastCp, expectedLength) { + var _a; + if (this.consumed <= expectedLength) { + (_a = this.errors) === null || _a === void 0 ? void 0 : _a.absenceOfDigitsInNumericCharacterReference(this.consumed); + return 0; + } + if (lastCp === CharCodes.SEMI) { + this.consumed += 1; + } else if (this.decodeMode === DecodingMode.Strict) { + return 0; + } + this.emitCodePoint((0, decode_codepoint_js_1.replaceCodePoint)(this.result), this.consumed); + if (this.errors) { + if (lastCp !== CharCodes.SEMI) { + this.errors.missingSemicolonAfterCharacterReference(); + } + this.errors.validateNumericCharacterReference(this.result); + } + return this.consumed; + }; + EntityDecoder2.prototype.stateNamedEntity = function(str, offset) { + var decodeTree = this.decodeTree; + var current = decodeTree[this.treeIndex]; + var valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14; + for (; offset < str.length; offset++, this.excess++) { + var char = str.charCodeAt(offset); + this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char); + if (this.treeIndex < 0) { + return this.result === 0 || // If we are parsing an attribute + this.decodeMode === DecodingMode.Attribute && // We shouldn't have consumed any characters after the entity, + (valueLength === 0 || // And there should be no invalid characters. + isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity(); + } + current = decodeTree[this.treeIndex]; + valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14; + if (valueLength !== 0) { + if (char === CharCodes.SEMI) { + return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess); + } + if (this.decodeMode !== DecodingMode.Strict) { + this.result = this.treeIndex; + this.consumed += this.excess; + this.excess = 0; + } + } + } + return -1; + }; + EntityDecoder2.prototype.emitNotTerminatedNamedEntity = function() { + var _a; + var _b = this, result = _b.result, decodeTree = _b.decodeTree; + var valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14; + this.emitNamedEntityData(result, valueLength, this.consumed); + (_a = this.errors) === null || _a === void 0 ? void 0 : _a.missingSemicolonAfterCharacterReference(); + return this.consumed; + }; + EntityDecoder2.prototype.emitNamedEntityData = function(result, valueLength, consumed) { + var decodeTree = this.decodeTree; + this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~BinTrieFlags.VALUE_LENGTH : decodeTree[result + 1], consumed); + if (valueLength === 3) { + this.emitCodePoint(decodeTree[result + 2], consumed); + } + return consumed; + }; + EntityDecoder2.prototype.end = function() { + var _a; + switch (this.state) { + case EntityDecoderState.NamedEntity: { + return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0; + } + // Otherwise, emit a numeric entity if we have one. + case EntityDecoderState.NumericDecimal: { + return this.emitNumericEntity(0, 2); + } + case EntityDecoderState.NumericHex: { + return this.emitNumericEntity(0, 3); + } + case EntityDecoderState.NumericStart: { + (_a = this.errors) === null || _a === void 0 ? void 0 : _a.absenceOfDigitsInNumericCharacterReference(this.consumed); + return 0; + } + case EntityDecoderState.EntityStart: { + return 0; + } + } + }; + return EntityDecoder2; + })() + ); + exports2.EntityDecoder = EntityDecoder; + function getDecoder(decodeTree) { + var ret = ""; + var decoder = new EntityDecoder(decodeTree, function(str) { + return ret += (0, decode_codepoint_js_1.fromCodePoint)(str); + }); + return function decodeWithTrie(str, decodeMode) { + var lastIndex = 0; + var offset = 0; + while ((offset = str.indexOf("&", offset)) >= 0) { + ret += str.slice(lastIndex, offset); + decoder.startEntity(decodeMode); + var len = decoder.write( + str, + // Skip the "&" + offset + 1 + ); + if (len < 0) { + lastIndex = offset + decoder.end(); + break; + } + lastIndex = offset + len; + offset = len === 0 ? lastIndex + 1 : lastIndex; + } + var result = ret + str.slice(lastIndex); + ret = ""; + return result; + }; + } + function determineBranch(decodeTree, current, nodeIdx, char) { + var branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7; + var jumpOffset = current & BinTrieFlags.JUMP_TABLE; + if (branchCount === 0) { + return jumpOffset !== 0 && char === jumpOffset ? nodeIdx : -1; + } + if (jumpOffset) { + var value = char - jumpOffset; + return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIdx + value] - 1; + } + var lo = nodeIdx; + var hi = lo + branchCount - 1; + while (lo <= hi) { + var mid = lo + hi >>> 1; + var midVal = decodeTree[mid]; + if (midVal < char) { + lo = mid + 1; + } else if (midVal > char) { + hi = mid - 1; + } else { + return decodeTree[mid + branchCount]; + } + } + return -1; + } + exports2.determineBranch = determineBranch; + var htmlDecoder = getDecoder(decode_data_html_js_1.default); + var xmlDecoder = getDecoder(decode_data_xml_js_1.default); + function decodeHTML(str, mode) { + if (mode === void 0) { + mode = DecodingMode.Legacy; + } + return htmlDecoder(str, mode); + } + exports2.decodeHTML = decodeHTML; + function decodeHTMLAttribute(str) { + return htmlDecoder(str, DecodingMode.Attribute); + } + exports2.decodeHTMLAttribute = decodeHTMLAttribute; + function decodeHTMLStrict(str) { + return htmlDecoder(str, DecodingMode.Strict); + } + exports2.decodeHTMLStrict = decodeHTMLStrict; + function decodeXML(str) { + return xmlDecoder(str, DecodingMode.Strict); + } + exports2.decodeXML = decodeXML; + } +}); + +// node_modules/htmlparser2/lib/Tokenizer.js +var require_Tokenizer = __commonJS({ + "node_modules/htmlparser2/lib/Tokenizer.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.QuoteType = void 0; + var decode_js_1 = require_decode2(); + var CharCodes; + (function(CharCodes2) { + CharCodes2[CharCodes2["Tab"] = 9] = "Tab"; + CharCodes2[CharCodes2["NewLine"] = 10] = "NewLine"; + CharCodes2[CharCodes2["FormFeed"] = 12] = "FormFeed"; + CharCodes2[CharCodes2["CarriageReturn"] = 13] = "CarriageReturn"; + CharCodes2[CharCodes2["Space"] = 32] = "Space"; + CharCodes2[CharCodes2["ExclamationMark"] = 33] = "ExclamationMark"; + CharCodes2[CharCodes2["Number"] = 35] = "Number"; + CharCodes2[CharCodes2["Amp"] = 38] = "Amp"; + CharCodes2[CharCodes2["SingleQuote"] = 39] = "SingleQuote"; + CharCodes2[CharCodes2["DoubleQuote"] = 34] = "DoubleQuote"; + CharCodes2[CharCodes2["Dash"] = 45] = "Dash"; + CharCodes2[CharCodes2["Slash"] = 47] = "Slash"; + CharCodes2[CharCodes2["Zero"] = 48] = "Zero"; + CharCodes2[CharCodes2["Nine"] = 57] = "Nine"; + CharCodes2[CharCodes2["Semi"] = 59] = "Semi"; + CharCodes2[CharCodes2["Lt"] = 60] = "Lt"; + CharCodes2[CharCodes2["Eq"] = 61] = "Eq"; + CharCodes2[CharCodes2["Gt"] = 62] = "Gt"; + CharCodes2[CharCodes2["Questionmark"] = 63] = "Questionmark"; + CharCodes2[CharCodes2["UpperA"] = 65] = "UpperA"; + CharCodes2[CharCodes2["LowerA"] = 97] = "LowerA"; + CharCodes2[CharCodes2["UpperF"] = 70] = "UpperF"; + CharCodes2[CharCodes2["LowerF"] = 102] = "LowerF"; + CharCodes2[CharCodes2["UpperZ"] = 90] = "UpperZ"; + CharCodes2[CharCodes2["LowerZ"] = 122] = "LowerZ"; + CharCodes2[CharCodes2["LowerX"] = 120] = "LowerX"; + CharCodes2[CharCodes2["OpeningSquareBracket"] = 91] = "OpeningSquareBracket"; + })(CharCodes || (CharCodes = {})); + var State; + (function(State2) { + State2[State2["Text"] = 1] = "Text"; + State2[State2["BeforeTagName"] = 2] = "BeforeTagName"; + State2[State2["InTagName"] = 3] = "InTagName"; + State2[State2["InSelfClosingTag"] = 4] = "InSelfClosingTag"; + State2[State2["BeforeClosingTagName"] = 5] = "BeforeClosingTagName"; + State2[State2["InClosingTagName"] = 6] = "InClosingTagName"; + State2[State2["AfterClosingTagName"] = 7] = "AfterClosingTagName"; + State2[State2["BeforeAttributeName"] = 8] = "BeforeAttributeName"; + State2[State2["InAttributeName"] = 9] = "InAttributeName"; + State2[State2["AfterAttributeName"] = 10] = "AfterAttributeName"; + State2[State2["BeforeAttributeValue"] = 11] = "BeforeAttributeValue"; + State2[State2["InAttributeValueDq"] = 12] = "InAttributeValueDq"; + State2[State2["InAttributeValueSq"] = 13] = "InAttributeValueSq"; + State2[State2["InAttributeValueNq"] = 14] = "InAttributeValueNq"; + State2[State2["BeforeDeclaration"] = 15] = "BeforeDeclaration"; + State2[State2["InDeclaration"] = 16] = "InDeclaration"; + State2[State2["InProcessingInstruction"] = 17] = "InProcessingInstruction"; + State2[State2["BeforeComment"] = 18] = "BeforeComment"; + State2[State2["CDATASequence"] = 19] = "CDATASequence"; + State2[State2["InSpecialComment"] = 20] = "InSpecialComment"; + State2[State2["InCommentLike"] = 21] = "InCommentLike"; + State2[State2["BeforeSpecialS"] = 22] = "BeforeSpecialS"; + State2[State2["BeforeSpecialT"] = 23] = "BeforeSpecialT"; + State2[State2["SpecialStartSequence"] = 24] = "SpecialStartSequence"; + State2[State2["InSpecialTag"] = 25] = "InSpecialTag"; + State2[State2["InEntity"] = 26] = "InEntity"; + })(State || (State = {})); + function isWhitespace(c) { + return c === CharCodes.Space || c === CharCodes.NewLine || c === CharCodes.Tab || c === CharCodes.FormFeed || c === CharCodes.CarriageReturn; + } + function isEndOfTagSection(c) { + return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace(c); + } + function isASCIIAlpha(c) { + return c >= CharCodes.LowerA && c <= CharCodes.LowerZ || c >= CharCodes.UpperA && c <= CharCodes.UpperZ; + } + var QuoteType; + (function(QuoteType2) { + QuoteType2[QuoteType2["NoValue"] = 0] = "NoValue"; + QuoteType2[QuoteType2["Unquoted"] = 1] = "Unquoted"; + QuoteType2[QuoteType2["Single"] = 2] = "Single"; + QuoteType2[QuoteType2["Double"] = 3] = "Double"; + })(QuoteType || (exports2.QuoteType = QuoteType = {})); + var Sequences = { + Cdata: new Uint8Array([67, 68, 65, 84, 65, 91]), + // CDATA[ + CdataEnd: new Uint8Array([93, 93, 62]), + // ]]> + CommentEnd: new Uint8Array([45, 45, 62]), + // `-->` + ScriptEnd: new Uint8Array([60, 47, 115, 99, 114, 105, 112, 116]), + // ` this.sectionStart) { + this.cbs.ontext(this.sectionStart, this.index); + } + this.state = State.BeforeTagName; + this.sectionStart = this.index; + } else if (this.decodeEntities && c === CharCodes.Amp) { + this.startEntity(); + } + }; + Tokenizer2.prototype.stateSpecialStartSequence = function(c) { + var isEnd = this.sequenceIndex === this.currentSequence.length; + var isMatch = isEnd ? ( + // If we are at the end of the sequence, make sure the tag name has ended + isEndOfTagSection(c) + ) : ( + // Otherwise, do a case-insensitive comparison + (c | 32) === this.currentSequence[this.sequenceIndex] + ); + if (!isMatch) { + this.isSpecial = false; + } else if (!isEnd) { + this.sequenceIndex++; + return; + } + this.sequenceIndex = 0; + this.state = State.InTagName; + this.stateInTagName(c); + }; + Tokenizer2.prototype.stateInSpecialTag = function(c) { + if (this.sequenceIndex === this.currentSequence.length) { + if (c === CharCodes.Gt || isWhitespace(c)) { + var endOfText = this.index - this.currentSequence.length; + if (this.sectionStart < endOfText) { + var actualIndex = this.index; + this.index = endOfText; + this.cbs.ontext(this.sectionStart, endOfText); + this.index = actualIndex; + } + this.isSpecial = false; + this.sectionStart = endOfText + 2; + this.stateInClosingTagName(c); + return; + } + this.sequenceIndex = 0; + } + if ((c | 32) === this.currentSequence[this.sequenceIndex]) { + this.sequenceIndex += 1; + } else if (this.sequenceIndex === 0) { + if (this.currentSequence === Sequences.TitleEnd) { + if (this.decodeEntities && c === CharCodes.Amp) { + this.startEntity(); + } + } else if (this.fastForwardTo(CharCodes.Lt)) { + this.sequenceIndex = 1; + } + } else { + this.sequenceIndex = Number(c === CharCodes.Lt); + } + }; + Tokenizer2.prototype.stateCDATASequence = function(c) { + if (c === Sequences.Cdata[this.sequenceIndex]) { + if (++this.sequenceIndex === Sequences.Cdata.length) { + this.state = State.InCommentLike; + this.currentSequence = Sequences.CdataEnd; + this.sequenceIndex = 0; + this.sectionStart = this.index + 1; + } + } else { + this.sequenceIndex = 0; + this.state = State.InDeclaration; + this.stateInDeclaration(c); + } + }; + Tokenizer2.prototype.fastForwardTo = function(c) { + while (++this.index < this.buffer.length + this.offset) { + if (this.buffer.charCodeAt(this.index - this.offset) === c) { + return true; + } + } + this.index = this.buffer.length + this.offset - 1; + return false; + }; + Tokenizer2.prototype.stateInCommentLike = function(c) { + if (c === this.currentSequence[this.sequenceIndex]) { + if (++this.sequenceIndex === this.currentSequence.length) { + if (this.currentSequence === Sequences.CdataEnd) { + this.cbs.oncdata(this.sectionStart, this.index, 2); + } else { + this.cbs.oncomment(this.sectionStart, this.index, 2); + } + this.sequenceIndex = 0; + this.sectionStart = this.index + 1; + this.state = State.Text; + } + } else if (this.sequenceIndex === 0) { + if (this.fastForwardTo(this.currentSequence[0])) { + this.sequenceIndex = 1; + } + } else if (c !== this.currentSequence[this.sequenceIndex - 1]) { + this.sequenceIndex = 0; + } + }; + Tokenizer2.prototype.isTagStartChar = function(c) { + return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c); + }; + Tokenizer2.prototype.startSpecial = function(sequence, offset) { + this.isSpecial = true; + this.currentSequence = sequence; + this.sequenceIndex = offset; + this.state = State.SpecialStartSequence; + }; + Tokenizer2.prototype.stateBeforeTagName = function(c) { + if (c === CharCodes.ExclamationMark) { + this.state = State.BeforeDeclaration; + this.sectionStart = this.index + 1; + } else if (c === CharCodes.Questionmark) { + this.state = State.InProcessingInstruction; + this.sectionStart = this.index + 1; + } else if (this.isTagStartChar(c)) { + var lower = c | 32; + this.sectionStart = this.index; + if (this.xmlMode) { + this.state = State.InTagName; + } else if (lower === Sequences.ScriptEnd[2]) { + this.state = State.BeforeSpecialS; + } else if (lower === Sequences.TitleEnd[2]) { + this.state = State.BeforeSpecialT; + } else { + this.state = State.InTagName; + } + } else if (c === CharCodes.Slash) { + this.state = State.BeforeClosingTagName; + } else { + this.state = State.Text; + this.stateText(c); + } + }; + Tokenizer2.prototype.stateInTagName = function(c) { + if (isEndOfTagSection(c)) { + this.cbs.onopentagname(this.sectionStart, this.index); + this.sectionStart = -1; + this.state = State.BeforeAttributeName; + this.stateBeforeAttributeName(c); + } + }; + Tokenizer2.prototype.stateBeforeClosingTagName = function(c) { + if (isWhitespace(c)) { + } else if (c === CharCodes.Gt) { + this.state = State.Text; + } else { + this.state = this.isTagStartChar(c) ? State.InClosingTagName : State.InSpecialComment; + this.sectionStart = this.index; + } + }; + Tokenizer2.prototype.stateInClosingTagName = function(c) { + if (c === CharCodes.Gt || isWhitespace(c)) { + this.cbs.onclosetag(this.sectionStart, this.index); + this.sectionStart = -1; + this.state = State.AfterClosingTagName; + this.stateAfterClosingTagName(c); + } + }; + Tokenizer2.prototype.stateAfterClosingTagName = function(c) { + if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) { + this.state = State.Text; + this.sectionStart = this.index + 1; + } + }; + Tokenizer2.prototype.stateBeforeAttributeName = function(c) { + if (c === CharCodes.Gt) { + this.cbs.onopentagend(this.index); + if (this.isSpecial) { + this.state = State.InSpecialTag; + this.sequenceIndex = 0; + } else { + this.state = State.Text; + } + this.sectionStart = this.index + 1; + } else if (c === CharCodes.Slash) { + this.state = State.InSelfClosingTag; + } else if (!isWhitespace(c)) { + this.state = State.InAttributeName; + this.sectionStart = this.index; + } + }; + Tokenizer2.prototype.stateInSelfClosingTag = function(c) { + if (c === CharCodes.Gt) { + this.cbs.onselfclosingtag(this.index); + this.state = State.Text; + this.sectionStart = this.index + 1; + this.isSpecial = false; + } else if (!isWhitespace(c)) { + this.state = State.BeforeAttributeName; + this.stateBeforeAttributeName(c); + } + }; + Tokenizer2.prototype.stateInAttributeName = function(c) { + if (c === CharCodes.Eq || isEndOfTagSection(c)) { + this.cbs.onattribname(this.sectionStart, this.index); + this.sectionStart = this.index; + this.state = State.AfterAttributeName; + this.stateAfterAttributeName(c); + } + }; + Tokenizer2.prototype.stateAfterAttributeName = function(c) { + if (c === CharCodes.Eq) { + this.state = State.BeforeAttributeValue; + } else if (c === CharCodes.Slash || c === CharCodes.Gt) { + this.cbs.onattribend(QuoteType.NoValue, this.sectionStart); + this.sectionStart = -1; + this.state = State.BeforeAttributeName; + this.stateBeforeAttributeName(c); + } else if (!isWhitespace(c)) { + this.cbs.onattribend(QuoteType.NoValue, this.sectionStart); + this.state = State.InAttributeName; + this.sectionStart = this.index; + } + }; + Tokenizer2.prototype.stateBeforeAttributeValue = function(c) { + if (c === CharCodes.DoubleQuote) { + this.state = State.InAttributeValueDq; + this.sectionStart = this.index + 1; + } else if (c === CharCodes.SingleQuote) { + this.state = State.InAttributeValueSq; + this.sectionStart = this.index + 1; + } else if (!isWhitespace(c)) { + this.sectionStart = this.index; + this.state = State.InAttributeValueNq; + this.stateInAttributeValueNoQuotes(c); + } + }; + Tokenizer2.prototype.handleInAttributeValue = function(c, quote) { + if (c === quote || !this.decodeEntities && this.fastForwardTo(quote)) { + this.cbs.onattribdata(this.sectionStart, this.index); + this.sectionStart = -1; + this.cbs.onattribend(quote === CharCodes.DoubleQuote ? QuoteType.Double : QuoteType.Single, this.index + 1); + this.state = State.BeforeAttributeName; + } else if (this.decodeEntities && c === CharCodes.Amp) { + this.startEntity(); + } + }; + Tokenizer2.prototype.stateInAttributeValueDoubleQuotes = function(c) { + this.handleInAttributeValue(c, CharCodes.DoubleQuote); + }; + Tokenizer2.prototype.stateInAttributeValueSingleQuotes = function(c) { + this.handleInAttributeValue(c, CharCodes.SingleQuote); + }; + Tokenizer2.prototype.stateInAttributeValueNoQuotes = function(c) { + if (isWhitespace(c) || c === CharCodes.Gt) { + this.cbs.onattribdata(this.sectionStart, this.index); + this.sectionStart = -1; + this.cbs.onattribend(QuoteType.Unquoted, this.index); + this.state = State.BeforeAttributeName; + this.stateBeforeAttributeName(c); + } else if (this.decodeEntities && c === CharCodes.Amp) { + this.startEntity(); + } + }; + Tokenizer2.prototype.stateBeforeDeclaration = function(c) { + if (c === CharCodes.OpeningSquareBracket) { + this.state = State.CDATASequence; + this.sequenceIndex = 0; + } else { + this.state = c === CharCodes.Dash ? State.BeforeComment : State.InDeclaration; + } + }; + Tokenizer2.prototype.stateInDeclaration = function(c) { + if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) { + this.cbs.ondeclaration(this.sectionStart, this.index); + this.state = State.Text; + this.sectionStart = this.index + 1; + } + }; + Tokenizer2.prototype.stateInProcessingInstruction = function(c) { + if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) { + this.cbs.onprocessinginstruction(this.sectionStart, this.index); + this.state = State.Text; + this.sectionStart = this.index + 1; + } + }; + Tokenizer2.prototype.stateBeforeComment = function(c) { + if (c === CharCodes.Dash) { + this.state = State.InCommentLike; + this.currentSequence = Sequences.CommentEnd; + this.sequenceIndex = 2; + this.sectionStart = this.index + 1; + } else { + this.state = State.InDeclaration; + } + }; + Tokenizer2.prototype.stateInSpecialComment = function(c) { + if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) { + this.cbs.oncomment(this.sectionStart, this.index, 0); + this.state = State.Text; + this.sectionStart = this.index + 1; + } + }; + Tokenizer2.prototype.stateBeforeSpecialS = function(c) { + var lower = c | 32; + if (lower === Sequences.ScriptEnd[3]) { + this.startSpecial(Sequences.ScriptEnd, 4); + } else if (lower === Sequences.StyleEnd[3]) { + this.startSpecial(Sequences.StyleEnd, 4); + } else { + this.state = State.InTagName; + this.stateInTagName(c); + } + }; + Tokenizer2.prototype.stateBeforeSpecialT = function(c) { + var lower = c | 32; + if (lower === Sequences.TitleEnd[3]) { + this.startSpecial(Sequences.TitleEnd, 4); + } else if (lower === Sequences.TextareaEnd[3]) { + this.startSpecial(Sequences.TextareaEnd, 4); + } else { + this.state = State.InTagName; + this.stateInTagName(c); + } + }; + Tokenizer2.prototype.startEntity = function() { + this.baseState = this.state; + this.state = State.InEntity; + this.entityStart = this.index; + this.entityDecoder.startEntity(this.xmlMode ? decode_js_1.DecodingMode.Strict : this.baseState === State.Text || this.baseState === State.InSpecialTag ? decode_js_1.DecodingMode.Legacy : decode_js_1.DecodingMode.Attribute); + }; + Tokenizer2.prototype.stateInEntity = function() { + var length = this.entityDecoder.write(this.buffer, this.index - this.offset); + if (length >= 0) { + this.state = this.baseState; + if (length === 0) { + this.index = this.entityStart; + } + } else { + this.index = this.offset + this.buffer.length - 1; + } + }; + Tokenizer2.prototype.cleanup = function() { + if (this.running && this.sectionStart !== this.index) { + if (this.state === State.Text || this.state === State.InSpecialTag && this.sequenceIndex === 0) { + this.cbs.ontext(this.sectionStart, this.index); + this.sectionStart = this.index; + } else if (this.state === State.InAttributeValueDq || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueNq) { + this.cbs.onattribdata(this.sectionStart, this.index); + this.sectionStart = this.index; + } + } + }; + Tokenizer2.prototype.shouldContinue = function() { + return this.index < this.buffer.length + this.offset && this.running; + }; + Tokenizer2.prototype.parse = function() { + while (this.shouldContinue()) { + var c = this.buffer.charCodeAt(this.index - this.offset); + switch (this.state) { + case State.Text: { + this.stateText(c); + break; + } + case State.SpecialStartSequence: { + this.stateSpecialStartSequence(c); + break; + } + case State.InSpecialTag: { + this.stateInSpecialTag(c); + break; + } + case State.CDATASequence: { + this.stateCDATASequence(c); + break; + } + case State.InAttributeValueDq: { + this.stateInAttributeValueDoubleQuotes(c); + break; + } + case State.InAttributeName: { + this.stateInAttributeName(c); + break; + } + case State.InCommentLike: { + this.stateInCommentLike(c); + break; + } + case State.InSpecialComment: { + this.stateInSpecialComment(c); + break; + } + case State.BeforeAttributeName: { + this.stateBeforeAttributeName(c); + break; + } + case State.InTagName: { + this.stateInTagName(c); + break; + } + case State.InClosingTagName: { + this.stateInClosingTagName(c); + break; + } + case State.BeforeTagName: { + this.stateBeforeTagName(c); + break; + } + case State.AfterAttributeName: { + this.stateAfterAttributeName(c); + break; + } + case State.InAttributeValueSq: { + this.stateInAttributeValueSingleQuotes(c); + break; + } + case State.BeforeAttributeValue: { + this.stateBeforeAttributeValue(c); + break; + } + case State.BeforeClosingTagName: { + this.stateBeforeClosingTagName(c); + break; + } + case State.AfterClosingTagName: { + this.stateAfterClosingTagName(c); + break; + } + case State.BeforeSpecialS: { + this.stateBeforeSpecialS(c); + break; + } + case State.BeforeSpecialT: { + this.stateBeforeSpecialT(c); + break; + } + case State.InAttributeValueNq: { + this.stateInAttributeValueNoQuotes(c); + break; + } + case State.InSelfClosingTag: { + this.stateInSelfClosingTag(c); + break; + } + case State.InDeclaration: { + this.stateInDeclaration(c); + break; + } + case State.BeforeDeclaration: { + this.stateBeforeDeclaration(c); + break; + } + case State.BeforeComment: { + this.stateBeforeComment(c); + break; + } + case State.InProcessingInstruction: { + this.stateInProcessingInstruction(c); + break; + } + case State.InEntity: { + this.stateInEntity(); + break; + } + } + this.index++; + } + this.cleanup(); + }; + Tokenizer2.prototype.finish = function() { + if (this.state === State.InEntity) { + this.entityDecoder.end(); + this.state = this.baseState; + } + this.handleTrailingData(); + this.cbs.onend(); + }; + Tokenizer2.prototype.handleTrailingData = function() { + var endIndex = this.buffer.length + this.offset; + if (this.sectionStart >= endIndex) { + return; + } + if (this.state === State.InCommentLike) { + if (this.currentSequence === Sequences.CdataEnd) { + this.cbs.oncdata(this.sectionStart, endIndex, 0); + } else { + this.cbs.oncomment(this.sectionStart, endIndex, 0); + } + } else if (this.state === State.InTagName || this.state === State.BeforeAttributeName || this.state === State.BeforeAttributeValue || this.state === State.AfterAttributeName || this.state === State.InAttributeName || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueDq || this.state === State.InAttributeValueNq || this.state === State.InClosingTagName) { + } else { + this.cbs.ontext(this.sectionStart, endIndex); + } + }; + Tokenizer2.prototype.emitCodePoint = function(cp, consumed) { + if (this.baseState !== State.Text && this.baseState !== State.InSpecialTag) { + if (this.sectionStart < this.entityStart) { + this.cbs.onattribdata(this.sectionStart, this.entityStart); + } + this.sectionStart = this.entityStart + consumed; + this.index = this.sectionStart - 1; + this.cbs.onattribentity(cp); + } else { + if (this.sectionStart < this.entityStart) { + this.cbs.ontext(this.sectionStart, this.entityStart); + } + this.sectionStart = this.entityStart + consumed; + this.index = this.sectionStart - 1; + this.cbs.ontextentity(cp, this.sectionStart); + } + }; + return Tokenizer2; + })() + ); + exports2.default = Tokenizer; + } +}); + +// node_modules/htmlparser2/lib/Parser.js +var require_Parser = __commonJS({ + "node_modules/htmlparser2/lib/Parser.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Parser = void 0; + var Tokenizer_js_1 = __importStar2(require_Tokenizer()); + var decode_js_1 = require_decode2(); + var formTags = /* @__PURE__ */ new Set([ + "input", + "option", + "optgroup", + "select", + "button", + "datalist", + "textarea" + ]); + var pTag = /* @__PURE__ */ new Set(["p"]); + var tableSectionTags = /* @__PURE__ */ new Set(["thead", "tbody"]); + var ddtTags = /* @__PURE__ */ new Set(["dd", "dt"]); + var rtpTags = /* @__PURE__ */ new Set(["rt", "rp"]); + var openImpliesClose = /* @__PURE__ */ new Map([ + ["tr", /* @__PURE__ */ new Set(["tr", "th", "td"])], + ["th", /* @__PURE__ */ new Set(["th"])], + ["td", /* @__PURE__ */ new Set(["thead", "th", "td"])], + ["body", /* @__PURE__ */ new Set(["head", "link", "script"])], + ["li", /* @__PURE__ */ new Set(["li"])], + ["p", pTag], + ["h1", pTag], + ["h2", pTag], + ["h3", pTag], + ["h4", pTag], + ["h5", pTag], + ["h6", pTag], + ["select", formTags], + ["input", formTags], + ["output", formTags], + ["button", formTags], + ["datalist", formTags], + ["textarea", formTags], + ["option", /* @__PURE__ */ new Set(["option"])], + ["optgroup", /* @__PURE__ */ new Set(["optgroup", "option"])], + ["dd", ddtTags], + ["dt", ddtTags], + ["address", pTag], + ["article", pTag], + ["aside", pTag], + ["blockquote", pTag], + ["details", pTag], + ["div", pTag], + ["dl", pTag], + ["fieldset", pTag], + ["figcaption", pTag], + ["figure", pTag], + ["footer", pTag], + ["form", pTag], + ["header", pTag], + ["hr", pTag], + ["main", pTag], + ["nav", pTag], + ["ol", pTag], + ["pre", pTag], + ["section", pTag], + ["table", pTag], + ["ul", pTag], + ["rt", rtpTags], + ["rp", rtpTags], + ["tbody", tableSectionTags], + ["tfoot", tableSectionTags] + ]); + var voidElements = /* @__PURE__ */ new Set([ + "area", + "base", + "basefont", + "br", + "col", + "command", + "embed", + "frame", + "hr", + "img", + "input", + "isindex", + "keygen", + "link", + "meta", + "param", + "source", + "track", + "wbr" + ]); + var foreignContextElements = /* @__PURE__ */ new Set(["math", "svg"]); + var htmlIntegrationElements = /* @__PURE__ */ new Set([ + "mi", + "mo", + "mn", + "ms", + "mtext", + "annotation-xml", + "foreignobject", + "desc", + "title" + ]); + var reNameEnd = /\s|\//; + var Parser = ( + /** @class */ + (function() { + function Parser2(cbs, options) { + if (options === void 0) { + options = {}; + } + var _a, _b, _c, _d, _e, _f; + this.options = options; + this.startIndex = 0; + this.endIndex = 0; + this.openTagStart = 0; + this.tagname = ""; + this.attribname = ""; + this.attribvalue = ""; + this.attribs = null; + this.stack = []; + this.buffers = []; + this.bufferOffset = 0; + this.writeIndex = 0; + this.ended = false; + this.cbs = cbs !== null && cbs !== void 0 ? cbs : {}; + this.htmlMode = !this.options.xmlMode; + this.lowerCaseTagNames = (_a = options.lowerCaseTags) !== null && _a !== void 0 ? _a : this.htmlMode; + this.lowerCaseAttributeNames = (_b = options.lowerCaseAttributeNames) !== null && _b !== void 0 ? _b : this.htmlMode; + this.recognizeSelfClosing = (_c = options.recognizeSelfClosing) !== null && _c !== void 0 ? _c : !this.htmlMode; + this.tokenizer = new ((_d = options.Tokenizer) !== null && _d !== void 0 ? _d : Tokenizer_js_1.default)(this.options, this); + this.foreignContext = [!this.htmlMode]; + (_f = (_e = this.cbs).onparserinit) === null || _f === void 0 ? void 0 : _f.call(_e, this); + } + Parser2.prototype.ontext = function(start, endIndex) { + var _a, _b; + var data = this.getSlice(start, endIndex); + this.endIndex = endIndex - 1; + (_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, data); + this.startIndex = endIndex; + }; + Parser2.prototype.ontextentity = function(cp, endIndex) { + var _a, _b; + this.endIndex = endIndex - 1; + (_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, (0, decode_js_1.fromCodePoint)(cp)); + this.startIndex = endIndex; + }; + Parser2.prototype.isVoidElement = function(name) { + return this.htmlMode && voidElements.has(name); + }; + Parser2.prototype.onopentagname = function(start, endIndex) { + this.endIndex = endIndex; + var name = this.getSlice(start, endIndex); + if (this.lowerCaseTagNames) { + name = name.toLowerCase(); + } + this.emitOpenTag(name); + }; + Parser2.prototype.emitOpenTag = function(name) { + var _a, _b, _c, _d; + this.openTagStart = this.startIndex; + this.tagname = name; + var impliesClose = this.htmlMode && openImpliesClose.get(name); + if (impliesClose) { + while (this.stack.length > 0 && impliesClose.has(this.stack[0])) { + var element = this.stack.shift(); + (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, element, true); + } + } + if (!this.isVoidElement(name)) { + this.stack.unshift(name); + if (this.htmlMode) { + if (foreignContextElements.has(name)) { + this.foreignContext.unshift(true); + } else if (htmlIntegrationElements.has(name)) { + this.foreignContext.unshift(false); + } + } + } + (_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, name); + if (this.cbs.onopentag) + this.attribs = {}; + }; + Parser2.prototype.endOpenTag = function(isImplied) { + var _a, _b; + this.startIndex = this.openTagStart; + if (this.attribs) { + (_b = (_a = this.cbs).onopentag) === null || _b === void 0 ? void 0 : _b.call(_a, this.tagname, this.attribs, isImplied); + this.attribs = null; + } + if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) { + this.cbs.onclosetag(this.tagname, true); + } + this.tagname = ""; + }; + Parser2.prototype.onopentagend = function(endIndex) { + this.endIndex = endIndex; + this.endOpenTag(false); + this.startIndex = endIndex + 1; + }; + Parser2.prototype.onclosetag = function(start, endIndex) { + var _a, _b, _c, _d, _e, _f, _g, _h; + this.endIndex = endIndex; + var name = this.getSlice(start, endIndex); + if (this.lowerCaseTagNames) { + name = name.toLowerCase(); + } + if (this.htmlMode && (foreignContextElements.has(name) || htmlIntegrationElements.has(name))) { + this.foreignContext.shift(); + } + if (!this.isVoidElement(name)) { + var pos = this.stack.indexOf(name); + if (pos !== -1) { + for (var index = 0; index <= pos; index++) { + var element = this.stack.shift(); + (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, element, index !== pos); + } + } else if (this.htmlMode && name === "p") { + this.emitOpenTag("p"); + this.closeCurrentTag(true); + } + } else if (this.htmlMode && name === "br") { + (_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, "br"); + (_f = (_e = this.cbs).onopentag) === null || _f === void 0 ? void 0 : _f.call(_e, "br", {}, true); + (_h = (_g = this.cbs).onclosetag) === null || _h === void 0 ? void 0 : _h.call(_g, "br", false); + } + this.startIndex = endIndex + 1; + }; + Parser2.prototype.onselfclosingtag = function(endIndex) { + this.endIndex = endIndex; + if (this.recognizeSelfClosing || this.foreignContext[0]) { + this.closeCurrentTag(false); + this.startIndex = endIndex + 1; + } else { + this.onopentagend(endIndex); + } + }; + Parser2.prototype.closeCurrentTag = function(isOpenImplied) { + var _a, _b; + var name = this.tagname; + this.endOpenTag(isOpenImplied); + if (this.stack[0] === name) { + (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, name, !isOpenImplied); + this.stack.shift(); + } + }; + Parser2.prototype.onattribname = function(start, endIndex) { + this.startIndex = start; + var name = this.getSlice(start, endIndex); + this.attribname = this.lowerCaseAttributeNames ? name.toLowerCase() : name; + }; + Parser2.prototype.onattribdata = function(start, endIndex) { + this.attribvalue += this.getSlice(start, endIndex); + }; + Parser2.prototype.onattribentity = function(cp) { + this.attribvalue += (0, decode_js_1.fromCodePoint)(cp); + }; + Parser2.prototype.onattribend = function(quote, endIndex) { + var _a, _b; + this.endIndex = endIndex; + (_b = (_a = this.cbs).onattribute) === null || _b === void 0 ? void 0 : _b.call(_a, this.attribname, this.attribvalue, quote === Tokenizer_js_1.QuoteType.Double ? '"' : quote === Tokenizer_js_1.QuoteType.Single ? "'" : quote === Tokenizer_js_1.QuoteType.NoValue ? void 0 : null); + if (this.attribs && !Object.prototype.hasOwnProperty.call(this.attribs, this.attribname)) { + this.attribs[this.attribname] = this.attribvalue; + } + this.attribvalue = ""; + }; + Parser2.prototype.getInstructionName = function(value) { + var index = value.search(reNameEnd); + var name = index < 0 ? value : value.substr(0, index); + if (this.lowerCaseTagNames) { + name = name.toLowerCase(); + } + return name; + }; + Parser2.prototype.ondeclaration = function(start, endIndex) { + this.endIndex = endIndex; + var value = this.getSlice(start, endIndex); + if (this.cbs.onprocessinginstruction) { + var name = this.getInstructionName(value); + this.cbs.onprocessinginstruction("!".concat(name), "!".concat(value)); + } + this.startIndex = endIndex + 1; + }; + Parser2.prototype.onprocessinginstruction = function(start, endIndex) { + this.endIndex = endIndex; + var value = this.getSlice(start, endIndex); + if (this.cbs.onprocessinginstruction) { + var name = this.getInstructionName(value); + this.cbs.onprocessinginstruction("?".concat(name), "?".concat(value)); + } + this.startIndex = endIndex + 1; + }; + Parser2.prototype.oncomment = function(start, endIndex, offset) { + var _a, _b, _c, _d; + this.endIndex = endIndex; + (_b = (_a = this.cbs).oncomment) === null || _b === void 0 ? void 0 : _b.call(_a, this.getSlice(start, endIndex - offset)); + (_d = (_c = this.cbs).oncommentend) === null || _d === void 0 ? void 0 : _d.call(_c); + this.startIndex = endIndex + 1; + }; + Parser2.prototype.oncdata = function(start, endIndex, offset) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; + this.endIndex = endIndex; + var value = this.getSlice(start, endIndex - offset); + if (!this.htmlMode || this.options.recognizeCDATA) { + (_b = (_a = this.cbs).oncdatastart) === null || _b === void 0 ? void 0 : _b.call(_a); + (_d = (_c = this.cbs).ontext) === null || _d === void 0 ? void 0 : _d.call(_c, value); + (_f = (_e = this.cbs).oncdataend) === null || _f === void 0 ? void 0 : _f.call(_e); + } else { + (_h = (_g = this.cbs).oncomment) === null || _h === void 0 ? void 0 : _h.call(_g, "[CDATA[".concat(value, "]]")); + (_k = (_j = this.cbs).oncommentend) === null || _k === void 0 ? void 0 : _k.call(_j); + } + this.startIndex = endIndex + 1; + }; + Parser2.prototype.onend = function() { + var _a, _b; + if (this.cbs.onclosetag) { + this.endIndex = this.startIndex; + for (var index = 0; index < this.stack.length; index++) { + this.cbs.onclosetag(this.stack[index], true); + } + } + (_b = (_a = this.cbs).onend) === null || _b === void 0 ? void 0 : _b.call(_a); + }; + Parser2.prototype.reset = function() { + var _a, _b, _c, _d; + (_b = (_a = this.cbs).onreset) === null || _b === void 0 ? void 0 : _b.call(_a); + this.tokenizer.reset(); + this.tagname = ""; + this.attribname = ""; + this.attribs = null; + this.stack.length = 0; + this.startIndex = 0; + this.endIndex = 0; + (_d = (_c = this.cbs).onparserinit) === null || _d === void 0 ? void 0 : _d.call(_c, this); + this.buffers.length = 0; + this.foreignContext.length = 0; + this.foreignContext.unshift(!this.htmlMode); + this.bufferOffset = 0; + this.writeIndex = 0; + this.ended = false; + }; + Parser2.prototype.parseComplete = function(data) { + this.reset(); + this.end(data); + }; + Parser2.prototype.getSlice = function(start, end) { + while (start - this.bufferOffset >= this.buffers[0].length) { + this.shiftBuffer(); + } + var slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset); + while (end - this.bufferOffset > this.buffers[0].length) { + this.shiftBuffer(); + slice += this.buffers[0].slice(0, end - this.bufferOffset); + } + return slice; + }; + Parser2.prototype.shiftBuffer = function() { + this.bufferOffset += this.buffers[0].length; + this.writeIndex--; + this.buffers.shift(); + }; + Parser2.prototype.write = function(chunk) { + var _a, _b; + if (this.ended) { + (_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, new Error(".write() after done!")); + return; + } + this.buffers.push(chunk); + if (this.tokenizer.running) { + this.tokenizer.write(chunk); + this.writeIndex++; + } + }; + Parser2.prototype.end = function(chunk) { + var _a, _b; + if (this.ended) { + (_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, new Error(".end() after done!")); + return; + } + if (chunk) + this.write(chunk); + this.ended = true; + this.tokenizer.end(); + }; + Parser2.prototype.pause = function() { + this.tokenizer.pause(); + }; + Parser2.prototype.resume = function() { + this.tokenizer.resume(); + while (this.tokenizer.running && this.writeIndex < this.buffers.length) { + this.tokenizer.write(this.buffers[this.writeIndex++]); + } + if (this.ended) + this.tokenizer.end(); + }; + Parser2.prototype.parseChunk = function(chunk) { + this.write(chunk); + }; + Parser2.prototype.done = function(chunk) { + this.end(chunk); + }; + return Parser2; + })() + ); + exports2.Parser = Parser; + } +}); + +// node_modules/domelementtype/lib/index.js +var require_lib12 = __commonJS({ + "node_modules/domelementtype/lib/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Doctype = exports2.CDATA = exports2.Tag = exports2.Style = exports2.Script = exports2.Comment = exports2.Directive = exports2.Text = exports2.Root = exports2.isTag = exports2.ElementType = void 0; + var ElementType; + (function(ElementType2) { + ElementType2["Root"] = "root"; + ElementType2["Text"] = "text"; + ElementType2["Directive"] = "directive"; + ElementType2["Comment"] = "comment"; + ElementType2["Script"] = "script"; + ElementType2["Style"] = "style"; + ElementType2["Tag"] = "tag"; + ElementType2["CDATA"] = "cdata"; + ElementType2["Doctype"] = "doctype"; + })(ElementType = exports2.ElementType || (exports2.ElementType = {})); + function isTag(elem) { + return elem.type === ElementType.Tag || elem.type === ElementType.Script || elem.type === ElementType.Style; + } + exports2.isTag = isTag; + exports2.Root = ElementType.Root; + exports2.Text = ElementType.Text; + exports2.Directive = ElementType.Directive; + exports2.Comment = ElementType.Comment; + exports2.Script = ElementType.Script; + exports2.Style = ElementType.Style; + exports2.Tag = ElementType.Tag; + exports2.CDATA = ElementType.CDATA; + exports2.Doctype = ElementType.Doctype; + } +}); + +// node_modules/domhandler/lib/node.js +var require_node6 = __commonJS({ + "node_modules/domhandler/lib/node.js"(exports2) { + "use strict"; + var __extends2 = exports2 && exports2.__extends || /* @__PURE__ */ (function() { + var extendStatics2 = function(d, b) { + extendStatics2 = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { + d2.__proto__ = b2; + } || function(d2, b2) { + for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p]; + }; + return extendStatics2(d, b); + }; + return function(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics2(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + })(); + var __assign2 = exports2 && exports2.__assign || function() { + __assign2 = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign2.apply(this, arguments); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.cloneNode = exports2.hasChildren = exports2.isDocument = exports2.isDirective = exports2.isComment = exports2.isText = exports2.isCDATA = exports2.isTag = exports2.Element = exports2.Document = exports2.CDATA = exports2.NodeWithChildren = exports2.ProcessingInstruction = exports2.Comment = exports2.Text = exports2.DataNode = exports2.Node = void 0; + var domelementtype_1 = require_lib12(); + var Node = ( + /** @class */ + (function() { + function Node2() { + this.parent = null; + this.prev = null; + this.next = null; + this.startIndex = null; + this.endIndex = null; + } + Object.defineProperty(Node2.prototype, "parentNode", { + // Read-write aliases for properties + /** + * Same as {@link parent}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function() { + return this.parent; + }, + set: function(parent) { + this.parent = parent; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node2.prototype, "previousSibling", { + /** + * Same as {@link prev}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function() { + return this.prev; + }, + set: function(prev) { + this.prev = prev; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node2.prototype, "nextSibling", { + /** + * Same as {@link next}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function() { + return this.next; + }, + set: function(next) { + this.next = next; + }, + enumerable: false, + configurable: true + }); + Node2.prototype.cloneNode = function(recursive) { + if (recursive === void 0) { + recursive = false; + } + return cloneNode(this, recursive); + }; + return Node2; + })() + ); + exports2.Node = Node; + var DataNode = ( + /** @class */ + (function(_super) { + __extends2(DataNode2, _super); + function DataNode2(data) { + var _this = _super.call(this) || this; + _this.data = data; + return _this; + } + Object.defineProperty(DataNode2.prototype, "nodeValue", { + /** + * Same as {@link data}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function() { + return this.data; + }, + set: function(data) { + this.data = data; + }, + enumerable: false, + configurable: true + }); + return DataNode2; + })(Node) + ); + exports2.DataNode = DataNode; + var Text = ( + /** @class */ + (function(_super) { + __extends2(Text2, _super); + function Text2() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = domelementtype_1.ElementType.Text; + return _this; + } + Object.defineProperty(Text2.prototype, "nodeType", { + get: function() { + return 3; + }, + enumerable: false, + configurable: true + }); + return Text2; + })(DataNode) + ); + exports2.Text = Text; + var Comment = ( + /** @class */ + (function(_super) { + __extends2(Comment2, _super); + function Comment2() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = domelementtype_1.ElementType.Comment; + return _this; + } + Object.defineProperty(Comment2.prototype, "nodeType", { + get: function() { + return 8; + }, + enumerable: false, + configurable: true + }); + return Comment2; + })(DataNode) + ); + exports2.Comment = Comment; + var ProcessingInstruction = ( + /** @class */ + (function(_super) { + __extends2(ProcessingInstruction2, _super); + function ProcessingInstruction2(name, data) { + var _this = _super.call(this, data) || this; + _this.name = name; + _this.type = domelementtype_1.ElementType.Directive; + return _this; + } + Object.defineProperty(ProcessingInstruction2.prototype, "nodeType", { + get: function() { + return 1; + }, + enumerable: false, + configurable: true + }); + return ProcessingInstruction2; + })(DataNode) + ); + exports2.ProcessingInstruction = ProcessingInstruction; + var NodeWithChildren = ( + /** @class */ + (function(_super) { + __extends2(NodeWithChildren2, _super); + function NodeWithChildren2(children) { + var _this = _super.call(this) || this; + _this.children = children; + return _this; + } + Object.defineProperty(NodeWithChildren2.prototype, "firstChild", { + // Aliases + /** First child of the node. */ + get: function() { + var _a; + return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(NodeWithChildren2.prototype, "lastChild", { + /** Last child of the node. */ + get: function() { + return this.children.length > 0 ? this.children[this.children.length - 1] : null; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(NodeWithChildren2.prototype, "childNodes", { + /** + * Same as {@link children}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function() { + return this.children; + }, + set: function(children) { + this.children = children; + }, + enumerable: false, + configurable: true + }); + return NodeWithChildren2; + })(Node) + ); + exports2.NodeWithChildren = NodeWithChildren; + var CDATA = ( + /** @class */ + (function(_super) { + __extends2(CDATA2, _super); + function CDATA2() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = domelementtype_1.ElementType.CDATA; + return _this; + } + Object.defineProperty(CDATA2.prototype, "nodeType", { + get: function() { + return 4; + }, + enumerable: false, + configurable: true + }); + return CDATA2; + })(NodeWithChildren) + ); + exports2.CDATA = CDATA; + var Document = ( + /** @class */ + (function(_super) { + __extends2(Document2, _super); + function Document2() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = domelementtype_1.ElementType.Root; + return _this; + } + Object.defineProperty(Document2.prototype, "nodeType", { + get: function() { + return 9; + }, + enumerable: false, + configurable: true + }); + return Document2; + })(NodeWithChildren) + ); + exports2.Document = Document; + var Element = ( + /** @class */ + (function(_super) { + __extends2(Element2, _super); + function Element2(name, attribs, children, type) { + if (children === void 0) { + children = []; + } + if (type === void 0) { + type = name === "script" ? domelementtype_1.ElementType.Script : name === "style" ? domelementtype_1.ElementType.Style : domelementtype_1.ElementType.Tag; + } + var _this = _super.call(this, children) || this; + _this.name = name; + _this.attribs = attribs; + _this.type = type; + return _this; + } + Object.defineProperty(Element2.prototype, "nodeType", { + get: function() { + return 1; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Element2.prototype, "tagName", { + // DOM Level 1 aliases + /** + * Same as {@link name}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function() { + return this.name; + }, + set: function(name) { + this.name = name; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Element2.prototype, "attributes", { + get: function() { + var _this = this; + return Object.keys(this.attribs).map(function(name) { + var _a, _b; + return { + name, + value: _this.attribs[name], + namespace: (_a = _this["x-attribsNamespace"]) === null || _a === void 0 ? void 0 : _a[name], + prefix: (_b = _this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name] + }; + }); + }, + enumerable: false, + configurable: true + }); + return Element2; + })(NodeWithChildren) + ); + exports2.Element = Element; + function isTag(node) { + return (0, domelementtype_1.isTag)(node); + } + exports2.isTag = isTag; + function isCDATA(node) { + return node.type === domelementtype_1.ElementType.CDATA; + } + exports2.isCDATA = isCDATA; + function isText(node) { + return node.type === domelementtype_1.ElementType.Text; + } + exports2.isText = isText; + function isComment(node) { + return node.type === domelementtype_1.ElementType.Comment; + } + exports2.isComment = isComment; + function isDirective(node) { + return node.type === domelementtype_1.ElementType.Directive; + } + exports2.isDirective = isDirective; + function isDocument(node) { + return node.type === domelementtype_1.ElementType.Root; + } + exports2.isDocument = isDocument; + function hasChildren(node) { + return Object.prototype.hasOwnProperty.call(node, "children"); + } + exports2.hasChildren = hasChildren; + function cloneNode(node, recursive) { + if (recursive === void 0) { + recursive = false; + } + var result; + if (isText(node)) { + result = new Text(node.data); + } else if (isComment(node)) { + result = new Comment(node.data); + } else if (isTag(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_1 = new Element(node.name, __assign2({}, node.attribs), children); + children.forEach(function(child) { + return child.parent = clone_1; + }); + if (node.namespace != null) { + clone_1.namespace = node.namespace; + } + if (node["x-attribsNamespace"]) { + clone_1["x-attribsNamespace"] = __assign2({}, node["x-attribsNamespace"]); + } + if (node["x-attribsPrefix"]) { + clone_1["x-attribsPrefix"] = __assign2({}, node["x-attribsPrefix"]); + } + result = clone_1; + } else if (isCDATA(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_2 = new CDATA(children); + children.forEach(function(child) { + return child.parent = clone_2; + }); + result = clone_2; + } else if (isDocument(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_3 = new Document(children); + children.forEach(function(child) { + return child.parent = clone_3; + }); + if (node["x-mode"]) { + clone_3["x-mode"] = node["x-mode"]; + } + result = clone_3; + } else if (isDirective(node)) { + var instruction = new ProcessingInstruction(node.name, node.data); + if (node["x-name"] != null) { + instruction["x-name"] = node["x-name"]; + instruction["x-publicId"] = node["x-publicId"]; + instruction["x-systemId"] = node["x-systemId"]; + } + result = instruction; + } else { + throw new Error("Not implemented yet: ".concat(node.type)); + } + result.startIndex = node.startIndex; + result.endIndex = node.endIndex; + if (node.sourceCodeLocation != null) { + result.sourceCodeLocation = node.sourceCodeLocation; + } + return result; + } + exports2.cloneNode = cloneNode; + function cloneChildren(childs) { + var children = childs.map(function(child) { + return cloneNode(child, true); + }); + for (var i = 1; i < children.length; i++) { + children[i].prev = children[i - 1]; + children[i - 1].next = children[i]; + } + return children; + } + } +}); + +// node_modules/domhandler/lib/index.js +var require_lib13 = __commonJS({ + "node_modules/domhandler/lib/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DomHandler = void 0; + var domelementtype_1 = require_lib12(); + var node_js_1 = require_node6(); + __exportStar2(require_node6(), exports2); + var defaultOpts = { + withStartIndices: false, + withEndIndices: false, + xmlMode: false + }; + var DomHandler = ( + /** @class */ + (function() { + function DomHandler2(callback, options, elementCB) { + this.dom = []; + this.root = new node_js_1.Document(this.dom); + this.done = false; + this.tagStack = [this.root]; + this.lastNode = null; + this.parser = null; + if (typeof options === "function") { + elementCB = options; + options = defaultOpts; + } + if (typeof callback === "object") { + options = callback; + callback = void 0; + } + this.callback = callback !== null && callback !== void 0 ? callback : null; + this.options = options !== null && options !== void 0 ? options : defaultOpts; + this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null; + } + DomHandler2.prototype.onparserinit = function(parser) { + this.parser = parser; + }; + DomHandler2.prototype.onreset = function() { + this.dom = []; + this.root = new node_js_1.Document(this.dom); + this.done = false; + this.tagStack = [this.root]; + this.lastNode = null; + this.parser = null; + }; + DomHandler2.prototype.onend = function() { + if (this.done) + return; + this.done = true; + this.parser = null; + this.handleCallback(null); + }; + DomHandler2.prototype.onerror = function(error) { + this.handleCallback(error); + }; + DomHandler2.prototype.onclosetag = function() { + this.lastNode = null; + var elem = this.tagStack.pop(); + if (this.options.withEndIndices) { + elem.endIndex = this.parser.endIndex; + } + if (this.elementCB) + this.elementCB(elem); + }; + DomHandler2.prototype.onopentag = function(name, attribs) { + var type = this.options.xmlMode ? domelementtype_1.ElementType.Tag : void 0; + var element = new node_js_1.Element(name, attribs, void 0, type); + this.addNode(element); + this.tagStack.push(element); + }; + DomHandler2.prototype.ontext = function(data) { + var lastNode = this.lastNode; + if (lastNode && lastNode.type === domelementtype_1.ElementType.Text) { + lastNode.data += data; + if (this.options.withEndIndices) { + lastNode.endIndex = this.parser.endIndex; + } + } else { + var node = new node_js_1.Text(data); + this.addNode(node); + this.lastNode = node; + } + }; + DomHandler2.prototype.oncomment = function(data) { + if (this.lastNode && this.lastNode.type === domelementtype_1.ElementType.Comment) { + this.lastNode.data += data; + return; + } + var node = new node_js_1.Comment(data); + this.addNode(node); + this.lastNode = node; + }; + DomHandler2.prototype.oncommentend = function() { + this.lastNode = null; + }; + DomHandler2.prototype.oncdatastart = function() { + var text = new node_js_1.Text(""); + var node = new node_js_1.CDATA([text]); + this.addNode(node); + text.parent = node; + this.lastNode = text; + }; + DomHandler2.prototype.oncdataend = function() { + this.lastNode = null; + }; + DomHandler2.prototype.onprocessinginstruction = function(name, data) { + var node = new node_js_1.ProcessingInstruction(name, data); + this.addNode(node); + }; + DomHandler2.prototype.handleCallback = function(error) { + if (typeof this.callback === "function") { + this.callback(error, this.dom); + } else if (error) { + throw error; + } + }; + DomHandler2.prototype.addNode = function(node) { + var parent = this.tagStack[this.tagStack.length - 1]; + var previousSibling = parent.children[parent.children.length - 1]; + if (this.options.withStartIndices) { + node.startIndex = this.parser.startIndex; + } + if (this.options.withEndIndices) { + node.endIndex = this.parser.endIndex; + } + parent.children.push(node); + if (previousSibling) { + node.prev = previousSibling; + previousSibling.next = node; + } + node.parent = parent; + this.lastNode = null; + }; + return DomHandler2; + })() + ); + exports2.DomHandler = DomHandler; + exports2.default = DomHandler; + } +}); + +// node_modules/entities/lib/generated/encode-html.js +var require_encode_html = __commonJS({ + "node_modules/entities/lib/generated/encode-html.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + function restoreDiff(arr) { + for (var i = 1; i < arr.length; i++) { + arr[i][0] += arr[i - 1][0] + 1; + } + return arr; + } + exports2.default = new Map(/* @__PURE__ */ restoreDiff([[9, " "], [0, " "], [22, "!"], [0, """], [0, "#"], [0, "$"], [0, "%"], [0, "&"], [0, "'"], [0, "("], [0, ")"], [0, "*"], [0, "+"], [0, ","], [1, "."], [0, "/"], [10, ":"], [0, ";"], [0, { v: "<", n: 8402, o: "<⃒" }], [0, { v: "=", n: 8421, o: "=⃥" }], [0, { v: ">", n: 8402, o: ">⃒" }], [0, "?"], [0, "@"], [26, "["], [0, "\"], [0, "]"], [0, "^"], [0, "_"], [0, "`"], [5, { n: 106, o: "fj" }], [20, "{"], [0, "|"], [0, "}"], [34, " "], [0, "¡"], [0, "¢"], [0, "£"], [0, "¤"], [0, "¥"], [0, "¦"], [0, "§"], [0, "¨"], [0, "©"], [0, "ª"], [0, "«"], [0, "¬"], [0, "­"], [0, "®"], [0, "¯"], [0, "°"], [0, "±"], [0, "²"], [0, "³"], [0, "´"], [0, "µ"], [0, "¶"], [0, "·"], [0, "¸"], [0, "¹"], [0, "º"], [0, "»"], [0, "¼"], [0, "½"], [0, "¾"], [0, "¿"], [0, "À"], [0, "Á"], [0, "Â"], [0, "Ã"], [0, "Ä"], [0, "Å"], [0, "Æ"], [0, "Ç"], [0, "È"], [0, "É"], [0, "Ê"], [0, "Ë"], [0, "Ì"], [0, "Í"], [0, "Î"], [0, "Ï"], [0, "Ð"], [0, "Ñ"], [0, "Ò"], [0, "Ó"], [0, "Ô"], [0, "Õ"], [0, "Ö"], [0, "×"], [0, "Ø"], [0, "Ù"], [0, "Ú"], [0, "Û"], [0, "Ü"], [0, "Ý"], [0, "Þ"], [0, "ß"], [0, "à"], [0, "á"], [0, "â"], [0, "ã"], [0, "ä"], [0, "å"], [0, "æ"], [0, "ç"], [0, "è"], [0, "é"], [0, "ê"], [0, "ë"], [0, "ì"], [0, "í"], [0, "î"], [0, "ï"], [0, "ð"], [0, "ñ"], [0, "ò"], [0, "ó"], [0, "ô"], [0, "õ"], [0, "ö"], [0, "÷"], [0, "ø"], [0, "ù"], [0, "ú"], [0, "û"], [0, "ü"], [0, "ý"], [0, "þ"], [0, "ÿ"], [0, "Ā"], [0, "ā"], [0, "Ă"], [0, "ă"], [0, "Ą"], [0, "ą"], [0, "Ć"], [0, "ć"], [0, "Ĉ"], [0, "ĉ"], [0, "Ċ"], [0, "ċ"], [0, "Č"], [0, "č"], [0, "Ď"], [0, "ď"], [0, "Đ"], [0, "đ"], [0, "Ē"], [0, "ē"], [2, "Ė"], [0, "ė"], [0, "Ę"], [0, "ę"], [0, "Ě"], [0, "ě"], [0, "Ĝ"], [0, "ĝ"], [0, "Ğ"], [0, "ğ"], [0, "Ġ"], [0, "ġ"], [0, "Ģ"], [1, "Ĥ"], [0, "ĥ"], [0, "Ħ"], [0, "ħ"], [0, "Ĩ"], [0, "ĩ"], [0, "Ī"], [0, "ī"], [2, "Į"], [0, "į"], [0, "İ"], [0, "ı"], [0, "IJ"], [0, "ij"], [0, "Ĵ"], [0, "ĵ"], [0, "Ķ"], [0, "ķ"], [0, "ĸ"], [0, "Ĺ"], [0, "ĺ"], [0, "Ļ"], [0, "ļ"], [0, "Ľ"], [0, "ľ"], [0, "Ŀ"], [0, "ŀ"], [0, "Ł"], [0, "ł"], [0, "Ń"], [0, "ń"], [0, "Ņ"], [0, "ņ"], [0, "Ň"], [0, "ň"], [0, "ʼn"], [0, "Ŋ"], [0, "ŋ"], [0, "Ō"], [0, "ō"], [2, "Ő"], [0, "ő"], [0, "Œ"], [0, "œ"], [0, "Ŕ"], [0, "ŕ"], [0, "Ŗ"], [0, "ŗ"], [0, "Ř"], [0, "ř"], [0, "Ś"], [0, "ś"], [0, "Ŝ"], [0, "ŝ"], [0, "Ş"], [0, "ş"], [0, "Š"], [0, "š"], [0, "Ţ"], [0, "ţ"], [0, "Ť"], [0, "ť"], [0, "Ŧ"], [0, "ŧ"], [0, "Ũ"], [0, "ũ"], [0, "Ū"], [0, "ū"], [0, "Ŭ"], [0, "ŭ"], [0, "Ů"], [0, "ů"], [0, "Ű"], [0, "ű"], [0, "Ų"], [0, "ų"], [0, "Ŵ"], [0, "ŵ"], [0, "Ŷ"], [0, "ŷ"], [0, "Ÿ"], [0, "Ź"], [0, "ź"], [0, "Ż"], [0, "ż"], [0, "Ž"], [0, "ž"], [19, "ƒ"], [34, "Ƶ"], [63, "ǵ"], [65, "ȷ"], [142, "ˆ"], [0, "ˇ"], [16, "˘"], [0, "˙"], [0, "˚"], [0, "˛"], [0, "˜"], [0, "˝"], [51, "̑"], [127, "Α"], [0, "Β"], [0, "Γ"], [0, "Δ"], [0, "Ε"], [0, "Ζ"], [0, "Η"], [0, "Θ"], [0, "Ι"], [0, "Κ"], [0, "Λ"], [0, "Μ"], [0, "Ν"], [0, "Ξ"], [0, "Ο"], [0, "Π"], [0, "Ρ"], [1, "Σ"], [0, "Τ"], [0, "Υ"], [0, "Φ"], [0, "Χ"], [0, "Ψ"], [0, "Ω"], [7, "α"], [0, "β"], [0, "γ"], [0, "δ"], [0, "ε"], [0, "ζ"], [0, "η"], [0, "θ"], [0, "ι"], [0, "κ"], [0, "λ"], [0, "μ"], [0, "ν"], [0, "ξ"], [0, "ο"], [0, "π"], [0, "ρ"], [0, "ς"], [0, "σ"], [0, "τ"], [0, "υ"], [0, "φ"], [0, "χ"], [0, "ψ"], [0, "ω"], [7, "ϑ"], [0, "ϒ"], [2, "ϕ"], [0, "ϖ"], [5, "Ϝ"], [0, "ϝ"], [18, "ϰ"], [0, "ϱ"], [3, "ϵ"], [0, "϶"], [10, "Ё"], [0, "Ђ"], [0, "Ѓ"], [0, "Є"], [0, "Ѕ"], [0, "І"], [0, "Ї"], [0, "Ј"], [0, "Љ"], [0, "Њ"], [0, "Ћ"], [0, "Ќ"], [1, "Ў"], [0, "Џ"], [0, "А"], [0, "Б"], [0, "В"], [0, "Г"], [0, "Д"], [0, "Е"], [0, "Ж"], [0, "З"], [0, "И"], [0, "Й"], [0, "К"], [0, "Л"], [0, "М"], [0, "Н"], [0, "О"], [0, "П"], [0, "Р"], [0, "С"], [0, "Т"], [0, "У"], [0, "Ф"], [0, "Х"], [0, "Ц"], [0, "Ч"], [0, "Ш"], [0, "Щ"], [0, "Ъ"], [0, "Ы"], [0, "Ь"], [0, "Э"], [0, "Ю"], [0, "Я"], [0, "а"], [0, "б"], [0, "в"], [0, "г"], [0, "д"], [0, "е"], [0, "ж"], [0, "з"], [0, "и"], [0, "й"], [0, "к"], [0, "л"], [0, "м"], [0, "н"], [0, "о"], [0, "п"], [0, "р"], [0, "с"], [0, "т"], [0, "у"], [0, "ф"], [0, "х"], [0, "ц"], [0, "ч"], [0, "ш"], [0, "щ"], [0, "ъ"], [0, "ы"], [0, "ь"], [0, "э"], [0, "ю"], [0, "я"], [1, "ё"], [0, "ђ"], [0, "ѓ"], [0, "є"], [0, "ѕ"], [0, "і"], [0, "ї"], [0, "ј"], [0, "љ"], [0, "њ"], [0, "ћ"], [0, "ќ"], [1, "ў"], [0, "џ"], [7074, " "], [0, " "], [0, " "], [0, " "], [1, " "], [0, " "], [0, " "], [0, " "], [0, "​"], [0, "‌"], [0, "‍"], [0, "‎"], [0, "‏"], [0, "‐"], [2, "–"], [0, "—"], [0, "―"], [0, "‖"], [1, "‘"], [0, "’"], [0, "‚"], [1, "“"], [0, "”"], [0, "„"], [1, "†"], [0, "‡"], [0, "•"], [2, "‥"], [0, "…"], [9, "‰"], [0, "‱"], [0, "′"], [0, "″"], [0, "‴"], [0, "‵"], [3, "‹"], [0, "›"], [3, "‾"], [2, "⁁"], [1, "⁃"], [0, "⁄"], [10, "⁏"], [7, "⁗"], [7, { v: " ", n: 8202, o: "  " }], [0, "⁠"], [0, "⁡"], [0, "⁢"], [0, "⁣"], [72, "€"], [46, "⃛"], [0, "⃜"], [37, "ℂ"], [2, "℅"], [4, "ℊ"], [0, "ℋ"], [0, "ℌ"], [0, "ℍ"], [0, "ℎ"], [0, "ℏ"], [0, "ℐ"], [0, "ℑ"], [0, "ℒ"], [0, "ℓ"], [1, "ℕ"], [0, "№"], [0, "℗"], [0, "℘"], [0, "ℙ"], [0, "ℚ"], [0, "ℛ"], [0, "ℜ"], [0, "ℝ"], [0, "℞"], [3, "™"], [1, "ℤ"], [2, "℧"], [0, "ℨ"], [0, "℩"], [2, "ℬ"], [0, "ℭ"], [1, "ℯ"], [0, "ℰ"], [0, "ℱ"], [1, "ℳ"], [0, "ℴ"], [0, "ℵ"], [0, "ℶ"], [0, "ℷ"], [0, "ℸ"], [12, "ⅅ"], [0, "ⅆ"], [0, "ⅇ"], [0, "ⅈ"], [10, "⅓"], [0, "⅔"], [0, "⅕"], [0, "⅖"], [0, "⅗"], [0, "⅘"], [0, "⅙"], [0, "⅚"], [0, "⅛"], [0, "⅜"], [0, "⅝"], [0, "⅞"], [49, "←"], [0, "↑"], [0, "→"], [0, "↓"], [0, "↔"], [0, "↕"], [0, "↖"], [0, "↗"], [0, "↘"], [0, "↙"], [0, "↚"], [0, "↛"], [1, { v: "↝", n: 824, o: "↝̸" }], [0, "↞"], [0, "↟"], [0, "↠"], [0, "↡"], [0, "↢"], [0, "↣"], [0, "↤"], [0, "↥"], [0, "↦"], [0, "↧"], [1, "↩"], [0, "↪"], [0, "↫"], [0, "↬"], [0, "↭"], [0, "↮"], [1, "↰"], [0, "↱"], [0, "↲"], [0, "↳"], [1, "↵"], [0, "↶"], [0, "↷"], [2, "↺"], [0, "↻"], [0, "↼"], [0, "↽"], [0, "↾"], [0, "↿"], [0, "⇀"], [0, "⇁"], [0, "⇂"], [0, "⇃"], [0, "⇄"], [0, "⇅"], [0, "⇆"], [0, "⇇"], [0, "⇈"], [0, "⇉"], [0, "⇊"], [0, "⇋"], [0, "⇌"], [0, "⇍"], [0, "⇎"], [0, "⇏"], [0, "⇐"], [0, "⇑"], [0, "⇒"], [0, "⇓"], [0, "⇔"], [0, "⇕"], [0, "⇖"], [0, "⇗"], [0, "⇘"], [0, "⇙"], [0, "⇚"], [0, "⇛"], [1, "⇝"], [6, "⇤"], [0, "⇥"], [15, "⇵"], [7, "⇽"], [0, "⇾"], [0, "⇿"], [0, "∀"], [0, "∁"], [0, { v: "∂", n: 824, o: "∂̸" }], [0, "∃"], [0, "∄"], [0, "∅"], [1, "∇"], [0, "∈"], [0, "∉"], [1, "∋"], [0, "∌"], [2, "∏"], [0, "∐"], [0, "∑"], [0, "−"], [0, "∓"], [0, "∔"], [1, "∖"], [0, "∗"], [0, "∘"], [1, "√"], [2, "∝"], [0, "∞"], [0, "∟"], [0, { v: "∠", n: 8402, o: "∠⃒" }], [0, "∡"], [0, "∢"], [0, "∣"], [0, "∤"], [0, "∥"], [0, "∦"], [0, "∧"], [0, "∨"], [0, { v: "∩", n: 65024, o: "∩︀" }], [0, { v: "∪", n: 65024, o: "∪︀" }], [0, "∫"], [0, "∬"], [0, "∭"], [0, "∮"], [0, "∯"], [0, "∰"], [0, "∱"], [0, "∲"], [0, "∳"], [0, "∴"], [0, "∵"], [0, "∶"], [0, "∷"], [0, "∸"], [1, "∺"], [0, "∻"], [0, { v: "∼", n: 8402, o: "∼⃒" }], [0, { v: "∽", n: 817, o: "∽̱" }], [0, { v: "∾", n: 819, o: "∾̳" }], [0, "∿"], [0, "≀"], [0, "≁"], [0, { v: "≂", n: 824, o: "≂̸" }], [0, "≃"], [0, "≄"], [0, "≅"], [0, "≆"], [0, "≇"], [0, "≈"], [0, "≉"], [0, "≊"], [0, { v: "≋", n: 824, o: "≋̸" }], [0, "≌"], [0, { v: "≍", n: 8402, o: "≍⃒" }], [0, { v: "≎", n: 824, o: "≎̸" }], [0, { v: "≏", n: 824, o: "≏̸" }], [0, { v: "≐", n: 824, o: "≐̸" }], [0, "≑"], [0, "≒"], [0, "≓"], [0, "≔"], [0, "≕"], [0, "≖"], [0, "≗"], [1, "≙"], [0, "≚"], [1, "≜"], [2, "≟"], [0, "≠"], [0, { v: "≡", n: 8421, o: "≡⃥" }], [0, "≢"], [1, { v: "≤", n: 8402, o: "≤⃒" }], [0, { v: "≥", n: 8402, o: "≥⃒" }], [0, { v: "≦", n: 824, o: "≦̸" }], [0, { v: "≧", n: 824, o: "≧̸" }], [0, { v: "≨", n: 65024, o: "≨︀" }], [0, { v: "≩", n: 65024, o: "≩︀" }], [0, { v: "≪", n: new Map(/* @__PURE__ */ restoreDiff([[824, "≪̸"], [7577, "≪⃒"]])) }], [0, { v: "≫", n: new Map(/* @__PURE__ */ restoreDiff([[824, "≫̸"], [7577, "≫⃒"]])) }], [0, "≬"], [0, "≭"], [0, "≮"], [0, "≯"], [0, "≰"], [0, "≱"], [0, "≲"], [0, "≳"], [0, "≴"], [0, "≵"], [0, "≶"], [0, "≷"], [0, "≸"], [0, "≹"], [0, "≺"], [0, "≻"], [0, "≼"], [0, "≽"], [0, "≾"], [0, { v: "≿", n: 824, o: "≿̸" }], [0, "⊀"], [0, "⊁"], [0, { v: "⊂", n: 8402, o: "⊂⃒" }], [0, { v: "⊃", n: 8402, o: "⊃⃒" }], [0, "⊄"], [0, "⊅"], [0, "⊆"], [0, "⊇"], [0, "⊈"], [0, "⊉"], [0, { v: "⊊", n: 65024, o: "⊊︀" }], [0, { v: "⊋", n: 65024, o: "⊋︀" }], [1, "⊍"], [0, "⊎"], [0, { v: "⊏", n: 824, o: "⊏̸" }], [0, { v: "⊐", n: 824, o: "⊐̸" }], [0, "⊑"], [0, "⊒"], [0, { v: "⊓", n: 65024, o: "⊓︀" }], [0, { v: "⊔", n: 65024, o: "⊔︀" }], [0, "⊕"], [0, "⊖"], [0, "⊗"], [0, "⊘"], [0, "⊙"], [0, "⊚"], [0, "⊛"], [1, "⊝"], [0, "⊞"], [0, "⊟"], [0, "⊠"], [0, "⊡"], [0, "⊢"], [0, "⊣"], [0, "⊤"], [0, "⊥"], [1, "⊧"], [0, "⊨"], [0, "⊩"], [0, "⊪"], [0, "⊫"], [0, "⊬"], [0, "⊭"], [0, "⊮"], [0, "⊯"], [0, "⊰"], [1, "⊲"], [0, "⊳"], [0, { v: "⊴", n: 8402, o: "⊴⃒" }], [0, { v: "⊵", n: 8402, o: "⊵⃒" }], [0, "⊶"], [0, "⊷"], [0, "⊸"], [0, "⊹"], [0, "⊺"], [0, "⊻"], [1, "⊽"], [0, "⊾"], [0, "⊿"], [0, "⋀"], [0, "⋁"], [0, "⋂"], [0, "⋃"], [0, "⋄"], [0, "⋅"], [0, "⋆"], [0, "⋇"], [0, "⋈"], [0, "⋉"], [0, "⋊"], [0, "⋋"], [0, "⋌"], [0, "⋍"], [0, "⋎"], [0, "⋏"], [0, "⋐"], [0, "⋑"], [0, "⋒"], [0, "⋓"], [0, "⋔"], [0, "⋕"], [0, "⋖"], [0, "⋗"], [0, { v: "⋘", n: 824, o: "⋘̸" }], [0, { v: "⋙", n: 824, o: "⋙̸" }], [0, { v: "⋚", n: 65024, o: "⋚︀" }], [0, { v: "⋛", n: 65024, o: "⋛︀" }], [2, "⋞"], [0, "⋟"], [0, "⋠"], [0, "⋡"], [0, "⋢"], [0, "⋣"], [2, "⋦"], [0, "⋧"], [0, "⋨"], [0, "⋩"], [0, "⋪"], [0, "⋫"], [0, "⋬"], [0, "⋭"], [0, "⋮"], [0, "⋯"], [0, "⋰"], [0, "⋱"], [0, "⋲"], [0, "⋳"], [0, "⋴"], [0, { v: "⋵", n: 824, o: "⋵̸" }], [0, "⋶"], [0, "⋷"], [1, { v: "⋹", n: 824, o: "⋹̸" }], [0, "⋺"], [0, "⋻"], [0, "⋼"], [0, "⋽"], [0, "⋾"], [6, "⌅"], [0, "⌆"], [1, "⌈"], [0, "⌉"], [0, "⌊"], [0, "⌋"], [0, "⌌"], [0, "⌍"], [0, "⌎"], [0, "⌏"], [0, "⌐"], [1, "⌒"], [0, "⌓"], [1, "⌕"], [0, "⌖"], [5, "⌜"], [0, "⌝"], [0, "⌞"], [0, "⌟"], [2, "⌢"], [0, "⌣"], [9, "⌭"], [0, "⌮"], [7, "⌶"], [6, "⌽"], [1, "⌿"], [60, "⍼"], [51, "⎰"], [0, "⎱"], [2, "⎴"], [0, "⎵"], [0, "⎶"], [37, "⏜"], [0, "⏝"], [0, "⏞"], [0, "⏟"], [2, "⏢"], [4, "⏧"], [59, "␣"], [164, "Ⓢ"], [55, "─"], [1, "│"], [9, "┌"], [3, "┐"], [3, "└"], [3, "┘"], [3, "├"], [7, "┤"], [7, "┬"], [7, "┴"], [7, "┼"], [19, "═"], [0, "║"], [0, "╒"], [0, "╓"], [0, "╔"], [0, "╕"], [0, "╖"], [0, "╗"], [0, "╘"], [0, "╙"], [0, "╚"], [0, "╛"], [0, "╜"], [0, "╝"], [0, "╞"], [0, "╟"], [0, "╠"], [0, "╡"], [0, "╢"], [0, "╣"], [0, "╤"], [0, "╥"], [0, "╦"], [0, "╧"], [0, "╨"], [0, "╩"], [0, "╪"], [0, "╫"], [0, "╬"], [19, "▀"], [3, "▄"], [3, "█"], [8, "░"], [0, "▒"], [0, "▓"], [13, "□"], [8, "▪"], [0, "▫"], [1, "▭"], [0, "▮"], [2, "▱"], [1, "△"], [0, "▴"], [0, "▵"], [2, "▸"], [0, "▹"], [3, "▽"], [0, "▾"], [0, "▿"], [2, "◂"], [0, "◃"], [6, "◊"], [0, "○"], [32, "◬"], [2, "◯"], [8, "◸"], [0, "◹"], [0, "◺"], [0, "◻"], [0, "◼"], [8, "★"], [0, "☆"], [7, "☎"], [49, "♀"], [1, "♂"], [29, "♠"], [2, "♣"], [1, "♥"], [0, "♦"], [3, "♪"], [2, "♭"], [0, "♮"], [0, "♯"], [163, "✓"], [3, "✗"], [8, "✠"], [21, "✶"], [33, "❘"], [25, "❲"], [0, "❳"], [84, "⟈"], [0, "⟉"], [28, "⟦"], [0, "⟧"], [0, "⟨"], [0, "⟩"], [0, "⟪"], [0, "⟫"], [0, "⟬"], [0, "⟭"], [7, "⟵"], [0, "⟶"], [0, "⟷"], [0, "⟸"], [0, "⟹"], [0, "⟺"], [1, "⟼"], [2, "⟿"], [258, "⤂"], [0, "⤃"], [0, "⤄"], [0, "⤅"], [6, "⤌"], [0, "⤍"], [0, "⤎"], [0, "⤏"], [0, "⤐"], [0, "⤑"], [0, "⤒"], [0, "⤓"], [2, "⤖"], [2, "⤙"], [0, "⤚"], [0, "⤛"], [0, "⤜"], [0, "⤝"], [0, "⤞"], [0, "⤟"], [0, "⤠"], [2, "⤣"], [0, "⤤"], [0, "⤥"], [0, "⤦"], [0, "⤧"], [0, "⤨"], [0, "⤩"], [0, "⤪"], [8, { v: "⤳", n: 824, o: "⤳̸" }], [1, "⤵"], [0, "⤶"], [0, "⤷"], [0, "⤸"], [0, "⤹"], [2, "⤼"], [0, "⤽"], [7, "⥅"], [2, "⥈"], [0, "⥉"], [0, "⥊"], [0, "⥋"], [2, "⥎"], [0, "⥏"], [0, "⥐"], [0, "⥑"], [0, "⥒"], [0, "⥓"], [0, "⥔"], [0, "⥕"], [0, "⥖"], [0, "⥗"], [0, "⥘"], [0, "⥙"], [0, "⥚"], [0, "⥛"], [0, "⥜"], [0, "⥝"], [0, "⥞"], [0, "⥟"], [0, "⥠"], [0, "⥡"], [0, "⥢"], [0, "⥣"], [0, "⥤"], [0, "⥥"], [0, "⥦"], [0, "⥧"], [0, "⥨"], [0, "⥩"], [0, "⥪"], [0, "⥫"], [0, "⥬"], [0, "⥭"], [0, "⥮"], [0, "⥯"], [0, "⥰"], [0, "⥱"], [0, "⥲"], [0, "⥳"], [0, "⥴"], [0, "⥵"], [0, "⥶"], [1, "⥸"], [0, "⥹"], [1, "⥻"], [0, "⥼"], [0, "⥽"], [0, "⥾"], [0, "⥿"], [5, "⦅"], [0, "⦆"], [4, "⦋"], [0, "⦌"], [0, "⦍"], [0, "⦎"], [0, "⦏"], [0, "⦐"], [0, "⦑"], [0, "⦒"], [0, "⦓"], [0, "⦔"], [0, "⦕"], [0, "⦖"], [3, "⦚"], [1, "⦜"], [0, "⦝"], [6, "⦤"], [0, "⦥"], [0, "⦦"], [0, "⦧"], [0, "⦨"], [0, "⦩"], [0, "⦪"], [0, "⦫"], [0, "⦬"], [0, "⦭"], [0, "⦮"], [0, "⦯"], [0, "⦰"], [0, "⦱"], [0, "⦲"], [0, "⦳"], [0, "⦴"], [0, "⦵"], [0, "⦶"], [0, "⦷"], [1, "⦹"], [1, "⦻"], [0, "⦼"], [1, "⦾"], [0, "⦿"], [0, "⧀"], [0, "⧁"], [0, "⧂"], [0, "⧃"], [0, "⧄"], [0, "⧅"], [3, "⧉"], [3, "⧍"], [0, "⧎"], [0, { v: "⧏", n: 824, o: "⧏̸" }], [0, { v: "⧐", n: 824, o: "⧐̸" }], [11, "⧜"], [0, "⧝"], [0, "⧞"], [4, "⧣"], [0, "⧤"], [0, "⧥"], [5, "⧫"], [8, "⧴"], [1, "⧶"], [9, "⨀"], [0, "⨁"], [0, "⨂"], [1, "⨄"], [1, "⨆"], [5, "⨌"], [0, "⨍"], [2, "⨐"], [0, "⨑"], [0, "⨒"], [0, "⨓"], [0, "⨔"], [0, "⨕"], [0, "⨖"], [0, "⨗"], [10, "⨢"], [0, "⨣"], [0, "⨤"], [0, "⨥"], [0, "⨦"], [0, "⨧"], [1, "⨩"], [0, "⨪"], [2, "⨭"], [0, "⨮"], [0, "⨯"], [0, "⨰"], [0, "⨱"], [1, "⨳"], [0, "⨴"], [0, "⨵"], [0, "⨶"], [0, "⨷"], [0, "⨸"], [0, "⨹"], [0, "⨺"], [0, "⨻"], [0, "⨼"], [2, "⨿"], [0, "⩀"], [1, "⩂"], [0, "⩃"], [0, "⩄"], [0, "⩅"], [0, "⩆"], [0, "⩇"], [0, "⩈"], [0, "⩉"], [0, "⩊"], [0, "⩋"], [0, "⩌"], [0, "⩍"], [2, "⩐"], [2, "⩓"], [0, "⩔"], [0, "⩕"], [0, "⩖"], [0, "⩗"], [0, "⩘"], [1, "⩚"], [0, "⩛"], [0, "⩜"], [0, "⩝"], [1, "⩟"], [6, "⩦"], [3, "⩪"], [2, { v: "⩭", n: 824, o: "⩭̸" }], [0, "⩮"], [0, "⩯"], [0, { v: "⩰", n: 824, o: "⩰̸" }], [0, "⩱"], [0, "⩲"], [0, "⩳"], [0, "⩴"], [0, "⩵"], [1, "⩷"], [0, "⩸"], [0, "⩹"], [0, "⩺"], [0, "⩻"], [0, "⩼"], [0, { v: "⩽", n: 824, o: "⩽̸" }], [0, { v: "⩾", n: 824, o: "⩾̸" }], [0, "⩿"], [0, "⪀"], [0, "⪁"], [0, "⪂"], [0, "⪃"], [0, "⪄"], [0, "⪅"], [0, "⪆"], [0, "⪇"], [0, "⪈"], [0, "⪉"], [0, "⪊"], [0, "⪋"], [0, "⪌"], [0, "⪍"], [0, "⪎"], [0, "⪏"], [0, "⪐"], [0, "⪑"], [0, "⪒"], [0, "⪓"], [0, "⪔"], [0, "⪕"], [0, "⪖"], [0, "⪗"], [0, "⪘"], [0, "⪙"], [0, "⪚"], [2, "⪝"], [0, "⪞"], [0, "⪟"], [0, "⪠"], [0, { v: "⪡", n: 824, o: "⪡̸" }], [0, { v: "⪢", n: 824, o: "⪢̸" }], [1, "⪤"], [0, "⪥"], [0, "⪦"], [0, "⪧"], [0, "⪨"], [0, "⪩"], [0, "⪪"], [0, "⪫"], [0, { v: "⪬", n: 65024, o: "⪬︀" }], [0, { v: "⪭", n: 65024, o: "⪭︀" }], [0, "⪮"], [0, { v: "⪯", n: 824, o: "⪯̸" }], [0, { v: "⪰", n: 824, o: "⪰̸" }], [2, "⪳"], [0, "⪴"], [0, "⪵"], [0, "⪶"], [0, "⪷"], [0, "⪸"], [0, "⪹"], [0, "⪺"], [0, "⪻"], [0, "⪼"], [0, "⪽"], [0, "⪾"], [0, "⪿"], [0, "⫀"], [0, "⫁"], [0, "⫂"], [0, "⫃"], [0, "⫄"], [0, { v: "⫅", n: 824, o: "⫅̸" }], [0, { v: "⫆", n: 824, o: "⫆̸" }], [0, "⫇"], [0, "⫈"], [2, { v: "⫋", n: 65024, o: "⫋︀" }], [0, { v: "⫌", n: 65024, o: "⫌︀" }], [2, "⫏"], [0, "⫐"], [0, "⫑"], [0, "⫒"], [0, "⫓"], [0, "⫔"], [0, "⫕"], [0, "⫖"], [0, "⫗"], [0, "⫘"], [0, "⫙"], [0, "⫚"], [0, "⫛"], [8, "⫤"], [1, "⫦"], [0, "⫧"], [0, "⫨"], [0, "⫩"], [1, "⫫"], [0, "⫬"], [0, "⫭"], [0, "⫮"], [0, "⫯"], [0, "⫰"], [0, "⫱"], [0, "⫲"], [0, "⫳"], [9, { v: "⫽", n: 8421, o: "⫽⃥" }], [44343, { n: new Map(/* @__PURE__ */ restoreDiff([[56476, "𝒜"], [1, "𝒞"], [0, "𝒟"], [2, "𝒢"], [2, "𝒥"], [0, "𝒦"], [2, "𝒩"], [0, "𝒪"], [0, "𝒫"], [0, "𝒬"], [1, "𝒮"], [0, "𝒯"], [0, "𝒰"], [0, "𝒱"], [0, "𝒲"], [0, "𝒳"], [0, "𝒴"], [0, "𝒵"], [0, "𝒶"], [0, "𝒷"], [0, "𝒸"], [0, "𝒹"], [1, "𝒻"], [1, "𝒽"], [0, "𝒾"], [0, "𝒿"], [0, "𝓀"], [0, "𝓁"], [0, "𝓂"], [0, "𝓃"], [1, "𝓅"], [0, "𝓆"], [0, "𝓇"], [0, "𝓈"], [0, "𝓉"], [0, "𝓊"], [0, "𝓋"], [0, "𝓌"], [0, "𝓍"], [0, "𝓎"], [0, "𝓏"], [52, "𝔄"], [0, "𝔅"], [1, "𝔇"], [0, "𝔈"], [0, "𝔉"], [0, "𝔊"], [2, "𝔍"], [0, "𝔎"], [0, "𝔏"], [0, "𝔐"], [0, "𝔑"], [0, "𝔒"], [0, "𝔓"], [0, "𝔔"], [1, "𝔖"], [0, "𝔗"], [0, "𝔘"], [0, "𝔙"], [0, "𝔚"], [0, "𝔛"], [0, "𝔜"], [1, "𝔞"], [0, "𝔟"], [0, "𝔠"], [0, "𝔡"], [0, "𝔢"], [0, "𝔣"], [0, "𝔤"], [0, "𝔥"], [0, "𝔦"], [0, "𝔧"], [0, "𝔨"], [0, "𝔩"], [0, "𝔪"], [0, "𝔫"], [0, "𝔬"], [0, "𝔭"], [0, "𝔮"], [0, "𝔯"], [0, "𝔰"], [0, "𝔱"], [0, "𝔲"], [0, "𝔳"], [0, "𝔴"], [0, "𝔵"], [0, "𝔶"], [0, "𝔷"], [0, "𝔸"], [0, "𝔹"], [1, "𝔻"], [0, "𝔼"], [0, "𝔽"], [0, "𝔾"], [1, "𝕀"], [0, "𝕁"], [0, "𝕂"], [0, "𝕃"], [0, "𝕄"], [1, "𝕆"], [3, "𝕊"], [0, "𝕋"], [0, "𝕌"], [0, "𝕍"], [0, "𝕎"], [0, "𝕏"], [0, "𝕐"], [1, "𝕒"], [0, "𝕓"], [0, "𝕔"], [0, "𝕕"], [0, "𝕖"], [0, "𝕗"], [0, "𝕘"], [0, "𝕙"], [0, "𝕚"], [0, "𝕛"], [0, "𝕜"], [0, "𝕝"], [0, "𝕞"], [0, "𝕟"], [0, "𝕠"], [0, "𝕡"], [0, "𝕢"], [0, "𝕣"], [0, "𝕤"], [0, "𝕥"], [0, "𝕦"], [0, "𝕧"], [0, "𝕨"], [0, "𝕩"], [0, "𝕪"], [0, "𝕫"]])) }], [8906, "ff"], [0, "fi"], [0, "fl"], [0, "ffi"], [0, "ffl"]])); + } +}); + +// node_modules/entities/lib/escape.js +var require_escape = __commonJS({ + "node_modules/entities/lib/escape.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.escapeText = exports2.escapeAttribute = exports2.escapeUTF8 = exports2.escape = exports2.encodeXML = exports2.getCodePoint = exports2.xmlReplacer = void 0; + exports2.xmlReplacer = /["&'<>$\x80-\uFFFF]/g; + var xmlCodeMap = /* @__PURE__ */ new Map([ + [34, """], + [38, "&"], + [39, "'"], + [60, "<"], + [62, ">"] + ]); + exports2.getCodePoint = // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + String.prototype.codePointAt != null ? function(str, index) { + return str.codePointAt(index); + } : ( + // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + function(c, index) { + return (c.charCodeAt(index) & 64512) === 55296 ? (c.charCodeAt(index) - 55296) * 1024 + c.charCodeAt(index + 1) - 56320 + 65536 : c.charCodeAt(index); + } + ); + function encodeXML(str) { + var ret = ""; + var lastIdx = 0; + var match; + while ((match = exports2.xmlReplacer.exec(str)) !== null) { + var i = match.index; + var char = str.charCodeAt(i); + var next = xmlCodeMap.get(char); + if (next !== void 0) { + ret += str.substring(lastIdx, i) + next; + lastIdx = i + 1; + } else { + ret += "".concat(str.substring(lastIdx, i), "&#x").concat((0, exports2.getCodePoint)(str, i).toString(16), ";"); + lastIdx = exports2.xmlReplacer.lastIndex += Number((char & 64512) === 55296); + } + } + return ret + str.substr(lastIdx); + } + exports2.encodeXML = encodeXML; + exports2.escape = encodeXML; + function getEscaper(regex, map) { + return function escape2(data) { + var match; + var lastIdx = 0; + var result = ""; + while (match = regex.exec(data)) { + if (lastIdx !== match.index) { + result += data.substring(lastIdx, match.index); + } + result += map.get(match[0].charCodeAt(0)); + lastIdx = match.index + 1; + } + return result + data.substring(lastIdx); + }; + } + exports2.escapeUTF8 = getEscaper(/[&<>'"]/g, xmlCodeMap); + exports2.escapeAttribute = getEscaper(/["&\u00A0]/g, /* @__PURE__ */ new Map([ + [34, """], + [38, "&"], + [160, " "] + ])); + exports2.escapeText = getEscaper(/[&<>\u00A0]/g, /* @__PURE__ */ new Map([ + [38, "&"], + [60, "<"], + [62, ">"], + [160, " "] + ])); + } +}); + +// node_modules/entities/lib/encode.js +var require_encode = __commonJS({ + "node_modules/entities/lib/encode.js"(exports2) { + "use strict"; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.encodeNonAsciiHTML = exports2.encodeHTML = void 0; + var encode_html_js_1 = __importDefault2(require_encode_html()); + var escape_js_1 = require_escape(); + var htmlReplacer = /[\t\n!-,./:-@[-`\f{-}$\x80-\uFFFF]/g; + function encodeHTML(data) { + return encodeHTMLTrieRe(htmlReplacer, data); + } + exports2.encodeHTML = encodeHTML; + function encodeNonAsciiHTML(data) { + return encodeHTMLTrieRe(escape_js_1.xmlReplacer, data); + } + exports2.encodeNonAsciiHTML = encodeNonAsciiHTML; + function encodeHTMLTrieRe(regExp, str) { + var ret = ""; + var lastIdx = 0; + var match; + while ((match = regExp.exec(str)) !== null) { + var i = match.index; + ret += str.substring(lastIdx, i); + var char = str.charCodeAt(i); + var next = encode_html_js_1.default.get(char); + if (typeof next === "object") { + if (i + 1 < str.length) { + var nextChar = str.charCodeAt(i + 1); + var value = typeof next.n === "number" ? next.n === nextChar ? next.o : void 0 : next.n.get(nextChar); + if (value !== void 0) { + ret += value; + lastIdx = regExp.lastIndex += 1; + continue; + } + } + next = next.v; + } + if (next !== void 0) { + ret += next; + lastIdx = i + 1; + } else { + var cp = (0, escape_js_1.getCodePoint)(str, i); + ret += "&#x".concat(cp.toString(16), ";"); + lastIdx = regExp.lastIndex += Number(cp !== char); + } + } + return ret + str.substr(lastIdx); + } + } +}); + +// node_modules/entities/lib/index.js +var require_lib14 = __commonJS({ + "node_modules/entities/lib/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.decodeXMLStrict = exports2.decodeHTML5Strict = exports2.decodeHTML4Strict = exports2.decodeHTML5 = exports2.decodeHTML4 = exports2.decodeHTMLAttribute = exports2.decodeHTMLStrict = exports2.decodeHTML = exports2.decodeXML = exports2.DecodingMode = exports2.EntityDecoder = exports2.encodeHTML5 = exports2.encodeHTML4 = exports2.encodeNonAsciiHTML = exports2.encodeHTML = exports2.escapeText = exports2.escapeAttribute = exports2.escapeUTF8 = exports2.escape = exports2.encodeXML = exports2.encode = exports2.decodeStrict = exports2.decode = exports2.EncodingMode = exports2.EntityLevel = void 0; + var decode_js_1 = require_decode2(); + var encode_js_1 = require_encode(); + var escape_js_1 = require_escape(); + var EntityLevel; + (function(EntityLevel2) { + EntityLevel2[EntityLevel2["XML"] = 0] = "XML"; + EntityLevel2[EntityLevel2["HTML"] = 1] = "HTML"; + })(EntityLevel = exports2.EntityLevel || (exports2.EntityLevel = {})); + var EncodingMode; + (function(EncodingMode2) { + EncodingMode2[EncodingMode2["UTF8"] = 0] = "UTF8"; + EncodingMode2[EncodingMode2["ASCII"] = 1] = "ASCII"; + EncodingMode2[EncodingMode2["Extensive"] = 2] = "Extensive"; + EncodingMode2[EncodingMode2["Attribute"] = 3] = "Attribute"; + EncodingMode2[EncodingMode2["Text"] = 4] = "Text"; + })(EncodingMode = exports2.EncodingMode || (exports2.EncodingMode = {})); + function decode(data, options) { + if (options === void 0) { + options = EntityLevel.XML; + } + var level = typeof options === "number" ? options : options.level; + if (level === EntityLevel.HTML) { + var mode = typeof options === "object" ? options.mode : void 0; + return (0, decode_js_1.decodeHTML)(data, mode); + } + return (0, decode_js_1.decodeXML)(data); + } + exports2.decode = decode; + function decodeStrict(data, options) { + var _a; + if (options === void 0) { + options = EntityLevel.XML; + } + var opts = typeof options === "number" ? { level: options } : options; + (_a = opts.mode) !== null && _a !== void 0 ? _a : opts.mode = decode_js_1.DecodingMode.Strict; + return decode(data, opts); + } + exports2.decodeStrict = decodeStrict; + function encode(data, options) { + if (options === void 0) { + options = EntityLevel.XML; + } + var opts = typeof options === "number" ? { level: options } : options; + if (opts.mode === EncodingMode.UTF8) + return (0, escape_js_1.escapeUTF8)(data); + if (opts.mode === EncodingMode.Attribute) + return (0, escape_js_1.escapeAttribute)(data); + if (opts.mode === EncodingMode.Text) + return (0, escape_js_1.escapeText)(data); + if (opts.level === EntityLevel.HTML) { + if (opts.mode === EncodingMode.ASCII) { + return (0, encode_js_1.encodeNonAsciiHTML)(data); + } + return (0, encode_js_1.encodeHTML)(data); + } + return (0, escape_js_1.encodeXML)(data); + } + exports2.encode = encode; + var escape_js_2 = require_escape(); + Object.defineProperty(exports2, "encodeXML", { enumerable: true, get: function() { + return escape_js_2.encodeXML; + } }); + Object.defineProperty(exports2, "escape", { enumerable: true, get: function() { + return escape_js_2.escape; + } }); + Object.defineProperty(exports2, "escapeUTF8", { enumerable: true, get: function() { + return escape_js_2.escapeUTF8; + } }); + Object.defineProperty(exports2, "escapeAttribute", { enumerable: true, get: function() { + return escape_js_2.escapeAttribute; + } }); + Object.defineProperty(exports2, "escapeText", { enumerable: true, get: function() { + return escape_js_2.escapeText; + } }); + var encode_js_2 = require_encode(); + Object.defineProperty(exports2, "encodeHTML", { enumerable: true, get: function() { + return encode_js_2.encodeHTML; + } }); + Object.defineProperty(exports2, "encodeNonAsciiHTML", { enumerable: true, get: function() { + return encode_js_2.encodeNonAsciiHTML; + } }); + Object.defineProperty(exports2, "encodeHTML4", { enumerable: true, get: function() { + return encode_js_2.encodeHTML; + } }); + Object.defineProperty(exports2, "encodeHTML5", { enumerable: true, get: function() { + return encode_js_2.encodeHTML; + } }); + var decode_js_2 = require_decode2(); + Object.defineProperty(exports2, "EntityDecoder", { enumerable: true, get: function() { + return decode_js_2.EntityDecoder; + } }); + Object.defineProperty(exports2, "DecodingMode", { enumerable: true, get: function() { + return decode_js_2.DecodingMode; + } }); + Object.defineProperty(exports2, "decodeXML", { enumerable: true, get: function() { + return decode_js_2.decodeXML; + } }); + Object.defineProperty(exports2, "decodeHTML", { enumerable: true, get: function() { + return decode_js_2.decodeHTML; + } }); + Object.defineProperty(exports2, "decodeHTMLStrict", { enumerable: true, get: function() { + return decode_js_2.decodeHTMLStrict; + } }); + Object.defineProperty(exports2, "decodeHTMLAttribute", { enumerable: true, get: function() { + return decode_js_2.decodeHTMLAttribute; + } }); + Object.defineProperty(exports2, "decodeHTML4", { enumerable: true, get: function() { + return decode_js_2.decodeHTML; + } }); + Object.defineProperty(exports2, "decodeHTML5", { enumerable: true, get: function() { + return decode_js_2.decodeHTML; + } }); + Object.defineProperty(exports2, "decodeHTML4Strict", { enumerable: true, get: function() { + return decode_js_2.decodeHTMLStrict; + } }); + Object.defineProperty(exports2, "decodeHTML5Strict", { enumerable: true, get: function() { + return decode_js_2.decodeHTMLStrict; + } }); + Object.defineProperty(exports2, "decodeXMLStrict", { enumerable: true, get: function() { + return decode_js_2.decodeXML; + } }); + } +}); + +// node_modules/dom-serializer/lib/foreignNames.js +var require_foreignNames = __commonJS({ + "node_modules/dom-serializer/lib/foreignNames.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.attributeNames = exports2.elementNames = void 0; + exports2.elementNames = new Map([ + "altGlyph", + "altGlyphDef", + "altGlyphItem", + "animateColor", + "animateMotion", + "animateTransform", + "clipPath", + "feBlend", + "feColorMatrix", + "feComponentTransfer", + "feComposite", + "feConvolveMatrix", + "feDiffuseLighting", + "feDisplacementMap", + "feDistantLight", + "feDropShadow", + "feFlood", + "feFuncA", + "feFuncB", + "feFuncG", + "feFuncR", + "feGaussianBlur", + "feImage", + "feMerge", + "feMergeNode", + "feMorphology", + "feOffset", + "fePointLight", + "feSpecularLighting", + "feSpotLight", + "feTile", + "feTurbulence", + "foreignObject", + "glyphRef", + "linearGradient", + "radialGradient", + "textPath" + ].map(function(val) { + return [val.toLowerCase(), val]; + })); + exports2.attributeNames = new Map([ + "definitionURL", + "attributeName", + "attributeType", + "baseFrequency", + "baseProfile", + "calcMode", + "clipPathUnits", + "diffuseConstant", + "edgeMode", + "filterUnits", + "glyphRef", + "gradientTransform", + "gradientUnits", + "kernelMatrix", + "kernelUnitLength", + "keyPoints", + "keySplines", + "keyTimes", + "lengthAdjust", + "limitingConeAngle", + "markerHeight", + "markerUnits", + "markerWidth", + "maskContentUnits", + "maskUnits", + "numOctaves", + "pathLength", + "patternContentUnits", + "patternTransform", + "patternUnits", + "pointsAtX", + "pointsAtY", + "pointsAtZ", + "preserveAlpha", + "preserveAspectRatio", + "primitiveUnits", + "refX", + "refY", + "repeatCount", + "repeatDur", + "requiredExtensions", + "requiredFeatures", + "specularConstant", + "specularExponent", + "spreadMethod", + "startOffset", + "stdDeviation", + "stitchTiles", + "surfaceScale", + "systemLanguage", + "tableValues", + "targetX", + "targetY", + "textLength", + "viewBox", + "viewTarget", + "xChannelSelector", + "yChannelSelector", + "zoomAndPan" + ].map(function(val) { + return [val.toLowerCase(), val]; + })); + } +}); + +// node_modules/dom-serializer/lib/index.js +var require_lib15 = __commonJS({ + "node_modules/dom-serializer/lib/index.js"(exports2) { + "use strict"; + var __assign2 = exports2 && exports2.__assign || function() { + __assign2 = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign2.apply(this, arguments); + }; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.render = void 0; + var ElementType = __importStar2(require_lib12()); + var entities_1 = require_lib14(); + var foreignNames_js_1 = require_foreignNames(); + var unencodedElements = /* @__PURE__ */ new Set([ + "style", + "script", + "xmp", + "iframe", + "noembed", + "noframes", + "plaintext", + "noscript" + ]); + function replaceQuotes(value) { + return value.replace(/"/g, """); + } + function formatAttributes(attributes, opts) { + var _a; + if (!attributes) + return; + var encode = ((_a = opts.encodeEntities) !== null && _a !== void 0 ? _a : opts.decodeEntities) === false ? replaceQuotes : opts.xmlMode || opts.encodeEntities !== "utf8" ? entities_1.encodeXML : entities_1.escapeAttribute; + return Object.keys(attributes).map(function(key) { + var _a2, _b; + var value = (_a2 = attributes[key]) !== null && _a2 !== void 0 ? _a2 : ""; + if (opts.xmlMode === "foreign") { + key = (_b = foreignNames_js_1.attributeNames.get(key)) !== null && _b !== void 0 ? _b : key; + } + if (!opts.emptyAttrs && !opts.xmlMode && value === "") { + return key; + } + return "".concat(key, '="').concat(encode(value), '"'); + }).join(" "); + } + var singleTag = /* @__PURE__ */ new Set([ + "area", + "base", + "basefont", + "br", + "col", + "command", + "embed", + "frame", + "hr", + "img", + "input", + "isindex", + "keygen", + "link", + "meta", + "param", + "source", + "track", + "wbr" + ]); + function render(node, options) { + if (options === void 0) { + options = {}; + } + var nodes = "length" in node ? node : [node]; + var output = ""; + for (var i = 0; i < nodes.length; i++) { + output += renderNode(nodes[i], options); + } + return output; + } + exports2.render = render; + exports2.default = render; + function renderNode(node, options) { + switch (node.type) { + case ElementType.Root: + return render(node.children, options); + // @ts-expect-error We don't use `Doctype` yet + case ElementType.Doctype: + case ElementType.Directive: + return renderDirective(node); + case ElementType.Comment: + return renderComment(node); + case ElementType.CDATA: + return renderCdata(node); + case ElementType.Script: + case ElementType.Style: + case ElementType.Tag: + return renderTag(node, options); + case ElementType.Text: + return renderText(node, options); + } + } + var foreignModeIntegrationPoints = /* @__PURE__ */ new Set([ + "mi", + "mo", + "mn", + "ms", + "mtext", + "annotation-xml", + "foreignObject", + "desc", + "title" + ]); + var foreignElements = /* @__PURE__ */ new Set(["svg", "math"]); + function renderTag(elem, opts) { + var _a; + if (opts.xmlMode === "foreign") { + elem.name = (_a = foreignNames_js_1.elementNames.get(elem.name)) !== null && _a !== void 0 ? _a : elem.name; + if (elem.parent && foreignModeIntegrationPoints.has(elem.parent.name)) { + opts = __assign2(__assign2({}, opts), { xmlMode: false }); + } + } + if (!opts.xmlMode && foreignElements.has(elem.name)) { + opts = __assign2(__assign2({}, opts), { xmlMode: "foreign" }); + } + var tag = "<".concat(elem.name); + var attribs = formatAttributes(elem.attribs, opts); + if (attribs) { + tag += " ".concat(attribs); + } + if (elem.children.length === 0 && (opts.xmlMode ? ( + // In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags + opts.selfClosingTags !== false + ) : ( + // User explicitly asked for self-closing tags, even in HTML mode + opts.selfClosingTags && singleTag.has(elem.name) + ))) { + if (!opts.xmlMode) + tag += " "; + tag += "/>"; + } else { + tag += ">"; + if (elem.children.length > 0) { + tag += render(elem.children, opts); + } + if (opts.xmlMode || !singleTag.has(elem.name)) { + tag += ""); + } + } + return tag; + } + function renderDirective(elem) { + return "<".concat(elem.data, ">"); + } + function renderText(elem, opts) { + var _a; + var data = elem.data || ""; + if (((_a = opts.encodeEntities) !== null && _a !== void 0 ? _a : opts.decodeEntities) !== false && !(!opts.xmlMode && elem.parent && unencodedElements.has(elem.parent.name))) { + data = opts.xmlMode || opts.encodeEntities !== "utf8" ? (0, entities_1.encodeXML)(data) : (0, entities_1.escapeText)(data); + } + return data; + } + function renderCdata(elem) { + return ""); + } + function renderComment(elem) { + return ""); + } + } +}); + +// node_modules/domutils/lib/stringify.js +var require_stringify3 = __commonJS({ + "node_modules/domutils/lib/stringify.js"(exports2) { + "use strict"; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getOuterHTML = getOuterHTML; + exports2.getInnerHTML = getInnerHTML; + exports2.getText = getText; + exports2.textContent = textContent; + exports2.innerText = innerText; + var domhandler_1 = require_lib13(); + var dom_serializer_1 = __importDefault2(require_lib15()); + var domelementtype_1 = require_lib12(); + function getOuterHTML(node, options) { + return (0, dom_serializer_1.default)(node, options); + } + function getInnerHTML(node, options) { + return (0, domhandler_1.hasChildren)(node) ? node.children.map(function(node2) { + return getOuterHTML(node2, options); + }).join("") : ""; + } + function getText(node) { + if (Array.isArray(node)) + return node.map(getText).join(""); + if ((0, domhandler_1.isTag)(node)) + return node.name === "br" ? "\n" : getText(node.children); + if ((0, domhandler_1.isCDATA)(node)) + return getText(node.children); + if ((0, domhandler_1.isText)(node)) + return node.data; + return ""; + } + function textContent(node) { + if (Array.isArray(node)) + return node.map(textContent).join(""); + if ((0, domhandler_1.hasChildren)(node) && !(0, domhandler_1.isComment)(node)) { + return textContent(node.children); + } + if ((0, domhandler_1.isText)(node)) + return node.data; + return ""; + } + function innerText(node) { + if (Array.isArray(node)) + return node.map(innerText).join(""); + if ((0, domhandler_1.hasChildren)(node) && (node.type === domelementtype_1.ElementType.Tag || (0, domhandler_1.isCDATA)(node))) { + return innerText(node.children); + } + if ((0, domhandler_1.isText)(node)) + return node.data; + return ""; + } + } +}); + +// node_modules/domutils/lib/traversal.js +var require_traversal = __commonJS({ + "node_modules/domutils/lib/traversal.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getChildren = getChildren; + exports2.getParent = getParent; + exports2.getSiblings = getSiblings; + exports2.getAttributeValue = getAttributeValue; + exports2.hasAttrib = hasAttrib; + exports2.getName = getName; + exports2.nextElementSibling = nextElementSibling; + exports2.prevElementSibling = prevElementSibling; + var domhandler_1 = require_lib13(); + function getChildren(elem) { + return (0, domhandler_1.hasChildren)(elem) ? elem.children : []; + } + function getParent(elem) { + return elem.parent || null; + } + function getSiblings(elem) { + var _a, _b; + var parent = getParent(elem); + if (parent != null) + return getChildren(parent); + var siblings = [elem]; + var prev = elem.prev, next = elem.next; + while (prev != null) { + siblings.unshift(prev); + _a = prev, prev = _a.prev; + } + while (next != null) { + siblings.push(next); + _b = next, next = _b.next; + } + return siblings; + } + function getAttributeValue(elem, name) { + var _a; + return (_a = elem.attribs) === null || _a === void 0 ? void 0 : _a[name]; + } + function hasAttrib(elem, name) { + return elem.attribs != null && Object.prototype.hasOwnProperty.call(elem.attribs, name) && elem.attribs[name] != null; + } + function getName(elem) { + return elem.name; + } + function nextElementSibling(elem) { + var _a; + var next = elem.next; + while (next !== null && !(0, domhandler_1.isTag)(next)) + _a = next, next = _a.next; + return next; + } + function prevElementSibling(elem) { + var _a; + var prev = elem.prev; + while (prev !== null && !(0, domhandler_1.isTag)(prev)) + _a = prev, prev = _a.prev; + return prev; + } + } +}); + +// node_modules/domutils/lib/manipulation.js +var require_manipulation = __commonJS({ + "node_modules/domutils/lib/manipulation.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.removeElement = removeElement; + exports2.replaceElement = replaceElement; + exports2.appendChild = appendChild; + exports2.append = append; + exports2.prependChild = prependChild; + exports2.prepend = prepend; + function removeElement(elem) { + if (elem.prev) + elem.prev.next = elem.next; + if (elem.next) + elem.next.prev = elem.prev; + if (elem.parent) { + var childs = elem.parent.children; + var childsIndex = childs.lastIndexOf(elem); + if (childsIndex >= 0) { + childs.splice(childsIndex, 1); + } + } + elem.next = null; + elem.prev = null; + elem.parent = null; + } + function replaceElement(elem, replacement) { + var prev = replacement.prev = elem.prev; + if (prev) { + prev.next = replacement; + } + var next = replacement.next = elem.next; + if (next) { + next.prev = replacement; + } + var parent = replacement.parent = elem.parent; + if (parent) { + var childs = parent.children; + childs[childs.lastIndexOf(elem)] = replacement; + elem.parent = null; + } + } + function appendChild(parent, child) { + removeElement(child); + child.next = null; + child.parent = parent; + if (parent.children.push(child) > 1) { + var sibling = parent.children[parent.children.length - 2]; + sibling.next = child; + child.prev = sibling; + } else { + child.prev = null; + } + } + function append(elem, next) { + removeElement(next); + var parent = elem.parent; + var currNext = elem.next; + next.next = currNext; + next.prev = elem; + elem.next = next; + next.parent = parent; + if (currNext) { + currNext.prev = next; + if (parent) { + var childs = parent.children; + childs.splice(childs.lastIndexOf(currNext), 0, next); + } + } else if (parent) { + parent.children.push(next); + } + } + function prependChild(parent, child) { + removeElement(child); + child.parent = parent; + child.prev = null; + if (parent.children.unshift(child) !== 1) { + var sibling = parent.children[1]; + sibling.prev = child; + child.next = sibling; + } else { + child.next = null; + } + } + function prepend(elem, prev) { + removeElement(prev); + var parent = elem.parent; + if (parent) { + var childs = parent.children; + childs.splice(childs.indexOf(elem), 0, prev); + } + if (elem.prev) { + elem.prev.next = prev; + } + prev.parent = parent; + prev.prev = elem.prev; + prev.next = elem; + elem.prev = prev; + } + } +}); + +// node_modules/domutils/lib/querying.js +var require_querying = __commonJS({ + "node_modules/domutils/lib/querying.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.filter = filter; + exports2.find = find; + exports2.findOneChild = findOneChild; + exports2.findOne = findOne; + exports2.existsOne = existsOne; + exports2.findAll = findAll; + var domhandler_1 = require_lib13(); + function filter(test, node, recurse, limit) { + if (recurse === void 0) { + recurse = true; + } + if (limit === void 0) { + limit = Infinity; + } + return find(test, Array.isArray(node) ? node : [node], recurse, limit); + } + function find(test, nodes, recurse, limit) { + var result = []; + var nodeStack = [Array.isArray(nodes) ? nodes : [nodes]]; + var indexStack = [0]; + for (; ; ) { + if (indexStack[0] >= nodeStack[0].length) { + if (indexStack.length === 1) { + return result; + } + nodeStack.shift(); + indexStack.shift(); + continue; + } + var elem = nodeStack[0][indexStack[0]++]; + if (test(elem)) { + result.push(elem); + if (--limit <= 0) + return result; + } + if (recurse && (0, domhandler_1.hasChildren)(elem) && elem.children.length > 0) { + indexStack.unshift(0); + nodeStack.unshift(elem.children); + } + } + } + function findOneChild(test, nodes) { + return nodes.find(test); + } + function findOne(test, nodes, recurse) { + if (recurse === void 0) { + recurse = true; + } + var searchedNodes = Array.isArray(nodes) ? nodes : [nodes]; + for (var i = 0; i < searchedNodes.length; i++) { + var node = searchedNodes[i]; + if ((0, domhandler_1.isTag)(node) && test(node)) { + return node; + } + if (recurse && (0, domhandler_1.hasChildren)(node) && node.children.length > 0) { + var found = findOne(test, node.children, true); + if (found) + return found; + } + } + return null; + } + function existsOne(test, nodes) { + return (Array.isArray(nodes) ? nodes : [nodes]).some(function(node) { + return (0, domhandler_1.isTag)(node) && test(node) || (0, domhandler_1.hasChildren)(node) && existsOne(test, node.children); + }); + } + function findAll(test, nodes) { + var result = []; + var nodeStack = [Array.isArray(nodes) ? nodes : [nodes]]; + var indexStack = [0]; + for (; ; ) { + if (indexStack[0] >= nodeStack[0].length) { + if (nodeStack.length === 1) { + return result; + } + nodeStack.shift(); + indexStack.shift(); + continue; + } + var elem = nodeStack[0][indexStack[0]++]; + if ((0, domhandler_1.isTag)(elem) && test(elem)) + result.push(elem); + if ((0, domhandler_1.hasChildren)(elem) && elem.children.length > 0) { + indexStack.unshift(0); + nodeStack.unshift(elem.children); + } + } + } + } +}); + +// node_modules/domutils/lib/legacy.js +var require_legacy = __commonJS({ + "node_modules/domutils/lib/legacy.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.testElement = testElement; + exports2.getElements = getElements; + exports2.getElementById = getElementById; + exports2.getElementsByTagName = getElementsByTagName; + exports2.getElementsByClassName = getElementsByClassName; + exports2.getElementsByTagType = getElementsByTagType; + var domhandler_1 = require_lib13(); + var querying_js_1 = require_querying(); + var Checks = { + tag_name: function(name) { + if (typeof name === "function") { + return function(elem) { + return (0, domhandler_1.isTag)(elem) && name(elem.name); + }; + } else if (name === "*") { + return domhandler_1.isTag; + } + return function(elem) { + return (0, domhandler_1.isTag)(elem) && elem.name === name; + }; + }, + tag_type: function(type) { + if (typeof type === "function") { + return function(elem) { + return type(elem.type); + }; + } + return function(elem) { + return elem.type === type; + }; + }, + tag_contains: function(data) { + if (typeof data === "function") { + return function(elem) { + return (0, domhandler_1.isText)(elem) && data(elem.data); + }; + } + return function(elem) { + return (0, domhandler_1.isText)(elem) && elem.data === data; + }; + } + }; + function getAttribCheck(attrib, value) { + if (typeof value === "function") { + return function(elem) { + return (0, domhandler_1.isTag)(elem) && value(elem.attribs[attrib]); + }; + } + return function(elem) { + return (0, domhandler_1.isTag)(elem) && elem.attribs[attrib] === value; + }; + } + function combineFuncs(a, b) { + return function(elem) { + return a(elem) || b(elem); + }; + } + function compileTest(options) { + var funcs = Object.keys(options).map(function(key) { + var value = options[key]; + return Object.prototype.hasOwnProperty.call(Checks, key) ? Checks[key](value) : getAttribCheck(key, value); + }); + return funcs.length === 0 ? null : funcs.reduce(combineFuncs); + } + function testElement(options, node) { + var test = compileTest(options); + return test ? test(node) : true; + } + function getElements(options, nodes, recurse, limit) { + if (limit === void 0) { + limit = Infinity; + } + var test = compileTest(options); + return test ? (0, querying_js_1.filter)(test, nodes, recurse, limit) : []; + } + function getElementById(id, nodes, recurse) { + if (recurse === void 0) { + recurse = true; + } + if (!Array.isArray(nodes)) + nodes = [nodes]; + return (0, querying_js_1.findOne)(getAttribCheck("id", id), nodes, recurse); + } + function getElementsByTagName(tagName, nodes, recurse, limit) { + if (recurse === void 0) { + recurse = true; + } + if (limit === void 0) { + limit = Infinity; + } + return (0, querying_js_1.filter)(Checks["tag_name"](tagName), nodes, recurse, limit); + } + function getElementsByClassName(className, nodes, recurse, limit) { + if (recurse === void 0) { + recurse = true; + } + if (limit === void 0) { + limit = Infinity; + } + return (0, querying_js_1.filter)(getAttribCheck("class", className), nodes, recurse, limit); + } + function getElementsByTagType(type, nodes, recurse, limit) { + if (recurse === void 0) { + recurse = true; + } + if (limit === void 0) { + limit = Infinity; + } + return (0, querying_js_1.filter)(Checks["tag_type"](type), nodes, recurse, limit); + } + } +}); + +// node_modules/domutils/lib/helpers.js +var require_helpers3 = __commonJS({ + "node_modules/domutils/lib/helpers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DocumentPosition = void 0; + exports2.removeSubsets = removeSubsets; + exports2.compareDocumentPosition = compareDocumentPosition; + exports2.uniqueSort = uniqueSort; + var domhandler_1 = require_lib13(); + function removeSubsets(nodes) { + var idx = nodes.length; + while (--idx >= 0) { + var node = nodes[idx]; + if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) { + nodes.splice(idx, 1); + continue; + } + for (var ancestor = node.parent; ancestor; ancestor = ancestor.parent) { + if (nodes.includes(ancestor)) { + nodes.splice(idx, 1); + break; + } + } + } + return nodes; + } + var DocumentPosition; + (function(DocumentPosition2) { + DocumentPosition2[DocumentPosition2["DISCONNECTED"] = 1] = "DISCONNECTED"; + DocumentPosition2[DocumentPosition2["PRECEDING"] = 2] = "PRECEDING"; + DocumentPosition2[DocumentPosition2["FOLLOWING"] = 4] = "FOLLOWING"; + DocumentPosition2[DocumentPosition2["CONTAINS"] = 8] = "CONTAINS"; + DocumentPosition2[DocumentPosition2["CONTAINED_BY"] = 16] = "CONTAINED_BY"; + })(DocumentPosition || (exports2.DocumentPosition = DocumentPosition = {})); + function compareDocumentPosition(nodeA, nodeB) { + var aParents = []; + var bParents = []; + if (nodeA === nodeB) { + return 0; + } + var current = (0, domhandler_1.hasChildren)(nodeA) ? nodeA : nodeA.parent; + while (current) { + aParents.unshift(current); + current = current.parent; + } + current = (0, domhandler_1.hasChildren)(nodeB) ? nodeB : nodeB.parent; + while (current) { + bParents.unshift(current); + current = current.parent; + } + var maxIdx = Math.min(aParents.length, bParents.length); + var idx = 0; + while (idx < maxIdx && aParents[idx] === bParents[idx]) { + idx++; + } + if (idx === 0) { + return DocumentPosition.DISCONNECTED; + } + var sharedParent = aParents[idx - 1]; + var siblings = sharedParent.children; + var aSibling = aParents[idx]; + var bSibling = bParents[idx]; + if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) { + if (sharedParent === nodeB) { + return DocumentPosition.FOLLOWING | DocumentPosition.CONTAINED_BY; + } + return DocumentPosition.FOLLOWING; + } + if (sharedParent === nodeA) { + return DocumentPosition.PRECEDING | DocumentPosition.CONTAINS; + } + return DocumentPosition.PRECEDING; + } + function uniqueSort(nodes) { + nodes = nodes.filter(function(node, i, arr) { + return !arr.includes(node, i + 1); + }); + nodes.sort(function(a, b) { + var relative = compareDocumentPosition(a, b); + if (relative & DocumentPosition.PRECEDING) { + return -1; + } else if (relative & DocumentPosition.FOLLOWING) { + return 1; + } + return 0; + }); + return nodes; + } + } +}); + +// node_modules/domutils/lib/feeds.js +var require_feeds = __commonJS({ + "node_modules/domutils/lib/feeds.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getFeed = getFeed; + var stringify_js_1 = require_stringify3(); + var legacy_js_1 = require_legacy(); + function getFeed(doc) { + var feedRoot = getOneElement(isValidFeed, doc); + return !feedRoot ? null : feedRoot.name === "feed" ? getAtomFeed(feedRoot) : getRssFeed(feedRoot); + } + function getAtomFeed(feedRoot) { + var _a; + var childs = feedRoot.children; + var feed = { + type: "atom", + items: (0, legacy_js_1.getElementsByTagName)("entry", childs).map(function(item) { + var _a2; + var children = item.children; + var entry = { media: getMediaElements(children) }; + addConditionally(entry, "id", "id", children); + addConditionally(entry, "title", "title", children); + var href2 = (_a2 = getOneElement("link", children)) === null || _a2 === void 0 ? void 0 : _a2.attribs["href"]; + if (href2) { + entry.link = href2; + } + var description = fetch2("summary", children) || fetch2("content", children); + if (description) { + entry.description = description; + } + var pubDate = fetch2("updated", children); + if (pubDate) { + entry.pubDate = new Date(pubDate); + } + return entry; + }) + }; + addConditionally(feed, "id", "id", childs); + addConditionally(feed, "title", "title", childs); + var href = (_a = getOneElement("link", childs)) === null || _a === void 0 ? void 0 : _a.attribs["href"]; + if (href) { + feed.link = href; + } + addConditionally(feed, "description", "subtitle", childs); + var updated = fetch2("updated", childs); + if (updated) { + feed.updated = new Date(updated); + } + addConditionally(feed, "author", "email", childs, true); + return feed; + } + function getRssFeed(feedRoot) { + var _a, _b; + var childs = (_b = (_a = getOneElement("channel", feedRoot.children)) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : []; + var feed = { + type: feedRoot.name.substr(0, 3), + id: "", + items: (0, legacy_js_1.getElementsByTagName)("item", feedRoot.children).map(function(item) { + var children = item.children; + var entry = { media: getMediaElements(children) }; + addConditionally(entry, "id", "guid", children); + addConditionally(entry, "title", "title", children); + addConditionally(entry, "link", "link", children); + addConditionally(entry, "description", "description", children); + var pubDate = fetch2("pubDate", children) || fetch2("dc:date", children); + if (pubDate) + entry.pubDate = new Date(pubDate); + return entry; + }) + }; + addConditionally(feed, "title", "title", childs); + addConditionally(feed, "link", "link", childs); + addConditionally(feed, "description", "description", childs); + var updated = fetch2("lastBuildDate", childs); + if (updated) { + feed.updated = new Date(updated); + } + addConditionally(feed, "author", "managingEditor", childs, true); + return feed; + } + var MEDIA_KEYS_STRING = ["url", "type", "lang"]; + var MEDIA_KEYS_INT = [ + "fileSize", + "bitrate", + "framerate", + "samplingrate", + "channels", + "duration", + "height", + "width" + ]; + function getMediaElements(where) { + return (0, legacy_js_1.getElementsByTagName)("media:content", where).map(function(elem) { + var attribs = elem.attribs; + var media = { + medium: attribs["medium"], + isDefault: !!attribs["isDefault"] + }; + for (var _i = 0, MEDIA_KEYS_STRING_1 = MEDIA_KEYS_STRING; _i < MEDIA_KEYS_STRING_1.length; _i++) { + var attrib = MEDIA_KEYS_STRING_1[_i]; + if (attribs[attrib]) { + media[attrib] = attribs[attrib]; + } + } + for (var _a = 0, MEDIA_KEYS_INT_1 = MEDIA_KEYS_INT; _a < MEDIA_KEYS_INT_1.length; _a++) { + var attrib = MEDIA_KEYS_INT_1[_a]; + if (attribs[attrib]) { + media[attrib] = parseInt(attribs[attrib], 10); + } + } + if (attribs["expression"]) { + media.expression = attribs["expression"]; + } + return media; + }); + } + function getOneElement(tagName, node) { + return (0, legacy_js_1.getElementsByTagName)(tagName, node, true, 1)[0]; + } + function fetch2(tagName, where, recurse) { + if (recurse === void 0) { + recurse = false; + } + return (0, stringify_js_1.textContent)((0, legacy_js_1.getElementsByTagName)(tagName, where, recurse, 1)).trim(); + } + function addConditionally(obj, prop, tagName, where, recurse) { + if (recurse === void 0) { + recurse = false; + } + var val = fetch2(tagName, where, recurse); + if (val) + obj[prop] = val; + } + function isValidFeed(value) { + return value === "rss" || value === "feed" || value === "rdf:RDF"; + } + } +}); + +// node_modules/domutils/lib/index.js +var require_lib16 = __commonJS({ + "node_modules/domutils/lib/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.hasChildren = exports2.isDocument = exports2.isComment = exports2.isText = exports2.isCDATA = exports2.isTag = void 0; + __exportStar2(require_stringify3(), exports2); + __exportStar2(require_traversal(), exports2); + __exportStar2(require_manipulation(), exports2); + __exportStar2(require_querying(), exports2); + __exportStar2(require_legacy(), exports2); + __exportStar2(require_helpers3(), exports2); + __exportStar2(require_feeds(), exports2); + var domhandler_1 = require_lib13(); + Object.defineProperty(exports2, "isTag", { enumerable: true, get: function() { + return domhandler_1.isTag; + } }); + Object.defineProperty(exports2, "isCDATA", { enumerable: true, get: function() { + return domhandler_1.isCDATA; + } }); + Object.defineProperty(exports2, "isText", { enumerable: true, get: function() { + return domhandler_1.isText; + } }); + Object.defineProperty(exports2, "isComment", { enumerable: true, get: function() { + return domhandler_1.isComment; + } }); + Object.defineProperty(exports2, "isDocument", { enumerable: true, get: function() { + return domhandler_1.isDocument; + } }); + Object.defineProperty(exports2, "hasChildren", { enumerable: true, get: function() { + return domhandler_1.hasChildren; + } }); + } +}); + +// node_modules/htmlparser2/lib/index.js +var require_lib17 = __commonJS({ + "node_modules/htmlparser2/lib/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DomUtils = exports2.parseFeed = exports2.getFeed = exports2.ElementType = exports2.QuoteType = exports2.Tokenizer = exports2.createDomStream = exports2.createDocumentStream = exports2.parseDOM = exports2.parseDocument = exports2.DefaultHandler = exports2.DomHandler = exports2.Parser = void 0; + var Parser_js_1 = require_Parser(); + var Parser_js_2 = require_Parser(); + Object.defineProperty(exports2, "Parser", { enumerable: true, get: function() { + return Parser_js_2.Parser; + } }); + var domhandler_1 = require_lib13(); + var domhandler_2 = require_lib13(); + Object.defineProperty(exports2, "DomHandler", { enumerable: true, get: function() { + return domhandler_2.DomHandler; + } }); + Object.defineProperty(exports2, "DefaultHandler", { enumerable: true, get: function() { + return domhandler_2.DomHandler; + } }); + function parseDocument(data, options) { + var handler = new domhandler_1.DomHandler(void 0, options); + new Parser_js_1.Parser(handler, options).end(data); + return handler.root; + } + exports2.parseDocument = parseDocument; + function parseDOM(data, options) { + return parseDocument(data, options).children; + } + exports2.parseDOM = parseDOM; + function createDocumentStream(callback, options, elementCallback) { + var handler = new domhandler_1.DomHandler(function(error) { + return callback(error, handler.root); + }, options, elementCallback); + return new Parser_js_1.Parser(handler, options); + } + exports2.createDocumentStream = createDocumentStream; + function createDomStream(callback, options, elementCallback) { + var handler = new domhandler_1.DomHandler(callback, options, elementCallback); + return new Parser_js_1.Parser(handler, options); + } + exports2.createDomStream = createDomStream; + var Tokenizer_js_1 = require_Tokenizer(); + Object.defineProperty(exports2, "Tokenizer", { enumerable: true, get: function() { + return __importDefault2(Tokenizer_js_1).default; + } }); + Object.defineProperty(exports2, "QuoteType", { enumerable: true, get: function() { + return Tokenizer_js_1.QuoteType; + } }); + exports2.ElementType = __importStar2(require_lib12()); + var domutils_1 = require_lib16(); + var domutils_2 = require_lib16(); + Object.defineProperty(exports2, "getFeed", { enumerable: true, get: function() { + return domutils_2.getFeed; + } }); + var parseFeedDefaultOptions = { xmlMode: true }; + function parseFeed(feed, options) { + if (options === void 0) { + options = parseFeedDefaultOptions; + } + return (0, domutils_1.getFeed)(parseDOM(feed, options)); + } + exports2.parseFeed = parseFeed; + exports2.DomUtils = __importStar2(require_lib16()); + } +}); + +// node_modules/botbuilder/lib/setSpeakMiddleware.js +var require_setSpeakMiddleware = __commonJS({ + "node_modules/botbuilder/lib/setSpeakMiddleware.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SetSpeakMiddleware = void 0; + var z = __importStar2(require_zod()); + var botbuilder_core_1 = require_lib10(); + var htmlparser2_1 = require_lib17(); + var supportedChannels = /* @__PURE__ */ new Set([botbuilder_core_1.Channels.DirectlineSpeech, botbuilder_core_1.Channels.Emulator, botbuilder_core_1.Channels.Telephony]); + function hasTag(tag, nodes) { + while (nodes.length) { + const item = nodes.shift(); + const itemParsed = z.object({ tagName: z.string(), children: z.array(z.unknown()) }).partial().nonstrict().safeParse(item); + if (itemParsed.success) { + if (itemParsed.data.tagName === tag) { + return true; + } + if (itemParsed.data.children) { + nodes.push(...itemParsed.data.children); + } + } + } + return false; + } + var SetSpeakMiddleware = class { + /** + * Initializes a new instance of the SetSpeakMiddleware class. + * + * @param voiceName The SSML voice name attribute value. + * @param fallbackToTextForSpeak true if an empty Activity.Speak is populated with Activity.Text. + */ + constructor(voiceName, fallbackToTextForSpeak) { + this.voiceName = voiceName; + this.fallbackToTextForSpeak = fallbackToTextForSpeak; + } + /** + * Processes an incoming activity. + * + * @param turnContext The context object for this turn. + * @param next The delegate to call to continue the bot middleware pipeline. + * @returns A promise representing the async operation. + */ + onTurn(turnContext, next) { + turnContext.onSendActivities((_ctx, activities, next2) => __awaiter2(this, void 0, void 0, function* () { + yield Promise.all(activities.map((activity) => __awaiter2(this, void 0, void 0, function* () { + var _a, _b; + if (activity.type !== botbuilder_core_1.ActivityTypes.Message) { + return; + } + if (this.fallbackToTextForSpeak && !activity.speak) { + activity.speak = activity.text; + } + const channelId = (_a = turnContext.activity.channelId) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase(); + if (activity.speak && this.voiceName !== null && supportedChannels.has(channelId)) { + const nodes = (0, htmlparser2_1.parseDocument)(activity.speak).childNodes; + if (!hasTag("speak", nodes.slice())) { + if (!hasTag("voice", nodes.slice())) { + activity.speak = `${activity.speak}`; + } + activity.speak = `${activity.speak}`; + } + } + }))); + return next2(); + })); + return next(); + } + }; + exports2.SetSpeakMiddleware = SetSpeakMiddleware; + } +}); + +// node_modules/botbuilder/lib/statusCodeError.js +var require_statusCodeError = __commonJS({ + "node_modules/botbuilder/lib/statusCodeError.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.StatusCodeError = void 0; + var StatusCodeError = class extends Error { + /** + * Creates a new instance of the [StatusCodeError](xref:botbuilder.StatusCodeError) class. + * + * @param statusCode The status code. + * @param message Optional. The error message. + */ + constructor(statusCode, message) { + super(message); + this.statusCode = statusCode; + this.name = "StatusCodeError"; + } + }; + exports2.StatusCodeError = StatusCodeError; + } +}); + +// node_modules/botbuilder/lib/channelServiceHandlerBase.js +var require_channelServiceHandlerBase = __commonJS({ + "node_modules/botbuilder/lib/channelServiceHandlerBase.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ChannelServiceHandlerBase = void 0; + var http_1 = require("http"); + var statusCodeError_1 = require_statusCodeError(); + var botbuilder_core_1 = require_lib10(); + var ChannelServiceHandlerBase = class { + /** + * Sends an [Activity](xref:botframework-schema.Activity) to the end of a conversation. + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param activity The [Activity](xref:botframework-schema.Activity) to send. + * @returns A `Promise` representing the [ResourceResponse](xref:botframework-schema.ResourceResponse) for the operation. + */ + handleSendToConversation(authHeader, conversationId, activity) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onSendToConversation(claimsIdentity, conversationId, activity); + }); + } + /** + * Sends a reply to an [Activity](xref:botframework-schema.Activity). + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param activityId The activity Id the reply is to. + * @param activity The [Activity](xref:botframework-schema.Activity) to send. + * @returns A `Promise` representing the [ResourceResponse](xref:botframework-schema.ResourceResponse) for the operation. + */ + handleReplyToActivity(authHeader, conversationId, activityId, activity) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onReplyToActivity(claimsIdentity, conversationId, activityId, activity); + }); + } + /** + * Edits a previously sent existing [Activity](xref:botframework-schema.Activity). + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param activityId The activity Id to update. + * @param activity The replacement [Activity](xref:botframework-schema.Activity). + * @returns A `Promise` representing the [ResourceResponse](xref:botframework-schema.ResourceResponse) for the operation. + */ + handleUpdateActivity(authHeader, conversationId, activityId, activity) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onUpdateActivity(claimsIdentity, conversationId, activityId, activity); + }); + } + /** + * Deletes an existing [Activity](xref:botframework-schema.Activity). + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param activityId The activity Id to delete. + */ + handleDeleteActivity(authHeader, conversationId, activityId) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + yield this.onDeleteActivity(claimsIdentity, conversationId, activityId); + }); + } + /** + * Enumerates the members of an [Activity](xref:botframework-schema.Activity). + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param activityId The activity Id. + * @returns The enumerated [ChannelAccount](xref:botframework-schema.ChannelAccount) list. + */ + handleGetActivityMembers(authHeader, conversationId, activityId) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onGetActivityMembers(claimsIdentity, conversationId, activityId); + }); + } + /** + * Creates a new Conversation. + * + * @param authHeader The authentication header. + * @param parameters [ConversationParameters](xref:botbuilder-core.ConversationParameters) to create the conversation from. + * @returns A `Promise` representation for the operation. + */ + handleCreateConversation(authHeader, parameters) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onCreateConversation(claimsIdentity, parameters); + }); + } + /** + * Lists the Conversations in which the bot has participated. + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param continuationToken A skip or continuation token. + * @returns A `Promise` representation for the operation. + */ + handleGetConversations(authHeader, conversationId, continuationToken) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onGetConversations(claimsIdentity, conversationId, continuationToken); + }); + } + /** + * Enumerates the members of a conversation. + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @returns The enumerated [ChannelAccount](xref:botframework-schema.ChannelAccount) list. + */ + handleGetConversationMembers(authHeader, conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onGetConversationMembers(claimsIdentity, conversationId); + }); + } + /** + * Gets the account of a single conversation member. + * + * @param authHeader The authentication header. + * @param userId The user Id. + * @param conversationId The conversation Id. + * @returns The [ChannelAccount](xref:botframework-schema.ChannelAccount) for the provided user id. + */ + handleGetConversationMember(authHeader, userId, conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onGetConversationMember(claimsIdentity, userId, conversationId); + }); + } + /** + * Enumerates the members of a conversation one page at a time. + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param pageSize Suggested page size. + * @param continuationToken A continuation token. + * @returns A `Promise` representing the [PagedMembersResult](xref:botframework-schema.PagedMembersResult) for the operation. + */ + handleGetConversationPagedMembers(authHeader, conversationId, pageSize = -1, continuationToken) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onGetConversationPagedMembers(claimsIdentity, conversationId, pageSize, continuationToken); + }); + } + /** + * Deletes a member from a conversation. + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param memberId Id of the member to delete from this conversation. + */ + handleDeleteConversationMember(authHeader, conversationId, memberId) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + yield this.onDeleteConversationMember(claimsIdentity, conversationId, memberId); + }); + } + /** + * Uploads the historic activities of the conversation. + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param transcript [Transcript](xref:botframework-schema.Transcript) of activities. + * @returns A `Promise` representing the [ResourceResponse](xref:botframework-schema.ResourceResponse) for the operation. + */ + handleSendConversationHistory(authHeader, conversationId, transcript) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onSendConversationHistory(claimsIdentity, conversationId, transcript); + }); + } + /** + * Stores data in a compliant store when dealing with enterprises. + * + * @param authHeader The authentication header. + * @param conversationId The conversation Id. + * @param attachmentUpload [AttachmentData](xref:botframework-schema.AttachmentData). + * @returns A `Promise` representing the [ResourceResponse](xref:botframework-schema.ResourceResponse) for the operation. + */ + handleUploadAttachment(authHeader, conversationId, attachmentUpload) { + return __awaiter2(this, void 0, void 0, function* () { + const claimsIdentity = yield this.authenticate(authHeader); + return this.onUploadAttachment(claimsIdentity, conversationId, attachmentUpload); + }); + } + /** + * SendToConversation() API for Skill. + * + * @remarks + * This method allows you to send an activity to the end of a conversation. + * This is slightly different from ReplyToActivity(). + * SendToConversation(conversationId) - will append the activity to the end + * of the conversation according to the timestamp or semantics of the channel. + * ReplyToActivity(conversationId,ActivityId) - adds the activity as a reply + * to another activity, if the channel supports it. If the channel does not + * support nested replies, ReplyToActivity falls back to SendToConversation. + * + * Use ReplyToActivity when replying to a specific activity in the + * conversation. + * + * Use SendToConversation in all other cases. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation identifier + * @param _activity Activity to send + */ + onSendToConversation(_claimsIdentity, _conversationId, _activity) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onSendToConversation(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * ReplyToActivity() API for Skill. + * + * @remarks + * This method allows you to reply to an activity. + * + * This is slightly different from SendToConversation(). + * SendToConversation(conversationId) - will append the activity to the end + * of the conversation according to the timestamp or semantics of the channel. + * ReplyToActivity(conversationId,ActivityId) - adds the activity as a reply + * to another activity, if the channel supports it. If the channel does not + * support nested replies, ReplyToActivity falls back to SendToConversation. + * + * Use ReplyToActivity when replying to a specific activity in the + * conversation. + * + * Use SendToConversation in all other cases. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _activityId activityId the reply is to (OPTIONAL). + * @param _activity Activity to send. + */ + onReplyToActivity(_claimsIdentity, _conversationId, _activityId, _activity) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onReplyToActivity(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * UpdateActivity() API for Skill. + * + * @remarks + * Edit an existing activity. + * + * Some channels allow you to edit an existing activity to reflect the new + * state of a bot conversation. + * + * For example, you can remove buttons after someone has clicked "Approve" button. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _activityId activityId to update. + * @param _activity replacement Activity. + */ + onUpdateActivity(_claimsIdentity, _conversationId, _activityId, _activity) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onUpdateActivity(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * DeleteActivity() API for Skill. + * + * @remarks + * Delete an existing activity. + * + * Some channels allow you to delete an existing activity, and if successful + * this method will remove the specified activity. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _activityId activityId to delete. + */ + onDeleteActivity(_claimsIdentity, _conversationId, _activityId) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onDeleteActivity(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * GetActivityMembers() API for Skill. + * + * @remarks + * Enumerate the members of an activity. + * + * This REST API takes a ConversationId and a ActivityId, returning an array + * of ChannelAccount objects representing the members of the particular + * activity in the conversation. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _activityId Activity ID. + */ + onGetActivityMembers(_claimsIdentity, _conversationId, _activityId) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetActivityMembers(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * CreateConversation() API for Skill. + * + * @remarks + * Create a new Conversation. + * + * POST to this method with a + * Bot being the bot creating the conversation + * IsGroup set to true if this is not a direct message (default is false) + * Array containing the members to include in the conversation + * + * The return value is a ResourceResponse which contains a conversation id + * which is suitable for use in the message payload and REST API uris. + * + * Most channels only support the semantics of bots initiating a direct + * message conversation. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _parameters Parameters to create the conversation from. + */ + onCreateConversation(_claimsIdentity, _parameters) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onCreateConversation(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * onGetConversations() API for Skill. + * + * @remarks + * List the Conversations in which this bot has participated. + * + * GET from this method with a skip token + * + * The return value is a ConversationsResult, which contains an array of + * ConversationMembers and a skip token. If the skip token is not empty, then + * there are further values to be returned. Call this method again with the + * returned token to get more values. + * + * Each ConversationMembers object contains the ID of the conversation and an + * array of ChannelAccounts that describe the members of the conversation. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _continuationToken Skip or continuation token. + */ + onGetConversations(_claimsIdentity, _conversationId, _continuationToken) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetConversations(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * getConversationMembers() API for Skill. + * + * @remarks + * Enumerate the members of a conversation. + * + * This REST API takes a ConversationId and returns an array of ChannelAccount + * objects representing the members of the conversation. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + */ + onGetConversationMembers(_claimsIdentity, _conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetConversationMembers(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * getConversationMember() API for Skill. + * + * @remarks + * Get the account of a single conversation member. + * + * This REST API takes a ConversationId and UserId and returns the ChannelAccount + * object representing the member of the conversation. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _userId User ID. + * @param _conversationId Conversation ID. + */ + onGetConversationMember(_claimsIdentity, _userId, _conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetConversationMember(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * getConversationPagedMembers() API for Skill. + * + * @remarks + * Enumerate the members of a conversation one page at a time. + * + * This REST API takes a ConversationId. Optionally a pageSize and/or + * continuationToken can be provided. It returns a PagedMembersResult, which + * contains an array + * of ChannelAccounts representing the members of the conversation and a + * continuation token that can be used to get more values. + * + * One page of ChannelAccounts records are returned with each call. The number + * of records in a page may vary between channels and calls. The pageSize + * parameter can be used as + * a suggestion. If there are no additional results the response will not + * contain a continuation token. If there are no members in the conversation + * the Members will be empty or not present in the response. + * + * A response to a request that has a continuation token from a prior request + * may rarely return members from a previous request. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _pageSize Suggested page size. + * @param _continuationToken Continuation Token. + */ + onGetConversationPagedMembers(_claimsIdentity, _conversationId, _pageSize = -1, _continuationToken) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetConversationPagedMembers(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * DeleteConversationMember() API for Skill. + * + * @remarks + * Deletes a member from a conversation. + * + * This REST API takes a ConversationId and a memberId (of type string) and + * removes that member from the conversation. If that member was the last member + * of the conversation, the conversation will also be deleted. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _memberId ID of the member to delete from this conversation. + */ + onDeleteConversationMember(_claimsIdentity, _conversationId, _memberId) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onDeleteConversationMember(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * SendConversationHistory() API for Skill. + * + * @remarks + * This method allows you to upload the historic activities to the + * conversation. + * + * Sender must ensure that the historic activities have unique ids and + * appropriate timestamps. The ids are used by the client to deal with + * duplicate activities and the timestamps are used by the client to render + * the activities in the right order. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _transcript Transcript of activities. + */ + onSendConversationHistory(_claimsIdentity, _conversationId, _transcript) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onSendConversationHistory(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + /** + * UploadAttachment() API for Skill. + * + * @remarks + * Upload an attachment directly into a channel's blob storage. + * + * This is useful because it allows you to store data in a compliant store + * when dealing with enterprises. + * + * The response is a ResourceResponse which contains an AttachmentId which is + * suitable for using with the attachments API. + * @param _claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param _conversationId Conversation ID. + * @param _attachmentUpload Attachment data. + */ + onUploadAttachment(_claimsIdentity, _conversationId, _attachmentUpload) { + return __awaiter2(this, void 0, void 0, function* () { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onUploadAttachment(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`); + }); + } + }; + exports2.ChannelServiceHandlerBase = ChannelServiceHandlerBase; + } +}); + +// node_modules/botbuilder/lib/channelServiceHandler.js +var require_channelServiceHandler = __commonJS({ + "node_modules/botbuilder/lib/channelServiceHandler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ChannelServiceHandler = void 0; + var channelServiceHandlerBase_1 = require_channelServiceHandlerBase(); + var statusCodeError_1 = require_statusCodeError(); + var botbuilder_core_1 = require_lib10(); + var botframework_connector_1 = require_lib9(); + var ChannelServiceHandler = class extends channelServiceHandlerBase_1.ChannelServiceHandlerBase { + /** + * Initializes a new instance of the ChannelServiceHandler class, using a credential provider. + * + * @param credentialProvider The credential provider. + * @param authConfig The authentication configuration. + * @param channelService A string representing the channel provider. + */ + constructor(credentialProvider, authConfig, channelService = process.env[botframework_connector_1.AuthenticationConstants.ChannelService]) { + super(); + this.credentialProvider = credentialProvider; + this.authConfig = authConfig; + this.channelService = channelService; + if (!credentialProvider) { + throw new Error("ChannelServiceHandler(): missing credentialProvider"); + } + if (!authConfig) { + throw new Error("ChannelServiceHandler(): missing authConfig"); + } + } + authenticate(authHeader) { + return __awaiter2(this, void 0, void 0, function* () { + const isAuthDisabled = yield this.credentialProvider.isAuthenticationDisabled(); + if (isAuthDisabled) { + return botframework_connector_1.SkillValidation.createAnonymousSkillClaim(); + } else { + if (!authHeader) { + throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.UNAUTHORIZED); + } + return botframework_connector_1.JwtTokenValidation.validateAuthHeader(authHeader, this.credentialProvider, this.channelService, "unknown", void 0, this.authConfig); + } + }); + } + }; + exports2.ChannelServiceHandler = ChannelServiceHandler; + } +}); + +// node_modules/botbuilder/lib/skills/skillHandlerImpl.js +var require_skillHandlerImpl = __commonJS({ + "node_modules/botbuilder/lib/skills/skillHandlerImpl.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkillHandlerImpl = void 0; + var botframework_connector_1 = require_lib9(); + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + var botbuilder_core_1 = require_lib10(); + var SkillHandlerImpl = class { + /** + * @internal + */ + constructor(skillConversationReferenceKey, adapter, logic, conversationIdFactory, getOauthScope = () => void 0) { + this.skillConversationReferenceKey = skillConversationReferenceKey; + this.adapter = adapter; + this.logic = logic; + this.conversationIdFactory = conversationIdFactory; + this.getOauthScope = getOauthScope; + } + /** + * @internal + */ + onSendToConversation(claimsIdentity, conversationId, activity) { + return this.processActivity(claimsIdentity, conversationId, null, activity); + } + /** + * @internal + */ + onReplyToActivity(claimsIdentity, conversationId, activityId, activity) { + return this.processActivity(claimsIdentity, conversationId, activityId, activity); + } + /** + * @internal + */ + onUpdateActivity(claimsIdentity, conversationId, activityId, activity) { + return __awaiter2(this, void 0, void 0, function* () { + let resourceResponse; + yield this.continueConversation(claimsIdentity, conversationId, (context, ref) => __awaiter2(this, void 0, void 0, function* () { + const newActivity = botbuilder_core_1.TurnContext.applyConversationReference(activity, ref.conversationReference); + context.activity.id = activityId; + context.activity.callerId = `${botbuilder_core_1.CallerIdConstants.BotToBotPrefix}${botframework_connector_1.JwtTokenValidation.getAppIdFromClaims(claimsIdentity.claims)}`; + resourceResponse = yield context.updateActivity(newActivity); + })); + return resourceResponse ? resourceResponse : { id: activityId }; + }); + } + /** + * @internal + */ + onDeleteActivity(claimsIdentity, conversationId, activityId) { + return __awaiter2(this, void 0, void 0, function* () { + return this.continueConversation(claimsIdentity, conversationId, (context) => context.deleteActivity(activityId)); + }); + } + /** + * @internal + */ + onGetMember(claimsIdentity, userId, conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + let member = null; + yield this.continueConversation(claimsIdentity, conversationId, (context) => __awaiter2(this, void 0, void 0, function* () { + const client = context.turnState.get(context.adapter.ConnectorClientKey); + const conversationId2 = context.activity.conversation.id; + member = yield client.conversations.getConversationMember(conversationId2, userId); + })); + return member; + }); + } + getSkillConversationReference(conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + let skillConversationReference; + try { + skillConversationReference = yield this.conversationIdFactory.getSkillConversationReference(conversationId); + } catch (err) { + if (err.message === "NotImplemented") { + skillConversationReference = { + conversationReference: yield this.conversationIdFactory.getConversationReference(conversationId), + oAuthScope: this.getOauthScope() + }; + } else { + throw err; + } + } + if (!skillConversationReference) { + throw new Error("skillConversationReference not found"); + } else if (!skillConversationReference.conversationReference) { + throw new Error("conversationReference not found."); + } + return skillConversationReference; + }); + } + processActivity(claimsIdentity, conversationId, replyToActivityId, activity) { + return __awaiter2(this, void 0, void 0, function* () { + let resourceResponse; + yield this.continueConversation(claimsIdentity, conversationId, (context, ref) => __awaiter2(this, void 0, void 0, function* () { + const newActivity = botbuilder_core_1.TurnContext.applyConversationReference(activity, ref.conversationReference); + context.activity.id = replyToActivityId; + context.activity.callerId = `${botbuilder_core_1.CallerIdConstants.BotToBotPrefix}${botframework_connector_1.JwtTokenValidation.getAppIdFromClaims(claimsIdentity.claims)}`; + switch (newActivity.type) { + case botbuilder_core_1.ActivityTypes.EndOfConversation: + yield this.conversationIdFactory.deleteConversationReference(conversationId); + this.applySkillActivityToTurnContext(context, newActivity); + yield this.logic(context); + break; + case botbuilder_core_1.ActivityTypes.Event: + this.applySkillActivityToTurnContext(context, newActivity); + yield this.logic(context); + break; + default: + resourceResponse = yield context.sendActivity(newActivity); + break; + } + })); + if (!resourceResponse) { + resourceResponse = { id: (0, uuid_1.v4)() }; + } + return resourceResponse; + }); + } + continueConversation(claimsIdentity, conversationId, callback) { + return __awaiter2(this, void 0, void 0, function* () { + const ref = yield this.getSkillConversationReference(conversationId); + const continueCallback = (context) => { + context.turnState.set(this.skillConversationReferenceKey, ref); + return callback(context, ref); + }; + try { + yield this.adapter.continueConversationAsync(claimsIdentity, ref.conversationReference, ref.oAuthScope, continueCallback); + } catch (err) { + if (err.message === "NotImplemented") { + yield this.adapter.continueConversation(ref.conversationReference, (context) => __awaiter2(this, void 0, void 0, function* () { + context.turnState.set(context.adapter.BotIdentityKey, claimsIdentity); + return continueCallback(context); + })); + } else { + throw err; + } + } + }); + } + // adapter.continueConversation() sends an event activity with continueConversation in the name. + // this warms up the incoming middlewares but once that's done and we hit the custom callback, + // we need to swap the values back to the ones received from the skill so the bot gets the actual activity. + applySkillActivityToTurnContext(context, activity) { + context.activity.channelData = activity.channelData; + context.activity.code = activity.code; + context.activity.entities = activity.entities; + context.activity.locale = activity.locale; + context.activity.localTimestamp = activity.localTimestamp; + context.activity.name = activity.name; + context.activity.relatesTo = activity.relatesTo; + context.activity.replyToId = activity.replyToId; + context.activity.timestamp = activity.timestamp; + context.activity.text = activity.text; + context.activity.type = activity.type; + context.activity.value = activity.value; + } + }; + exports2.SkillHandlerImpl = SkillHandlerImpl; + } +}); + +// node_modules/botbuilder/lib/skills/skillHandler.js +var require_skillHandler = __commonJS({ + "node_modules/botbuilder/lib/skills/skillHandler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkillHandler = void 0; + var channelServiceHandler_1 = require_channelServiceHandler(); + var skillHandlerImpl_1 = require_skillHandlerImpl(); + var botframework_connector_1 = require_lib9(); + var botbuilder_core_1 = require_lib10(); + var SkillHandler = class extends channelServiceHandler_1.ChannelServiceHandler { + /** + * Initializes a new instance of the SkillHandler class. + * + * @param adapter An instance of the BotAdapter that will handle the request. + * @param bot The ActivityHandlerBase instance. + * @param conversationIdFactory A SkillConversationIdFactoryBase to unpack the conversation ID and map it to the calling bot. + * @param credentialProvider The credential provider. + * @param authConfig The authentication configuration. + * @param channelService The string indicating if the bot is working in Public Azure or in Azure Government (https://aka.ms/AzureGovDocs). + */ + constructor(adapter, bot, conversationIdFactory, credentialProvider, authConfig, channelService) { + super(credentialProvider, authConfig, channelService); + this.SkillConversationReferenceKey = botbuilder_core_1.SkillConversationReferenceKey; + if (!adapter) { + throw new Error("missing adapter."); + } + if (!bot) { + throw new Error("missing bot."); + } + if (!conversationIdFactory) { + throw new Error("missing conversationIdFactory."); + } + this.inner = new skillHandlerImpl_1.SkillHandlerImpl(this.SkillConversationReferenceKey, adapter, (context) => bot.run(context), conversationIdFactory, () => botframework_connector_1.JwtTokenValidation.isGovernment(channelService) ? botframework_connector_1.GovernmentConstants.ToChannelFromBotOAuthScope : botframework_connector_1.AuthenticationConstants.ToChannelFromBotOAuthScope); + } + /** + * sendToConversation() API for Skill. + * + * @remarks + * This method allows you to send an activity to the end of a conversation. + * + * This is slightly different from replyToActivity(). + * - sendToConversation(conversationId) - will append the activity to the end + * of the conversation according to the timestamp or semantics of the channel. + * - replyToActivity(conversationId,ActivityId) - adds the activity as a reply + * to another activity, if the channel supports it. If the channel does not + * support nested replies, replyToActivity falls back to sendToConversation. + * + * Use replyToActivity when replying to a specific activity in the conversation. + * + * Use sendToConversation in all other cases. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param conversationId Conversation ID. + * @param activity Activity to send. + * @returns A Promise with a ResourceResponse. + */ + onSendToConversation(claimsIdentity, conversationId, activity) { + return this.inner.onSendToConversation(claimsIdentity, conversationId, activity); + } + /** + * replyToActivity() API for Skill. + * + * @remarks + * This method allows you to reply to an activity. + * + * This is slightly different from sendToConversation(). + * - sendToConversation(conversationId) - will append the activity to the end + * of the conversation according to the timestamp or semantics of the channel. + * - replyToActivity(conversationId,ActivityId) - adds the activity as a reply + * to another activity, if the channel supports it. If the channel does not + * support nested replies, replyToActivity falls back to sendToConversation. + * + * Use replyToActivity when replying to a specific activity in the conversation. + * + * Use sendToConversation in all other cases. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param conversationId Conversation ID. + * @param activityId activityId the reply is to. + * @param activity Activity to send. + * @returns A Promise with a ResourceResponse. + */ + onReplyToActivity(claimsIdentity, conversationId, activityId, activity) { + return this.inner.onReplyToActivity(claimsIdentity, conversationId, activityId, activity); + } + /** + * + * UpdateActivity() API for Skill. + * + * @remarks + * Edit an existing activity. + * + * Some channels allow you to edit an existing activity to reflect the new + * state of a bot conversation. + * + * For example, you can remove buttons after someone has clicked "Approve" button. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param conversationId Conversation ID. + * @param activityId activityId to update. + * @param activity replacement Activity. + * @returns a promise resolving to the underlying resource response + */ + onUpdateActivity(claimsIdentity, conversationId, activityId, activity) { + return this.inner.onUpdateActivity(claimsIdentity, conversationId, activityId, activity); + } + /** + * DeleteActivity() API for Skill. + * + * @remarks + * Delete an existing activity. + * + * Some channels allow you to delete an existing activity, and if successful + * this method will remove the specified activity. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param conversationId Conversation ID. + * @param activityId activityId to delete. + * @returns a promise representing the async operation + */ + onDeleteActivity(claimsIdentity, conversationId, activityId) { + return __awaiter2(this, void 0, void 0, function* () { + return this.inner.onDeleteActivity(claimsIdentity, conversationId, activityId); + }); + } + }; + exports2.SkillHandler = SkillHandler; + } +}); + +// node_modules/botbuilder/lib/interfaces/request.js +var require_request2 = __commonJS({ + "node_modules/botbuilder/lib/interfaces/request.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botbuilder/lib/interfaces/response.js +var require_response4 = __commonJS({ + "node_modules/botbuilder/lib/interfaces/response.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ResponseT = void 0; + var z = __importStar2(require_zod()); + exports2.ResponseT = z.custom((val) => typeof val.end === "function" && typeof val.header === "function" && typeof val.send === "function" && typeof val.status === "function", { + message: "Response" + }); + } +}); + +// node_modules/botbuilder/lib/interfaces/index.js +var require_interfaces3 = __commonJS({ + "node_modules/botbuilder/lib/interfaces/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_request2(), exports2); + __exportStar2(require_response4(), exports2); + } +}); + +// node_modules/botbuilder/lib/zod.js +var require_zod2 = __commonJS({ + "node_modules/botbuilder/lib/zod.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.LogicT = exports2.INodeSocketT = exports2.INodeBufferT = void 0; + var z = __importStar2(require_zod()); + exports2.INodeBufferT = z.custom(Buffer.isBuffer, { message: "INodeBufferT" }); + exports2.INodeSocketT = z.custom((val) => typeof val.emit === "function" && typeof val.end === "function" && typeof val.off === "function" && typeof val.on === "function" && typeof val.once === "function" && typeof val.pipe === "function" && typeof val.write === "function", { message: "INodeSocket" }); + exports2.LogicT = z.custom((val) => typeof val === "function"); + } +}); + +// node_modules/botbuilder/lib/activityValidator.js +var require_activityValidator = __commonJS({ + "node_modules/botbuilder/lib/activityValidator.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.validateAndFixActivity = void 0; + function validateAndFixActivity(activity) { + if (typeof activity !== "object") { + throw new Error("validateAndFixActivity(): invalid request body."); + } + if (typeof activity.type !== "string") { + throw new Error("validateAndFixActivity(): missing activity type."); + } + if (typeof activity.timestamp === "string") { + activity.rawTimestamp = activity.timestamp; + activity.timestamp = new Date(activity.timestamp); + } + if (typeof activity.expiration === "string") { + activity.rawExpiration = activity.expiration; + activity.expiration = new Date(activity.expiration); + } + if (typeof activity.localTimestamp === "string") { + activity.rawLocalTimestamp = activity.localTimestamp; + activity.localTimestamp = new Date(activity.localTimestamp); + } + return activity; + } + exports2.validateAndFixActivity = validateAndFixActivity; + } +}); + +// node_modules/botframework-streaming/lib/contentStream.js +var require_contentStream = __commonJS({ + "node_modules/botframework-streaming/lib/contentStream.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ContentStream = void 0; + var ContentStream = class { + /** + * Initializes a new instance of the [ContentStream](xref:botframework-streaming.ContentStream) class. + * + * @param id The ID assigned to this instance. + * @param assembler The [PayloadAssembler](xref:botframework-streaming.PayloadAssembler) assigned to this instance. + */ + constructor(id, assembler) { + if (!assembler) { + throw Error("Null Argument Exception"); + } + this.id = id; + this.assembler = assembler; + } + /** + * Gets the name of the type of the object contained within this [ContentStream](xref:botframework-streaming.ContentStream). + * + * @returns The [PayloadType](xref:botframework-streaming.PayloadType) of this [ContentStream](xref:botframework-streaming.ContentStream). + */ + get contentType() { + return this.assembler.payloadType; + } + /** + * Gets the length of this [ContentStream](xref:botframework-streaming.ContentStream). + * + * @returns A number representing the length of this [ContentStream](xref:botframework-streaming.ContentStream). + */ + get length() { + return this.assembler.contentLength; + } + /** + * Gets the data contained within this [ContentStream](xref:botframework-streaming.ContentStream). + * + * @returns This [ContentStream's](xref:botframework-streaming.ContentStream) [SubscribableStream](xref:botframework-streaming.SubscribableStream). + */ + getStream() { + if (!this.stream) { + this.stream = this.assembler.getPayloadStream(); + } + return this.stream; + } + /** + * Closes the assembler. + */ + cancel() { + this.assembler.close(); + } + /** + * Gets the [SubscribableStream](xref:botframework-streaming.SubscribableStream) content as a string. + * + * @returns A string Promise with [SubscribableStream](xref:botframework-streaming.SubscribableStream) content. + */ + readAsString() { + return __awaiter2(this, void 0, void 0, function* () { + const { bufferArray } = yield this.readAll(); + return (bufferArray || []).map((result) => result.toString("utf8")).join(""); + }); + } + /** + * Gets the [SubscribableStream](xref:botframework-streaming.SubscribableStream) content as a typed JSON object. + * + * @returns A typed object Promise with `SubscribableStream` content. + */ + readAsJson() { + return __awaiter2(this, void 0, void 0, function* () { + const stringToParse = yield this.readAsString(); + return JSON.parse(stringToParse); + }); + } + readAll() { + return __awaiter2(this, void 0, void 0, function* () { + const allData = []; + let count = 0; + const stream = this.getStream(); + while (count < stream.length) { + const chunk = stream.read(stream.length); + allData.push(chunk); + count += chunk.length; + } + if (count < this.length) { + const readToEnd = new Promise((resolve) => { + const callback = (cs) => (chunk) => { + allData.push(chunk); + count += chunk.length; + if (count === cs.length) { + resolve(true); + } + }; + stream.subscribe(callback(this)); + }); + yield readToEnd; + } + return { bufferArray: allData, size: count }; + }); + } + }; + exports2.ContentStream = ContentStream; + } +}); + +// node_modules/botframework-streaming/lib/utilities/protocol-base.js +var require_protocol_base = __commonJS({ + "node_modules/botframework-streaming/lib/utilities/protocol-base.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.generateGuid = void 0; + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + function generateGuid() { + return (0, uuid_1.v4)(); + } + exports2.generateGuid = generateGuid; + } +}); + +// node_modules/botframework-streaming/lib/httpContentStream.js +var require_httpContentStream = __commonJS({ + "node_modules/botframework-streaming/lib/httpContentStream.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.HttpContent = exports2.HttpContentStream = void 0; + var protocol_base_1 = require_protocol_base(); + var HttpContentStream = class { + /** + * Initializes a new instance of the [HttpContentStream](xref:botframework-streaming.HttpContentStream) class. + * + * @param content The [HttpContent](xref:botframework-streaming.HttpContent) to assign to the [HttpContentStream](xref:botframework-streaming.HttpContentStream). + */ + constructor(content) { + var _a, _b, _c, _d, _e, _f; + this.content = content; + this.id = (0, protocol_base_1.generateGuid)(); + this.description = { + id: this.id, + type: (_c = (_b = (_a = this.content) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : "unknown", + length: (_f = (_e = (_d = this.content) === null || _d === void 0 ? void 0 : _d.headers) === null || _e === void 0 ? void 0 : _e.contentLength) !== null && _f !== void 0 ? _f : 0 + }; + } + }; + exports2.HttpContentStream = HttpContentStream; + var HttpContent = class { + /** + * Initializes a new instance of the [HttpContent](xref:botframework-streaming.HttpContent) class. + * + * @param headers The Streaming Http content header definition. + * @param stream The stream of buffered data. + */ + constructor(headers, stream) { + this.headers = headers; + this.stream = stream; + } + /** + * Gets the data contained within this [HttpContent](xref:botframework-streaming.HttpContent). + * + * @returns This [HttpContent's](xref:botframework-streaming.HttpContent) [SubscribableStream](xref:botframework-streaming.SubscribableStream) member. + */ + getStream() { + return this.stream; + } + }; + exports2.HttpContent = HttpContent; + } +}); + +// node_modules/botframework-streaming/lib/subscribableStream.js +var require_subscribableStream = __commonJS({ + "node_modules/botframework-streaming/lib/subscribableStream.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SubscribableStream = void 0; + var stream_1 = require("stream"); + var SubscribableStream = class extends stream_1.Duplex { + /** + * Initializes a new instance of the [SubscribableStream](xref:botframework-streaming.SubscribableStream) class. + * + * @param options The `DuplexOptions` to use when constructing this stream. + */ + constructor(options) { + super(options); + this.length = 0; + this.bufferList = []; + } + /** + * Writes data to the buffered list. + * All calls to writable.write() that occur between the time writable._write() is called and the callback is called will cause the written data to be buffered. + * + * @param chunk The Buffer to be written. + * @param _encoding The encoding. Unused in the implementation of Duplex. + * @param callback Callback for when this chunk of data is flushed. + */ + _write(chunk, _encoding, callback) { + const buffer = Buffer.from(chunk); + this.bufferList.push(buffer); + this.length += chunk.length; + if (this._onData) { + this._onData(buffer); + } + callback(); + } + /** + * Reads the buffered list. + * Once the readable._read() method has been called, it will not be called again until more data is pushed through the readable.push() method. + * Empty data such as empty buffers and strings will not cause readable._read() to be called. + * + * @param size Number of bytes to read. + */ + _read(size) { + if (this.bufferList.length === 0) { + this.push(null); + } else { + let total = 0; + while (total < size && this.bufferList.length > 0) { + const buffer = this.bufferList[0]; + this.push(buffer); + this.bufferList.splice(0, 1); + total += buffer.length; + } + } + } + /** + * Subscribes to the stream when receives data. + * + * @param onData Callback to be called when onData is executed. + */ + subscribe(onData) { + this._onData = onData; + } + }; + exports2.SubscribableStream = SubscribableStream; + } +}); + +// node_modules/botframework-streaming/lib/payloads/payloadConstants.js +var require_payloadConstants = __commonJS({ + "node_modules/botframework-streaming/lib/payloads/payloadConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PayloadConstants = void 0; + var PayloadConstants; + (function(PayloadConstants2) { + PayloadConstants2[PayloadConstants2["MaxPayloadLength"] = 4096] = "MaxPayloadLength"; + PayloadConstants2[PayloadConstants2["MaxHeaderLength"] = 48] = "MaxHeaderLength"; + PayloadConstants2[PayloadConstants2["MaxLength"] = 999999] = "MaxLength"; + PayloadConstants2[PayloadConstants2["MinLength"] = 0] = "MinLength"; + })(PayloadConstants = exports2.PayloadConstants || (exports2.PayloadConstants = {})); + } +}); + +// node_modules/botframework-streaming/lib/payloads/headerSerializer.js +var require_headerSerializer = __commonJS({ + "node_modules/botframework-streaming/lib/payloads/headerSerializer.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.HeaderSerializer = void 0; + var payloadConstants_1 = require_payloadConstants(); + var HeaderSerializer = class { + /** + * Serializes the header into a buffer + * + * @param header The header to serialize. + * @param buffer The buffer into which to serialize the header. + */ + static serialize(header, buffer) { + buffer.write(header.payloadType, this.TypeOffset, 1, this.Encoding); + buffer.write(this.Delimiter, this.TypeDelimiterOffset, 1, this.Encoding); + buffer.write(this.headerLengthPadder(header.payloadLength, this.LengthLength, "0"), this.LengthOffset, this.LengthLength, this.Encoding); + buffer.write(this.Delimiter, this.LengthDelimeterOffset, 1, this.Encoding); + buffer.write(header.id, this.IdOffset); + buffer.write(this.Delimiter, this.IdDelimeterOffset, 1, this.Encoding); + buffer.write(header.end ? this.End : this.NotEnd, this.EndOffset); + buffer.write(this.Terminator, this.TerminatorOffset); + } + /** + * Deserializes a buffer containing header information. + * + * @param buffer The buffer from which to obtain the data to deserialize. + * @returns The deserialized header from the buffer. + */ + static deserialize(buffer) { + const jsonBuffer = buffer.toString(this.Encoding); + const headerArray = jsonBuffer.split(this.Delimiter); + if (headerArray.length !== 4) { + throw Error(`Cannot parse header, header is malformed. Header: ${jsonBuffer}`); + } + const [payloadType, length, id, headerEnd] = headerArray; + const end = headerEnd === "1\n"; + const payloadLength = Number(length); + const header = { end, payloadLength, payloadType, id }; + if (!(header.payloadLength <= payloadConstants_1.PayloadConstants.MaxPayloadLength && header.payloadLength >= payloadConstants_1.PayloadConstants.MinLength)) { + throw Error(`Header length of ${header.payloadLength} is missing or malformed`); + } + if (header.payloadType.length !== this.TypeDelimiterOffset) { + throw Error(`Header type '${header.payloadType.length}' is missing or malformed.`); + } + if (!header.id || !header.id.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i) || header.id.length !== this.IdLength) { + throw Error(`Header ID '${header.id}' is missing or malformed.`); + } + if (!(headerEnd === "0\n" || headerEnd === "1\n")) { + throw Error(`Header End is missing or not a valid value. Header end: '${headerEnd}'`); + } + return header; + } + /** + * Creates a padded string based on a length and character to be padded to. + * + * @param lengthValue The value to be assingned on the result. + * @param totalLength The length of the padded string result. + * @param padChar The character value to use as filling. + * @returns The padded string. + */ + static headerLengthPadder(lengthValue, totalLength, padChar) { + const result = Array(totalLength + 1).join(padChar); + const lengthString = lengthValue.toString(); + return (result + lengthString).slice(lengthString.length); + } + }; + exports2.HeaderSerializer = HeaderSerializer; + HeaderSerializer.Delimiter = "."; + HeaderSerializer.Terminator = "\n"; + HeaderSerializer.End = "1"; + HeaderSerializer.NotEnd = "0"; + HeaderSerializer.TypeOffset = 0; + HeaderSerializer.TypeDelimiterOffset = 1; + HeaderSerializer.LengthOffset = 2; + HeaderSerializer.LengthLength = 6; + HeaderSerializer.LengthDelimeterOffset = 8; + HeaderSerializer.IdOffset = 9; + HeaderSerializer.IdLength = 36; + HeaderSerializer.IdDelimeterOffset = 45; + HeaderSerializer.EndOffset = 46; + HeaderSerializer.TerminatorOffset = 47; + HeaderSerializer.Encoding = "utf8"; + } +}); + +// node_modules/botframework-streaming/lib/payloads/streamManager.js +var require_streamManager = __commonJS({ + "node_modules/botframework-streaming/lib/payloads/streamManager.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.StreamManager = void 0; + var payloadAssembler_1 = require_payloadAssembler(); + var StreamManager = class { + /** + * Initializes a new instance of the [StreamManager](xref:botframework-streaming.StreamManager) class. + * + * @param onCancelStream Function to trigger if the managed stream is cancelled. + */ + constructor(onCancelStream) { + this.onCancelStream = onCancelStream; + this.activeAssemblers = []; + } + /** + * Retrieves a [PayloadAssembler](xref:botframework-streaming.PayloadAssembler) with the given ID if one exists, otherwise a new instance is created and assigned the given ID. + * + * @param id The ID of the [PayloadAssembler](xref:botframework-streaming.PayloadAssembler) to retrieve or create. + * @returns The [PayloadAssembler](xref:botframework-streaming.PayloadAssembler) with the given ID. + */ + getPayloadAssembler(id) { + if (!this.activeAssemblers[id]) { + const assembler = new payloadAssembler_1.PayloadAssembler(this, { id }); + this.activeAssemblers[id] = assembler; + return assembler; + } else { + return this.activeAssemblers[id]; + } + } + /** + * Retrieves the [SubscribableStream](xref:botframework-streaming.SubscribableStream) from the [PayloadAssembler](xref:botframework-streaming.PayloadAssembler) this manager manages. + * + * @param header The Header of the [SubscribableStream](xref:botframework-streaming.SubscribableStream) to retrieve. + * @returns The [SubscribableStream](xref:botframework-streaming.SubscribableStream) with the given header. + */ + getPayloadStream(header) { + const assembler = this.getPayloadAssembler(header.id); + return assembler.getPayloadStream(); + } + /** + * Used to set the behavior of the managed [PayloadAssembler](xref:botframework-streaming.PayloadAssembler) when data is received. + * + * @param header The Header of the stream. + * @param contentStream The [SubscribableStream](xref:botframework-streaming.SubscribableStream) to write incoming data to. + * @param contentLength The amount of data to write to the contentStream. + */ + onReceive(header, contentStream, contentLength) { + if (!this.activeAssemblers[header.id]) { + return; + } + this.activeAssemblers[header.id].onReceive(header, contentStream, contentLength); + } + /** + * Closes the [PayloadAssembler](xref:botframework-streaming.PayloadAssembler) assigned to the [SubscribableStream](xref:botframework-streaming.SubscribableStream) with the given ID. + * + * @param id The ID of the [SubscribableStream](xref:botframework-streaming.SubscribableStream) to close. + */ + closeStream(id) { + if (!this.activeAssemblers[id]) { + return; + } else { + const assembler = this.activeAssemblers[id]; + this.activeAssemblers.splice(this.activeAssemblers.indexOf(id), 1); + const targetStream = assembler.getPayloadStream(); + if (assembler.contentLength && targetStream.length < assembler.contentLength || !assembler.end) { + this.onCancelStream(assembler); + } + } + } + }; + exports2.StreamManager = StreamManager; + } +}); + +// node_modules/botframework-streaming/lib/payloads/payloadTypes.js +var require_payloadTypes = __commonJS({ + "node_modules/botframework-streaming/lib/payloads/payloadTypes.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PayloadTypes = void 0; + var PayloadTypes; + (function(PayloadTypes2) { + PayloadTypes2["request"] = "A"; + PayloadTypes2["response"] = "B"; + PayloadTypes2["stream"] = "S"; + PayloadTypes2["cancelAll"] = "X"; + PayloadTypes2["cancelStream"] = "C"; + })(PayloadTypes = exports2.PayloadTypes || (exports2.PayloadTypes = {})); + } +}); + +// node_modules/botframework-streaming/lib/payloads/requestManager.js +var require_requestManager = __commonJS({ + "node_modules/botframework-streaming/lib/payloads/requestManager.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RequestManager = void 0; + var PendingRequest = class { + }; + var RequestManager = class { + constructor() { + this._pendingRequests = {}; + } + /** + * Gets the count of the pending requests. + * + * @returns Number with the pending requests count. + */ + pendingRequestCount() { + return Object.keys(this._pendingRequests).length; + } + /** + * Signal fired when all response tasks have completed. + * + * @param requestId The ID of the StreamingRequest. + * @param response The [IReceiveResponse](xref:botframework-streaming.IReceiveResponse) in response to the request. + * @returns A Promise that when completed returns `true` if the `requestId`'s pending response task was completed, otherwise `false`. + */ + signalResponse(requestId, response) { + return __awaiter2(this, void 0, void 0, function* () { + const pendingRequest = this._pendingRequests[requestId]; + if (pendingRequest) { + pendingRequest.resolve(response); + delete this._pendingRequests[requestId]; + return true; + } + return false; + }); + } + /** + * Constructs and returns a response for this request. + * + * @param requestId The ID of the StreamingRequest being responded to. + * @returns The response to the specified request. + */ + getResponse(requestId) { + let pendingRequest = this._pendingRequests[requestId]; + if (pendingRequest) { + return Promise.reject(`requestId '${requestId}' already exists in RequestManager`); + } + pendingRequest = new PendingRequest(); + pendingRequest.requestId = requestId; + const promise = new Promise((resolve, reject) => { + pendingRequest.resolve = resolve; + pendingRequest.reject = reject; + }); + this._pendingRequests[requestId] = pendingRequest; + return promise; + } + /** + * Rejects all requests pending a response. + * + * @param reason The reason for rejection. + */ + rejectAllResponses(reason) { + Object.entries(this._pendingRequests).forEach(([requestId, { reject }]) => { + reject(reason); + delete this._pendingRequests[requestId]; + }); + } + }; + exports2.RequestManager = RequestManager; + } +}); + +// node_modules/botframework-streaming/lib/disassemblers/cancelDisassembler.js +var require_cancelDisassembler = __commonJS({ + "node_modules/botframework-streaming/lib/disassemblers/cancelDisassembler.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CancelDisassembler = void 0; + var CancelDisassembler = class { + /** + * Initializes a new instance of the [CancelDisassembler](xref:botframework-streaming.CancelDisassembler) class. + * + * @param sender The [PayloadSender](xref:botframework-streaming.PayloadSender) that this Cancel request will be sent by. + * @param id The ID of the Stream to cancel. + * @param payloadType The type of the Stream that is being cancelled. + */ + constructor(sender, id, payloadType) { + this.sender = sender; + this.id = id; + this.payloadType = payloadType; + } + /** + * Initiates the process of disassembling the request and signals the [PayloadSender](xref:botframework-streaming.PayloadSender) to begin sending. + */ + disassemble() { + const header = { + payloadType: this.payloadType, + payloadLength: 0, + id: this.id, + end: true + }; + this.sender.sendPayload(header); + } + }; + exports2.CancelDisassembler = CancelDisassembler; + } +}); + +// node_modules/botframework-streaming/lib/disassemblers/payloadDisassembler.js +var require_payloadDisassembler = __commonJS({ + "node_modules/botframework-streaming/lib/disassemblers/payloadDisassembler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PayloadDisassembler = void 0; + var subscribableStream_1 = require_subscribableStream(); + var PayloadDisassembler = class { + /** + * Initializes a new instance of the [PayloadDisassembler](xref:botframework-streaming.PayloadDisassembler) class. + * + * @param sender The [PayloadSender](xref:botframework-streaming.PayloadSender) used to send the disassembled payload chunks. + * @param id The ID of this disassembler. + */ + constructor(sender, id) { + this.sender = sender; + this.id = id; + } + /** + * Serializes the item into the [IStreamWrapper](xref:botframework-streaming.IStreamWrapper) that exposes the stream and length of the result. + * + * @param item The item to be serialized. + * @returns The stream containing the serialized item and the length of the stream. + */ + static serialize(item) { + const stream = new subscribableStream_1.SubscribableStream(); + stream.write(JSON.stringify(item)); + stream.end(); + return { stream, streamLength: stream.length }; + } + /** + * Begins the process of disassembling a payload and sending the resulting chunks to the [PayloadSender](xref:botframework-streaming.PayloadSender) to dispatch over the transport. + * + * @returns A completed Promise after the disassembled payload has been sent. + */ + disassemble() { + return __awaiter2(this, void 0, void 0, function* () { + const { stream, streamLength } = yield this.getStream(); + this.stream = stream; + this.streamLength = streamLength; + return this.send(); + }); + } + /** + * Begins the process of disassembling a payload and signals the [PayloadSender](xref:botframework-streaming.PayloadSender). + */ + send() { + return __awaiter2(this, void 0, void 0, function* () { + const header = { + payloadType: this.payloadType, + payloadLength: this.streamLength, + id: this.id, + end: true + }; + this.sender.sendPayload(header, this.stream); + }); + } + }; + exports2.PayloadDisassembler = PayloadDisassembler; + } +}); + +// node_modules/botframework-streaming/lib/disassemblers/httpContentStreamDisassembler.js +var require_httpContentStreamDisassembler = __commonJS({ + "node_modules/botframework-streaming/lib/disassemblers/httpContentStreamDisassembler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.HttpContentStreamDisassembler = void 0; + var payloadDisassembler_1 = require_payloadDisassembler(); + var payloads_1 = require_payloads(); + var HttpContentStreamDisassembler = class extends payloadDisassembler_1.PayloadDisassembler { + /** + * Initializes a new instance of the [HttpContentStreamDisassembler](xref:botframework-streaming.HttpContentStreamDisassembler) class. + * + * @param sender The [PayloadSender](xref:botframework-streaming.PayloadSender) to send the disassembled data to. + * @param contentStream The [HttpContentStream](xref:botframework-streaming.HttpContentStream) to be disassembled. + */ + constructor(sender, contentStream) { + super(sender, contentStream.id); + this.payloadType = payloads_1.PayloadTypes.stream; + this.contentStream = contentStream; + } + /** + * Gets the stream this disassembler is operating on. + * + * @returns An [IStreamWrapper](xref:botframework-streaming.IStreamWrapper) with a Subscribable Strea. + */ + getStream() { + return __awaiter2(this, void 0, void 0, function* () { + const stream = this.contentStream.content.getStream(); + return { stream, streamLength: stream.length }; + }); + } + }; + exports2.HttpContentStreamDisassembler = HttpContentStreamDisassembler; + } +}); + +// node_modules/botframework-streaming/lib/disassemblers/requestDisassembler.js +var require_requestDisassembler = __commonJS({ + "node_modules/botframework-streaming/lib/disassemblers/requestDisassembler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RequestDisassembler = void 0; + var payloadTypes_1 = require_payloadTypes(); + var payloadDisassembler_1 = require_payloadDisassembler(); + var RequestDisassembler = class extends payloadDisassembler_1.PayloadDisassembler { + /** + * Initializes a new instance of the [RequestDisassembler](xref:botframework-streaming.RequestDisassembler) class. + * + * @param sender The [PayloadSender](xref:botframework-streaming.PayloadSender) to send the disassembled data to. + * @param id The ID of this disassembler. + * @param request The request to be disassembled. + */ + constructor(sender, id, request) { + super(sender, id); + this.request = request; + this.payloadType = payloadTypes_1.PayloadTypes.request; + } + /** + * Gets the stream this disassembler is operating on. + * + * @returns An [IStreamWrapper](xref:botframework-streaming.IStreamWrapper) with a Subscribable Stream. + */ + getStream() { + var _a, _b, _c, _d; + return __awaiter2(this, void 0, void 0, function* () { + const payload = { verb: (_a = this.request) === null || _a === void 0 ? void 0 : _a.verb, path: (_b = this.request) === null || _b === void 0 ? void 0 : _b.path, streams: [] }; + (_d = (_c = this.request) === null || _c === void 0 ? void 0 : _c.streams) === null || _d === void 0 ? void 0 : _d.forEach(function(stream) { + payload.streams.push(stream.description); + }); + return payloadDisassembler_1.PayloadDisassembler.serialize(payload); + }); + } + }; + exports2.RequestDisassembler = RequestDisassembler; + } +}); + +// node_modules/botframework-streaming/lib/disassemblers/responseDisassembler.js +var require_responseDisassembler = __commonJS({ + "node_modules/botframework-streaming/lib/disassemblers/responseDisassembler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ResponseDisassembler = void 0; + var payloadTypes_1 = require_payloadTypes(); + var payloadDisassembler_1 = require_payloadDisassembler(); + var ResponseDisassembler = class extends payloadDisassembler_1.PayloadDisassembler { + /** + * Initializes a new instance of the [ResponseDisassembler](xref:botframework-streaming.ResponseDisassembler) class. + * + * @param sender The [PayloadSender](xref:botframework-streaming.PayloadSender) to send the disassembled data to. + * @param id The ID of this disassembler. + * @param response The response to be disassembled. + */ + constructor(sender, id, response) { + super(sender, id); + this.payloadType = payloadTypes_1.PayloadTypes.response; + this.response = response; + } + /** + * Gets the stream this disassembler is operating on. + * + * @returns An [IStreamWrapper](xref:botframework-streaming.IStreamWrapper) with a Subscribable Stream. + */ + getStream() { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + const payload = { statusCode: this.response.statusCode, streams: [] }; + (_a = this.response.streams) === null || _a === void 0 ? void 0 : _a.forEach(({ description }) => { + payload.streams.push({ + id: description.id, + contentType: description.type, + length: description.length + }); + }); + return payloadDisassembler_1.PayloadDisassembler.serialize(payload); + }); + } + }; + exports2.ResponseDisassembler = ResponseDisassembler; + } +}); + +// node_modules/botframework-streaming/lib/payloads/sendOperations.js +var require_sendOperations = __commonJS({ + "node_modules/botframework-streaming/lib/payloads/sendOperations.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SendOperations = void 0; + var cancelDisassembler_1 = require_cancelDisassembler(); + var httpContentStreamDisassembler_1 = require_httpContentStreamDisassembler(); + var requestDisassembler_1 = require_requestDisassembler(); + var responseDisassembler_1 = require_responseDisassembler(); + var payloadTypes_1 = require_payloadTypes(); + var SendOperations = class { + /** + * Initializes a new instance of the [SendOperations](xref:botframework-streaming.SendOperations) class. + * + * @param payloadSender The [PayloadSender](xref:botframework-streaming.PayloadSender) that will send the disassembled data from all of this instance's send operations. + */ + constructor(payloadSender) { + this.payloadSender = payloadSender; + } + /** + * The send operation used to send a [StreamingRequest](xref:botframework-streaming.StreamingRequest). + * + * @param id The ID to assign to the [RequestDisassembler](xref:botframework-streaming.RequestDisassembler) used by this operation. + * @param request The request to send. + */ + sendRequest(id, request) { + return __awaiter2(this, void 0, void 0, function* () { + const disassembler = new requestDisassembler_1.RequestDisassembler(this.payloadSender, id, request); + yield disassembler.disassemble(); + if (request.streams) { + request.streams.forEach((contentStream) => __awaiter2(this, void 0, void 0, function* () { + yield new httpContentStreamDisassembler_1.HttpContentStreamDisassembler(this.payloadSender, contentStream).disassemble(); + })); + } + }); + } + /** + * The send operation used to send a [PayloadTypes.response](xref:botframework-streaming.PayloadTypes.response). + * + * @param id The ID to assign to the [ResponseDisassembler](xref:botframework-streaming.ResponseDisassembler) used by this operation. + * @param response The response to send. + */ + sendResponse(id, response) { + return __awaiter2(this, void 0, void 0, function* () { + const disassembler = new responseDisassembler_1.ResponseDisassembler(this.payloadSender, id, response); + yield disassembler.disassemble(); + if (response.streams) { + response.streams.forEach((contentStream) => __awaiter2(this, void 0, void 0, function* () { + yield new httpContentStreamDisassembler_1.HttpContentStreamDisassembler(this.payloadSender, contentStream).disassemble(); + })); + } + }); + } + /** + * The send operation used to send a [PayloadTypes.cancelStream](xref:botframework-streaming.PayloadTypes.cancelStream). + * + * @param id The ID to assign to the [CancelDisassembler](xref:botframework-streaming.CancelDisassembler) used by this operation. + */ + sendCancelStream(id) { + return __awaiter2(this, void 0, void 0, function* () { + const disassembler = new cancelDisassembler_1.CancelDisassembler(this.payloadSender, id, payloadTypes_1.PayloadTypes.cancelStream); + disassembler.disassemble(); + }); + } + }; + exports2.SendOperations = SendOperations; + } +}); + +// node_modules/botframework-streaming/lib/payloads/index.js +var require_payloads = __commonJS({ + "node_modules/botframework-streaming/lib/payloads/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_headerSerializer(), exports2); + __exportStar2(require_streamManager(), exports2); + __exportStar2(require_payloadAssemblerManager(), exports2); + __exportStar2(require_payloadTypes(), exports2); + __exportStar2(require_requestManager(), exports2); + __exportStar2(require_sendOperations(), exports2); + } +}); + +// node_modules/botframework-streaming/lib/assemblers/payloadAssembler.js +var require_payloadAssembler = __commonJS({ + "node_modules/botframework-streaming/lib/assemblers/payloadAssembler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PayloadAssembler = void 0; + var subscribableStream_1 = require_subscribableStream(); + var payloads_1 = require_payloads(); + var contentStream_1 = require_contentStream(); + var PayloadAssembler = class { + /** + * Initializes a new instance of the [PayloadAssembler](xref:botframework-streaming.PayloadAssembler) class. + * + * @param streamManager The [StreamManager](xref:botframework-streaming.StreamManager) managing the stream being assembled. + * @param params Parameters for a streaming assembler. + */ + constructor(streamManager, params) { + this.streamManager = streamManager; + this._byteOrderMark = 65279; + this._utf = "utf8"; + if (params.header) { + this.id = params.header.id; + this.payloadType = params.header.payloadType; + this.contentLength = params.header.payloadLength; + this.end = params.header.end; + } else { + this.id = params.id; + } + if (!this.id) { + throw Error("An ID must be supplied when creating an assembler."); + } + this._onCompleted = params.onCompleted; + } + /** + * Retrieves the assembler's payload as a stream. + * + * @returns A [SubscribableStream](xref:botframework-streaming.SubscribableStream) of the assembler's payload. + */ + getPayloadStream() { + if (!this.stream) { + this.stream = this.createPayloadStream(); + } + return this.stream; + } + /** + * The action the assembler executes when new bytes are received on the incoming stream. + * + * @param header The stream's Header. + * @param stream The incoming stream being assembled. + * @param _contentLength The length of the stream, if finite. + */ + onReceive(header, stream, _contentLength) { + this.end = header.end; + if (header.payloadType === payloads_1.PayloadTypes.response || header.payloadType === payloads_1.PayloadTypes.request) { + this.process(stream).then().catch(); + } else if (header.end) { + stream.end(); + } + } + /** + * Closes the assembler. + */ + close() { + this.streamManager.closeStream(this.id); + } + /** + * Creates a new [SubscribableStream](xref:botframework-streaming.SubscribableStream) instance. + * + * @returns The new stream ready for consumption. + */ + createPayloadStream() { + return new subscribableStream_1.SubscribableStream(); + } + payloadFromJson(json) { + return JSON.parse(json.charCodeAt(0) === this._byteOrderMark ? json.slice(1) : json); + } + stripBOM(input) { + return input.charCodeAt(0) === this._byteOrderMark ? input.slice(1) : input; + } + process(stream) { + return __awaiter2(this, void 0, void 0, function* () { + const streamData = stream.read(stream.length); + if (!streamData) { + return; + } + const streamDataAsString = streamData.toString(this._utf); + if (this.payloadType === payloads_1.PayloadTypes.request) { + yield this.processRequest(streamDataAsString); + } else if (this.payloadType === payloads_1.PayloadTypes.response) { + yield this.processResponse(streamDataAsString); + } + }); + } + processResponse(streamDataAsString) { + return __awaiter2(this, void 0, void 0, function* () { + const responsePayload = this.payloadFromJson(this.stripBOM(streamDataAsString)); + const receiveResponse = { streams: [], statusCode: responsePayload.statusCode }; + yield this.processStreams(responsePayload, receiveResponse); + }); + } + processRequest(streamDataAsString) { + return __awaiter2(this, void 0, void 0, function* () { + const requestPayload = this.payloadFromJson(streamDataAsString); + const receiveRequest = { streams: [], path: requestPayload.path, verb: requestPayload.verb }; + yield this.processStreams(requestPayload, receiveRequest); + }); + } + processStreams(responsePayload, receiveResponse) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + (_a = responsePayload.streams) === null || _a === void 0 ? void 0 : _a.forEach((responseStream) => { + var _a2; + const contentType = (_a2 = responseStream.type) !== null && _a2 !== void 0 ? _a2 : responseStream.contentType; + const contentAssembler = this.streamManager.getPayloadAssembler(responseStream.id); + contentAssembler.payloadType = contentType; + contentAssembler.contentLength = responseStream.length; + receiveResponse.streams.push(new contentStream_1.ContentStream(responseStream.id, contentAssembler)); + }); + yield this._onCompleted(this.id, receiveResponse); + }); + } + }; + exports2.PayloadAssembler = PayloadAssembler; + } +}); + +// node_modules/botframework-streaming/lib/payloads/payloadAssemblerManager.js +var require_payloadAssemblerManager = __commonJS({ + "node_modules/botframework-streaming/lib/payloads/payloadAssemblerManager.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PayloadAssemblerManager = void 0; + var payloadAssembler_1 = require_payloadAssembler(); + var payloadTypes_1 = require_payloadTypes(); + var PayloadAssemblerManager = class { + /** + * Initializes a new instance of the [PayloadAssemblerManager](xref:botframework-streaming.PayloadAssemblerManager) class. + * + * @param streamManager The [StreamManager](xref:botframework-streaming.StreamManager) managing the stream being assembled. + * @param onReceiveResponse Function that executes when new bytes are received on a `response` stream. + * @param onReceiveRequest Function that executes when new bytes are received on a `request` stream. + */ + constructor(streamManager, onReceiveResponse, onReceiveRequest) { + this.streamManager = streamManager; + this.onReceiveResponse = onReceiveResponse; + this.onReceiveRequest = onReceiveRequest; + this.activeAssemblers = {}; + } + /** + * Retrieves the assembler's payload as a stream. + * + * @param header The Header of the Stream to retrieve. + * @returns A [SubscribableStream](xref:botframework-streaming.SubscribableStream) of the assembler's payload. + */ + getPayloadStream(header) { + if (header.payloadType === payloadTypes_1.PayloadTypes.stream) { + return this.streamManager.getPayloadStream(header); + } else if (!this.activeAssemblers[header.id]) { + const assembler = this.createPayloadAssembler(header); + if (assembler) { + this.activeAssemblers[header.id] = assembler; + return assembler.getPayloadStream(); + } + } + } + /** + * The action the assembler executes when new bytes are received on the incoming stream. + * + * @param header The stream's Header. + * @param contentStream The incoming stream being assembled. + * @param contentLength The length of the stream, if finite. + */ + onReceive(header, contentStream, contentLength) { + if (header.payloadType === payloadTypes_1.PayloadTypes.stream) { + this.streamManager.onReceive(header, contentStream, contentLength); + } else { + if (this.activeAssemblers && this.activeAssemblers[header.id]) { + const assembler = this.activeAssemblers[header.id]; + assembler.onReceive(header, contentStream, contentLength); + } + if (header.end) { + delete this.activeAssemblers[header.id]; + } + } + } + createPayloadAssembler(header) { + if (header.payloadType === payloadTypes_1.PayloadTypes.request) { + return new payloadAssembler_1.PayloadAssembler(this.streamManager, { + header, + onCompleted: this.onReceiveRequest + }); + } else if (header.payloadType === payloadTypes_1.PayloadTypes.response) { + return new payloadAssembler_1.PayloadAssembler(this.streamManager, { + header, + onCompleted: this.onReceiveResponse + }); + } + } + }; + exports2.PayloadAssemblerManager = PayloadAssemblerManager; + } +}); + +// node_modules/botframework-streaming/lib/protocolAdapter.js +var require_protocolAdapter = __commonJS({ + "node_modules/botframework-streaming/lib/protocolAdapter.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ProtocolAdapter = void 0; + var payloadAssemblerManager_1 = require_payloadAssemblerManager(); + var sendOperations_1 = require_sendOperations(); + var streamManager_1 = require_streamManager(); + var protocol_base_1 = require_protocol_base(); + var ProtocolAdapter = class { + /** + * Creates a new instance of the protocol adapter class. + * + * @param requestHandler The [RequestHandler](xref:botframework-streaming.RequestHandler) that will process incoming requests. + * @param requestManager The [RequestManager](xref:botframework-streaming.RequestManager) that will process outgoing requests. + * @param sender The [PayloadSender](xref:botframework-streaming.PayloadSender) for use with outgoing requests. + * @param receiver The [PayloadReceiver](xref:botframework-streaming.PayloadReceiver) for use with incoming requests. + */ + constructor(requestHandler, requestManager, sender, receiver) { + this.requestHandler = requestHandler; + this.requestManager = requestManager; + this.payloadSender = sender; + this.payloadReceiver = receiver; + this.sendOperations = new sendOperations_1.SendOperations(this.payloadSender); + this.streamManager = new streamManager_1.StreamManager(this.onCancelStream); + this.assemblerManager = new payloadAssemblerManager_1.PayloadAssemblerManager(this.streamManager, (id, response) => this.onReceiveResponse(id, response), (id, request) => this.onReceiveRequest(id, request)); + this.payloadReceiver.subscribe((header) => this.assemblerManager.getPayloadStream(header), (header, contentStream, contentLength) => this.assemblerManager.onReceive(header, contentStream, contentLength)); + } + /** + * Sends a request over the attached request manager. + * + * @param request The outgoing request to send. + * @returns The response to the specified request. + */ + sendRequest(request) { + return __awaiter2(this, void 0, void 0, function* () { + const requestId = (0, protocol_base_1.generateGuid)(); + const getResponsePromise = this.requestManager.getResponse(requestId); + yield this.sendOperations.sendRequest(requestId, request); + return getResponsePromise; + }); + } + /** + * Executes the receive pipeline when a request comes in. + * + * @param id The id the resources created for the response will be assigned. + * @param request The incoming request to process. + */ + onReceiveRequest(id, request) { + return __awaiter2(this, void 0, void 0, function* () { + if (this.requestHandler) { + const response = yield this.requestHandler.processRequest(request); + if (response) { + yield this.sendOperations.sendResponse(id, response); + } + } + }); + } + /** + * Executes the receive pipeline when a response comes in. + * + * @param id The id the resources created for the response will be assigned. + * @param response The incoming response to process. + */ + onReceiveResponse(id, response) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.requestManager.signalResponse(id, response); + }); + } + /** + * Executes the receive pipeline when a cancellation comes in. + * + * @param contentStreamAssembler The payload assembler processing the incoming data that this cancellation request targets. + */ + onCancelStream(contentStreamAssembler) { + this.sendOperations.sendCancelStream(contentStreamAssembler.id).catch(); + } + }; + exports2.ProtocolAdapter = ProtocolAdapter; + } +}); + +// node_modules/botframework-streaming/lib/payloadTransport/transportDisconnectedEvent.js +var require_transportDisconnectedEvent = __commonJS({ + "node_modules/botframework-streaming/lib/payloadTransport/transportDisconnectedEvent.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TransportDisconnectedEvent = void 0; + var TransportDisconnectedEvent = class { + /** + * Indicates a transport disconnected with the reason provided via the constructor. + * + * @remarks + * This class is used for communicating disconnection events between the + * PayloadReceiver and PayloadSender. + * @param reason The reason the disconnection event fired, in plain text. + */ + constructor(reason) { + this.reason = reason; + } + }; + exports2.TransportDisconnectedEvent = TransportDisconnectedEvent; + TransportDisconnectedEvent.Empty = new TransportDisconnectedEvent(); + } +}); + +// node_modules/botframework-streaming/lib/payloadTransport/payloadReceiver.js +var require_payloadReceiver = __commonJS({ + "node_modules/botframework-streaming/lib/payloadTransport/payloadReceiver.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PayloadReceiver = void 0; + var payloadTypes_1 = require_payloadTypes(); + var headerSerializer_1 = require_headerSerializer(); + var payloadConstants_1 = require_payloadConstants(); + var transportDisconnectedEvent_1 = require_transportDisconnectedEvent(); + var PayloadReceiver = class { + /** + * Get current connected state + * + * @returns true if connected to a transport sender. + */ + get isConnected() { + return this._receiver != null; + } + /** + * Connects to a transport receiver + * + * @param receiver The [ITransportReceiver](xref:botframework-streaming.ITransportReceiver) object to pull incoming data from. + * @returns a promise that resolves when the receiver is complete + */ + connect(receiver) { + this._receiver = receiver; + return this.receivePackets(); + } + /** + * Allows subscribing to this receiver in order to be notified when new data comes in. + * + * @param getStream Callback when a new stream has been received. + * @param receiveAction Callback when a new message has been received. + */ + subscribe(getStream, receiveAction) { + this._getStream = getStream; + this._receiveAction = receiveAction; + } + /** + * Force this receiver to disconnect. + * + * @param event Event arguments to include when broadcasting disconnection event. + */ + disconnect(event = transportDisconnectedEvent_1.TransportDisconnectedEvent.Empty) { + var _a, _b; + if (!this.isConnected) { + return; + } + try { + this._receiver.close(); + (_a = this.disconnected) === null || _a === void 0 ? void 0 : _a.call(this, this, event); + } catch (err) { + (_b = this.disconnected) === null || _b === void 0 ? void 0 : _b.call(this, this, new transportDisconnectedEvent_1.TransportDisconnectedEvent(err.message)); + } finally { + this._receiver = null; + } + } + receivePackets() { + return __awaiter2(this, void 0, void 0, function* () { + while (this.isConnected) { + try { + let readSoFar = 0; + while (readSoFar < payloadConstants_1.PayloadConstants.MaxHeaderLength) { + this._receiveHeaderBuffer = yield this._receiver.receive(payloadConstants_1.PayloadConstants.MaxHeaderLength - readSoFar); + if (this._receiveHeaderBuffer) { + readSoFar += this._receiveHeaderBuffer.length; + } + } + const header = headerSerializer_1.HeaderSerializer.deserialize(this._receiveHeaderBuffer); + const isStream = header.payloadType === payloadTypes_1.PayloadTypes.stream; + if (header.payloadLength > 0) { + let bytesActuallyRead = 0; + const contentStream = this._getStream(header); + while (bytesActuallyRead < header.payloadLength && bytesActuallyRead < payloadConstants_1.PayloadConstants.MaxPayloadLength) { + const count = Math.min(header.payloadLength - bytesActuallyRead, payloadConstants_1.PayloadConstants.MaxPayloadLength); + this._receivePayloadBuffer = yield this._receiver.receive(count); + bytesActuallyRead += this._receivePayloadBuffer.byteLength; + contentStream.write(this._receivePayloadBuffer); + if (isStream) { + this._receiveAction(header, contentStream, bytesActuallyRead); + } + } + if (!isStream) { + this._receiveAction(header, contentStream, bytesActuallyRead); + } + } + } catch (err) { + this.disconnect(new transportDisconnectedEvent_1.TransportDisconnectedEvent(err.message)); + } + } + }); + } + }; + exports2.PayloadReceiver = PayloadReceiver; + } +}); + +// node_modules/botframework-streaming/lib/payloadTransport/payloadSender.js +var require_payloadSender = __commonJS({ + "node_modules/botframework-streaming/lib/payloadTransport/payloadSender.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.PayloadSender = void 0; + var headerSerializer_1 = require_headerSerializer(); + var payloadConstants_1 = require_payloadConstants(); + var transportDisconnectedEvent_1 = require_transportDisconnectedEvent(); + var PayloadSender = class { + /** + * Get current connected state + * + * @returns true if connected to a transport sender. + */ + get isConnected() { + return this._sender != null; + } + /** + * Connects to the given transport sender. + * + * @param sender The transport sender to connect this payload sender to. + */ + connect(sender) { + this._sender = sender; + } + /** + * Sends a payload out over the connected transport sender. + * + * @param header The header to attach to the outgoing payload. + * @param payload The stream of buffered data to send. + * @param sentCallback The function to execute when the send has completed. + */ + sendPayload(header, payload, sentCallback) { + const packet = { header, payload, sentCallback }; + this.writePacket(packet); + } + /** + * Disconnects this payload sender. + * + * @param event The disconnected event arguments to include in the disconnected event broadcast. + */ + disconnect(event = transportDisconnectedEvent_1.TransportDisconnectedEvent.Empty) { + var _a, _b; + if (!this.isConnected) { + return; + } + try { + this._sender.close(); + (_a = this.disconnected) === null || _a === void 0 ? void 0 : _a.call(this, this, event); + } catch (err) { + (_b = this.disconnected) === null || _b === void 0 ? void 0 : _b.call(this, this, new transportDisconnectedEvent_1.TransportDisconnectedEvent(err.message)); + } finally { + this._sender = null; + } + } + writePacket(packet) { + try { + if (packet.header.payloadLength > 0 && packet.payload) { + let leftOver = packet.header.payloadLength; + while (leftOver > 0) { + const count = leftOver <= payloadConstants_1.PayloadConstants.MaxPayloadLength ? leftOver : payloadConstants_1.PayloadConstants.MaxPayloadLength; + const chunk = packet.payload.read(count); + const header = packet.header; + header.payloadLength = count; + header.end = leftOver <= payloadConstants_1.PayloadConstants.MaxPayloadLength; + const sendHeaderBuffer = Buffer.alloc(payloadConstants_1.PayloadConstants.MaxHeaderLength); + headerSerializer_1.HeaderSerializer.serialize(header, sendHeaderBuffer); + this._sender.send(sendHeaderBuffer); + this._sender.send(chunk); + leftOver -= chunk.length; + } + if (packet.sentCallback) { + packet.sentCallback(); + } + } + } catch (err) { + this.disconnect(new transportDisconnectedEvent_1.TransportDisconnectedEvent(err.message)); + } + } + }; + exports2.PayloadSender = PayloadSender; + } +}); + +// node_modules/botframework-streaming/lib/payloadTransport/transportDisconnectedEventHandler.js +var require_transportDisconnectedEventHandler = __commonJS({ + "node_modules/botframework-streaming/lib/payloadTransport/transportDisconnectedEventHandler.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + } +}); + +// node_modules/botframework-streaming/lib/payloadTransport/index.js +var require_payloadTransport = __commonJS({ + "node_modules/botframework-streaming/lib/payloadTransport/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_payloadReceiver(), exports2); + __exportStar2(require_payloadSender(), exports2); + __exportStar2(require_transportDisconnectedEvent(), exports2); + __exportStar2(require_transportDisconnectedEventHandler(), exports2); + } +}); + +// node_modules/botframework-streaming/lib/namedPipe/namedPipeTransport.js +var require_namedPipeTransport = __commonJS({ + "node_modules/botframework-streaming/lib/namedPipe/namedPipeTransport.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NamedPipeTransport = void 0; + var NamedPipeTransport = class { + /** + * Creates a new instance of the [NamedPipeTransport](xref:botframework-streaming.NamedPipeTransport) class. + * + * @param socket The socket object to build this connection on. + */ + constructor(socket) { + this.socket = socket; + this._activeOffset = 0; + this._activeReceiveCount = 0; + this._queue = []; + if (socket) { + this.socket.on("data", (data) => { + this.socketReceive(data); + }); + this.socket.on("close", () => { + this.socketClose(); + }); + this.socket.on("error", (err) => { + this.socketError(err); + }); + } + } + /** + * Writes to the pipe and sends. + * + * @param buffer The buffer full of data to send out across the socket. + * @returns A number indicating the length of the sent data if the data was successfully sent, otherwise 0. + */ + send(buffer) { + if (this.socket && !this.socket.connecting && this.socket.writable) { + this.socket.write(buffer); + return buffer.length; + } + return 0; + } + /** + * Returns `true` if currently connected. + * + * @returns `true` if the the transport is connected and ready to send data, `false` otherwise. + */ + get isConnected() { + return !(!this.socket || this.socket.destroyed || this.socket.connecting); + } + /** + * Closes the transport. + */ + close() { + if (this.socket) { + this.socket.end("end"); + this.socket = null; + } + } + /** + * Receive from the transport into the buffer. + * + * @param count The maximum amount of bytes to write to the buffer. + * @returns The buffer containing the data from the transport. + */ + receive(count) { + if (this._activeReceiveResolve) { + throw new Error("Cannot call receive more than once before it has returned."); + } + this._activeReceiveCount = count; + const promise = new Promise((resolve, reject) => { + this._activeReceiveResolve = resolve; + this._activeReceiveReject = reject; + }); + this.trySignalData(); + return promise; + } + socketReceive(data) { + if (this._queue && data && data.length > 0) { + this._queue.push(data); + this.trySignalData(); + } + } + socketClose() { + if (this._activeReceiveReject) { + this._activeReceiveReject(new Error("Socket was closed.")); + } + this._active = null; + this._activeOffset = 0; + this._activeReceiveResolve = null; + this._activeReceiveReject = null; + this._activeReceiveCount = 0; + this.socket = null; + } + socketError(err) { + if (this._activeReceiveReject) { + this._activeReceiveReject(err); + } + this.socketClose(); + } + trySignalData() { + if (this._activeReceiveResolve) { + if (!this._active && this._queue.length > 0) { + this._active = this._queue.shift(); + this._activeOffset = 0; + } + if (this._active) { + if (this._activeOffset === 0 && this._active.length === this._activeReceiveCount) { + const buffer = this._active; + this._active = null; + this._activeReceiveResolve(buffer); + } else { + const available = Math.min(this._activeReceiveCount, this._active.length - this._activeOffset); + const buffer = Buffer.alloc(available); + this._active.copy(buffer, 0, this._activeOffset, this._activeOffset + available); + this._activeOffset += available; + if (this._activeOffset >= this._active.length) { + this._active = null; + this._activeOffset = 0; + } + this._activeReceiveResolve(buffer); + } + this._activeReceiveCount = 0; + this._activeReceiveReject = null; + this._activeReceiveResolve = null; + } + } + } + }; + exports2.NamedPipeTransport = NamedPipeTransport; + NamedPipeTransport.PipePath = "\\\\.\\pipe\\"; + NamedPipeTransport.ServerIncomingPath = ".incoming"; + NamedPipeTransport.ServerOutgoingPath = ".outgoing"; + } +}); + +// node_modules/botframework-streaming/lib/namedPipe/namedPipeClient.js +var require_namedPipeClient = __commonJS({ + "node_modules/botframework-streaming/lib/namedPipe/namedPipeClient.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NamedPipeClient = void 0; + var net_1 = require("net"); + var protocolAdapter_1 = require_protocolAdapter(); + var payloads_1 = require_payloads(); + var payloadTransport_1 = require_payloadTransport(); + var namedPipeTransport_1 = require_namedPipeTransport(); + var NamedPipeClient = class { + /** + * Creates a new instance of the [NamedPipeClient](xref:botframework-streaming.NamedPipeClient) class. + * + * @param baseName The named pipe to connect to. + * @param requestHandler Optional [RequestHandler](xref:botframework-streaming.RequestHandler) to process incoming messages received by this client. + * @param autoReconnect Optional setting to determine if the client sould attempt to reconnect automatically on disconnection events. Defaults to true. + */ + constructor(baseName, requestHandler, autoReconnect = true) { + this._baseName = baseName; + this._requestHandler = requestHandler; + this._autoReconnect = autoReconnect; + this._requestManager = new payloads_1.RequestManager(); + this._sender = new payloadTransport_1.PayloadSender(); + this._sender.disconnected = this.onConnectionDisconnected.bind(this); + this._receiver = new payloadTransport_1.PayloadReceiver(); + this._receiver.disconnected = this.onConnectionDisconnected.bind(this); + this._protocolAdapter = new protocolAdapter_1.ProtocolAdapter(this._requestHandler, this._requestManager, this._sender, this._receiver); + } + /** + * Establish a connection with no custom headers. + */ + connect() { + return __awaiter2(this, void 0, void 0, function* () { + const outgoingPipeName = namedPipeTransport_1.NamedPipeTransport.PipePath + this._baseName + namedPipeTransport_1.NamedPipeTransport.ServerIncomingPath; + const outgoing = (0, net_1.connect)(outgoingPipeName); + const incomingPipeName = namedPipeTransport_1.NamedPipeTransport.PipePath + this._baseName + namedPipeTransport_1.NamedPipeTransport.ServerOutgoingPath; + const incoming = (0, net_1.connect)(incomingPipeName); + this._sender.connect(new namedPipeTransport_1.NamedPipeTransport(outgoing)); + this._receiver.connect(new namedPipeTransport_1.NamedPipeTransport(incoming)); + }); + } + /** + * Disconnect the client. + */ + disconnect() { + this._sender.disconnect(); + this._receiver.disconnect(); + } + /** + * Task used to send data over this client connection. + * + * @param request The [StreamingRequest](xref:botframework-streaming.StreamingRequest) to send. + * @returns A promise for an instance of [IReceiveResponse](xref:botframework-streaming.IReceiveResponse) on completion of the send operation. + */ + send(request) { + return __awaiter2(this, void 0, void 0, function* () { + return this._protocolAdapter.sendRequest(request); + }); + } + onConnectionDisconnected(sender, args) { + if (!this._isDisconnecting) { + this._isDisconnecting = true; + try { + if (this._sender.isConnected) { + this._sender.disconnect(); + } + if (this._receiver.isConnected) { + this._receiver.disconnect(); + } + if (this._autoReconnect) { + this.connect().then(() => { + }).catch((error) => { + throw new Error(`Failed to reconnect. Reason: ${error.message} Sender: ${sender} Args: ${args}. `); + }); + } + } finally { + this._isDisconnecting = false; + } + } + } + }; + exports2.NamedPipeClient = NamedPipeClient; + } +}); + +// node_modules/botframework-streaming/lib/utilities/createNodeServer.js +var require_createNodeServer = __commonJS({ + "node_modules/botframework-streaming/lib/utilities/createNodeServer.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getServerFactory = exports2.createNodeServer = void 0; + function createNodeServer(callback) { + if (callback && typeof callback !== "function") { + throw new TypeError("Invalid callback; callback parameter must be a function to create Node 'net' Server."); + } + const server2 = getServerFactory()(callback); + if (!isNetServer(server2)) { + throw new Error("Unable to create Node 'net' server"); + } + return server2; + } + exports2.createNodeServer = createNodeServer; + function getServerFactory() { + if (typeof require !== "undefined") { + return require("net").Server; + } + throw TypeError("require is undefined. Must be in a Node module to require 'net' dynamically in order to fetch Server factory."); + } + exports2.getServerFactory = getServerFactory; + function isNetServer(o) { + return hasCloseMethod(o) && hasListenMethod(o); + } + function hasCloseMethod(o) { + return o.close && typeof o.close === "function"; + } + function hasListenMethod(o) { + return o.listen && typeof o.listen === "function"; + } + } +}); + +// node_modules/botframework-streaming/lib/namedPipe/namedPipeServer.js +var require_namedPipeServer = __commonJS({ + "node_modules/botframework-streaming/lib/namedPipe/namedPipeServer.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NamedPipeServer = void 0; + var namedPipeTransport_1 = require_namedPipeTransport(); + var payloadTransport_1 = require_payloadTransport(); + var protocolAdapter_1 = require_protocolAdapter(); + var payloads_1 = require_payloads(); + var createNodeServer_1 = require_createNodeServer(); + var NamedPipeServer = class { + /** + * Creates a new instance of the [NamedPipeServer](xref:botframework-streaming.NamedPipeServer) class. + * + * @param baseName The named pipe to connect to. + * @param requestHandler Optional [RequestHandler](xref:botframework-streaming.RequestHandler) to process incoming messages received by this client. + * @param autoReconnect Deprecated: Automatic reconnection is the default behavior. + */ + constructor(baseName, requestHandler, autoReconnect) { + this.baseName = baseName; + this._sender = new payloadTransport_1.PayloadSender(); + this._receiver = new payloadTransport_1.PayloadReceiver(); + if (!baseName) { + throw new TypeError("NamedPipeServer: Missing baseName parameter"); + } + if (autoReconnect != null) { + console.warn("NamedPipeServer: The autoReconnect parameter is deprecated"); + } + this._sender = new payloadTransport_1.PayloadSender(); + this._receiver = new payloadTransport_1.PayloadReceiver(); + this._protocolAdapter = new protocolAdapter_1.ProtocolAdapter(requestHandler, new payloads_1.RequestManager(), this._sender, this._receiver); + } + /** + * Get connected status + * + * @returns true if currently connected. + */ + get isConnected() { + return this._receiver.isConnected && this._sender.isConnected; + } + /** + * Used to establish the connection used by this server and begin listening for incoming messages. + * + * @param onListen Optional callback that fires once when server is listening on both incoming and outgoing pipe + * @returns A promised string that will not resolve as long as the server is running. + */ + start(onListen) { + return __awaiter2(this, void 0, void 0, function* () { + const { PipePath, ServerIncomingPath, ServerOutgoingPath } = namedPipeTransport_1.NamedPipeTransport; + const [incoming] = yield new Promise((resolveListening, rejectListening) => { + const server2 = (0, createNodeServer_1.createNodeServer)((socket) => { + if (this._receiver.isConnected) { + return; + } + this._receiver.connect(new namedPipeTransport_1.NamedPipeTransport(socket)); + }).once("error", rejectListening); + this._incomingServer = server2; + const isListening = new Promise((resolveClosed, rejectClosed) => { + server2.once("listening", () => server2.once("error", rejectClosed)); + server2.once("closed", resolveClosed); + }); + server2.once("listening", () => resolveListening([isListening])); + server2.listen(PipePath + this.baseName + ServerIncomingPath); + }); + const [outgoing] = yield new Promise((resolveListening, rejectListening) => { + const server2 = (0, createNodeServer_1.createNodeServer)((socket) => { + if (this._sender.isConnected) { + return; + } + this._sender.connect(new namedPipeTransport_1.NamedPipeTransport(socket)); + socket.once("close", () => this._sender.disconnect()); + }).once("error", rejectListening); + this._outgoingServer = server2; + const isListening = new Promise((resolveClosed, rejectClosed) => { + server2.once("listening", () => server2.once("error", rejectClosed)); + server2.once("closed", resolveClosed); + }); + server2.once("listening", () => resolveListening([isListening])); + server2.listen(PipePath + this.baseName + ServerOutgoingPath); + }); + onListen === null || onListen === void 0 ? void 0 : onListen(); + yield Promise.all([incoming, outgoing]); + return "connected"; + }); + } + /** + * Allows for manually disconnecting the server. + */ + disconnect() { + var _a, _b; + this._receiver.disconnect(); + (_a = this._incomingServer) === null || _a === void 0 ? void 0 : _a.close(); + this._incomingServer = null; + this._sender.disconnect(); + (_b = this._outgoingServer) === null || _b === void 0 ? void 0 : _b.close(); + this._outgoingServer = null; + } + /** + * Task used to send data over this client connection. + * + * @param request The [StreamingRequest](xref:botframework-streaming.StreamingRequest) to send. + * @returns A promise for an instance of [IReceiveResponse](xref:botframework-streaming.IReceiveResponse) on completion of the send operation. + */ + send(request) { + return __awaiter2(this, void 0, void 0, function* () { + return this._protocolAdapter.sendRequest(request); + }); + } + }; + exports2.NamedPipeServer = NamedPipeServer; + } +}); + +// node_modules/botframework-streaming/lib/namedPipe/index.js +var require_namedPipe = __commonJS({ + "node_modules/botframework-streaming/lib/namedPipe/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_namedPipeClient(), exports2); + __exportStar2(require_namedPipeServer(), exports2); + __exportStar2(require_namedPipeTransport(), exports2); + } +}); + +// node_modules/botframework-streaming/lib/requestHandler.js +var require_requestHandler = __commonJS({ + "node_modules/botframework-streaming/lib/requestHandler.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RequestHandler = void 0; + var RequestHandler = class { + }; + exports2.RequestHandler = RequestHandler; + } +}); + +// node_modules/botframework-streaming/lib/streamingRequest.js +var require_streamingRequest = __commonJS({ + "node_modules/botframework-streaming/lib/streamingRequest.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.StreamingRequest = void 0; + var httpContentStream_1 = require_httpContentStream(); + var subscribableStream_1 = require_subscribableStream(); + var StreamingRequest = class _StreamingRequest { + constructor() { + this.streams = []; + } + /** + * Creates a streaming request with the passed in method, path, and body. + * + * @param method The HTTP verb to use for this request. + * @param path Optional path where the resource can be found on the remote server. + * @param body Optional body to send to the remote server. + * @returns On success returns a streaming request with appropriate status code and body. + */ + static create(method, path3, body) { + const request = new _StreamingRequest(); + request.verb = method; + request.path = path3; + if (body) { + request.setBody(body); + } + return request; + } + /** + * Adds a new stream attachment to this streaming request. + * + * @param content The Http content to include in the new stream attachment. + */ + addStream(content) { + if (!content) { + throw new Error("Argument Undefined Exception: content undefined."); + } + this.streams.push(new httpContentStream_1.HttpContentStream(content)); + } + /** + * Sets the contents of the body of this streamingRequest. + * + * @param body The JSON text to write to the body of the streamingRequest. + */ + setBody(body) { + if (typeof body === "string") { + const stream = new subscribableStream_1.SubscribableStream(); + stream.write(body, "utf8"); + this.addStream(new httpContentStream_1.HttpContent({ + type: "application/json; charset=utf-8", + contentLength: stream.length + }, stream)); + } else if (typeof body === "object") { + this.addStream(body); + } + } + }; + exports2.StreamingRequest = StreamingRequest; + } +}); + +// node_modules/botframework-streaming/lib/streamingResponse.js +var require_streamingResponse = __commonJS({ + "node_modules/botframework-streaming/lib/streamingResponse.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.StreamingResponse = void 0; + var httpContentStream_1 = require_httpContentStream(); + var subscribableStream_1 = require_subscribableStream(); + var StreamingResponse = class _StreamingResponse { + constructor() { + this.streams = []; + } + /** + * Creates a streaming response with the passed in method, path, and body. + * + * @param statusCode The HTTP verb to use for this request. + * @param body Optional body containing additional information. + * @returns A streaming response with the appropriate statuscode and passed in body. + */ + static create(statusCode, body) { + const response = new _StreamingResponse(); + response.statusCode = statusCode; + if (body) { + response.addStream(body); + } + return response; + } + /** + * Adds a new stream attachment to this streaming request. + * + * @param content The Http content to include in the new stream attachment. + */ + addStream(content) { + this.streams.push(new httpContentStream_1.HttpContentStream(content)); + } + /** + * Sets the contents of the body of this streaming response. + * + * @param body The JSON text to write to the body of the streaming response. + */ + setBody(body) { + const stream = new subscribableStream_1.SubscribableStream(); + stream.write(JSON.stringify(body), "utf8"); + this.addStream(new httpContentStream_1.HttpContent({ + type: "application/json; charset=utf-8", + contentLength: stream.length + }, stream)); + } + }; + exports2.StreamingResponse = StreamingResponse; + } +}); + +// node_modules/ws/lib/constants.js +var require_constants6 = __commonJS({ + "node_modules/ws/lib/constants.js"(exports2, module2) { + "use strict"; + module2.exports = { + BINARY_TYPES: ["nodebuffer", "arraybuffer", "fragments"], + GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", + kStatusCode: Symbol("status-code"), + kWebSocket: Symbol("websocket"), + EMPTY_BUFFER: Buffer.alloc(0), + NOOP: () => { + } + }; + } +}); + +// node_modules/ws/lib/buffer-util.js +var require_buffer_util = __commonJS({ + "node_modules/ws/lib/buffer-util.js"(exports2, module2) { + "use strict"; + var { EMPTY_BUFFER } = require_constants6(); + function concat(list, totalLength) { + if (list.length === 0) return EMPTY_BUFFER; + if (list.length === 1) return list[0]; + const target = Buffer.allocUnsafe(totalLength); + let offset = 0; + for (let i = 0; i < list.length; i++) { + const buf = list[i]; + target.set(buf, offset); + offset += buf.length; + } + if (offset < totalLength) return target.slice(0, offset); + return target; + } + function _mask(source, mask, output, offset, length) { + for (let i = 0; i < length; i++) { + output[offset + i] = source[i] ^ mask[i & 3]; + } + } + function _unmask(buffer, mask) { + const length = buffer.length; + for (let i = 0; i < length; i++) { + buffer[i] ^= mask[i & 3]; + } + } + function toArrayBuffer(buf) { + if (buf.byteLength === buf.buffer.byteLength) { + return buf.buffer; + } + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + } + function toBuffer(data) { + toBuffer.readOnly = true; + if (Buffer.isBuffer(data)) return data; + let buf; + if (data instanceof ArrayBuffer) { + buf = Buffer.from(data); + } else if (ArrayBuffer.isView(data)) { + buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength); + } else { + buf = Buffer.from(data); + toBuffer.readOnly = false; + } + return buf; + } + try { + const bufferUtil = require("bufferutil"); + const bu = bufferUtil.BufferUtil || bufferUtil; + module2.exports = { + concat, + mask(source, mask, output, offset, length) { + if (length < 48) _mask(source, mask, output, offset, length); + else bu.mask(source, mask, output, offset, length); + }, + toArrayBuffer, + toBuffer, + unmask(buffer, mask) { + if (buffer.length < 32) _unmask(buffer, mask); + else bu.unmask(buffer, mask); + } + }; + } catch (e) { + module2.exports = { + concat, + mask: _mask, + toArrayBuffer, + toBuffer, + unmask: _unmask + }; + } + } +}); + +// node_modules/ws/lib/limiter.js +var require_limiter = __commonJS({ + "node_modules/ws/lib/limiter.js"(exports2, module2) { + "use strict"; + var kDone = Symbol("kDone"); + var kRun = Symbol("kRun"); + var Limiter = class { + /** + * Creates a new `Limiter`. + * + * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed + * to run concurrently + */ + constructor(concurrency) { + this[kDone] = () => { + this.pending--; + this[kRun](); + }; + this.concurrency = concurrency || Infinity; + this.jobs = []; + this.pending = 0; + } + /** + * Adds a job to the queue. + * + * @param {Function} job The job to run + * @public + */ + add(job) { + this.jobs.push(job); + this[kRun](); + } + /** + * Removes a job from the queue and runs it if possible. + * + * @private + */ + [kRun]() { + if (this.pending === this.concurrency) return; + if (this.jobs.length) { + const job = this.jobs.shift(); + this.pending++; + job(this[kDone]); + } + } + }; + module2.exports = Limiter; + } +}); + +// node_modules/ws/lib/permessage-deflate.js +var require_permessage_deflate = __commonJS({ + "node_modules/ws/lib/permessage-deflate.js"(exports2, module2) { + "use strict"; + var zlib = require("zlib"); + var bufferUtil = require_buffer_util(); + var Limiter = require_limiter(); + var { kStatusCode, NOOP } = require_constants6(); + var TRAILER = Buffer.from([0, 0, 255, 255]); + var kPerMessageDeflate = Symbol("permessage-deflate"); + var kTotalLength = Symbol("total-length"); + var kCallback = Symbol("callback"); + var kBuffers = Symbol("buffers"); + var kError = Symbol("error"); + var zlibLimiter; + var PerMessageDeflate = class { + /** + * Creates a PerMessageDeflate instance. + * + * @param {Object} [options] Configuration options + * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept + * disabling of server context takeover + * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/ + * acknowledge disabling of client context takeover + * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the + * use of a custom server window size + * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support + * for, or request, a custom client window size + * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on + * deflate + * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on + * inflate + * @param {Number} [options.threshold=1024] Size (in bytes) below which + * messages should not be compressed + * @param {Number} [options.concurrencyLimit=10] The number of concurrent + * calls to zlib + * @param {Boolean} [isServer=false] Create the instance in either server or + * client mode + * @param {Number} [maxPayload=0] The maximum allowed message length + */ + constructor(options, isServer, maxPayload) { + this._maxPayload = maxPayload | 0; + this._options = options || {}; + this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024; + this._isServer = !!isServer; + this._deflate = null; + this._inflate = null; + this.params = null; + if (!zlibLimiter) { + const concurrency = this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10; + zlibLimiter = new Limiter(concurrency); + } + } + /** + * @type {String} + */ + static get extensionName() { + return "permessage-deflate"; + } + /** + * Create an extension negotiation offer. + * + * @return {Object} Extension parameters + * @public + */ + offer() { + const params = {}; + if (this._options.serverNoContextTakeover) { + params.server_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover) { + params.client_no_context_takeover = true; + } + if (this._options.serverMaxWindowBits) { + params.server_max_window_bits = this._options.serverMaxWindowBits; + } + if (this._options.clientMaxWindowBits) { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } else if (this._options.clientMaxWindowBits == null) { + params.client_max_window_bits = true; + } + return params; + } + /** + * Accept an extension negotiation offer/response. + * + * @param {Array} configurations The extension negotiation offers/reponse + * @return {Object} Accepted configuration + * @public + */ + accept(configurations) { + configurations = this.normalizeParams(configurations); + this.params = this._isServer ? this.acceptAsServer(configurations) : this.acceptAsClient(configurations); + return this.params; + } + /** + * Releases all resources used by the extension. + * + * @public + */ + cleanup() { + if (this._inflate) { + this._inflate.close(); + this._inflate = null; + } + if (this._deflate) { + const callback = this._deflate[kCallback]; + this._deflate.close(); + this._deflate = null; + if (callback) { + callback( + new Error( + "The deflate stream was closed while data was being processed" + ) + ); + } + } + } + /** + * Accept an extension negotiation offer. + * + * @param {Array} offers The extension negotiation offers + * @return {Object} Accepted configuration + * @private + */ + acceptAsServer(offers) { + const opts = this._options; + const accepted = offers.find((params) => { + if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && !params.client_max_window_bits) { + return false; + } + return true; + }); + if (!accepted) { + throw new Error("None of the extension offers can be accepted"); + } + if (opts.serverNoContextTakeover) { + accepted.server_no_context_takeover = true; + } + if (opts.clientNoContextTakeover) { + accepted.client_no_context_takeover = true; + } + if (typeof opts.serverMaxWindowBits === "number") { + accepted.server_max_window_bits = opts.serverMaxWindowBits; + } + if (typeof opts.clientMaxWindowBits === "number") { + accepted.client_max_window_bits = opts.clientMaxWindowBits; + } else if (accepted.client_max_window_bits === true || opts.clientMaxWindowBits === false) { + delete accepted.client_max_window_bits; + } + return accepted; + } + /** + * Accept the extension negotiation response. + * + * @param {Array} response The extension negotiation response + * @return {Object} Accepted configuration + * @private + */ + acceptAsClient(response) { + const params = response[0]; + if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) { + throw new Error('Unexpected parameter "client_no_context_takeover"'); + } + if (!params.client_max_window_bits) { + if (typeof this._options.clientMaxWindowBits === "number") { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } + } else if (this._options.clientMaxWindowBits === false || typeof this._options.clientMaxWindowBits === "number" && params.client_max_window_bits > this._options.clientMaxWindowBits) { + throw new Error( + 'Unexpected or invalid parameter "client_max_window_bits"' + ); + } + return params; + } + /** + * Normalize parameters. + * + * @param {Array} configurations The extension negotiation offers/reponse + * @return {Array} The offers/response with normalized parameters + * @private + */ + normalizeParams(configurations) { + configurations.forEach((params) => { + Object.keys(params).forEach((key) => { + let value = params[key]; + if (value.length > 1) { + throw new Error(`Parameter "${key}" must have only a single value`); + } + value = value[0]; + if (key === "client_max_window_bits") { + if (value !== true) { + const num = +value; + if (!Number.isInteger(num) || num < 8 || num > 15) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + value = num; + } else if (!this._isServer) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + } else if (key === "server_max_window_bits") { + const num = +value; + if (!Number.isInteger(num) || num < 8 || num > 15) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + value = num; + } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") { + if (value !== true) { + throw new TypeError( + `Invalid value for parameter "${key}": ${value}` + ); + } + } else { + throw new Error(`Unknown parameter "${key}"`); + } + params[key] = value; + }); + }); + return configurations; + } + /** + * Decompress data. Concurrency limited. + * + * @param {Buffer} data Compressed data + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @public + */ + decompress(data, fin, callback) { + zlibLimiter.add((done) => { + this._decompress(data, fin, (err, result) => { + done(); + callback(err, result); + }); + }); + } + /** + * Compress data. Concurrency limited. + * + * @param {Buffer} data Data to compress + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @public + */ + compress(data, fin, callback) { + zlibLimiter.add((done) => { + this._compress(data, fin, (err, result) => { + done(); + callback(err, result); + }); + }); + } + /** + * Decompress data. + * + * @param {Buffer} data Compressed data + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @private + */ + _decompress(data, fin, callback) { + const endpoint = this._isServer ? "client" : "server"; + if (!this._inflate) { + const key = `${endpoint}_max_window_bits`; + const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key]; + this._inflate = zlib.createInflateRaw({ + ...this._options.zlibInflateOptions, + windowBits + }); + this._inflate[kPerMessageDeflate] = this; + this._inflate[kTotalLength] = 0; + this._inflate[kBuffers] = []; + this._inflate.on("error", inflateOnError); + this._inflate.on("data", inflateOnData); + } + this._inflate[kCallback] = callback; + this._inflate.write(data); + if (fin) this._inflate.write(TRAILER); + this._inflate.flush(() => { + const err = this._inflate[kError]; + if (err) { + this._inflate.close(); + this._inflate = null; + callback(err); + return; + } + const data2 = bufferUtil.concat( + this._inflate[kBuffers], + this._inflate[kTotalLength] + ); + if (this._inflate._readableState.endEmitted) { + this._inflate.close(); + this._inflate = null; + } else { + this._inflate[kTotalLength] = 0; + this._inflate[kBuffers] = []; + if (fin && this.params[`${endpoint}_no_context_takeover`]) { + this._inflate.reset(); + } + } + callback(null, data2); + }); + } + /** + * Compress data. + * + * @param {Buffer} data Data to compress + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @private + */ + _compress(data, fin, callback) { + const endpoint = this._isServer ? "server" : "client"; + if (!this._deflate) { + const key = `${endpoint}_max_window_bits`; + const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key]; + this._deflate = zlib.createDeflateRaw({ + ...this._options.zlibDeflateOptions, + windowBits + }); + this._deflate[kTotalLength] = 0; + this._deflate[kBuffers] = []; + this._deflate.on("error", NOOP); + this._deflate.on("data", deflateOnData); + } + this._deflate[kCallback] = callback; + this._deflate.write(data); + this._deflate.flush(zlib.Z_SYNC_FLUSH, () => { + if (!this._deflate) { + return; + } + let data2 = bufferUtil.concat( + this._deflate[kBuffers], + this._deflate[kTotalLength] + ); + if (fin) data2 = data2.slice(0, data2.length - 4); + this._deflate[kCallback] = null; + this._deflate[kTotalLength] = 0; + this._deflate[kBuffers] = []; + if (fin && this.params[`${endpoint}_no_context_takeover`]) { + this._deflate.reset(); + } + callback(null, data2); + }); + } + }; + module2.exports = PerMessageDeflate; + function deflateOnData(chunk) { + this[kBuffers].push(chunk); + this[kTotalLength] += chunk.length; + } + function inflateOnData(chunk) { + this[kTotalLength] += chunk.length; + if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) { + this[kBuffers].push(chunk); + return; + } + this[kError] = new RangeError("Max payload size exceeded"); + this[kError].code = "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"; + this[kError][kStatusCode] = 1009; + this.removeListener("data", inflateOnData); + this.reset(); + } + function inflateOnError(err) { + this[kPerMessageDeflate]._inflate = null; + err[kStatusCode] = 1007; + this[kCallback](err); + } + } +}); + +// node_modules/ws/lib/validation.js +var require_validation = __commonJS({ + "node_modules/ws/lib/validation.js"(exports2, module2) { + "use strict"; + function isValidStatusCode(code) { + return code >= 1e3 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3e3 && code <= 4999; + } + function _isValidUTF8(buf) { + const len = buf.length; + let i = 0; + while (i < len) { + if ((buf[i] & 128) === 0) { + i++; + } else if ((buf[i] & 224) === 192) { + if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) { + return false; + } + i += 2; + } else if ((buf[i] & 240) === 224) { + if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || // Overlong + buf[i] === 237 && (buf[i + 1] & 224) === 160) { + return false; + } + i += 3; + } else if ((buf[i] & 248) === 240) { + if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || // Overlong + buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) { + return false; + } + i += 4; + } else { + return false; + } + } + return true; + } + try { + let isValidUTF8 = require("utf-8-validate"); + if (typeof isValidUTF8 === "object") { + isValidUTF8 = isValidUTF8.Validation.isValidUTF8; + } + module2.exports = { + isValidStatusCode, + isValidUTF8(buf) { + return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf); + } + }; + } catch (e) { + module2.exports = { + isValidStatusCode, + isValidUTF8: _isValidUTF8 + }; + } + } +}); + +// node_modules/ws/lib/receiver.js +var require_receiver = __commonJS({ + "node_modules/ws/lib/receiver.js"(exports2, module2) { + "use strict"; + var { Writable } = require("stream"); + var PerMessageDeflate = require_permessage_deflate(); + var { + BINARY_TYPES, + EMPTY_BUFFER, + kStatusCode, + kWebSocket + } = require_constants6(); + var { concat, toArrayBuffer, unmask } = require_buffer_util(); + var { isValidStatusCode, isValidUTF8 } = require_validation(); + var GET_INFO = 0; + var GET_PAYLOAD_LENGTH_16 = 1; + var GET_PAYLOAD_LENGTH_64 = 2; + var GET_MASK = 3; + var GET_DATA = 4; + var INFLATING = 5; + var Receiver = class extends Writable { + /** + * Creates a Receiver instance. + * + * @param {String} [binaryType=nodebuffer] The type for binary data + * @param {Object} [extensions] An object containing the negotiated extensions + * @param {Boolean} [isServer=false] Specifies whether to operate in client or + * server mode + * @param {Number} [maxPayload=0] The maximum allowed message length + */ + constructor(binaryType, extensions, isServer, maxPayload) { + super(); + this._binaryType = binaryType || BINARY_TYPES[0]; + this[kWebSocket] = void 0; + this._extensions = extensions || {}; + this._isServer = !!isServer; + this._maxPayload = maxPayload | 0; + this._bufferedBytes = 0; + this._buffers = []; + this._compressed = false; + this._payloadLength = 0; + this._mask = void 0; + this._fragmented = 0; + this._masked = false; + this._fin = false; + this._opcode = 0; + this._totalPayloadLength = 0; + this._messageLength = 0; + this._fragments = []; + this._state = GET_INFO; + this._loop = false; + } + /** + * Implements `Writable.prototype._write()`. + * + * @param {Buffer} chunk The chunk of data to write + * @param {String} encoding The character encoding of `chunk` + * @param {Function} cb Callback + * @private + */ + _write(chunk, encoding, cb) { + if (this._opcode === 8 && this._state == GET_INFO) return cb(); + this._bufferedBytes += chunk.length; + this._buffers.push(chunk); + this.startLoop(cb); + } + /** + * Consumes `n` bytes from the buffered data. + * + * @param {Number} n The number of bytes to consume + * @return {Buffer} The consumed bytes + * @private + */ + consume(n) { + this._bufferedBytes -= n; + if (n === this._buffers[0].length) return this._buffers.shift(); + if (n < this._buffers[0].length) { + const buf = this._buffers[0]; + this._buffers[0] = buf.slice(n); + return buf.slice(0, n); + } + const dst = Buffer.allocUnsafe(n); + do { + const buf = this._buffers[0]; + const offset = dst.length - n; + if (n >= buf.length) { + dst.set(this._buffers.shift(), offset); + } else { + dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset); + this._buffers[0] = buf.slice(n); + } + n -= buf.length; + } while (n > 0); + return dst; + } + /** + * Starts the parsing loop. + * + * @param {Function} cb Callback + * @private + */ + startLoop(cb) { + let err; + this._loop = true; + do { + switch (this._state) { + case GET_INFO: + err = this.getInfo(); + break; + case GET_PAYLOAD_LENGTH_16: + err = this.getPayloadLength16(); + break; + case GET_PAYLOAD_LENGTH_64: + err = this.getPayloadLength64(); + break; + case GET_MASK: + this.getMask(); + break; + case GET_DATA: + err = this.getData(cb); + break; + default: + this._loop = false; + return; + } + } while (this._loop); + cb(err); + } + /** + * Reads the first two bytes of a frame. + * + * @return {(RangeError|undefined)} A possible error + * @private + */ + getInfo() { + if (this._bufferedBytes < 2) { + this._loop = false; + return; + } + const buf = this.consume(2); + if ((buf[0] & 48) !== 0) { + this._loop = false; + return error( + RangeError, + "RSV2 and RSV3 must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_RSV_2_3" + ); + } + const compressed = (buf[0] & 64) === 64; + if (compressed && !this._extensions[PerMessageDeflate.extensionName]) { + this._loop = false; + return error( + RangeError, + "RSV1 must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + } + this._fin = (buf[0] & 128) === 128; + this._opcode = buf[0] & 15; + this._payloadLength = buf[1] & 127; + if (this._opcode === 0) { + if (compressed) { + this._loop = false; + return error( + RangeError, + "RSV1 must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + } + if (!this._fragmented) { + this._loop = false; + return error( + RangeError, + "invalid opcode 0", + true, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + } + this._opcode = this._fragmented; + } else if (this._opcode === 1 || this._opcode === 2) { + if (this._fragmented) { + this._loop = false; + return error( + RangeError, + `invalid opcode ${this._opcode}`, + true, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + } + this._compressed = compressed; + } else if (this._opcode > 7 && this._opcode < 11) { + if (!this._fin) { + this._loop = false; + return error( + RangeError, + "FIN must be set", + true, + 1002, + "WS_ERR_EXPECTED_FIN" + ); + } + if (compressed) { + this._loop = false; + return error( + RangeError, + "RSV1 must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + } + if (this._payloadLength > 125) { + this._loop = false; + return error( + RangeError, + `invalid payload length ${this._payloadLength}`, + true, + 1002, + "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH" + ); + } + } else { + this._loop = false; + return error( + RangeError, + `invalid opcode ${this._opcode}`, + true, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + } + if (!this._fin && !this._fragmented) this._fragmented = this._opcode; + this._masked = (buf[1] & 128) === 128; + if (this._isServer) { + if (!this._masked) { + this._loop = false; + return error( + RangeError, + "MASK must be set", + true, + 1002, + "WS_ERR_EXPECTED_MASK" + ); + } + } else if (this._masked) { + this._loop = false; + return error( + RangeError, + "MASK must be clear", + true, + 1002, + "WS_ERR_UNEXPECTED_MASK" + ); + } + if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16; + else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64; + else return this.haveLength(); + } + /** + * Gets extended payload length (7+16). + * + * @return {(RangeError|undefined)} A possible error + * @private + */ + getPayloadLength16() { + if (this._bufferedBytes < 2) { + this._loop = false; + return; + } + this._payloadLength = this.consume(2).readUInt16BE(0); + return this.haveLength(); + } + /** + * Gets extended payload length (7+64). + * + * @return {(RangeError|undefined)} A possible error + * @private + */ + getPayloadLength64() { + if (this._bufferedBytes < 8) { + this._loop = false; + return; + } + const buf = this.consume(8); + const num = buf.readUInt32BE(0); + if (num > Math.pow(2, 53 - 32) - 1) { + this._loop = false; + return error( + RangeError, + "Unsupported WebSocket frame: payload length > 2^53 - 1", + false, + 1009, + "WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH" + ); + } + this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4); + return this.haveLength(); + } + /** + * Payload length has been read. + * + * @return {(RangeError|undefined)} A possible error + * @private + */ + haveLength() { + if (this._payloadLength && this._opcode < 8) { + this._totalPayloadLength += this._payloadLength; + if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) { + this._loop = false; + return error( + RangeError, + "Max payload size exceeded", + false, + 1009, + "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" + ); + } + } + if (this._masked) this._state = GET_MASK; + else this._state = GET_DATA; + } + /** + * Reads mask bytes. + * + * @private + */ + getMask() { + if (this._bufferedBytes < 4) { + this._loop = false; + return; + } + this._mask = this.consume(4); + this._state = GET_DATA; + } + /** + * Reads data bytes. + * + * @param {Function} cb Callback + * @return {(Error|RangeError|undefined)} A possible error + * @private + */ + getData(cb) { + let data = EMPTY_BUFFER; + if (this._payloadLength) { + if (this._bufferedBytes < this._payloadLength) { + this._loop = false; + return; + } + data = this.consume(this._payloadLength); + if (this._masked) unmask(data, this._mask); + } + if (this._opcode > 7) return this.controlMessage(data); + if (this._compressed) { + this._state = INFLATING; + this.decompress(data, cb); + return; + } + if (data.length) { + this._messageLength = this._totalPayloadLength; + this._fragments.push(data); + } + return this.dataMessage(); + } + /** + * Decompresses data. + * + * @param {Buffer} data Compressed data + * @param {Function} cb Callback + * @private + */ + decompress(data, cb) { + const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; + perMessageDeflate.decompress(data, this._fin, (err, buf) => { + if (err) return cb(err); + if (buf.length) { + this._messageLength += buf.length; + if (this._messageLength > this._maxPayload && this._maxPayload > 0) { + return cb( + error( + RangeError, + "Max payload size exceeded", + false, + 1009, + "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" + ) + ); + } + this._fragments.push(buf); + } + const er = this.dataMessage(); + if (er) return cb(er); + this.startLoop(cb); + }); + } + /** + * Handles a data message. + * + * @return {(Error|undefined)} A possible error + * @private + */ + dataMessage() { + if (this._fin) { + const messageLength = this._messageLength; + const fragments = this._fragments; + this._totalPayloadLength = 0; + this._messageLength = 0; + this._fragmented = 0; + this._fragments = []; + if (this._opcode === 2) { + let data; + if (this._binaryType === "nodebuffer") { + data = concat(fragments, messageLength); + } else if (this._binaryType === "arraybuffer") { + data = toArrayBuffer(concat(fragments, messageLength)); + } else { + data = fragments; + } + this.emit("message", data); + } else { + const buf = concat(fragments, messageLength); + if (!isValidUTF8(buf)) { + this._loop = false; + return error( + Error, + "invalid UTF-8 sequence", + true, + 1007, + "WS_ERR_INVALID_UTF8" + ); + } + this.emit("message", buf.toString()); + } + } + this._state = GET_INFO; + } + /** + * Handles a control message. + * + * @param {Buffer} data Data to handle + * @return {(Error|RangeError|undefined)} A possible error + * @private + */ + controlMessage(data) { + if (this._opcode === 8) { + this._loop = false; + if (data.length === 0) { + this.emit("conclude", 1005, ""); + this.end(); + } else if (data.length === 1) { + return error( + RangeError, + "invalid payload length 1", + true, + 1002, + "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH" + ); + } else { + const code = data.readUInt16BE(0); + if (!isValidStatusCode(code)) { + return error( + RangeError, + `invalid status code ${code}`, + true, + 1002, + "WS_ERR_INVALID_CLOSE_CODE" + ); + } + const buf = data.slice(2); + if (!isValidUTF8(buf)) { + return error( + Error, + "invalid UTF-8 sequence", + true, + 1007, + "WS_ERR_INVALID_UTF8" + ); + } + this.emit("conclude", code, buf.toString()); + this.end(); + } + } else if (this._opcode === 9) { + this.emit("ping", data); + } else { + this.emit("pong", data); + } + this._state = GET_INFO; + } + }; + module2.exports = Receiver; + function error(ErrorCtor, message, prefix, statusCode, errorCode) { + const err = new ErrorCtor( + prefix ? `Invalid WebSocket frame: ${message}` : message + ); + Error.captureStackTrace(err, error); + err.code = errorCode; + err[kStatusCode] = statusCode; + return err; + } + } +}); + +// node_modules/ws/lib/sender.js +var require_sender = __commonJS({ + "node_modules/ws/lib/sender.js"(exports2, module2) { + "use strict"; + var net = require("net"); + var tls = require("tls"); + var { randomFillSync } = require("crypto"); + var PerMessageDeflate = require_permessage_deflate(); + var { EMPTY_BUFFER } = require_constants6(); + var { isValidStatusCode } = require_validation(); + var { mask: applyMask, toBuffer } = require_buffer_util(); + var mask = Buffer.alloc(4); + var Sender = class _Sender { + /** + * Creates a Sender instance. + * + * @param {(net.Socket|tls.Socket)} socket The connection socket + * @param {Object} [extensions] An object containing the negotiated extensions + */ + constructor(socket, extensions) { + this._extensions = extensions || {}; + this._socket = socket; + this._firstFragment = true; + this._compress = false; + this._bufferedBytes = 0; + this._deflating = false; + this._queue = []; + } + /** + * Frames a piece of data according to the HyBi WebSocket protocol. + * + * @param {Buffer} data The data to frame + * @param {Object} options Options object + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @return {Buffer[]} The framed data as a list of `Buffer` instances + * @public + */ + static frame(data, options) { + const merge = options.mask && options.readOnly; + let offset = options.mask ? 6 : 2; + let payloadLength = data.length; + if (data.length >= 65536) { + offset += 8; + payloadLength = 127; + } else if (data.length > 125) { + offset += 2; + payloadLength = 126; + } + const target = Buffer.allocUnsafe(merge ? data.length + offset : offset); + target[0] = options.fin ? options.opcode | 128 : options.opcode; + if (options.rsv1) target[0] |= 64; + target[1] = payloadLength; + if (payloadLength === 126) { + target.writeUInt16BE(data.length, 2); + } else if (payloadLength === 127) { + target.writeUInt32BE(0, 2); + target.writeUInt32BE(data.length, 6); + } + if (!options.mask) return [target, data]; + randomFillSync(mask, 0, 4); + target[1] |= 128; + target[offset - 4] = mask[0]; + target[offset - 3] = mask[1]; + target[offset - 2] = mask[2]; + target[offset - 1] = mask[3]; + if (merge) { + applyMask(data, mask, target, offset, data.length); + return [target]; + } + applyMask(data, mask, data, 0, data.length); + return [target, data]; + } + /** + * Sends a close message to the other peer. + * + * @param {Number} [code] The status code component of the body + * @param {String} [data] The message component of the body + * @param {Boolean} [mask=false] Specifies whether or not to mask the message + * @param {Function} [cb] Callback + * @public + */ + close(code, data, mask2, cb) { + let buf; + if (code === void 0) { + buf = EMPTY_BUFFER; + } else if (typeof code !== "number" || !isValidStatusCode(code)) { + throw new TypeError("First argument must be a valid error code number"); + } else if (data === void 0 || data === "") { + buf = Buffer.allocUnsafe(2); + buf.writeUInt16BE(code, 0); + } else { + const length = Buffer.byteLength(data); + if (length > 123) { + throw new RangeError("The message must not be greater than 123 bytes"); + } + buf = Buffer.allocUnsafe(2 + length); + buf.writeUInt16BE(code, 0); + buf.write(data, 2); + } + if (this._deflating) { + this.enqueue([this.doClose, buf, mask2, cb]); + } else { + this.doClose(buf, mask2, cb); + } + } + /** + * Frames and sends a close message. + * + * @param {Buffer} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @private + */ + doClose(data, mask2, cb) { + this.sendFrame( + _Sender.frame(data, { + fin: true, + rsv1: false, + opcode: 8, + mask: mask2, + readOnly: false + }), + cb + ); + } + /** + * Sends a ping message to the other peer. + * + * @param {*} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @public + */ + ping(data, mask2, cb) { + const buf = toBuffer(data); + if (buf.length > 125) { + throw new RangeError("The data size must not be greater than 125 bytes"); + } + if (this._deflating) { + this.enqueue([this.doPing, buf, mask2, toBuffer.readOnly, cb]); + } else { + this.doPing(buf, mask2, toBuffer.readOnly, cb); + } + } + /** + * Frames and sends a ping message. + * + * @param {Buffer} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Boolean} [readOnly=false] Specifies whether `data` can be modified + * @param {Function} [cb] Callback + * @private + */ + doPing(data, mask2, readOnly, cb) { + this.sendFrame( + _Sender.frame(data, { + fin: true, + rsv1: false, + opcode: 9, + mask: mask2, + readOnly + }), + cb + ); + } + /** + * Sends a pong message to the other peer. + * + * @param {*} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @public + */ + pong(data, mask2, cb) { + const buf = toBuffer(data); + if (buf.length > 125) { + throw new RangeError("The data size must not be greater than 125 bytes"); + } + if (this._deflating) { + this.enqueue([this.doPong, buf, mask2, toBuffer.readOnly, cb]); + } else { + this.doPong(buf, mask2, toBuffer.readOnly, cb); + } + } + /** + * Frames and sends a pong message. + * + * @param {Buffer} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Boolean} [readOnly=false] Specifies whether `data` can be modified + * @param {Function} [cb] Callback + * @private + */ + doPong(data, mask2, readOnly, cb) { + this.sendFrame( + _Sender.frame(data, { + fin: true, + rsv1: false, + opcode: 10, + mask: mask2, + readOnly + }), + cb + ); + } + /** + * Sends a data message to the other peer. + * + * @param {*} data The message to send + * @param {Object} options Options object + * @param {Boolean} [options.compress=false] Specifies whether or not to + * compress `data` + * @param {Boolean} [options.binary=false] Specifies whether `data` is binary + * or text + * @param {Boolean} [options.fin=false] Specifies whether the fragment is the + * last one + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Function} [cb] Callback + * @public + */ + send(data, options, cb) { + const buf = toBuffer(data); + const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; + let opcode = options.binary ? 2 : 1; + let rsv1 = options.compress; + if (this._firstFragment) { + this._firstFragment = false; + if (rsv1 && perMessageDeflate) { + rsv1 = buf.length >= perMessageDeflate._threshold; + } + this._compress = rsv1; + } else { + rsv1 = false; + opcode = 0; + } + if (options.fin) this._firstFragment = true; + if (perMessageDeflate) { + const opts = { + fin: options.fin, + rsv1, + opcode, + mask: options.mask, + readOnly: toBuffer.readOnly + }; + if (this._deflating) { + this.enqueue([this.dispatch, buf, this._compress, opts, cb]); + } else { + this.dispatch(buf, this._compress, opts, cb); + } + } else { + this.sendFrame( + _Sender.frame(buf, { + fin: options.fin, + rsv1: false, + opcode, + mask: options.mask, + readOnly: toBuffer.readOnly + }), + cb + ); + } + } + /** + * Dispatches a data message. + * + * @param {Buffer} data The message to send + * @param {Boolean} [compress=false] Specifies whether or not to compress + * `data` + * @param {Object} options Options object + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @param {Function} [cb] Callback + * @private + */ + dispatch(data, compress, options, cb) { + if (!compress) { + this.sendFrame(_Sender.frame(data, options), cb); + return; + } + const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; + this._bufferedBytes += data.length; + this._deflating = true; + perMessageDeflate.compress(data, options.fin, (_, buf) => { + if (this._socket.destroyed) { + const err = new Error( + "The socket was closed while data was being compressed" + ); + if (typeof cb === "function") cb(err); + for (let i = 0; i < this._queue.length; i++) { + const callback = this._queue[i][4]; + if (typeof callback === "function") callback(err); + } + return; + } + this._bufferedBytes -= data.length; + this._deflating = false; + options.readOnly = false; + this.sendFrame(_Sender.frame(buf, options), cb); + this.dequeue(); + }); + } + /** + * Executes queued send operations. + * + * @private + */ + dequeue() { + while (!this._deflating && this._queue.length) { + const params = this._queue.shift(); + this._bufferedBytes -= params[1].length; + Reflect.apply(params[0], this, params.slice(1)); + } + } + /** + * Enqueues a send operation. + * + * @param {Array} params Send operation parameters. + * @private + */ + enqueue(params) { + this._bufferedBytes += params[1].length; + this._queue.push(params); + } + /** + * Sends a frame. + * + * @param {Buffer[]} list The frame to send + * @param {Function} [cb] Callback + * @private + */ + sendFrame(list, cb) { + if (list.length === 2) { + this._socket.cork(); + this._socket.write(list[0]); + this._socket.write(list[1], cb); + this._socket.uncork(); + } else { + this._socket.write(list[0], cb); + } + } + }; + module2.exports = Sender; + } +}); + +// node_modules/ws/lib/event-target.js +var require_event_target = __commonJS({ + "node_modules/ws/lib/event-target.js"(exports2, module2) { + "use strict"; + var Event = class { + /** + * Create a new `Event`. + * + * @param {String} type The name of the event + * @param {Object} target A reference to the target to which the event was + * dispatched + */ + constructor(type, target) { + this.target = target; + this.type = type; + } + }; + var MessageEvent = class extends Event { + /** + * Create a new `MessageEvent`. + * + * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data + * @param {WebSocket} target A reference to the target to which the event was + * dispatched + */ + constructor(data, target) { + super("message", target); + this.data = data; + } + }; + var CloseEvent = class extends Event { + /** + * Create a new `CloseEvent`. + * + * @param {Number} code The status code explaining why the connection is being + * closed + * @param {String} reason A human-readable string explaining why the + * connection is closing + * @param {WebSocket} target A reference to the target to which the event was + * dispatched + */ + constructor(code, reason, target) { + super("close", target); + this.wasClean = target._closeFrameReceived && target._closeFrameSent; + this.reason = reason; + this.code = code; + } + }; + var OpenEvent = class extends Event { + /** + * Create a new `OpenEvent`. + * + * @param {WebSocket} target A reference to the target to which the event was + * dispatched + */ + constructor(target) { + super("open", target); + } + }; + var ErrorEvent = class extends Event { + /** + * Create a new `ErrorEvent`. + * + * @param {Object} error The error that generated this event + * @param {WebSocket} target A reference to the target to which the event was + * dispatched + */ + constructor(error, target) { + super("error", target); + this.message = error.message; + this.error = error; + } + }; + var EventTarget = { + /** + * Register an event listener. + * + * @param {String} type A string representing the event type to listen for + * @param {Function} listener The listener to add + * @param {Object} [options] An options object specifies characteristics about + * the event listener + * @param {Boolean} [options.once=false] A `Boolean`` indicating that the + * listener should be invoked at most once after being added. If `true`, + * the listener would be automatically removed when invoked. + * @public + */ + addEventListener(type, listener, options) { + if (typeof listener !== "function") return; + function onMessage(data) { + listener.call(this, new MessageEvent(data, this)); + } + function onClose(code, message) { + listener.call(this, new CloseEvent(code, message, this)); + } + function onError(error) { + listener.call(this, new ErrorEvent(error, this)); + } + function onOpen() { + listener.call(this, new OpenEvent(this)); + } + const method = options && options.once ? "once" : "on"; + if (type === "message") { + onMessage._listener = listener; + this[method](type, onMessage); + } else if (type === "close") { + onClose._listener = listener; + this[method](type, onClose); + } else if (type === "error") { + onError._listener = listener; + this[method](type, onError); + } else if (type === "open") { + onOpen._listener = listener; + this[method](type, onOpen); + } else { + this[method](type, listener); + } + }, + /** + * Remove an event listener. + * + * @param {String} type A string representing the event type to remove + * @param {Function} listener The listener to remove + * @public + */ + removeEventListener(type, listener) { + const listeners = this.listeners(type); + for (let i = 0; i < listeners.length; i++) { + if (listeners[i] === listener || listeners[i]._listener === listener) { + this.removeListener(type, listeners[i]); + } + } + } + }; + module2.exports = EventTarget; + } +}); + +// node_modules/ws/lib/extension.js +var require_extension2 = __commonJS({ + "node_modules/ws/lib/extension.js"(exports2, module2) { + "use strict"; + var tokenChars = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + // 0 - 15 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + // 16 - 31 + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + // 32 - 47 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + // 48 - 63 + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + // 64 - 79 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + // 80 - 95 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + // 96 - 111 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0 + // 112 - 127 + ]; + function push(dest, name, elem) { + if (dest[name] === void 0) dest[name] = [elem]; + else dest[name].push(elem); + } + function parse4(header) { + const offers = /* @__PURE__ */ Object.create(null); + if (header === void 0 || header === "") return offers; + let params = /* @__PURE__ */ Object.create(null); + let mustUnescape = false; + let isEscaping = false; + let inQuotes = false; + let extensionName; + let paramName; + let start = -1; + let end = -1; + let i = 0; + for (; i < header.length; i++) { + const code = header.charCodeAt(i); + if (extensionName === void 0) { + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (code === 32 || code === 9) { + if (end === -1 && start !== -1) end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) end = i; + const name = header.slice(start, end); + if (code === 44) { + push(offers, name, params); + params = /* @__PURE__ */ Object.create(null); + } else { + extensionName = name; + } + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else if (paramName === void 0) { + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (code === 32 || code === 9) { + if (end === -1 && start !== -1) end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) end = i; + push(params, header.slice(start, end), true); + if (code === 44) { + push(offers, extensionName, params); + params = /* @__PURE__ */ Object.create(null); + extensionName = void 0; + } + start = end = -1; + } else if (code === 61 && start !== -1 && end === -1) { + paramName = header.slice(start, i); + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else { + if (isEscaping) { + if (tokenChars[code] !== 1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (start === -1) start = i; + else if (!mustUnescape) mustUnescape = true; + isEscaping = false; + } else if (inQuotes) { + if (tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (code === 34 && start !== -1) { + inQuotes = false; + end = i; + } else if (code === 92) { + isEscaping = true; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else if (code === 34 && header.charCodeAt(i - 1) === 61) { + inQuotes = true; + } else if (end === -1 && tokenChars[code] === 1) { + if (start === -1) start = i; + } else if (start !== -1 && (code === 32 || code === 9)) { + if (end === -1) end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) end = i; + let value = header.slice(start, end); + if (mustUnescape) { + value = value.replace(/\\/g, ""); + mustUnescape = false; + } + push(params, paramName, value); + if (code === 44) { + push(offers, extensionName, params); + params = /* @__PURE__ */ Object.create(null); + extensionName = void 0; + } + paramName = void 0; + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } + } + if (start === -1 || inQuotes) { + throw new SyntaxError("Unexpected end of input"); + } + if (end === -1) end = i; + const token = header.slice(start, end); + if (extensionName === void 0) { + push(offers, token, params); + } else { + if (paramName === void 0) { + push(params, token, true); + } else if (mustUnescape) { + push(params, paramName, token.replace(/\\/g, "")); + } else { + push(params, paramName, token); + } + push(offers, extensionName, params); + } + return offers; + } + function format(extensions) { + return Object.keys(extensions).map((extension) => { + let configurations = extensions[extension]; + if (!Array.isArray(configurations)) configurations = [configurations]; + return configurations.map((params) => { + return [extension].concat( + Object.keys(params).map((k) => { + let values = params[k]; + if (!Array.isArray(values)) values = [values]; + return values.map((v) => v === true ? k : `${k}=${v}`).join("; "); + }) + ).join("; "); + }).join(", "); + }).join(", "); + } + module2.exports = { format, parse: parse4 }; + } +}); + +// node_modules/ws/lib/websocket.js +var require_websocket = __commonJS({ + "node_modules/ws/lib/websocket.js"(exports2, module2) { + "use strict"; + var EventEmitter = require("events"); + var https = require("https"); + var http = require("http"); + var net = require("net"); + var tls = require("tls"); + var { randomBytes, createHash } = require("crypto"); + var { Readable } = require("stream"); + var { URL: URL5 } = require("url"); + var PerMessageDeflate = require_permessage_deflate(); + var Receiver = require_receiver(); + var Sender = require_sender(); + var { + BINARY_TYPES, + EMPTY_BUFFER, + GUID, + kStatusCode, + kWebSocket, + NOOP + } = require_constants6(); + var { addEventListener, removeEventListener } = require_event_target(); + var { format, parse: parse4 } = require_extension2(); + var { toBuffer } = require_buffer_util(); + var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"]; + var protocolVersions = [8, 13]; + var closeTimeout = 30 * 1e3; + var WebSocket = class _WebSocket extends EventEmitter { + /** + * Create a new `WebSocket`. + * + * @param {(String|URL)} address The URL to which to connect + * @param {(String|String[])} [protocols] The subprotocols + * @param {Object} [options] Connection options + */ + constructor(address, protocols, options) { + super(); + this._binaryType = BINARY_TYPES[0]; + this._closeCode = 1006; + this._closeFrameReceived = false; + this._closeFrameSent = false; + this._closeMessage = ""; + this._closeTimer = null; + this._extensions = {}; + this._protocol = ""; + this._readyState = _WebSocket.CONNECTING; + this._receiver = null; + this._sender = null; + this._socket = null; + if (address !== null) { + this._bufferedAmount = 0; + this._isServer = false; + this._redirects = 0; + if (Array.isArray(protocols)) { + protocols = protocols.join(", "); + } else if (typeof protocols === "object" && protocols !== null) { + options = protocols; + protocols = void 0; + } + initAsClient(this, address, protocols, options); + } else { + this._isServer = true; + } + } + /** + * This deviates from the WHATWG interface since ws doesn't support the + * required default "blob" type (instead we define a custom "nodebuffer" + * type). + * + * @type {String} + */ + get binaryType() { + return this._binaryType; + } + set binaryType(type) { + if (!BINARY_TYPES.includes(type)) return; + this._binaryType = type; + if (this._receiver) this._receiver._binaryType = type; + } + /** + * @type {Number} + */ + get bufferedAmount() { + if (!this._socket) return this._bufferedAmount; + return this._socket._writableState.length + this._sender._bufferedBytes; + } + /** + * @type {String} + */ + get extensions() { + return Object.keys(this._extensions).join(); + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onclose() { + return void 0; + } + /* istanbul ignore next */ + set onclose(listener) { + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onerror() { + return void 0; + } + /* istanbul ignore next */ + set onerror(listener) { + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onopen() { + return void 0; + } + /* istanbul ignore next */ + set onopen(listener) { + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onmessage() { + return void 0; + } + /* istanbul ignore next */ + set onmessage(listener) { + } + /** + * @type {String} + */ + get protocol() { + return this._protocol; + } + /** + * @type {Number} + */ + get readyState() { + return this._readyState; + } + /** + * @type {String} + */ + get url() { + return this._url; + } + /** + * Set up the socket and the internal resources. + * + * @param {(net.Socket|tls.Socket)} socket The network socket between the + * server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Number} [maxPayload=0] The maximum allowed message size + * @private + */ + setSocket(socket, head, maxPayload) { + const receiver = new Receiver( + this.binaryType, + this._extensions, + this._isServer, + maxPayload + ); + this._sender = new Sender(socket, this._extensions); + this._receiver = receiver; + this._socket = socket; + receiver[kWebSocket] = this; + socket[kWebSocket] = this; + receiver.on("conclude", receiverOnConclude); + receiver.on("drain", receiverOnDrain); + receiver.on("error", receiverOnError); + receiver.on("message", receiverOnMessage); + receiver.on("ping", receiverOnPing); + receiver.on("pong", receiverOnPong); + socket.setTimeout(0); + socket.setNoDelay(); + if (head.length > 0) socket.unshift(head); + socket.on("close", socketOnClose); + socket.on("data", socketOnData); + socket.on("end", socketOnEnd); + socket.on("error", socketOnError); + this._readyState = _WebSocket.OPEN; + this.emit("open"); + } + /** + * Emit the `'close'` event. + * + * @private + */ + emitClose() { + if (!this._socket) { + this._readyState = _WebSocket.CLOSED; + this.emit("close", this._closeCode, this._closeMessage); + return; + } + if (this._extensions[PerMessageDeflate.extensionName]) { + this._extensions[PerMessageDeflate.extensionName].cleanup(); + } + this._receiver.removeAllListeners(); + this._readyState = _WebSocket.CLOSED; + this.emit("close", this._closeCode, this._closeMessage); + } + /** + * Start a closing handshake. + * + * +----------+ +-----------+ +----------+ + * - - -|ws.close()|-->|close frame|-->|ws.close()|- - - + * | +----------+ +-----------+ +----------+ | + * +----------+ +-----------+ | + * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING + * +----------+ +-----------+ | + * | | | +---+ | + * +------------------------+-->|fin| - - - - + * | +---+ | +---+ + * - - - - -|fin|<---------------------+ + * +---+ + * + * @param {Number} [code] Status code explaining why the connection is closing + * @param {String} [data] A string explaining why the connection is closing + * @public + */ + close(code, data) { + if (this.readyState === _WebSocket.CLOSED) return; + if (this.readyState === _WebSocket.CONNECTING) { + const msg = "WebSocket was closed before the connection was established"; + return abortHandshake(this, this._req, msg); + } + if (this.readyState === _WebSocket.CLOSING) { + if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) { + this._socket.end(); + } + return; + } + this._readyState = _WebSocket.CLOSING; + this._sender.close(code, data, !this._isServer, (err) => { + if (err) return; + this._closeFrameSent = true; + if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) { + this._socket.end(); + } + }); + this._closeTimer = setTimeout( + this._socket.destroy.bind(this._socket), + closeTimeout + ); + } + /** + * Send a ping. + * + * @param {*} [data] The data to send + * @param {Boolean} [mask] Indicates whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when the ping is sent + * @public + */ + ping(data, mask, cb) { + if (this.readyState === _WebSocket.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof data === "function") { + cb = data; + data = mask = void 0; + } else if (typeof mask === "function") { + cb = mask; + mask = void 0; + } + if (typeof data === "number") data = data.toString(); + if (this.readyState !== _WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + if (mask === void 0) mask = !this._isServer; + this._sender.ping(data || EMPTY_BUFFER, mask, cb); + } + /** + * Send a pong. + * + * @param {*} [data] The data to send + * @param {Boolean} [mask] Indicates whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when the pong is sent + * @public + */ + pong(data, mask, cb) { + if (this.readyState === _WebSocket.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof data === "function") { + cb = data; + data = mask = void 0; + } else if (typeof mask === "function") { + cb = mask; + mask = void 0; + } + if (typeof data === "number") data = data.toString(); + if (this.readyState !== _WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + if (mask === void 0) mask = !this._isServer; + this._sender.pong(data || EMPTY_BUFFER, mask, cb); + } + /** + * Send a data message. + * + * @param {*} data The message to send + * @param {Object} [options] Options object + * @param {Boolean} [options.compress] Specifies whether or not to compress + * `data` + * @param {Boolean} [options.binary] Specifies whether `data` is binary or + * text + * @param {Boolean} [options.fin=true] Specifies whether the fragment is the + * last one + * @param {Boolean} [options.mask] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when data is written out + * @public + */ + send(data, options, cb) { + if (this.readyState === _WebSocket.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof options === "function") { + cb = options; + options = {}; + } + if (typeof data === "number") data = data.toString(); + if (this.readyState !== _WebSocket.OPEN) { + sendAfterClose(this, data, cb); + return; + } + const opts = { + binary: typeof data !== "string", + mask: !this._isServer, + compress: true, + fin: true, + ...options + }; + if (!this._extensions[PerMessageDeflate.extensionName]) { + opts.compress = false; + } + this._sender.send(data || EMPTY_BUFFER, opts, cb); + } + /** + * Forcibly close the connection. + * + * @public + */ + terminate() { + if (this.readyState === _WebSocket.CLOSED) return; + if (this.readyState === _WebSocket.CONNECTING) { + const msg = "WebSocket was closed before the connection was established"; + return abortHandshake(this, this._req, msg); + } + if (this._socket) { + this._readyState = _WebSocket.CLOSING; + this._socket.destroy(); + } + } + }; + Object.defineProperty(WebSocket, "CONNECTING", { + enumerable: true, + value: readyStates.indexOf("CONNECTING") + }); + Object.defineProperty(WebSocket.prototype, "CONNECTING", { + enumerable: true, + value: readyStates.indexOf("CONNECTING") + }); + Object.defineProperty(WebSocket, "OPEN", { + enumerable: true, + value: readyStates.indexOf("OPEN") + }); + Object.defineProperty(WebSocket.prototype, "OPEN", { + enumerable: true, + value: readyStates.indexOf("OPEN") + }); + Object.defineProperty(WebSocket, "CLOSING", { + enumerable: true, + value: readyStates.indexOf("CLOSING") + }); + Object.defineProperty(WebSocket.prototype, "CLOSING", { + enumerable: true, + value: readyStates.indexOf("CLOSING") + }); + Object.defineProperty(WebSocket, "CLOSED", { + enumerable: true, + value: readyStates.indexOf("CLOSED") + }); + Object.defineProperty(WebSocket.prototype, "CLOSED", { + enumerable: true, + value: readyStates.indexOf("CLOSED") + }); + [ + "binaryType", + "bufferedAmount", + "extensions", + "protocol", + "readyState", + "url" + ].forEach((property) => { + Object.defineProperty(WebSocket.prototype, property, { enumerable: true }); + }); + ["open", "error", "close", "message"].forEach((method) => { + Object.defineProperty(WebSocket.prototype, `on${method}`, { + enumerable: true, + get() { + const listeners = this.listeners(method); + for (let i = 0; i < listeners.length; i++) { + if (listeners[i]._listener) return listeners[i]._listener; + } + return void 0; + }, + set(listener) { + const listeners = this.listeners(method); + for (let i = 0; i < listeners.length; i++) { + if (listeners[i]._listener) this.removeListener(method, listeners[i]); + } + this.addEventListener(method, listener); + } + }); + }); + WebSocket.prototype.addEventListener = addEventListener; + WebSocket.prototype.removeEventListener = removeEventListener; + module2.exports = WebSocket; + function initAsClient(websocket, address, protocols, options) { + const opts = { + protocolVersion: protocolVersions[1], + maxPayload: 100 * 1024 * 1024, + perMessageDeflate: true, + followRedirects: false, + maxRedirects: 10, + ...options, + createConnection: void 0, + socketPath: void 0, + hostname: void 0, + protocol: void 0, + timeout: void 0, + method: void 0, + host: void 0, + path: void 0, + port: void 0 + }; + if (!protocolVersions.includes(opts.protocolVersion)) { + throw new RangeError( + `Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})` + ); + } + let parsedUrl; + if (address instanceof URL5) { + parsedUrl = address; + websocket._url = address.href; + } else { + parsedUrl = new URL5(address); + websocket._url = address; + } + const isUnixSocket = parsedUrl.protocol === "ws+unix:"; + if (!parsedUrl.host && (!isUnixSocket || !parsedUrl.pathname)) { + const err = new Error(`Invalid URL: ${websocket.url}`); + if (websocket._redirects === 0) { + throw err; + } else { + emitErrorAndClose(websocket, err); + return; + } + } + const isSecure = parsedUrl.protocol === "wss:" || parsedUrl.protocol === "https:"; + const defaultPort = isSecure ? 443 : 80; + const key = randomBytes(16).toString("base64"); + const get = isSecure ? https.get : http.get; + let perMessageDeflate; + opts.createConnection = isSecure ? tlsConnect : netConnect; + opts.defaultPort = opts.defaultPort || defaultPort; + opts.port = parsedUrl.port || defaultPort; + opts.host = parsedUrl.hostname.startsWith("[") ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname; + opts.headers = { + "Sec-WebSocket-Version": opts.protocolVersion, + "Sec-WebSocket-Key": key, + Connection: "Upgrade", + Upgrade: "websocket", + ...opts.headers + }; + opts.path = parsedUrl.pathname + parsedUrl.search; + opts.timeout = opts.handshakeTimeout; + if (opts.perMessageDeflate) { + perMessageDeflate = new PerMessageDeflate( + opts.perMessageDeflate !== true ? opts.perMessageDeflate : {}, + false, + opts.maxPayload + ); + opts.headers["Sec-WebSocket-Extensions"] = format({ + [PerMessageDeflate.extensionName]: perMessageDeflate.offer() + }); + } + if (protocols) { + opts.headers["Sec-WebSocket-Protocol"] = protocols; + } + if (opts.origin) { + if (opts.protocolVersion < 13) { + opts.headers["Sec-WebSocket-Origin"] = opts.origin; + } else { + opts.headers.Origin = opts.origin; + } + } + if (parsedUrl.username || parsedUrl.password) { + opts.auth = `${parsedUrl.username}:${parsedUrl.password}`; + } + if (isUnixSocket) { + const parts = opts.path.split(":"); + opts.socketPath = parts[0]; + opts.path = parts[1]; + } + if (opts.followRedirects) { + if (websocket._redirects === 0) { + websocket._originalUnixSocket = isUnixSocket; + websocket._originalSecure = isSecure; + websocket._originalHostOrSocketPath = isUnixSocket ? opts.socketPath : parsedUrl.host; + const headers = options && options.headers; + options = { ...options, headers: {} }; + if (headers) { + for (const [key2, value] of Object.entries(headers)) { + options.headers[key2.toLowerCase()] = value; + } + } + } else { + const isSameHost = isUnixSocket ? websocket._originalUnixSocket ? opts.socketPath === websocket._originalHostOrSocketPath : false : websocket._originalUnixSocket ? false : parsedUrl.host === websocket._originalHostOrSocketPath; + if (!isSameHost || websocket._originalSecure && !isSecure) { + delete opts.headers.authorization; + delete opts.headers.cookie; + if (!isSameHost) delete opts.headers.host; + opts.auth = void 0; + } + } + if (opts.auth && !options.headers.authorization) { + options.headers.authorization = "Basic " + Buffer.from(opts.auth).toString("base64"); + } + } + let req = websocket._req = get(opts); + if (opts.timeout) { + req.on("timeout", () => { + abortHandshake(websocket, req, "Opening handshake has timed out"); + }); + } + req.on("error", (err) => { + if (req === null || req.aborted) return; + req = websocket._req = null; + emitErrorAndClose(websocket, err); + }); + req.on("response", (res) => { + const location = res.headers.location; + const statusCode = res.statusCode; + if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) { + if (++websocket._redirects > opts.maxRedirects) { + abortHandshake(websocket, req, "Maximum redirects exceeded"); + return; + } + req.abort(); + let addr; + try { + addr = new URL5(location, address); + } catch (err) { + emitErrorAndClose(websocket, err); + return; + } + initAsClient(websocket, addr, protocols, options); + } else if (!websocket.emit("unexpected-response", req, res)) { + abortHandshake( + websocket, + req, + `Unexpected server response: ${res.statusCode}` + ); + } + }); + req.on("upgrade", (res, socket, head) => { + websocket.emit("upgrade", res); + if (websocket.readyState !== WebSocket.CONNECTING) return; + req = websocket._req = null; + const upgrade = res.headers.upgrade; + if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") { + abortHandshake(websocket, socket, "Invalid Upgrade header"); + return; + } + const digest = createHash("sha1").update(key + GUID).digest("base64"); + if (res.headers["sec-websocket-accept"] !== digest) { + abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header"); + return; + } + const serverProt = res.headers["sec-websocket-protocol"]; + const protList = (protocols || "").split(/, */); + let protError; + if (!protocols && serverProt) { + protError = "Server sent a subprotocol but none was requested"; + } else if (protocols && !serverProt) { + protError = "Server sent no subprotocol"; + } else if (serverProt && !protList.includes(serverProt)) { + protError = "Server sent an invalid subprotocol"; + } + if (protError) { + abortHandshake(websocket, socket, protError); + return; + } + if (serverProt) websocket._protocol = serverProt; + const secWebSocketExtensions = res.headers["sec-websocket-extensions"]; + if (secWebSocketExtensions !== void 0) { + if (!perMessageDeflate) { + const message = "Server sent a Sec-WebSocket-Extensions header but no extension was requested"; + abortHandshake(websocket, socket, message); + return; + } + let extensions; + try { + extensions = parse4(secWebSocketExtensions); + } catch (err) { + const message = "Invalid Sec-WebSocket-Extensions header"; + abortHandshake(websocket, socket, message); + return; + } + const extensionNames = Object.keys(extensions); + if (extensionNames.length) { + if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate.extensionName) { + const message = "Server indicated an extension that was not requested"; + abortHandshake(websocket, socket, message); + return; + } + try { + perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]); + } catch (err) { + const message = "Invalid Sec-WebSocket-Extensions header"; + abortHandshake(websocket, socket, message); + return; + } + websocket._extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + } + websocket.setSocket(socket, head, opts.maxPayload); + }); + } + function emitErrorAndClose(websocket, err) { + websocket._readyState = WebSocket.CLOSING; + websocket.emit("error", err); + websocket.emitClose(); + } + function netConnect(options) { + options.path = options.socketPath; + return net.connect(options); + } + function tlsConnect(options) { + options.path = void 0; + if (!options.servername && options.servername !== "") { + options.servername = net.isIP(options.host) ? "" : options.host; + } + return tls.connect(options); + } + function abortHandshake(websocket, stream, message) { + websocket._readyState = WebSocket.CLOSING; + const err = new Error(message); + Error.captureStackTrace(err, abortHandshake); + if (stream.setHeader) { + stream.abort(); + if (stream.socket && !stream.socket.destroyed) { + stream.socket.destroy(); + } + stream.once("abort", websocket.emitClose.bind(websocket)); + websocket.emit("error", err); + } else { + stream.destroy(err); + stream.once("error", websocket.emit.bind(websocket, "error")); + stream.once("close", websocket.emitClose.bind(websocket)); + } + } + function sendAfterClose(websocket, data, cb) { + if (data) { + const length = toBuffer(data).length; + if (websocket._socket) websocket._sender._bufferedBytes += length; + else websocket._bufferedAmount += length; + } + if (cb) { + const err = new Error( + `WebSocket is not open: readyState ${websocket.readyState} (${readyStates[websocket.readyState]})` + ); + cb(err); + } + } + function receiverOnConclude(code, reason) { + const websocket = this[kWebSocket]; + websocket._closeFrameReceived = true; + websocket._closeMessage = reason; + websocket._closeCode = code; + if (websocket._socket[kWebSocket] === void 0) return; + websocket._socket.removeListener("data", socketOnData); + process.nextTick(resume, websocket._socket); + if (code === 1005) websocket.close(); + else websocket.close(code, reason); + } + function receiverOnDrain() { + this[kWebSocket]._socket.resume(); + } + function receiverOnError(err) { + const websocket = this[kWebSocket]; + if (websocket._socket[kWebSocket] !== void 0) { + websocket._socket.removeListener("data", socketOnData); + process.nextTick(resume, websocket._socket); + websocket.close(err[kStatusCode]); + } + websocket.emit("error", err); + } + function receiverOnFinish() { + this[kWebSocket].emitClose(); + } + function receiverOnMessage(data) { + this[kWebSocket].emit("message", data); + } + function receiverOnPing(data) { + const websocket = this[kWebSocket]; + websocket.pong(data, !websocket._isServer, NOOP); + websocket.emit("ping", data); + } + function receiverOnPong(data) { + this[kWebSocket].emit("pong", data); + } + function resume(stream) { + stream.resume(); + } + function socketOnClose() { + const websocket = this[kWebSocket]; + this.removeListener("close", socketOnClose); + this.removeListener("data", socketOnData); + this.removeListener("end", socketOnEnd); + websocket._readyState = WebSocket.CLOSING; + let chunk; + if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && (chunk = websocket._socket.read()) !== null) { + websocket._receiver.write(chunk); + } + websocket._receiver.end(); + this[kWebSocket] = void 0; + clearTimeout(websocket._closeTimer); + if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) { + websocket.emitClose(); + } else { + websocket._receiver.on("error", receiverOnFinish); + websocket._receiver.on("finish", receiverOnFinish); + } + } + function socketOnData(chunk) { + if (!this[kWebSocket]._receiver.write(chunk)) { + this.pause(); + } + } + function socketOnEnd() { + const websocket = this[kWebSocket]; + websocket._readyState = WebSocket.CLOSING; + websocket._receiver.end(); + this.end(); + } + function socketOnError() { + const websocket = this[kWebSocket]; + this.removeListener("error", socketOnError); + this.on("error", NOOP); + if (websocket) { + websocket._readyState = WebSocket.CLOSING; + this.destroy(); + } + } + } +}); + +// node_modules/ws/lib/stream.js +var require_stream = __commonJS({ + "node_modules/ws/lib/stream.js"(exports2, module2) { + "use strict"; + var { Duplex } = require("stream"); + function emitClose(stream) { + stream.emit("close"); + } + function duplexOnEnd() { + if (!this.destroyed && this._writableState.finished) { + this.destroy(); + } + } + function duplexOnError(err) { + this.removeListener("error", duplexOnError); + this.destroy(); + if (this.listenerCount("error") === 0) { + this.emit("error", err); + } + } + function createWebSocketStream(ws, options) { + let resumeOnReceiverDrain = true; + let terminateOnDestroy = true; + function receiverOnDrain() { + if (resumeOnReceiverDrain) ws._socket.resume(); + } + if (ws.readyState === ws.CONNECTING) { + ws.once("open", function open2() { + ws._receiver.removeAllListeners("drain"); + ws._receiver.on("drain", receiverOnDrain); + }); + } else { + ws._receiver.removeAllListeners("drain"); + ws._receiver.on("drain", receiverOnDrain); + } + const duplex = new Duplex({ + ...options, + autoDestroy: false, + emitClose: false, + objectMode: false, + writableObjectMode: false + }); + ws.on("message", function message(msg) { + if (!duplex.push(msg)) { + resumeOnReceiverDrain = false; + ws._socket.pause(); + } + }); + ws.once("error", function error(err) { + if (duplex.destroyed) return; + terminateOnDestroy = false; + duplex.destroy(err); + }); + ws.once("close", function close() { + if (duplex.destroyed) return; + duplex.push(null); + }); + duplex._destroy = function(err, callback) { + if (ws.readyState === ws.CLOSED) { + callback(err); + process.nextTick(emitClose, duplex); + return; + } + let called = false; + ws.once("error", function error(err2) { + called = true; + callback(err2); + }); + ws.once("close", function close() { + if (!called) callback(err); + process.nextTick(emitClose, duplex); + }); + if (terminateOnDestroy) ws.terminate(); + }; + duplex._final = function(callback) { + if (ws.readyState === ws.CONNECTING) { + ws.once("open", function open2() { + duplex._final(callback); + }); + return; + } + if (ws._socket === null) return; + if (ws._socket._writableState.finished) { + callback(); + if (duplex._readableState.endEmitted) duplex.destroy(); + } else { + ws._socket.once("finish", function finish() { + callback(); + }); + ws.close(); + } + }; + duplex._read = function() { + if ((ws.readyState === ws.OPEN || ws.readyState === ws.CLOSING) && !resumeOnReceiverDrain) { + resumeOnReceiverDrain = true; + if (!ws._receiver._writableState.needDrain) ws._socket.resume(); + } + }; + duplex._write = function(chunk, encoding, callback) { + if (ws.readyState === ws.CONNECTING) { + ws.once("open", function open2() { + duplex._write(chunk, encoding, callback); + }); + return; + } + ws.send(chunk, callback); + }; + duplex.on("end", duplexOnEnd); + duplex.on("error", duplexOnError); + return duplex; + } + module2.exports = createWebSocketStream; + } +}); + +// node_modules/ws/lib/websocket-server.js +var require_websocket_server = __commonJS({ + "node_modules/ws/lib/websocket-server.js"(exports2, module2) { + "use strict"; + var EventEmitter = require("events"); + var http = require("http"); + var https = require("https"); + var net = require("net"); + var tls = require("tls"); + var { createHash } = require("crypto"); + var PerMessageDeflate = require_permessage_deflate(); + var WebSocket = require_websocket(); + var { format, parse: parse4 } = require_extension2(); + var { GUID, kWebSocket } = require_constants6(); + var keyRegex = /^[+/0-9A-Za-z]{22}==$/; + var RUNNING = 0; + var CLOSING = 1; + var CLOSED = 2; + var WebSocketServer = class extends EventEmitter { + /** + * Create a `WebSocketServer` instance. + * + * @param {Object} options Configuration options + * @param {Number} [options.backlog=511] The maximum length of the queue of + * pending connections + * @param {Boolean} [options.clientTracking=true] Specifies whether or not to + * track clients + * @param {Function} [options.handleProtocols] A hook to handle protocols + * @param {String} [options.host] The hostname where to bind the server + * @param {Number} [options.maxPayload=104857600] The maximum allowed message + * size + * @param {Boolean} [options.noServer=false] Enable no server mode + * @param {String} [options.path] Accept only connections matching this path + * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable + * permessage-deflate + * @param {Number} [options.port] The port where to bind the server + * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S + * server to use + * @param {Function} [options.verifyClient] A hook to reject connections + * @param {Function} [callback] A listener for the `listening` event + */ + constructor(options, callback) { + super(); + options = { + maxPayload: 100 * 1024 * 1024, + perMessageDeflate: false, + handleProtocols: null, + clientTracking: true, + verifyClient: null, + noServer: false, + backlog: null, + // use default (511 as implemented in net.js) + server: null, + host: null, + path: null, + port: null, + ...options + }; + if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) { + throw new TypeError( + 'One and only one of the "port", "server", or "noServer" options must be specified' + ); + } + if (options.port != null) { + this._server = http.createServer((req, res) => { + const body = http.STATUS_CODES[426]; + res.writeHead(426, { + "Content-Length": body.length, + "Content-Type": "text/plain" + }); + res.end(body); + }); + this._server.listen( + options.port, + options.host, + options.backlog, + callback + ); + } else if (options.server) { + this._server = options.server; + } + if (this._server) { + const emitConnection = this.emit.bind(this, "connection"); + this._removeListeners = addListeners(this._server, { + listening: this.emit.bind(this, "listening"), + error: this.emit.bind(this, "error"), + upgrade: (req, socket, head) => { + this.handleUpgrade(req, socket, head, emitConnection); + } + }); + } + if (options.perMessageDeflate === true) options.perMessageDeflate = {}; + if (options.clientTracking) this.clients = /* @__PURE__ */ new Set(); + this.options = options; + this._state = RUNNING; + } + /** + * Returns the bound address, the address family name, and port of the server + * as reported by the operating system if listening on an IP socket. + * If the server is listening on a pipe or UNIX domain socket, the name is + * returned as a string. + * + * @return {(Object|String|null)} The address of the server + * @public + */ + address() { + if (this.options.noServer) { + throw new Error('The server is operating in "noServer" mode'); + } + if (!this._server) return null; + return this._server.address(); + } + /** + * Close the server. + * + * @param {Function} [cb] Callback + * @public + */ + close(cb) { + if (cb) this.once("close", cb); + if (this._state === CLOSED) { + process.nextTick(emitClose, this); + return; + } + if (this._state === CLOSING) return; + this._state = CLOSING; + if (this.clients) { + for (const client of this.clients) client.terminate(); + } + const server2 = this._server; + if (server2) { + this._removeListeners(); + this._removeListeners = this._server = null; + if (this.options.port != null) { + server2.close(emitClose.bind(void 0, this)); + return; + } + } + process.nextTick(emitClose, this); + } + /** + * See if a given request should be handled by this server instance. + * + * @param {http.IncomingMessage} req Request object to inspect + * @return {Boolean} `true` if the request is valid, else `false` + * @public + */ + shouldHandle(req) { + if (this.options.path) { + const index = req.url.indexOf("?"); + const pathname = index !== -1 ? req.url.slice(0, index) : req.url; + if (pathname !== this.options.path) return false; + } + return true; + } + /** + * Handle a HTTP Upgrade request. + * + * @param {http.IncomingMessage} req The request object + * @param {(net.Socket|tls.Socket)} socket The network socket between the + * server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Function} cb Callback + * @public + */ + handleUpgrade(req, socket, head, cb) { + socket.on("error", socketOnError); + const key = req.headers["sec-websocket-key"] !== void 0 ? req.headers["sec-websocket-key"].trim() : false; + const upgrade = req.headers.upgrade; + const version4 = +req.headers["sec-websocket-version"]; + const extensions = {}; + if (req.method !== "GET" || upgrade === void 0 || upgrade.toLowerCase() !== "websocket" || !key || !keyRegex.test(key) || version4 !== 8 && version4 !== 13 || !this.shouldHandle(req)) { + return abortHandshake(socket, 400); + } + if (this.options.perMessageDeflate) { + const perMessageDeflate = new PerMessageDeflate( + this.options.perMessageDeflate, + true, + this.options.maxPayload + ); + try { + const offers = parse4(req.headers["sec-websocket-extensions"]); + if (offers[PerMessageDeflate.extensionName]) { + perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]); + extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + } catch (err) { + return abortHandshake(socket, 400); + } + } + if (this.options.verifyClient) { + const info = { + origin: req.headers[`${version4 === 8 ? "sec-websocket-origin" : "origin"}`], + secure: !!(req.socket.authorized || req.socket.encrypted), + req + }; + if (this.options.verifyClient.length === 2) { + this.options.verifyClient(info, (verified, code, message, headers) => { + if (!verified) { + return abortHandshake(socket, code || 401, message, headers); + } + this.completeUpgrade(key, extensions, req, socket, head, cb); + }); + return; + } + if (!this.options.verifyClient(info)) return abortHandshake(socket, 401); + } + this.completeUpgrade(key, extensions, req, socket, head, cb); + } + /** + * Upgrade the connection to WebSocket. + * + * @param {String} key The value of the `Sec-WebSocket-Key` header + * @param {Object} extensions The accepted extensions + * @param {http.IncomingMessage} req The request object + * @param {(net.Socket|tls.Socket)} socket The network socket between the + * server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Function} cb Callback + * @throws {Error} If called more than once with the same socket + * @private + */ + completeUpgrade(key, extensions, req, socket, head, cb) { + if (!socket.readable || !socket.writable) return socket.destroy(); + if (socket[kWebSocket]) { + throw new Error( + "server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration" + ); + } + if (this._state > RUNNING) return abortHandshake(socket, 503); + const digest = createHash("sha1").update(key + GUID).digest("base64"); + const headers = [ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + `Sec-WebSocket-Accept: ${digest}` + ]; + const ws = new WebSocket(null); + let protocol = req.headers["sec-websocket-protocol"]; + if (protocol) { + protocol = protocol.split(",").map(trim); + if (this.options.handleProtocols) { + protocol = this.options.handleProtocols(protocol, req); + } else { + protocol = protocol[0]; + } + if (protocol) { + headers.push(`Sec-WebSocket-Protocol: ${protocol}`); + ws._protocol = protocol; + } + } + if (extensions[PerMessageDeflate.extensionName]) { + const params = extensions[PerMessageDeflate.extensionName].params; + const value = format({ + [PerMessageDeflate.extensionName]: [params] + }); + headers.push(`Sec-WebSocket-Extensions: ${value}`); + ws._extensions = extensions; + } + this.emit("headers", headers, req); + socket.write(headers.concat("\r\n").join("\r\n")); + socket.removeListener("error", socketOnError); + ws.setSocket(socket, head, this.options.maxPayload); + if (this.clients) { + this.clients.add(ws); + ws.on("close", () => this.clients.delete(ws)); + } + cb(ws, req); + } + }; + module2.exports = WebSocketServer; + function addListeners(server2, map) { + for (const event of Object.keys(map)) server2.on(event, map[event]); + return function removeListeners() { + for (const event of Object.keys(map)) { + server2.removeListener(event, map[event]); + } + }; + } + function emitClose(server2) { + server2._state = CLOSED; + server2.emit("close"); + } + function socketOnError() { + this.destroy(); + } + function abortHandshake(socket, code, message, headers) { + if (socket.writable) { + message = message || http.STATUS_CODES[code]; + headers = { + Connection: "close", + "Content-Type": "text/html", + "Content-Length": Buffer.byteLength(message), + ...headers + }; + socket.write( + `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r +` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message + ); + } + socket.removeListener("error", socketOnError); + socket.destroy(); + } + function trim(str) { + return str.trim(); + } + } +}); + +// node_modules/ws/index.js +var require_ws = __commonJS({ + "node_modules/ws/index.js"(exports2, module2) { + "use strict"; + var WebSocket = require_websocket(); + WebSocket.createWebSocketStream = require_stream(); + WebSocket.Server = require_websocket_server(); + WebSocket.Receiver = require_receiver(); + WebSocket.Sender = require_sender(); + module2.exports = WebSocket; + } +}); + +// node_modules/botframework-streaming/lib/webSocket/nodeWebSocket.js +var require_nodeWebSocket = __commonJS({ + "node_modules/botframework-streaming/lib/webSocket/nodeWebSocket.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NodeWebSocket = void 0; + var http_1 = require("http"); + var url_1 = require("url"); + var crypto_1 = __importDefault2(require("crypto")); + var ws_1 = __importDefault2(require_ws()); + var NONCE_LENGTH = 16; + var NodeWebSocket = class { + /** + * Creates a new [NodeWebSocket](xref:botframework-streaming.NodeWebSocket) instance. + * + * @param wsSocket The `ws` WebSocket instance to build this connection on. + */ + constructor(wsSocket) { + this.wsSocket = wsSocket; + } + /** + * @internal + */ + create(req, socket, head) { + return __awaiter2(this, void 0, void 0, function* () { + this.wsServer = new ws_1.default.Server({ noServer: true }); + return new Promise((resolve, reject) => { + try { + this.wsServer.handleUpgrade(req, socket, head, (websocket) => { + this.wsSocket = websocket; + resolve(); + }); + } catch (err) { + reject(err); + } + }); + }); + } + /** + * Indicates if the 'ws' WebSocket is currently connected and ready to send messages. + * + * @returns `true` if the underlying websocket is ready and availble to send messages, otherwise `false`. + */ + get isConnected() { + return this.wsSocket && this.wsSocket.readyState === ws_1.default.OPEN; + } + /** + * Writes a buffer to the socket and sends it. + * + * @param buffer The buffer of data to send across the connection. + */ + write(buffer) { + this.wsSocket.send(buffer); + } + /** + * Connects to the supporting socket using WebSocket protocol. + * + * @param serverAddressOrHostName The host name or URL the server is listening on. + * @param port If `serverAddressOrHostName` is a host name, the port the server is listening on, defaults to 8082. Otherwise, this argument is ignored. + * @returns A Promise that resolves when the websocket connection is closed, or rejects on an error. + */ + connect(serverAddressOrHostName, port = 8082) { + return __awaiter2(this, void 0, void 0, function* () { + let url; + try { + url = new url_1.URL(serverAddressOrHostName); + } catch (_error) { + } + if (url === null || url === void 0 ? void 0 : url.hostname) { + return new Promise((resolve, reject) => { + const ws = this.wsSocket = new ws_1.default(url); + ws.once("error", ({ message }) => reject(new Error(message))); + ws.once("open", () => resolve()); + }); + } + this.wsServer = new ws_1.default.Server({ noServer: true }); + const wskey = crypto_1.default.randomBytes(NONCE_LENGTH).toString("base64"); + const options = { + port, + hostname: serverAddressOrHostName, + headers: { + connection: "upgrade", + "Sec-WebSocket-Key": wskey, + "Sec-WebSocket-Version": "13" + } + }; + const req = (0, http_1.request)(options); + req.end(); + req.on("upgrade", (res, socket, head) => { + this.wsServer.completeUpgrade(wskey, void 0, res, socket, head, (websocket) => { + this.wsSocket = websocket; + }); + }); + return new Promise((resolve, reject) => { + req.on("close", resolve); + req.on("error", reject); + }); + }); + } + /** + * Set the handler for `'message'` events received on the socket. + * + * @param handler The callback to handle the "message" event. + */ + setOnMessageHandler(handler) { + this.wsSocket.on("message", handler); + } + /** + * Close the socket. + * + * @remarks + * Optionally pass in a status code and string explaining why the connection is closing. + * @param code Optional status code to explain why the connection has closed. + * @param data Optional additional data to explain why the connection has closed. + */ + close(code, data) { + this.wsSocket.close(code, data); + } + /** + * Set the callback to call when encountering socket closures. + * + * @param handler The callback to handle the "close" event. + */ + setOnCloseHandler(handler) { + this.wsSocket.on("close", handler); + } + /** + * Set the callback to call when encountering errors. + * + * @param handler The callback to handle the "error" event. + */ + setOnErrorHandler(handler) { + this.wsSocket.on("error", (error) => { + if (error) { + handler(error); + } + }); + } + }; + exports2.NodeWebSocket = NodeWebSocket; + } +}); + +// node_modules/botframework-streaming/lib/webSocket/factories/nodeWebSocketFactoryBase.js +var require_nodeWebSocketFactoryBase = __commonJS({ + "node_modules/botframework-streaming/lib/webSocket/factories/nodeWebSocketFactoryBase.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NodeWebSocketFactoryBase = void 0; + var NodeWebSocketFactoryBase = class { + }; + exports2.NodeWebSocketFactoryBase = NodeWebSocketFactoryBase; + } +}); + +// node_modules/botframework-streaming/lib/webSocket/factories/nodeWebSocketFactory.js +var require_nodeWebSocketFactory = __commonJS({ + "node_modules/botframework-streaming/lib/webSocket/factories/nodeWebSocketFactory.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NodeWebSocketFactory = void 0; + var nodeWebSocket_1 = require_nodeWebSocket(); + var nodeWebSocketFactoryBase_1 = require_nodeWebSocketFactoryBase(); + var NodeWebSocketFactory = class extends nodeWebSocketFactoryBase_1.NodeWebSocketFactoryBase { + /** + * Initializes a new instance of the [NodeWebSocketFactory](xref:botframework-streaming.NodeWebSocketFactory) class. + */ + constructor() { + super(); + } + /** + * Creates a [NodeWebSocket](xref:botframework-streaming.NodeWebSocket) instance. + * + * @remarks + * The parameters for this method should be associated with an 'upgrade' event off of a Node.js HTTP Server. + * @param req An IncomingMessage from the 'http' module in Node.js. + * @param socket The Socket connecting the bot and the server, from the 'net' module in Node.js. + * @param head The first packet of the upgraded stream which may be empty per https://nodejs.org/api/http.html#http_event_upgrade_1. + * @returns A [NodeWebSocket](xref:botframework-streaming.NodeWebSocket) instance ready for streaming. + */ + createWebSocket(req, socket, head) { + return __awaiter2(this, void 0, void 0, function* () { + const s = new nodeWebSocket_1.NodeWebSocket(); + yield s.create(req, socket, head); + return s; + }); + } + }; + exports2.NodeWebSocketFactory = NodeWebSocketFactory; + } +}); + +// node_modules/botframework-streaming/lib/webSocket/factories/index.js +var require_factories = __commonJS({ + "node_modules/botframework-streaming/lib/webSocket/factories/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_nodeWebSocketFactory(), exports2); + __exportStar2(require_nodeWebSocketFactoryBase(), exports2); + } +}); + +// node_modules/botframework-streaming/lib/webSocket/webSocketTransport.js +var require_webSocketTransport = __commonJS({ + "node_modules/botframework-streaming/lib/webSocket/webSocketTransport.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.WebSocketTransport = void 0; + var WebSocketTransport = class { + /** + * Creates a new instance of the [WebSocketTransport](xref:botframework-streaming.WebSocketTransport) class. + * + * @param ws The ISocket to build this transport on top of. + */ + constructor(ws) { + this.ws = ws; + this._queue = []; + this._activeOffset = 0; + this._activeReceiveCount = 0; + this.ws.setOnMessageHandler((data) => { + this.onReceive(data); + }); + this.ws.setOnErrorHandler((err) => { + this.onError(err); + }); + this.ws.setOnCloseHandler(() => { + this.onClose(); + }); + } + /** + * Sends the given buffer out over the socket's connection. + * + * @param buffer The buffered data to send out over the connection. + * @returns A number indicating the length of the sent data if the data was successfully sent, otherwise 0. + */ + send(buffer) { + var _a; + if ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.isConnected) { + this.ws.write(buffer); + return buffer.length; + } + return 0; + } + /** + * Returns true if the transport is connected to a socket. + * + * @returns `true` if the the transport is connected and ready to send data, `false` otherwise. + */ + get isConnected() { + var _a; + return !!((_a = this.ws) === null || _a === void 0 ? void 0 : _a.isConnected); + } + /** + * Close the socket this transport is connected to. + */ + close() { + var _a; + if ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.isConnected) { + this.ws.close(); + } + } + /** + * Attempt to receive incoming data from the connected socket. + * + * @param count The number of bytes to attempt to receive. + * @returns A buffer populated with the received data. + */ + receive(count) { + return __awaiter2(this, void 0, void 0, function* () { + if (this._activeReceiveResolve) { + throw new Error("Cannot call receive more than once before it has returned."); + } + this._activeReceiveCount = count; + const promise = new Promise((resolve, reject) => { + this._activeReceiveResolve = resolve; + this._activeReceiveReject = reject; + }); + this.trySignalData(); + return promise; + }); + } + /** + * Sets the transport to attempt to receive incoming data that has not yet arrived. + * + * @param data A buffer to store incoming data in. + */ + onReceive(data) { + if (this._queue && data && data.byteLength > 0) { + this._queue.push(Buffer.from(data)); + this.trySignalData(); + } + } + onClose() { + if (this._activeReceiveReject) { + this._activeReceiveReject(new Error("Socket was closed.")); + } + this._active = null; + this._activeOffset = 0; + this._activeReceiveResolve = null; + this._activeReceiveReject = null; + this._activeReceiveCount = 0; + this.ws = null; + } + onError(err) { + if (this._activeReceiveReject) { + this._activeReceiveReject(err); + } + this.onClose(); + } + trySignalData() { + if (this._activeReceiveResolve) { + if (!this._active && this._queue.length > 0) { + this._active = this._queue.shift(); + this._activeOffset = 0; + } + if (this._active) { + if (this._activeOffset === 0 && this._active.length === this._activeReceiveCount) { + const buffer = this._active; + this._active = null; + this._activeReceiveResolve(buffer); + } else { + const available = Math.min(this._activeReceiveCount, this._active.length - this._activeOffset); + const buffer = Buffer.alloc(available); + this._active.copy(buffer, 0, this._activeOffset, this._activeOffset + available); + this._activeOffset += available; + if (this._activeOffset >= this._active.length) { + this._active = null; + this._activeOffset = 0; + } + this._activeReceiveResolve(buffer); + } + this._activeReceiveCount = 0; + this._activeReceiveReject = null; + this._activeReceiveResolve = null; + } + } + } + }; + exports2.WebSocketTransport = WebSocketTransport; + } +}); + +// node_modules/botframework-streaming/lib/webSocket/nodeWebSocketClient.js +var require_nodeWebSocketClient = __commonJS({ + "node_modules/botframework-streaming/lib/webSocket/nodeWebSocketClient.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.WebSocketClient = void 0; + var protocolAdapter_1 = require_protocolAdapter(); + var payloads_1 = require_payloads(); + var payloadTransport_1 = require_payloadTransport(); + var nodeWebSocket_1 = require_nodeWebSocket(); + var webSocketTransport_1 = require_webSocketTransport(); + var WebSocketClient = class { + /** + * Creates a new instance of the [WebSocketClient](xref:botframework-streaming.WebSocketClient) class. + * + * @param config For configuring a [WebSocketClient](xref:botframework-streaming.WebSocketClient) instance to communicate with a WebSocket server. + * @param config.url The URL of the remote server to connect to. + * @param config.requestHandler The [RequestHandler](xref:botframework-streaming.RequestHandler) used to process incoming messages received by this client. + * @param config.disconnectionHandler Optional function to handle the disconnection message. + */ + constructor({ url, requestHandler, disconnectionHandler = null }) { + this._url = url; + this._requestHandler = requestHandler; + this._disconnectionHandler = disconnectionHandler; + this._requestManager = new payloads_1.RequestManager(); + this._sender = new payloadTransport_1.PayloadSender(); + this._sender.disconnected = this.onConnectionDisconnected.bind(this); + this._receiver = new payloadTransport_1.PayloadReceiver(); + this._receiver.disconnected = this.onConnectionDisconnected.bind(this); + this._protocolAdapter = new protocolAdapter_1.ProtocolAdapter(this._requestHandler, this._requestManager, this._sender, this._receiver); + } + /** + * Establish a connection with no custom headers. + * + * @returns A promise that will not resolve until the client stops listening for incoming messages. + */ + connect() { + return __awaiter2(this, void 0, void 0, function* () { + const ws = new nodeWebSocket_1.NodeWebSocket(); + try { + yield ws.connect(this._url); + const transport = new webSocketTransport_1.WebSocketTransport(ws); + this._sender.connect(transport); + this._receiver.connect(transport); + } catch (_error) { + throw new Error("Unable to connect client to Node transport."); + } + }); + } + /** + * Stop this client from listening. + */ + disconnect() { + this._sender.disconnect(new payloadTransport_1.TransportDisconnectedEvent("Disconnect was called.")); + this._receiver.disconnect(new payloadTransport_1.TransportDisconnectedEvent("Disconnect was called.")); + } + /** + * Task used to send data over this client connection. + * + * @param request The [StreamingRequest](xref:botframework-streaming.StreamingRequest) instance to send. + * @returns A promise that will produce an instance of receive response on completion of the send operation. + */ + send(request) { + return __awaiter2(this, void 0, void 0, function* () { + return this._protocolAdapter.sendRequest(request); + }); + } + onConnectionDisconnected(sender, args) { + this._requestManager.rejectAllResponses(new Error("Disconnect was called.")); + if (this._disconnectionHandler != null) { + this._disconnectionHandler("Disconnected"); + return; + } + throw new Error(`Unable to re-connect client to Node transport for url ${this._url}. Sender: '${JSON.stringify(sender)}'. Args:' ${JSON.stringify(args)}`); + } + }; + exports2.WebSocketClient = WebSocketClient; + } +}); + +// node_modules/botframework-streaming/lib/webSocket/webSocketServer.js +var require_webSocketServer = __commonJS({ + "node_modules/botframework-streaming/lib/webSocket/webSocketServer.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.WebSocketServer = void 0; + var protocolAdapter_1 = require_protocolAdapter(); + var payloads_1 = require_payloads(); + var payloadTransport_1 = require_payloadTransport(); + var webSocketTransport_1 = require_webSocketTransport(); + var WebSocketServer = class { + /** + * Creates a new instance of the [WebSocketServer](xref:botframework-streaming.WebSocketServer) class. + * + * @param socket The underlying web socket. + * @param requestHandler Optional [RequestHandler](xref:botframework-streaming.RequestHandler) to process incoming messages received by this server. + */ + constructor(socket, requestHandler) { + if (!socket) { + throw new TypeError("WebSocketServer: Missing socket parameter"); + } + this._socket = socket; + this._webSocketTransport = new webSocketTransport_1.WebSocketTransport(socket); + this._requestHandler = requestHandler; + this._requestManager = new payloads_1.RequestManager(); + this._sender = new payloadTransport_1.PayloadSender(); + this._sender.disconnected = this.onConnectionDisconnected.bind(this); + this._receiver = new payloadTransport_1.PayloadReceiver(); + this._receiver.disconnected = this.onConnectionDisconnected.bind(this); + this._protocolAdapter = new protocolAdapter_1.ProtocolAdapter(this._requestHandler, this._requestManager, this._sender, this._receiver); + this._closedSignal = (x) => { + return x; + }; + } + /** + * Examines the stored [ISocket](xref:botframework-streaming.ISocket) and returns `true` if the socket connection is open. + * + * @returns `true` if the underlying websocket is ready and availble to send messages, otherwise `false`. + */ + get isConnected() { + return this._socket.isConnected; + } + /** + * Used to establish the connection used by this server and begin listening for incoming messages. + * + * @returns A promise to handle the server listen operation. This task will not resolve as long as the server is running. + */ + start() { + return __awaiter2(this, void 0, void 0, function* () { + this._sender.connect(this._webSocketTransport); + this._receiver.connect(this._webSocketTransport); + return this._closedSignal; + }); + } + /** + * Task used to send data over this server connection. + * + * @param request The streaming request to send. + * @returns A promise that will produce an instance of receive response on completion of the send operation. + */ + send(request) { + return __awaiter2(this, void 0, void 0, function* () { + return this._protocolAdapter.sendRequest(request); + }); + } + /** + * Stop this server. + */ + disconnect() { + this._sender.disconnect(new payloadTransport_1.TransportDisconnectedEvent("Disconnect was called.")); + this._receiver.disconnect(new payloadTransport_1.TransportDisconnectedEvent("Disconnect was called.")); + } + /** + * @param sender The PayloadReceiver or PayloadSender that triggered or received a disconnect. + * @param e TransportDisconnectedEvent + */ + onConnectionDisconnected(sender, e) { + if (this._closedSignal) { + this._closedSignal("close"); + this._closedSignal = null; + } + if (sender === this._sender) { + this._receiver.disconnect(e); + } + if (sender === this._receiver) { + this._sender.disconnect(e); + } + } + }; + exports2.WebSocketServer = WebSocketServer; + } +}); + +// node_modules/botframework-streaming/lib/webSocket/index.js +var require_webSocket = __commonJS({ + "node_modules/botframework-streaming/lib/webSocket/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.WebSocketTransport = exports2.WebSocketServer = exports2.WebSocketClient = exports2.NodeWebSocket = exports2.NodeWebSocketFactoryBase = exports2.NodeWebSocketFactory = void 0; + var factories_1 = require_factories(); + Object.defineProperty(exports2, "NodeWebSocketFactory", { enumerable: true, get: function() { + return factories_1.NodeWebSocketFactory; + } }); + Object.defineProperty(exports2, "NodeWebSocketFactoryBase", { enumerable: true, get: function() { + return factories_1.NodeWebSocketFactoryBase; + } }); + var nodeWebSocket_1 = require_nodeWebSocket(); + Object.defineProperty(exports2, "NodeWebSocket", { enumerable: true, get: function() { + return nodeWebSocket_1.NodeWebSocket; + } }); + var nodeWebSocketClient_1 = require_nodeWebSocketClient(); + Object.defineProperty(exports2, "WebSocketClient", { enumerable: true, get: function() { + return nodeWebSocketClient_1.WebSocketClient; + } }); + var webSocketServer_1 = require_webSocketServer(); + Object.defineProperty(exports2, "WebSocketServer", { enumerable: true, get: function() { + return webSocketServer_1.WebSocketServer; + } }); + var webSocketTransport_1 = require_webSocketTransport(); + Object.defineProperty(exports2, "WebSocketTransport", { enumerable: true, get: function() { + return webSocketTransport_1.WebSocketTransport; + } }); + } +}); + +// node_modules/botframework-streaming/lib/index.js +var require_lib18 = __commonJS({ + "node_modules/botframework-streaming/lib/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.WebSocketServer = exports2.WebSocketClient = exports2.NodeWebSocketFactoryBase = exports2.NodeWebSocketFactory = exports2.NodeWebSocket = exports2.SubscribableStream = exports2.StreamingResponse = exports2.StreamingRequest = exports2.RequestHandler = exports2.NamedPipeServer = exports2.NamedPipeClient = exports2.HttpContent = exports2.ContentStream = void 0; + var contentStream_1 = require_contentStream(); + Object.defineProperty(exports2, "ContentStream", { enumerable: true, get: function() { + return contentStream_1.ContentStream; + } }); + var httpContentStream_1 = require_httpContentStream(); + Object.defineProperty(exports2, "HttpContent", { enumerable: true, get: function() { + return httpContentStream_1.HttpContent; + } }); + var namedPipe_1 = require_namedPipe(); + Object.defineProperty(exports2, "NamedPipeClient", { enumerable: true, get: function() { + return namedPipe_1.NamedPipeClient; + } }); + Object.defineProperty(exports2, "NamedPipeServer", { enumerable: true, get: function() { + return namedPipe_1.NamedPipeServer; + } }); + var requestHandler_1 = require_requestHandler(); + Object.defineProperty(exports2, "RequestHandler", { enumerable: true, get: function() { + return requestHandler_1.RequestHandler; + } }); + var streamingRequest_1 = require_streamingRequest(); + Object.defineProperty(exports2, "StreamingRequest", { enumerable: true, get: function() { + return streamingRequest_1.StreamingRequest; + } }); + var streamingResponse_1 = require_streamingResponse(); + Object.defineProperty(exports2, "StreamingResponse", { enumerable: true, get: function() { + return streamingResponse_1.StreamingResponse; + } }); + var subscribableStream_1 = require_subscribableStream(); + Object.defineProperty(exports2, "SubscribableStream", { enumerable: true, get: function() { + return subscribableStream_1.SubscribableStream; + } }); + var webSocket_1 = require_webSocket(); + Object.defineProperty(exports2, "NodeWebSocket", { enumerable: true, get: function() { + return webSocket_1.NodeWebSocket; + } }); + Object.defineProperty(exports2, "NodeWebSocketFactory", { enumerable: true, get: function() { + return webSocket_1.NodeWebSocketFactory; + } }); + Object.defineProperty(exports2, "NodeWebSocketFactoryBase", { enumerable: true, get: function() { + return webSocket_1.NodeWebSocketFactoryBase; + } }); + Object.defineProperty(exports2, "WebSocketClient", { enumerable: true, get: function() { + return webSocket_1.WebSocketClient; + } }); + Object.defineProperty(exports2, "WebSocketServer", { enumerable: true, get: function() { + return webSocket_1.WebSocketServer; + } }); + } +}); + +// node_modules/botbuilder/lib/streaming/constants.js +var require_constants7 = __commonJS({ + "node_modules/botbuilder/lib/streaming/constants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.POST = exports2.GET = exports2.MESSAGES_PATH = exports2.VERSION_PATH = exports2.defaultPipeName = void 0; + exports2.defaultPipeName = "bfv4.pipes"; + exports2.VERSION_PATH = "/api/version"; + exports2.MESSAGES_PATH = "/api/messages"; + exports2.GET = "GET"; + exports2.POST = "POST"; + } +}); + +// node_modules/botbuilder/lib/streaming/streamingHttpClient.js +var require_streamingHttpClient = __commonJS({ + "node_modules/botbuilder/lib/streaming/streamingHttpClient.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.StreamingHttpClient = void 0; + var botframework_streaming_1 = require_lib18(); + var StreamingHttpClient = class { + /** + * Creates a new streaming Http client. + * + * @param server Transport server implementation to be used. + */ + constructor(server2) { + if (!server2) { + throw new Error("StreamingHttpClient: Expected server."); + } + this.server = server2; + } + /** + * This function hides the default sendRequest of the HttpClient, replacing it + * with a version that takes the WebResource created by the BotFrameworkAdapter + * and converting it to a form that can be sent over a streaming transport. + * + * @param httpRequest The outgoing request created by the BotframeworkAdapter. + * @returns The streaming transport compatible response to send back to the client. + */ + sendRequest(httpRequest) { + return __awaiter2(this, void 0, void 0, function* () { + if (!httpRequest) { + throw new Error('StreamingHttpClient.sendRequest(): missing "httpRequest" parameter'); + } + if (!this.server.isConnected) { + throw new Error("StreamingHttpClient.sendRequest(): Streaming connection is disconnected, and the request could not be sent."); + } + const request = this.mapHttpRequestToProtocolRequest(httpRequest); + request.path = request.path.substring(request.path.indexOf("/v3")); + const res = yield this.server.send(request); + return { + request: httpRequest, + status: res.statusCode, + headers: httpRequest.headers, + readableStreamBody: res.streams.length > 0 ? res.streams[0].getStream() : void 0 + }; + }); + } + /** + * @private + */ + mapHttpRequestToProtocolRequest(httpRequest) { + return botframework_streaming_1.StreamingRequest.create(httpRequest.method, httpRequest.url, httpRequest.body); + } + }; + exports2.StreamingHttpClient = StreamingHttpClient; + } +}); + +// node_modules/botbuilder/lib/streaming/tokenResolver.js +var require_tokenResolver = __commonJS({ + "node_modules/botbuilder/lib/streaming/tokenResolver.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TokenResolver = void 0; + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + var botbuilder_core_1 = require_lib10(); + var TokenResolver = class _TokenResolver { + /** + * Checks if we have token responses from OAuth cards. + * + * @param adapter The [BotFrameworkAdapter](xref:botbuilder.BotFrameworkAdapter). + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param activity The [Activity](xref:botframework-schema.Activity) to be checked. + * @param log Optional. The log to write on. + */ + static checkForOAuthCards(adapter, context, activity, log) { + if (!activity || !activity.attachments) { + return; + } + for (const attachment of activity.attachments) { + if (attachment.contentType == botbuilder_core_1.CardFactory.contentTypes.oauthCard) { + const oauthCard = attachment.content; + if (!oauthCard.connectionName) { + throw new Error("The OAuthPrompt's ConnectionName property is missing a value."); + } + let pollingTimeoutMs = context.turnState.get(botbuilder_core_1.TokenPollingSettingsKey); + if (!pollingTimeoutMs) { + pollingTimeoutMs = botbuilder_core_1.OAuthLoginTimeoutMsValue; + } + const pollingTimeout = /* @__PURE__ */ new Date(); + pollingTimeout.setMilliseconds(pollingTimeout.getMilliseconds() + pollingTimeoutMs); + setTimeout(() => this.pollForToken(adapter, context, activity, oauthCard.connectionName, pollingTimeout, log), _TokenResolver.PollingIntervalMs); + } + } + } + /** + * @private + */ + static pollForToken(adapter, context, activity, connectionName, pollingTimeout, log) { + if (pollingTimeout > /* @__PURE__ */ new Date()) { + const tokenApiClientCredentials = context.turnState.get(adapter.TokenApiClientCredentialsKey); + adapter.getUserToken(context, connectionName, null, tokenApiClientCredentials).then((tokenResponse) => { + let pollingIntervalMs = _TokenResolver.PollingIntervalMs; + if (tokenResponse) { + if (tokenResponse.token) { + const logic = context.turnState.get(botbuilder_core_1.BotCallbackHandlerKey); + const eventActivity = _TokenResolver.createTokenResponseActivity(botbuilder_core_1.TurnContext.getConversationReference(activity), tokenResponse.token, connectionName); + adapter.processActivityDirect(eventActivity, logic).then(() => { + }).catch((reason) => { + adapter.onTurnError(context, new Error(reason)).then(() => { + }); + }); + if (log) + log.push("Returned token"); + return; + } else if (tokenResponse.properties && tokenResponse.properties[botbuilder_core_1.TokenPollingSettingsKey]) { + const pollingSettings = tokenResponse.properties[botbuilder_core_1.TokenPollingSettingsKey]; + if (pollingSettings.timeout <= 0) { + if (log) + log.push("End polling"); + return; + } + if (pollingSettings.interval > 0) { + if (log) + log.push(`Changing polling interval to ${pollingSettings.interval}`); + pollingIntervalMs = pollingSettings.interval; + } + } + } + if (log) + log.push("Polling again"); + setTimeout(() => this.pollForToken(adapter, context, activity, connectionName, pollingTimeout), pollingIntervalMs); + }); + } + } + static createTokenResponseActivity(relatesTo, token, connectionName) { + const tokenResponse = { + id: (0, uuid_1.v4)(), + timestamp: /* @__PURE__ */ new Date(), + type: botbuilder_core_1.ActivityTypes.Event, + serviceUrl: relatesTo.serviceUrl, + from: relatesTo.user, + recipient: relatesTo.bot, + replyToId: relatesTo.activityId, + channelId: relatesTo.channelId, + conversation: relatesTo.conversation, + name: botbuilder_core_1.tokenResponseEventName, + relatesTo, + value: { + token, + connectionName + } + }; + return tokenResponse; + } + }; + exports2.TokenResolver = TokenResolver; + TokenResolver.PollingIntervalMs = 1e3; + } +}); + +// node_modules/botbuilder/lib/streaming/index.js +var require_streaming = __commonJS({ + "node_modules/botbuilder/lib/streaming/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + __exportStar2(require_constants7(), exports2); + __exportStar2(require_streamingHttpClient(), exports2); + __exportStar2(require_tokenResolver(), exports2); + } +}); + +// node_modules/botbuilder/package.json +var require_package4 = __commonJS({ + "node_modules/botbuilder/package.json"(exports2, module2) { + module2.exports = { + name: "botbuilder", + author: "Microsoft Corp.", + description: "Bot Builder is a framework for building rich bots on virtually any platform.", + version: "4.23.3", + license: "MIT", + keywords: [ + "botbuilder", + "botframework", + "bots", + "chatbots" + ], + bugs: { + url: "https://github.com/Microsoft/botbuilder-js/issues" + }, + repository: { + type: "git", + url: "https://github.com/Microsoft/botbuilder-js.git" + }, + main: "./lib/index.js", + types: "./lib/index.d.ts", + typesVersions: { + "<3.9": { + "*": [ + "_ts3.4/*" + ] + } + }, + dependencies: { + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/msal-node": "^2.13.1", + axios: "^1.8.2", + "botbuilder-core": "4.23.3", + "botbuilder-stdlib": "4.23.3-internal", + "botframework-connector": "4.23.3", + "botframework-schema": "4.23.3", + "botframework-streaming": "4.23.3", + dayjs: "^1.11.13", + filenamify: "^6.0.0", + "fs-extra": "^11.2.0", + htmlparser2: "^9.0.1", + uuid: "^10.0.0", + zod: "^3.23.8" + }, + devDependencies: { + chai: "^5.1.2", + jsonwebtoken: "^9.0.2", + lodash: "^4.17.20", + nock: "^13.5.5", + "node-forge": "^1.3.1", + "node-mocks-http": "^1.16.0" + }, + scripts: { + build: "tsc -b", + "build-docs": 'typedoc --theme markdown --entryPoint botbuilder --excludePrivate --includeDeclarations --ignoreCompilerErrors --module amd --out ..\\..\\doc\\botbuilder .\\lib\\index.d.ts ..\\botbuilder-core\\lib\\index.d.ts ..\\botframework-schema\\lib\\index.d.ts --hideGenerator --name "Bot Builder SDK" --readme none', + "build:rollup": "yarn clean && yarn build && api-extractor run --verbose --local", + clean: "rimraf _ts3.4 lib vendors tsconfig.tsbuildinfo", + depcheck: "depcheck --config ../../.depcheckrc", + lint: "eslint . --config ../../eslint.config.cjs", + prebuild: "yarn prebuild-filenamify && yarn prebuild-chai", + "prebuild-filenamify": "tsup ./node_modules/filenamify/*.js --format cjs --dts --out-dir vendors/filenamify --clean --sourcemap", + "prebuild-chai": "tsup ./node_modules/chai/*.js --format cjs --dts --out-dir vendors/chai --clean --sourcemap --target es2020 --external jiti --external @web/dev-server-rollup --external @rollup/plugin-commonjs", + postbuild: "downlevel-dts lib _ts3.4/lib --checksum", + test: "npm-run-all build test:mocha", + "test:compat": "api-extractor run --verbose", + "test:mocha": "nyc mocha tests" + }, + mocha: { + checkLeaks: true, + exit: true, + recursive: true + }, + files: [ + "_ts3.4", + "lib", + "src", + "vendors" + ] + }; + } +}); + +// node_modules/botbuilder/lib/botFrameworkAdapter.js +var require_botFrameworkAdapter = __commonJS({ + "node_modules/botbuilder/lib/botFrameworkAdapter.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotFrameworkAdapter = exports2.USER_AGENT = void 0; + var z = __importStar2(require_zod()); + var interfaces_1 = require_interfaces3(); + var zod_1 = require_zod2(); + var os_1 = require("os"); + var botbuilder_stdlib_1 = require_lib5(); + var activityValidator_1 = require_activityValidator(); + var botbuilder_core_1 = require_lib10(); + var botframework_connector_1 = require_lib9(); + var botframework_streaming_1 = require_lib18(); + var streaming_1 = require_streaming(); + var ARCHITECTURE = (0, os_1.arch)(); + var TYPE = (0, os_1.type)(); + var RELEASE = (0, os_1.release)(); + var NODE_VERSION = process.version; + var pjson = require_package4(); + exports2.USER_AGENT = `Microsoft-BotFramework/3.1 BotBuilder/${pjson.version} (Node.js,Version=${NODE_VERSION}; ${TYPE} ${RELEASE}; ${ARCHITECTURE})`; + var OAUTH_ENDPOINT = "https://api.botframework.com"; + var US_GOV_OAUTH_ENDPOINT = "https://api.botframework.azure.us"; + var BotFrameworkAdapter = class _BotFrameworkAdapter extends botbuilder_core_1.BotAdapter { + /** + * Creates a new instance of the [BotFrameworkAdapter](xref:botbuilder.BotFrameworkAdapter) class. + * + * @param settings Optional. The settings to use for this adapter instance. + * @remarks + * If the `settings` parameter does not include + * [channelService](xref:botbuilder.BotFrameworkAdapterSettings.channelService) or + * [openIdMetadata](xref:botbuilder.BotFrameworkAdapterSettings.openIdMetadata) values, the + * constructor checks the process' environment variables for these values. These values may be + * set when a bot is provisioned on Azure and if so are required for the bot to work properly + * in the global cloud or in a national cloud. + * + * The [BotFrameworkAdapterSettings](xref:botbuilder.BotFrameworkAdapterSettings) class defines + * the available adapter settings. + */ + constructor(settings) { + super(); + this.TokenApiClientCredentialsKey = Symbol("TokenApiClientCredentials"); + this.settings = Object.assign({ appId: "", appPassword: "" }, settings); + if (this.settings.certificateThumbprint && this.settings.certificatePrivateKey) { + this.credentials = new botframework_connector_1.CertificateAppCredentials(this.settings.appId, settings.certificateThumbprint, settings.certificatePrivateKey, this.settings.channelAuthTenant); + this.credentialsProvider = new botframework_connector_1.SimpleCredentialProvider(this.credentials.appId, ""); + } else { + if (botframework_connector_1.JwtTokenValidation.isGovernment(this.settings.channelService)) { + this.credentials = new botframework_connector_1.MicrosoftGovernmentAppCredentials(this.settings.appId, this.settings.appPassword || "", this.settings.channelAuthTenant); + } else { + this.credentials = new botframework_connector_1.MicrosoftAppCredentials(this.settings.appId, this.settings.appPassword || "", this.settings.channelAuthTenant); + } + this.credentialsProvider = new botframework_connector_1.SimpleCredentialProvider(this.credentials.appId, this.settings.appPassword || ""); + } + this.isEmulatingOAuthCards = false; + this.settings.channelService = this.settings.channelService || process.env[botframework_connector_1.AuthenticationConstants.ChannelService]; + this.settings.openIdMetadata = this.settings.openIdMetadata || process.env[botframework_connector_1.AuthenticationConstants.BotOpenIdMetadataKey]; + this.authConfiguration = this.settings.authConfig || new botframework_connector_1.AuthenticationConfiguration(); + if (this.settings.openIdMetadata) { + botframework_connector_1.ChannelValidation.OpenIdMetadataEndpoint = this.settings.openIdMetadata; + botframework_connector_1.GovernmentChannelValidation.OpenIdMetadataEndpoint = this.settings.openIdMetadata; + } + if (this.settings.webSocketFactory) { + this.webSocketFactory = this.settings.webSocketFactory; + } + this.use((context, next) => __awaiter2(this, void 0, void 0, function* () { + if (context.activity.channelId === "msteams" && context.activity && context.activity.conversation && !context.activity.conversation.tenantId && context.activity.channelData && context.activity.channelData.tenant) { + context.activity.conversation.tenantId = context.activity.channelData.tenant.id; + } + yield next(); + })); + } + /** + * Used in streaming contexts to check if the streaming connection is still open for the bot to send activities. + * + * @returns True if the streaming connection is open, otherwise false. + */ + get isStreamingConnectionOpen() { + var _a, _b; + return (_b = (_a = this.streamingServer) === null || _a === void 0 ? void 0 : _a.isConnected) !== null && _b !== void 0 ? _b : false; + } + /** + * @internal + */ + continueConversation(reference, oAuthScopeOrlogic, maybeLogic) { + return __awaiter2(this, void 0, void 0, function* () { + let audience; + if (zod_1.LogicT.safeParse(oAuthScopeOrlogic).success) { + audience = botframework_connector_1.JwtTokenValidation.isGovernment(this.settings.channelService) ? botframework_connector_1.GovernmentConstants.ToChannelFromBotOAuthScope : botframework_connector_1.AuthenticationConstants.ToChannelFromBotOAuthScope; + } else { + audience = z.string().parse(oAuthScopeOrlogic); + } + const logicParse = zod_1.LogicT.safeParse(oAuthScopeOrlogic); + const logic = logicParse.success ? logicParse.data : zod_1.LogicT.parse(maybeLogic); + let credentials = this.credentials; + if (credentials.appId) { + if (credentials.oAuthScope !== audience) { + credentials = yield this.buildCredentials(credentials.appId, audience); + } + } + const connectorClient = this.createConnectorClientInternal(reference.serviceUrl, credentials); + const request = botbuilder_core_1.TurnContext.applyConversationReference({ type: botbuilder_core_1.ActivityTypes.Event, name: botbuilder_core_1.ActivityEventNames.ContinueConversation }, reference, true); + const context = this.createContext(request); + context.turnState.set(this.OAuthScopeKey, audience); + context.turnState.set(this.ConnectorClientKey, connectorClient); + yield this.runMiddleware(context, logic); + }); + } + /** + * @internal + */ + createConversation(reference, parametersOrLogic, maybeLogic) { + return __awaiter2(this, void 0, void 0, function* () { + if (!reference.serviceUrl) { + throw new Error("BotFrameworkAdapter.createConversation(): missing serviceUrl."); + } + const logicParse = zod_1.LogicT.safeParse(parametersOrLogic); + const parameterParse = botbuilder_core_1.conversationParametersObject.partial().safeParse(parametersOrLogic); + const parameters = parameterParse.success ? parameterParse.data : {}; + const logic = logicParse.success ? logicParse.data : zod_1.LogicT.parse(maybeLogic); + const conversationParameters = Object.assign({}, { + bot: reference.bot, + members: [reference.user], + isGroup: false, + activity: null, + channelData: null + }, parameters); + const client = this.createConnectorClient(reference.serviceUrl); + if (reference.conversation && reference.conversation.tenantId) { + conversationParameters.channelData = { tenant: { id: reference.conversation.tenantId } }; + conversationParameters.tenantId = reference.conversation.tenantId; + } + const response = yield client.conversations.createConversation(conversationParameters); + const request = botbuilder_core_1.TurnContext.applyConversationReference({ type: botbuilder_core_1.ActivityTypes.Event, name: botbuilder_core_1.ActivityEventNames.CreateConversation }, reference, true); + request.conversation = { + id: response.id, + isGroup: conversationParameters.isGroup, + conversationType: null, + tenantId: reference.conversation.tenantId, + name: null + }; + request.channelData = conversationParameters.channelData; + if (response.serviceUrl) { + request.serviceUrl = response.serviceUrl; + } + const context = this.createContext(request); + yield this.runMiddleware(context, logic); + }); + } + /** + * Asynchronously deletes an existing activity. + * + * This interface supports the framework and is not intended to be called directly for your code. + * Use [TurnContext.deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity) to delete + * an activity from your bot code. + * + * @param context The context object for the turn. + * @param reference Conversation reference information for the activity to delete. + * @remarks + * Not all channels support this operation. For channels that don't, this call may throw an exception. + */ + deleteActivity(context, reference) { + return __awaiter2(this, void 0, void 0, function* () { + if (!reference.serviceUrl) { + throw new Error("BotFrameworkAdapter.deleteActivity(): missing serviceUrl"); + } + if (!reference.conversation || !reference.conversation.id) { + throw new Error("BotFrameworkAdapter.deleteActivity(): missing conversation or conversation.id"); + } + if (!reference.activityId) { + throw new Error("BotFrameworkAdapter.deleteActivity(): missing activityId"); + } + const client = this.getOrCreateConnectorClient(context, reference.serviceUrl, this.credentials); + yield client.conversations.deleteActivity(reference.conversation.id, reference.activityId); + }); + } + /** + * Asynchronously removes a member from the current conversation. + * + * @param context The context object for the turn. + * @param memberId The ID of the member to remove from the conversation. + * @remarks + * Remove a member's identity information from the conversation. + * + * Not all channels support this operation. For channels that don't, this call may throw an exception. + */ + deleteConversationMember(context, memberId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context.activity.serviceUrl) { + throw new Error("BotFrameworkAdapter.deleteConversationMember(): missing serviceUrl"); + } + if (!context.activity.conversation || !context.activity.conversation.id) { + throw new Error("BotFrameworkAdapter.deleteConversationMember(): missing conversation or conversation.id"); + } + const serviceUrl = context.activity.serviceUrl; + const conversationId = context.activity.conversation.id; + const client = this.getOrCreateConnectorClient(context, serviceUrl, this.credentials); + yield client.conversations.deleteConversationMember(conversationId, memberId); + }); + } + /** + * Asynchronously lists the members of a given activity. + * + * @param context The context object for the turn. + * @param activityId Optional. The ID of the activity to get the members of. If not specified, the current activity ID is used. + * @returns An array of [ChannelAccount](xref:botframework-schema.ChannelAccount) objects for + * the users involved in a given activity. + * @remarks + * Returns an array of [ChannelAccount](xref:botframework-schema.ChannelAccount) objects for + * the users involved in a given activity. + * + * This is different from [getConversationMembers](xref:botbuilder.BotFrameworkAdapter.getConversationMembers) + * in that it will return only those users directly involved in the activity, not all members of the conversation. + */ + getActivityMembers(context, activityId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!activityId) { + activityId = context.activity.id; + } + if (!context.activity.serviceUrl) { + throw new Error("BotFrameworkAdapter.getActivityMembers(): missing serviceUrl"); + } + if (!context.activity.conversation || !context.activity.conversation.id) { + throw new Error("BotFrameworkAdapter.getActivityMembers(): missing conversation or conversation.id"); + } + if (!activityId) { + throw new Error("BotFrameworkAdapter.getActivityMembers(): missing both activityId and context.activity.id"); + } + const serviceUrl = context.activity.serviceUrl; + const conversationId = context.activity.conversation.id; + const client = this.getOrCreateConnectorClient(context, serviceUrl, this.credentials); + return yield client.conversations.getActivityMembers(conversationId, activityId); + }); + } + /** + * Asynchronously lists the members of the current conversation. + * + * @param context The context object for the turn. + * @returns An array of [ChannelAccount](xref:botframework-schema.ChannelAccount) objects for + * all users currently involved in a conversation. + * @remarks + * Returns an array of [ChannelAccount](xref:botframework-schema.ChannelAccount) objects for + * all users currently involved in a conversation. + * + * This is different from [getActivityMembers](xref:botbuilder.BotFrameworkAdapter.getActivityMembers) + * in that it will return all members of the conversation, not just those directly involved in a specific activity. + */ + getConversationMembers(context) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context.activity.serviceUrl) { + throw new Error("BotFrameworkAdapter.getConversationMembers(): missing serviceUrl"); + } + if (!context.activity.conversation || !context.activity.conversation.id) { + throw new Error("BotFrameworkAdapter.getConversationMembers(): missing conversation or conversation.id"); + } + const serviceUrl = context.activity.serviceUrl; + const conversationId = context.activity.conversation.id; + const client = this.getOrCreateConnectorClient(context, serviceUrl, this.credentials); + return yield client.conversations.getConversationMembers(conversationId); + }); + } + /** + * For the specified channel, asynchronously gets a page of the conversations in which this bot has participated. + * + * @param contextOrServiceUrl The URL of the channel server to query or a + * [TurnContext](xref:botbuilder-core.TurnContext) object from a conversation on the channel. + * @param continuationToken Optional. The continuation token from the previous page of results. + * Omit this parameter or use `undefined` to retrieve the first page of results. + * @returns A [ConversationsResult](xref:botframework-schema.ConversationsResult) object containing a page of results + * and a continuation token. + * @remarks + * The the return value's [conversations](xref:botframework-schema.ConversationsResult.conversations) property contains a page of + * [ConversationMembers](xref:botframework-schema.ConversationMembers) objects. Each object's + * [id](xref:botframework-schema.ConversationMembers.id) is the ID of a conversation in which the bot has participated on this channel. + * This method can be called from outside the context of a conversation, as only the bot's service URL and credentials are required. + * + * The channel batches results in pages. If the result's + * [continuationToken](xref:botframework-schema.ConversationsResult.continuationToken) property is not empty, then + * there are more pages to get. Use the returned token to get the next page of results. + * If the `contextOrServiceUrl` parameter is a [TurnContext](xref:botbuilder-core.TurnContext), the URL of the channel server is + * retrieved from + * `contextOrServiceUrl`.[activity](xref:botbuilder-core.TurnContext.activity).[serviceUrl](xref:botframework-schema.Activity.serviceUrl). + */ + getConversations(contextOrServiceUrl, continuationToken) { + return __awaiter2(this, void 0, void 0, function* () { + let client; + if (typeof contextOrServiceUrl === "object") { + const context = contextOrServiceUrl; + client = this.getOrCreateConnectorClient(context, context.activity.serviceUrl, this.credentials); + } else { + client = this.createConnectorClient(contextOrServiceUrl); + } + return yield client.conversations.getConversations(continuationToken ? { continuationToken } : void 0); + }); + } + /** + * Asynchronously attempts to retrieve the token for a user that's in a login flow. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn. + * @param connectionName The name of the auth connection to use. + * @param magicCode Optional. The validation code the user entered. + * @param oAuthAppCredentials Optional. [AppCredentials](xref:botframework-connector.AppCredentials) for OAuth. + * @returns A [TokenResponse](xref:botframework-schema.TokenResponse) object that contains the user token. + */ + getUserToken(context, connectionName, magicCode, oAuthAppCredentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context.activity.from || !context.activity.from.id) { + throw new Error("BotFrameworkAdapter.getUserToken(): missing from or from.id"); + } + if (!connectionName) { + throw new Error("getUserToken() requires a connectionName but none was provided."); + } + this.checkEmulatingOAuthCards(context); + const userId = context.activity.from.id; + const url = this.oauthApiUrl(context); + const client = this.createTokenApiClient(url, oAuthAppCredentials); + context.turnState.set(this.TokenApiClientCredentialsKey, client); + const result = yield client.userToken.getToken(userId, connectionName, { code: magicCode, channelId: context.activity.channelId }); + if (!result || !result.token || result._response.status == 404) { + return void 0; + } else { + return result; + } + }); + } + /** + * Asynchronously signs out the user from the token server. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn. + * @param connectionName Optional. The name of the auth connection to use. + * @param userId Optional. The ID of the user to sign out. + * @param oAuthAppCredentials Optional. [AppCredentials](xref:botframework-connector.AppCredentials) for OAuth. + */ + signOutUser(context, connectionName, userId, oAuthAppCredentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context.activity.from || !context.activity.from.id) { + throw new Error("BotFrameworkAdapter.signOutUser(): missing from or from.id"); + } + if (!userId) { + userId = context.activity.from.id; + } + this.checkEmulatingOAuthCards(context); + const url = this.oauthApiUrl(context); + const client = this.createTokenApiClient(url, oAuthAppCredentials); + context.turnState.set(this.TokenApiClientCredentialsKey, client); + yield client.userToken.signOut(userId, { + connectionName, + channelId: context.activity.channelId + }); + }); + } + /** + * Asynchronously gets a sign-in link from the token server that can be sent as part + * of a [SigninCard](xref:botframework-schema.SigninCard). + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn. + * @param connectionName The name of the auth connection to use. + * @param oAuthAppCredentials Optional. [AppCredentials](xref:botframework-connector.AppCredentials) for OAuth. + * @param userId Optional. The user id that will be associated with the token. + * @param finalRedirect Optional. The final URL that the OAuth flow will redirect to. + * @returns The sign in link. + */ + getSignInLink(context, connectionName, oAuthAppCredentials, userId, finalRedirect) { + return __awaiter2(this, void 0, void 0, function* () { + if (userId && userId != context.activity.from.id) { + throw new ReferenceError("cannot retrieve OAuth signin link for a user that's different from the conversation"); + } + this.checkEmulatingOAuthCards(context); + const conversation = botbuilder_core_1.TurnContext.getConversationReference(context.activity); + const url = this.oauthApiUrl(context); + const client = this.createTokenApiClient(url, oAuthAppCredentials); + context.turnState.set(this.TokenApiClientCredentialsKey, client); + const state = { + ConnectionName: connectionName, + Conversation: conversation, + MsAppId: client.credentials.appId, + RelatesTo: context.activity.relatesTo + }; + const finalState = Buffer.from(JSON.stringify(state)).toString("base64"); + return (yield client.botSignIn.getSignInUrl(finalState, { channelId: context.activity.channelId, finalRedirect }))._response.bodyAsText; + }); + } + /** + * Asynchronously retrieves the token status for each configured connection for the given user. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn. + * @param userId Optional. If present, the ID of the user to retrieve the token status for. + * Otherwise, the ID of the user who sent the current activity is used. + * @param includeFilter Optional. A comma-separated list of connection's to include. If present, + * the `includeFilter` parameter limits the tokens this method returns. + * @param oAuthAppCredentials Optional. [AppCredentials](xref:botframework-connector.AppCredentials) for OAuth. + * @returns The [TokenStatus](xref:botframework-connector.TokenStatus) objects retrieved. + */ + getTokenStatus(context, userId, includeFilter, oAuthAppCredentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!userId && (!context.activity.from || !context.activity.from.id)) { + throw new Error("BotFrameworkAdapter.getTokenStatus(): missing from or from.id"); + } + this.checkEmulatingOAuthCards(context); + userId = userId || context.activity.from.id; + const url = this.oauthApiUrl(context); + const client = this.createTokenApiClient(url, oAuthAppCredentials); + context.turnState.set(this.TokenApiClientCredentialsKey, client); + return (yield client.userToken.getTokenStatus(userId, { + channelId: context.activity.channelId, + include: includeFilter + }))._response.parsedBody; + }); + } + /** + * Asynchronously signs out the user from the token server. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn. + * @param connectionName The name of the auth connection to use. + * @param resourceUrls The list of resource URLs to retrieve tokens for. + * @param oAuthAppCredentials Optional. [AppCredentials](xref:botframework-connector.AppCredentials) for OAuth. + * @returns A map of the [TokenResponse](xref:botframework-schema.TokenResponse) objects by resource URL. + */ + getAadTokens(context, connectionName, resourceUrls, oAuthAppCredentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context.activity.from || !context.activity.from.id) { + throw new Error("BotFrameworkAdapter.getAadTokens(): missing from or from.id"); + } + this.checkEmulatingOAuthCards(context); + const userId = context.activity.from.id; + const url = this.oauthApiUrl(context); + const client = this.createTokenApiClient(url, oAuthAppCredentials); + context.turnState.set(this.TokenApiClientCredentialsKey, client); + return (yield client.userToken.getAadTokens(userId, connectionName, { resourceUrls }, { channelId: context.activity.channelId }))._response.parsedBody; + }); + } + /** + * Asynchronously Get the raw signin resource to be sent to the user for signin. + * + * @param context The context object for the turn. + * @param connectionName The name of the auth connection to use. + * @param userId The user id that will be associated with the token. + * @param finalRedirect The final URL that the OAuth flow will redirect to. + * @param appCredentials Optional. The CoreAppCredentials for OAuth. + * @returns The [BotSignInGetSignInResourceResponse](xref:botframework-connector.BotSignInGetSignInResourceResponse) object. + */ + getSignInResource(context, connectionName, userId, finalRedirect, appCredentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!connectionName) { + throw new Error("getUserToken() requires a connectionName but none was provided."); + } + if (!context.activity.from || !context.activity.from.id) { + throw new Error("BotFrameworkAdapter.getSignInResource(): missing from or from.id"); + } + if (userId && context.activity.from.id !== userId) { + throw new Error("BotFrameworkAdapter.getSiginInResource(): cannot get signin resource for a user that is different from the conversation"); + } + const url = this.oauthApiUrl(context); + const credentials = appCredentials; + const client = this.createTokenApiClient(url, credentials); + const conversation = botbuilder_core_1.TurnContext.getConversationReference(context.activity); + const state = { + ConnectionName: connectionName, + Conversation: conversation, + relatesTo: context.activity.relatesTo, + MSAppId: client.credentials.appId + }; + const finalState = Buffer.from(JSON.stringify(state)).toString("base64"); + const options = { finalRedirect }; + return yield client.botSignIn.getSignInResource(finalState, options); + }); + } + /** + * Asynchronously Performs a token exchange operation such as for single sign-on. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn. + * @param connectionName Name of the auth connection to use. + * @param userId The user id that will be associated with the token. + * @param tokenExchangeRequest The [TokenExchangeRequest](xref:botbuilder-schema.TokenExchangeRequest), either a token to exchange or a uri to exchange. + * @param appCredentials Optional. [AppCredentials](xref:botframework-connector.AppCredentials) for OAuth. + * @returns A `Promise` representing the exchanged [TokenResponse](xref:botframework-schema.TokenResponse). + */ + exchangeToken(context, connectionName, userId, tokenExchangeRequest, appCredentials) { + return __awaiter2(this, void 0, void 0, function* () { + if (!connectionName) { + throw new Error("exchangeToken() requires a connectionName but none was provided."); + } + if (!userId) { + throw new Error("exchangeToken() requires an userId but none was provided."); + } + if (tokenExchangeRequest && !tokenExchangeRequest.token && !tokenExchangeRequest.uri) { + throw new Error("BotFrameworkAdapter.exchangeToken(): Either a Token or Uri property is required on the TokenExchangeRequest"); + } + const url = this.oauthApiUrl(context); + const client = this.createTokenApiClient(url, appCredentials); + return (yield client.userToken.exchangeAsync(userId, connectionName, context.activity.channelId, tokenExchangeRequest))._response.parsedBody; + }); + } + /** + * Asynchronously sends an emulated OAuth card for a channel. + * + * This method supports the framework and is not intended to be called directly for your code. + * + * @param contextOrServiceUrl The URL of the emulator. + * @param emulate `true` to send an emulated OAuth card to the emulator; or `false` to not send the card. + * @remarks + * When testing a bot in the Bot Framework Emulator, this method can emulate the OAuth card interaction. + */ + emulateOAuthCards(contextOrServiceUrl, emulate) { + return __awaiter2(this, void 0, void 0, function* () { + this.isEmulatingOAuthCards = emulate; + const url = this.oauthApiUrl(contextOrServiceUrl); + yield botframework_connector_1.EmulatorApiClient.emulateOAuthCards(this.credentials, url, emulate); + }); + } + /** + * Asynchronously creates a turn context and runs the middleware pipeline for an incoming activity. + * + * @param req An Express or Restify style request object. + * @param res An Express or Restify style response object. + * @param logic The function to call at the end of the middleware pipeline. + * @remarks + * This is the main way a bot receives incoming messages and defines a turn in the conversation. This method: + * + * 1. Parses and authenticates an incoming request. + * - The activity is read from the body of the incoming request. An error will be returned + * if the activity can't be parsed. + * - The identity of the sender is authenticated as either the Emulator or a valid Microsoft + * server, using the bot's `appId` and `appPassword`. The request is rejected if the sender's + * identity is not verified. + * 1. Creates a [TurnContext](xref:botbuilder-core.TurnContext) object for the received activity. + * - This object is wrapped with a [revocable proxy](https://www.ecma-international.org/ecma-262/6.0/#sec-proxy.revocable). + * - When this method completes, the proxy is revoked. + * 1. Sends the turn context through the adapter's middleware pipeline. + * 1. Sends the turn context to the `logic` function. + * - The bot may perform additional routing or processing at this time. + * Returning a promise (or providing an `async` handler) will cause the adapter to wait for any asynchronous operations to complete. + * - After the `logic` function completes, the promise chain set up by the middleware is resolved. + * + * > [!TIP] + * > If you see the error `TypeError: Cannot perform 'set' on a proxy that has been revoked` + * > in your bot's console output, the likely cause is that an async function was used + * > without using the `await` keyword. Make sure all async functions use await! + * + * Middleware can _short circuit_ a turn. When this happens, subsequent middleware and the + * `logic` function is not called; however, all middleware prior to this point still run to completion. + * For more information about the middleware pipeline, see the + * [how bots work](https://docs.microsoft.com/azure/bot-service/bot-builder-basics) and + * [middleware](https://docs.microsoft.com/azure/bot-service/bot-builder-concept-middleware) articles. + * Use the adapter's [use](xref:botbuilder-core.BotAdapter.use) method to add middleware to the adapter. + * + * For example: + * ```JavaScript + * server.post('/api/messages', (req, res) => { + * // Route received request to adapter for processing + * adapter.processActivity(req, res, async (context) => { + * // Process any messages received + * if (context.activity.type === ActivityTypes.Message) { + * await context.sendActivity(`Hello World`); + * } + * }); + * }); + * ``` + */ + processActivity(req, res, logic) { + return __awaiter2(this, void 0, void 0, function* () { + let body; + let status; + let processError; + try { + status = 400; + const request = yield parseRequest(req); + status = 401; + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + const identity = yield this.authenticateRequestInternal(request, authHeader); + request.callerId = yield this.generateCallerId(identity); + status = 500; + const context = this.createContext(request); + context.turnState.set(this.BotIdentityKey, identity); + const connectorClient = yield this.createConnectorClientWithIdentity(request.serviceUrl, identity); + context.turnState.set(this.ConnectorClientKey, connectorClient); + const oAuthScope = botframework_connector_1.SkillValidation.isSkillClaim(identity.claims) ? botframework_connector_1.JwtTokenValidation.getAppIdFromClaims(identity.claims) : this.credentials.oAuthScope; + context.turnState.set(this.OAuthScopeKey, oAuthScope); + context.turnState.set(botbuilder_core_1.BotCallbackHandlerKey, logic); + yield this.runMiddleware(context, logic); + if (request.deliveryMode === botbuilder_core_1.DeliveryModes.ExpectReplies) { + let activities = context.bufferedReplyActivities; + if (request.channelId !== botbuilder_core_1.Channels.Emulator) { + activities = activities.filter((a) => a.type !== botbuilder_core_1.ActivityTypes.Trace); + } + body = { activities }; + status = botbuilder_core_1.StatusCodes.OK; + } else if (request.type === botbuilder_core_1.ActivityTypes.Invoke) { + const invokeResponse = context.turnState.get(botbuilder_core_1.INVOKE_RESPONSE_KEY); + if (invokeResponse && invokeResponse.value) { + const value = invokeResponse.value; + status = value.status; + body = value.body; + } else { + status = botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED; + } + } else { + status = botbuilder_core_1.StatusCodes.OK; + } + } catch (err) { + processError = err; + body = err.toString(); + } + res.status(status); + if (body) { + res.send(body); + } + res.end(); + if (status >= 400) { + if (processError && processError.stack) { + throw new Error(`BotFrameworkAdapter.processActivity(): ${status} ERROR + ${processError.stack}`); + } else { + throw new Error(`BotFrameworkAdapter.processActivity(): ${status} ERROR`); + } + } + }); + } + /** + * Asynchronously creates a turn context and runs the middleware pipeline for an incoming activity. + * + * Use [CloudAdapter.processActivityDirect] instead. + * + * @param activity The activity to process. + * @param logic The function to call at the end of the middleware pipeline. + * @remarks + * This is the main way a bot receives incoming messages and defines a turn in the conversation. This method: + * + * 1. Creates a [TurnContext](xref:botbuilder-core.TurnContext) object for the received activity. + * - This object is wrapped with a [revocable proxy](https://www.ecma-international.org/ecma-262/6.0/#sec-proxy.revocable). + * - When this method completes, the proxy is revoked. + * 1. Sends the turn context through the adapter's middleware pipeline. + * 1. Sends the turn context to the `logic` function. + * - The bot may perform additional routing or processing at this time. + * Returning a promise (or providing an `async` handler) will cause the adapter to wait for any asynchronous operations to complete. + * - After the `logic` function completes, the promise chain set up by the middleware is resolved. + * + * Middleware can _short circuit_ a turn. When this happens, subsequent middleware and the + * `logic` function is not called; however, all middleware prior to this point still run to completion. + * For more information about the middleware pipeline, see the + * [how bots work](https://docs.microsoft.com/azure/bot-service/bot-builder-basics) and + * [middleware](https://docs.microsoft.com/azure/bot-service/bot-builder-concept-middleware) articles. + * Use the adapter's [use](xref:botbuilder-core.BotAdapter.use) method to add middleware to the adapter. + */ + processActivityDirect(activity, logic) { + return __awaiter2(this, void 0, void 0, function* () { + let processError; + try { + const context = this.createContext(activity); + context.turnState.set(botbuilder_core_1.BotCallbackHandlerKey, logic); + yield this.runMiddleware(context, logic); + } catch (err) { + processError = err; + } + if (processError) { + if (processError && processError.stack) { + throw new Error(`BotFrameworkAdapter.processActivityDirect(): ERROR + ${processError.stack}`); + } else { + throw new Error("BotFrameworkAdapter.processActivityDirect(): ERROR"); + } + } + }); + } + /** + * Asynchronously sends a set of outgoing activities to a channel server. + * + * This method supports the framework and is not intended to be called directly for your code. + * Use the turn context's [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) or + * [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) method from your bot code. + * + * @param context The context object for the turn. + * @param activities The activities to send. + * @returns An array of [ResourceResponse](xref:) + * @remarks + * The activities will be sent one after another in the order in which they're received. A + * response object will be returned for each sent activity. For `message` activities this will + * contain the ID of the delivered message. + */ + sendActivities(context, activities) { + return __awaiter2(this, void 0, void 0, function* () { + const responses = []; + for (let i = 0; i < activities.length; i++) { + const activity = activities[i]; + switch (activity.type) { + case "delay": + yield (0, botbuilder_stdlib_1.delay)(typeof activity.value === "number" ? activity.value : 1e3); + responses.push({}); + break; + case botbuilder_core_1.ActivityTypes.InvokeResponse: + context.turnState.set(botbuilder_core_1.INVOKE_RESPONSE_KEY, activity); + responses.push({}); + break; + default: { + if (!activity.serviceUrl) { + throw new Error("BotFrameworkAdapter.sendActivity(): missing serviceUrl."); + } + if (!activity.conversation || !activity.conversation.id) { + throw new Error("BotFrameworkAdapter.sendActivity(): missing conversation id."); + } + if (activity && _BotFrameworkAdapter.isStreamingServiceUrl(activity.serviceUrl)) { + if (!this.isStreamingConnectionOpen) { + throw new Error("BotFrameworkAdapter.sendActivities(): Unable to send activity as Streaming connection is closed."); + } + streaming_1.TokenResolver.checkForOAuthCards(this, context, activity); + } + const client = this.getOrCreateConnectorClient(context, activity.serviceUrl, this.credentials); + if (activity.type === botbuilder_core_1.ActivityTypes.Trace && activity.channelId !== botbuilder_core_1.Channels.Emulator) { + responses.push({}); + } else if (activity.replyToId) { + responses.push(yield client.conversations.replyToActivity(activity.conversation.id, activity.replyToId, activity)); + } else { + responses.push(yield client.conversations.sendToConversation(activity.conversation.id, activity)); + } + break; + } + } + } + return responses; + }); + } + /** + * Asynchronously replaces a previous activity with an updated version. + * + * This interface supports the framework and is not intended to be called directly for your code. + * Use [TurnContext.updateActivity](xref:botbuilder-core.TurnContext.updateActivity) to update + * an activity from your bot code. + * + * @param context The context object for the turn. + * @param activity The updated version of the activity to replace. + * @returns A `Promise` representing the [ResourceResponse](xref:botframework-schema.ResourceResponse) for the operation. + * @remarks + * Not all channels support this operation. For channels that don't, this call may throw an exception. + */ + updateActivity(context, activity) { + return __awaiter2(this, void 0, void 0, function* () { + if (!activity.serviceUrl) { + throw new Error("BotFrameworkAdapter.updateActivity(): missing serviceUrl"); + } + if (!activity.conversation || !activity.conversation.id) { + throw new Error("BotFrameworkAdapter.updateActivity(): missing conversation or conversation.id"); + } + if (!activity.id) { + throw new Error("BotFrameworkAdapter.updateActivity(): missing activity.id"); + } + const client = this.getOrCreateConnectorClient(context, activity.serviceUrl, this.credentials); + return client.conversations.updateActivity(activity.conversation.id, activity.id, activity); + }); + } + /** + * Creates a connector client. + * + * @param serviceUrl The client's service URL. + * @returns The [ConnectorClient](xref:botbuilder-connector.ConnectorClient) instance. + * @remarks + * Override this in a derived class to create a mock connector client for unit testing. + */ + createConnectorClient(serviceUrl) { + return this.createConnectorClientInternal(serviceUrl, this.credentials); + } + /** + * Create a [ConnectorClient](xref:botbuilder-connector.ConnectorClient) with a [ClaimsIdentity](xref:botbuilder-connector.ClaimsIdentity). + * + * @remarks + * If the [ClaimsIdentity](xref:botbuilder-connector.ClaimsIdentity) contains the claims for a Skills request, create a [ConnectorClient](xref:botbuilder-connector.ConnectorClient) for use with Skills. + * Derives the correct audience from the [ClaimsIdentity](xref:botbuilder-connector.ClaimsIdentity), or the instance's credentials property. + * @param serviceUrl The client's service URL. + * @param identity [ClaimsIdentity](xref:botbuilder-connector.ClaimsIdentity). + * @param audience Optional. The recipient of the [ConnectorClient](xref:botbuilder-connector.ConnectorClient)'s messages. Normally the Bot Framework Channel Service or the AppId of another bot. + * @returns The client. + */ + createConnectorClientWithIdentity(serviceUrl, identity, audience) { + return __awaiter2(this, void 0, void 0, function* () { + if (!identity) { + throw new Error("BotFrameworkAdapter.createConnectorClientWithIdentity(): invalid identity parameter."); + } + const botAppId = identity.getClaimValue(botframework_connector_1.AuthenticationConstants.AudienceClaim) || identity.getClaimValue(botframework_connector_1.AuthenticationConstants.AppIdClaim); + const validAudience = typeof audience === "string" && audience.trim().length > 0; + const oAuthScope = validAudience ? audience : yield this.getOAuthScope(botAppId, identity.claims); + const credentials = yield this.buildCredentials(botAppId, oAuthScope); + const client = this.createConnectorClientInternal(serviceUrl, credentials); + return client; + }); + } + createConnectorClientInternal(serviceUrl, credentials) { + const options = Object.assign({}, this.settings.clientOptions); + if (_BotFrameworkAdapter.isStreamingServiceUrl(serviceUrl)) { + if (!this.streamingServer) { + throw new Error(`Cannot create streaming connector client for serviceUrl ${serviceUrl} without a streaming connection. Call 'useWebSocket' or 'useNamedPipe' to start a streaming connection.`); + } + options.httpClient = new streaming_1.StreamingHttpClient(this.streamingServer); + } + options.baseUri = serviceUrl; + const userAgent = typeof options.userAgent === "function" ? options.userAgent(exports2.USER_AGENT) : options.userAgent; + options.userAgent = `${exports2.USER_AGENT} ${userAgent !== null && userAgent !== void 0 ? userAgent : ""}`; + options.requestPolicyFactories = [ + { + create: (nextPolicy) => ({ + sendRequest: (httpRequest) => { + if (!httpRequest.headers.contains("accept")) { + httpRequest.headers.set("accept", "*/*"); + } + return nextPolicy.sendRequest(httpRequest); + } + }) + } + ]; + return new botframework_connector_1.ConnectorClient(credentials, options); + } + // Retrieves the ConnectorClient from the TurnContext or creates a new ConnectorClient with the provided serviceUrl and credentials. + getOrCreateConnectorClient(context, serviceUrl, credentials) { + if (!context || !context.turnState) + throw new Error("invalid context parameter"); + if (!serviceUrl) + throw new Error("invalid serviceUrl"); + if (!credentials) + throw new Error("invalid credentials"); + let client = context.turnState.get(this.ConnectorClientKey); + if (!client || client["baseUri"] !== serviceUrl) { + client = this.createConnectorClientInternal(serviceUrl, credentials); + } + return client; + } + /** + * Returns the correct [OAuthScope](xref:botframework-connector.AppCredentials.OAuthScope) for [AppCredentials](xref:botframework-connector.AppCredentials). + * + * @param botAppId The bot's AppId. + * @param claims The [Claim](xref:botbuilder-connector.Claim) list to check. + * @returns The current credentials' OAuthScope. + */ + getOAuthScope(botAppId, claims) { + return __awaiter2(this, void 0, void 0, function* () { + if (botAppId && botframework_connector_1.SkillValidation.isSkillClaim(claims)) { + return botframework_connector_1.JwtTokenValidation.getAppIdFromClaims(claims); + } + return this.credentials.oAuthScope; + }); + } + /** + * + * @remarks + * When building credentials for bot-to-bot communication, oAuthScope must be passed in. + * @param appId The application id. + * @param oAuthScope The optional OAuth scope. + * @returns The app credentials to be used to acquire tokens. + */ + buildCredentials(appId, oAuthScope) { + return __awaiter2(this, void 0, void 0, function* () { + const appPassword = yield this.credentialsProvider.getAppPassword(appId); + let credentials; + if (this.settings.certificateThumbprint && this.settings.certificatePrivateKey) { + credentials = new botframework_connector_1.CertificateAppCredentials(appId, this.settings.certificateThumbprint, this.settings.certificatePrivateKey, this.settings.channelAuthTenant); + } else { + if (botframework_connector_1.JwtTokenValidation.isGovernment(this.settings.channelService)) { + credentials = new botframework_connector_1.MicrosoftGovernmentAppCredentials(appId, appPassword, this.settings.channelAuthTenant, oAuthScope); + } else { + credentials = new botframework_connector_1.MicrosoftAppCredentials(appId, appPassword, this.settings.channelAuthTenant, oAuthScope); + } + } + return credentials; + }); + } + /** + * Creates an OAuth API client. + * + * @param serviceUrl The client's service URL. + * @param oAuthAppCredentials Optional. The [AppCredentials](xref:botframework-connector.AppCredentials)for OAuth. + * @remarks + * Override this in a derived class to create a mock OAuth API client for unit testing. + * @returns The client. + */ + createTokenApiClient(serviceUrl, oAuthAppCredentials) { + const tokenApiClientCredentials = oAuthAppCredentials ? oAuthAppCredentials : this.credentials; + const client = new botframework_connector_1.TokenApiClient(tokenApiClientCredentials, { baseUri: serviceUrl, userAgent: exports2.USER_AGENT }); + return client; + } + /** + * Allows for the overriding of authentication in unit tests. + * + * @param request Received request. + * @param authHeader Received authentication header. + */ + authenticateRequest(request, authHeader) { + return __awaiter2(this, void 0, void 0, function* () { + const identity = yield this.authenticateRequestInternal(request, authHeader); + if (!identity.isAuthenticated) { + throw new Error("Unauthorized Access. Request is not authorized"); + } + request.callerId = yield this.generateCallerId(identity); + }); + } + /** + * @ignore + * @private + * Returns the actual ClaimsIdentity from the JwtTokenValidation.authenticateRequest() call. + * @remarks + * This method is used instead of authenticateRequest() in processActivity() to obtain the ClaimsIdentity for caching in the TurnContext.turnState. + * + * @param request Received request. + * @param authHeader Received authentication header. + */ + authenticateRequestInternal(request, authHeader) { + return botframework_connector_1.JwtTokenValidation.authenticateRequest(request, authHeader, this.credentialsProvider, this.settings.channelService, this.authConfiguration); + } + /** + * Generates the CallerId property for the activity based on + * https://github.com/microsoft/botframework-obi/blob/main/protocols/botframework-activity/botframework-activity.md#appendix-v---caller-id-values. + * + * @param identity The inbound claims. + * @returns {Promise} a promise representing the generated callerId. + */ + generateCallerId(identity) { + return __awaiter2(this, void 0, void 0, function* () { + if (!identity) { + throw new TypeError("BotFrameworkAdapter.generateCallerId(): Missing identity parameter."); + } + const isAuthDisabled = yield this.credentialsProvider.isAuthenticationDisabled(); + if (isAuthDisabled) { + return; + } + if (botframework_connector_1.SkillValidation.isSkillClaim(identity.claims)) { + const callerId = botframework_connector_1.JwtTokenValidation.getAppIdFromClaims(identity.claims); + return `${botbuilder_core_1.CallerIdConstants.BotToBotPrefix}${callerId}`; + } + if (!this.settings.channelService || this.settings.channelService.length === 0) { + return botbuilder_core_1.CallerIdConstants.PublicAzureChannel; + } + if (botframework_connector_1.JwtTokenValidation.isGovernment(this.settings.channelService)) { + return botbuilder_core_1.CallerIdConstants.USGovChannel; + } + }); + } + /** + * Gets the OAuth API endpoint. + * + * @param contextOrServiceUrl The URL of the channel server to query or + * a [TurnContext](xref:botbuilder-core.TurnContext). For a turn context, the context's + * [activity](xref:botbuilder-core.TurnContext.activity).[serviceUrl](xref:botframework-schema.Activity.serviceUrl) + * is used for the URL. + * @returns The endpoint used for the API requests. + * @remarks + * Override this in a derived class to create a mock OAuth API endpoint for unit testing. + */ + oauthApiUrl(contextOrServiceUrl) { + return this.isEmulatingOAuthCards ? typeof contextOrServiceUrl === "object" ? contextOrServiceUrl.activity.serviceUrl : contextOrServiceUrl : this.settings.oAuthEndpoint ? this.settings.oAuthEndpoint : botframework_connector_1.JwtTokenValidation.isGovernment(this.settings.channelService) ? US_GOV_OAUTH_ENDPOINT : OAUTH_ENDPOINT; + } + /** + * Checks the environment and can set a flag to emulate OAuth cards. + * + * @param context The context object for the turn. + * @remarks + * Override this in a derived class to control how OAuth cards are emulated for unit testing. + */ + checkEmulatingOAuthCards(context) { + if (!this.isEmulatingOAuthCards && context.activity.channelId === "emulator" && !this.credentials.appId) { + this.isEmulatingOAuthCards = true; + } + } + /** + * Creates a turn context. + * + * @param request An incoming request body. + * @returns A new [TurnContext](xref:botbuilder-core.TurnContext) instance. + * @remarks + * Override this in a derived class to modify how the adapter creates a turn context. + */ + createContext(request) { + return new botbuilder_core_1.TurnContext(this, request); + } + /** + * Checks the validity of the request and attempts to map it the correct virtual endpoint, + * then generates and returns a response if appropriate. + * + * @param request A ReceiveRequest from the connected channel. + * @returns A response created by the BotAdapter to be sent to the client that originated the request. + */ + processRequest(request) { + return __awaiter2(this, void 0, void 0, function* () { + const response = new botframework_streaming_1.StreamingResponse(); + if (!request) { + response.statusCode = botbuilder_core_1.StatusCodes.BAD_REQUEST; + response.setBody("No request provided."); + return response; + } + if (!request.verb || !request.path) { + response.statusCode = botbuilder_core_1.StatusCodes.BAD_REQUEST; + response.setBody(`Request missing verb and/or path. Verb: ${request.verb}. Path: ${request.path}`); + return response; + } + if (request.verb.toLocaleUpperCase() !== streaming_1.POST && request.verb.toLocaleUpperCase() !== streaming_1.GET) { + response.statusCode = botbuilder_core_1.StatusCodes.METHOD_NOT_ALLOWED; + response.setBody(`Invalid verb received. Only GET and POST are accepted. Verb: ${request.verb}`); + } + if (request.path.toLocaleLowerCase() === streaming_1.VERSION_PATH) { + return yield this.handleVersionRequest(request, response); + } + let body; + try { + body = yield this.readRequestBodyAsString(request); + } catch (error) { + response.statusCode = botbuilder_core_1.StatusCodes.BAD_REQUEST; + response.setBody(`Request body missing or malformed: ${error}`); + return response; + } + if (request.path.toLocaleLowerCase() !== streaming_1.MESSAGES_PATH) { + response.statusCode = botbuilder_core_1.StatusCodes.NOT_FOUND; + response.setBody(`Path ${request.path.toLocaleLowerCase()} not not found. Expected ${streaming_1.MESSAGES_PATH}}.`); + return response; + } + if (request.verb.toLocaleUpperCase() !== streaming_1.POST) { + response.statusCode = botbuilder_core_1.StatusCodes.METHOD_NOT_ALLOWED; + response.setBody(`Invalid verb received for ${request.verb.toLocaleLowerCase()}. Only GET and POST are accepted. Verb: ${request.verb}`); + return response; + } + try { + const context = new botbuilder_core_1.TurnContext(this, body); + yield this.runMiddleware(context, this.logic); + if (body.type === botbuilder_core_1.ActivityTypes.Invoke) { + const invokeResponse = context.turnState.get(botbuilder_core_1.INVOKE_RESPONSE_KEY); + if (invokeResponse && invokeResponse.value) { + const value = invokeResponse.value; + response.statusCode = value.status; + if (value.body) { + response.setBody(value.body); + } + } else { + response.statusCode = botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED; + } + } else if (body.deliveryMode === botbuilder_core_1.DeliveryModes.ExpectReplies) { + const replies = { activities: context.bufferedReplyActivities }; + response.setBody(replies); + response.statusCode = botbuilder_core_1.StatusCodes.OK; + } else { + response.statusCode = botbuilder_core_1.StatusCodes.OK; + } + } catch (error) { + response.statusCode = botbuilder_core_1.StatusCodes.INTERNAL_SERVER_ERROR; + response.setBody(error); + return response; + } + return response; + }); + } + /** + * @internal + */ + process(req, resOrSocket, logicOrHead, maybeLogic) { + return __awaiter2(this, void 0, void 0, function* () { + if (maybeLogic) { + return this.useWebSocket(req, zod_1.INodeSocketT.parse(resOrSocket), zod_1.INodeBufferT.parse(logicOrHead), zod_1.LogicT.parse(maybeLogic)); + } else { + return this.processActivity(req, interfaces_1.ResponseT.parse(resOrSocket), zod_1.LogicT.parse(logicOrHead)); + } + }); + } + /** + * Connects the handler to a Named Pipe server and begins listening for incoming requests. + * + * @param logic The logic that will handle incoming requests. + * @param pipeName The name of the named pipe to use when creating the server. + * @param retryCount Number of times to attempt to bind incoming and outgoing pipe + * @param onListen Optional callback that fires once when server is listening on both incoming and outgoing pipe + */ + useNamedPipe(logic, pipeName = streaming_1.defaultPipeName, retryCount = 7, onListen) { + return __awaiter2(this, void 0, void 0, function* () { + if (!logic) { + throw new Error("Bot logic needs to be provided to `useNamedPipe`"); + } + if (this.isStreamingConnectionOpen) { + if (this.namedPipeName === pipeName) { + return; + } else { + throw new Error("This BotFrameworkAdapter instance is already connected to a different stream. Use a new instance to connect to the provided pipeName."); + } + } + this.logic = logic; + yield (0, botbuilder_stdlib_1.retry)(() => this.startNamedPipeServer(pipeName, onListen), retryCount); + }); + } + /** + * Process the initial request to establish a long lived connection via a streaming server. + * + * @param req The connection request. + * @param socket The raw socket connection between the bot (server) and channel/caller (client). + * @param head The first packet of the upgraded stream. + * @param logic The logic that handles incoming streaming requests for the lifetime of the WebSocket connection. + */ + useWebSocket(req, socket, head, logic) { + return __awaiter2(this, void 0, void 0, function* () { + const webSocketFactory = this.webSocketFactory || new botframework_streaming_1.NodeWebSocketFactory(); + if (!logic) { + throw new Error("Streaming logic needs to be provided to `useWebSocket`"); + } + this.logic = logic; + try { + yield this.authenticateConnection(req, this.settings.channelService); + } catch (err) { + abortWebSocketUpgrade(socket, err); + throw err; + } + const nodeWebSocket = yield webSocketFactory.createWebSocket(req, socket, head); + yield this.startWebSocket(nodeWebSocket); + }); + } + startNamedPipeServer(pipeName, onListen) { + return __awaiter2(this, void 0, void 0, function* () { + this.namedPipeName = pipeName; + this.streamingServer = new botframework_streaming_1.NamedPipeServer(pipeName, this); + try { + yield this.streamingServer.start(onListen); + } finally { + this.namedPipeName = void 0; + } + }); + } + authenticateConnection(req, channelService) { + return __awaiter2(this, void 0, void 0, function* () { + if (!this.credentials.appId) { + return; + } + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + const channelIdHeader = req.headers.channelid || req.headers.ChannelId || req.headers.ChannelID || ""; + const claims = yield botframework_connector_1.JwtTokenValidation.validateAuthHeader(authHeader, this.credentialsProvider, channelService, channelIdHeader); + if (!claims.isAuthenticated) { + throw new botframework_connector_1.AuthenticationError("Unauthorized Access. Request is not authorized", botbuilder_core_1.StatusCodes.UNAUTHORIZED); + } + }); + } + /** + * Connects the handler to a WebSocket server and begins listening for incoming requests. + * + * @param socket The socket to use when creating the server. + */ + startWebSocket(socket) { + return __awaiter2(this, void 0, void 0, function* () { + this.streamingServer = new botframework_streaming_1.WebSocketServer(socket, this); + yield this.streamingServer.start(); + }); + } + readRequestBodyAsString(request) { + return __awaiter2(this, void 0, void 0, function* () { + const [activityStream, ...attachmentStreams] = request.streams; + const activity = yield activityStream.readAsJson(); + activity.attachments = yield Promise.all(attachmentStreams.map((attachmentStream) => __awaiter2(this, void 0, void 0, function* () { + const contentType = attachmentStream.contentType; + const content = contentType === "application/json" ? yield attachmentStream.readAsJson() : yield attachmentStream.readAsString(); + return { contentType, content }; + }))); + return activity; + }); + } + handleVersionRequest(request, response) { + return __awaiter2(this, void 0, void 0, function* () { + if (request.verb.toLocaleUpperCase() === streaming_1.GET) { + response.statusCode = botbuilder_core_1.StatusCodes.OK; + if (!this.credentials.appId) { + response.setBody({ UserAgent: exports2.USER_AGENT }); + return response; + } + let token = ""; + try { + token = yield this.credentials.getToken(); + } catch (err) { + console.error(err.message); + } + response.setBody({ UserAgent: exports2.USER_AGENT, BotToken: token }); + } else { + response.statusCode = botbuilder_core_1.StatusCodes.METHOD_NOT_ALLOWED; + response.setBody(`Invalid verb received for path: ${request.path}. Only GET is accepted. Verb: ${request.verb}`); + } + return response; + }); + } + /** + * Determine if the serviceUrl was sent via an Http/Https connection or Streaming + * This can be determined by looking at the ServiceUrl property: + * (1) All channels that send messages via http/https are not streaming + * (2) Channels that send messages via streaming have a ServiceUrl that does not begin with http/https. + * + * @param serviceUrl the serviceUrl provided in the resquest. + * @returns True if the serviceUrl is a streaming url, otherwise false. + */ + static isStreamingServiceUrl(serviceUrl) { + return serviceUrl && !serviceUrl.toLowerCase().startsWith("http"); + } + }; + exports2.BotFrameworkAdapter = BotFrameworkAdapter; + function parseRequest(req) { + return new Promise((resolve, reject) => { + if (req.body) { + try { + const activity = (0, activityValidator_1.validateAndFixActivity)(req.body); + resolve(activity); + } catch (err) { + reject(err); + } + } else { + let requestData = ""; + req.on("data", (chunk) => { + requestData += chunk; + }); + req.on("end", () => { + try { + req.body = JSON.parse(requestData); + const activity = (0, activityValidator_1.validateAndFixActivity)(req.body); + resolve(activity); + } catch (err) { + reject(err); + } + }); + } + }); + } + function abortWebSocketUpgrade(socket, err) { + if (socket.writable) { + const connectionHeader = "Connection: 'close'\r\n"; + let message = ""; + if (botframework_connector_1.AuthenticationError.isStatusCodeError(err)) { + message = `HTTP/1.1 ${err.statusCode} ${botbuilder_core_1.StatusCodes[err.statusCode]}\r +${err.message}\r +${connectionHeader}\r +`; + } else { + message = botframework_connector_1.AuthenticationError.determineStatusCodeAndBuildMessage(err); + } + socket.write(message); + } + socket.destroy(); + } + } +}); + +// node_modules/botbuilder/lib/botFrameworkHttpClient.js +var require_botFrameworkHttpClient = __commonJS({ + "node_modules/botbuilder/lib/botFrameworkHttpClient.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.BotFrameworkHttpClient = void 0; + var axios_1 = __importDefault2(require_axios()); + var botbuilder_core_1 = require_lib10(); + var botframework_connector_1 = require_lib9(); + var botFrameworkAdapter_1 = require_botFrameworkAdapter(); + var BotFrameworkHttpClient = class _BotFrameworkHttpClient { + /** + * Creates a new instance of the [BotFrameworkHttpClient](xref:botbuilder.BotFrameworkHttpClient) class + * + * @param credentialProvider An instance of [ICredentialProvider](xref:botframework-connector.ICredentialProvider). + * @param channelService Optional. The channel service. + */ + constructor(credentialProvider, channelService) { + if (!credentialProvider) { + throw new Error("BotFrameworkHttpClient(): missing credentialProvider"); + } + this.credentialProvider = credentialProvider; + this.channelService = channelService || process.env[botframework_connector_1.AuthenticationConstants.ChannelService]; + } + /** + * Forwards an activity to another bot. + * + * @remarks + * @template T The type of body in the InvokeResponse. + * @param fromBotId The MicrosoftAppId of the bot sending the activity. + * @param toBotId The MicrosoftAppId of the bot receiving the activity. + * @param toUrl The URL of the bot receiving the activity. + * @param serviceUrl The callback Url for the skill host. + * @param conversationId A conversation ID to use for the conversation with the skill. + * @param activity Activity to forward. + * @returns {Promise>} A promise representing the asynchronous operation. + */ + postActivity(fromBotId, toBotId, toUrl, serviceUrl, conversationId, activity) { + return __awaiter2(this, void 0, void 0, function* () { + const appCredentials = yield this.getAppCredentials(fromBotId, toBotId); + if (!appCredentials) { + throw new Error("BotFrameworkHttpClient.postActivity(): Unable to get appCredentials to connect to the skill"); + } + if (!activity) { + throw new Error("BotFrameworkHttpClient.postActivity(): missing activity"); + } + if (activity.conversation === void 0) { + throw new Error("BotFrameworkHttpClient.postActivity(): Activity must have a ConversationReference"); + } + const token = appCredentials.appId ? yield appCredentials.getToken() : null; + const originalConversationId = activity.conversation.id; + const originalServiceUrl = activity.serviceUrl; + const originalRelatesTo = activity.relatesTo; + const originalRecipient = activity.recipient; + try { + activity.relatesTo = { + serviceUrl: activity.serviceUrl, + activityId: activity.id, + channelId: activity.channelId, + conversation: { + id: activity.conversation.id, + name: activity.conversation.name, + conversationType: activity.conversation.conversationType, + aadObjectId: activity.conversation.aadObjectId, + isGroup: activity.conversation.isGroup, + properties: activity.conversation.properties, + role: activity.conversation.role, + tenantId: activity.conversation.tenantId + }, + bot: null + }; + activity.conversation.id = conversationId; + activity.serviceUrl = serviceUrl; + if (!activity.recipient) { + activity.recipient = {}; + } + activity.recipient.role = botbuilder_core_1.RoleTypes.Skill; + const config = { + headers: { + Accept: "application/json", + [botframework_connector_1.ConversationConstants.ConversationIdHttpHeaderName]: conversationId, + "Content-Type": "application/json", + "User-Agent": botFrameworkAdapter_1.USER_AGENT + }, + validateStatus: () => true + }; + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + const response = yield axios_1.default.post(toUrl, activity, config); + return { status: response.status, body: response.data }; + } finally { + activity.conversation.id = originalConversationId; + activity.serviceUrl = originalServiceUrl; + activity.relatesTo = originalRelatesTo; + activity.recipient = originalRecipient; + } + }); + } + /** + * Logic to build an [AppCredentials](xref:botframework-connector.AppCredentials) to be used to acquire tokens for this `HttpClient`. + * + * @param appId The application id. + * @param oAuthScope Optional. The OAuth scope. + * @returns The app credentials to be used to acquire tokens. + */ + buildCredentials(appId, oAuthScope) { + return __awaiter2(this, void 0, void 0, function* () { + const appPassword = yield this.credentialProvider.getAppPassword(appId); + if (botframework_connector_1.JwtTokenValidation.isGovernment(this.channelService)) { + return new botframework_connector_1.MicrosoftGovernmentAppCredentials(appId, appPassword, void 0, oAuthScope); + } else { + return new botframework_connector_1.MicrosoftAppCredentials(appId, appPassword, void 0, oAuthScope); + } + }); + } + /** + * Gets the application credentials. App Credentials are cached so as to ensure we are not refreshing + * token every time. + * @private + * @param appId The application identifier (AAD Id for the bot). + * @param oAuthScope The scope for the token, skills will use the Skill App Id. + */ + getAppCredentials(appId, oAuthScope) { + return __awaiter2(this, void 0, void 0, function* () { + if (!appId) { + return new botframework_connector_1.MicrosoftAppCredentials("", ""); + } + const cacheKey = `${appId}${oAuthScope}`; + let appCredentials = _BotFrameworkHttpClient.appCredentialMapCache.get(cacheKey); + if (appCredentials) { + return appCredentials; + } + appCredentials = yield this.buildCredentials(appId, oAuthScope); + _BotFrameworkHttpClient.appCredentialMapCache.set(cacheKey, appCredentials); + return appCredentials; + }); + } + }; + exports2.BotFrameworkHttpClient = BotFrameworkHttpClient; + BotFrameworkHttpClient.appCredentialMapCache = /* @__PURE__ */ new Map(); + } +}); + +// node_modules/botbuilder/lib/skills/skillHttpClient.js +var require_skillHttpClient = __commonJS({ + "node_modules/botbuilder/lib/skills/skillHttpClient.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SkillHttpClient = void 0; + var botbuilder_core_1 = require_lib10(); + var botframework_connector_1 = require_lib9(); + var botFrameworkHttpClient_1 = require_botFrameworkHttpClient(); + var SkillHttpClient = class extends botFrameworkHttpClient_1.BotFrameworkHttpClient { + /** + * Creates a new instance of the [SkillHttpClient](xref:botbuilder-core.SkillHttpClient) class. + * + * @param credentialProvider An instance of [ICredentialProvider](xref:botframework-connector.ICredentialProvider). + * @param conversationIdFactory An instance of a class derived from [SkillConversationIdFactoryBase](xref:botbuilder-core.SkillConversationIdFactoryBase). + * @param channelService Optional. The channel service. + */ + constructor(credentialProvider, conversationIdFactory, channelService) { + super(credentialProvider, channelService); + if (!conversationIdFactory) { + throw new Error("conversationIdFactory missing"); + } + this.conversationIdFactory = conversationIdFactory; + } + /** + * Uses the `SkillConversationIdFactory` to create or retrieve a Skill Conversation Id, and sends the [Activity](xref:botframework-schema.Activity). + * + * @param audienceOrFromBotId The OAuth audience scope, used during token retrieval or the AppId of the bot sending the [Activity](xref:botframework-schema.Activity). + * @param fromBotIdOrSkill The AppId of the bot sending the [Activity](xref:botframework-schema.Activity) or the skill to create the Conversation Id for. + * @param toSkillOrCallbackUrl The skill to create the Conversation Id for or the callback Url for the skill host. + * @param callbackUrlOrActivity The callback Url for the skill host or the [Activity](xref:botframework-schema.Activity) to send. + * @param activityToForward Optional. The [Activity](xref:botframework-schema.Activity) to forward. + * @returns A `Promise` representing the [InvokeResponse](xref:botbuilder-core.InvokeResponse) for the operation. + */ + postToSkill(audienceOrFromBotId, fromBotIdOrSkill, toSkillOrCallbackUrl, callbackUrlOrActivity, activityToForward) { + return __awaiter2(this, void 0, void 0, function* () { + let originatingAudience; + let fromBotId; + if (typeof fromBotIdOrSkill === "string") { + fromBotId = fromBotIdOrSkill; + originatingAudience = audienceOrFromBotId; + } else { + fromBotId = audienceOrFromBotId; + originatingAudience = botframework_connector_1.JwtTokenValidation.isGovernment(this.channelService) ? botframework_connector_1.GovernmentConstants.ToChannelFromBotOAuthScope : botframework_connector_1.AuthenticationConstants.ToChannelFromBotOAuthScope; + } + const toSkill = typeof toSkillOrCallbackUrl === "object" ? toSkillOrCallbackUrl : fromBotIdOrSkill; + const callbackUrl = typeof callbackUrlOrActivity === "string" ? callbackUrlOrActivity : toSkillOrCallbackUrl; + const activity = typeof activityToForward === "object" ? activityToForward : callbackUrlOrActivity; + let skillConversationId; + try { + const createIdOptions = { + activity, + botFrameworkSkill: toSkill, + fromBotId, + fromBotOAuthScope: originatingAudience + }; + skillConversationId = yield this.conversationIdFactory.createSkillConversationIdWithOptions(createIdOptions); + } catch (err) { + if (err.message === "Not Implemented") { + skillConversationId = yield this.conversationIdFactory.createSkillConversationId(botbuilder_core_1.TurnContext.getConversationReference(activity)); + } else { + throw err; + } + } + return yield this.postActivity(fromBotId, toSkill.appId, toSkill.skillEndpoint, callbackUrl, skillConversationId, activity); + }); + } + }; + exports2.SkillHttpClient = SkillHttpClient; + } +}); + +// node_modules/botbuilder/lib/cloudChannelServiceHandler.js +var require_cloudChannelServiceHandler = __commonJS({ + "node_modules/botbuilder/lib/cloudChannelServiceHandler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CloudChannelServiceHandler = void 0; + var channelServiceHandlerBase_1 = require_channelServiceHandlerBase(); + var CloudChannelServiceHandler = class extends channelServiceHandlerBase_1.ChannelServiceHandlerBase { + /** + * @param auth Bot framework authentication + */ + constructor(auth) { + super(); + this.auth = auth; + } + authenticate(authHeader) { + return __awaiter2(this, void 0, void 0, function* () { + return this.auth.authenticateChannelRequest(authHeader); + }); + } + }; + exports2.CloudChannelServiceHandler = CloudChannelServiceHandler; + } +}); + +// node_modules/botbuilder/lib/skills/cloudSkillHandler.js +var require_cloudSkillHandler = __commonJS({ + "node_modules/botbuilder/lib/skills/cloudSkillHandler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CloudSkillHandler = void 0; + var cloudChannelServiceHandler_1 = require_cloudChannelServiceHandler(); + var skillHandlerImpl_1 = require_skillHandlerImpl(); + var botbuilder_core_1 = require_lib10(); + var CloudSkillHandler = class extends cloudChannelServiceHandler_1.CloudChannelServiceHandler { + /** + * Initializes a new instance of the CloudSkillHandler class. + * + * @param adapter An instance of the BotAdapter that will handle the request. + * @param logic The Bot logic function + * @param conversationIdFactory A SkillConversationIdFactoryBase to unpack the conversation ID and map it to the calling bot. + * @param auth Bot Framework Authentication to use + */ + constructor(adapter, logic, conversationIdFactory, auth) { + super(auth); + this.SkillConversationReferenceKey = botbuilder_core_1.SkillConversationReferenceKey; + if (!adapter) { + throw new Error("missing adapter."); + } + if (!logic) { + throw new Error("missing logic."); + } + if (!conversationIdFactory) { + throw new Error("missing conversationIdFactory."); + } + this.inner = new skillHandlerImpl_1.SkillHandlerImpl(this.SkillConversationReferenceKey, adapter, logic, conversationIdFactory, () => auth.getOriginatingAudience()); + } + /** + * sendToConversation() API for Skill. + * + * @remarks + * This method allows you to send an activity to the end of a conversation. + * + * This is slightly different from replyToActivity(). + * - sendToConversation(conversationId) - will append the activity to the end + * of the conversation according to the timestamp or semantics of the channel. + * - replyToActivity(conversationId,ActivityId) - adds the activity as a reply + * to another activity, if the channel supports it. If the channel does not + * support nested replies, replyToActivity falls back to sendToConversation. + * + * Use replyToActivity when replying to a specific activity in the conversation. + * + * Use sendToConversation in all other cases. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param conversationId Conversation ID. + * @param activity Activity to send. + * @returns A Promise with a ResourceResponse. + */ + onSendToConversation(claimsIdentity, conversationId, activity) { + return this.inner.onSendToConversation(claimsIdentity, conversationId, activity); + } + /** + * replyToActivity() API for Skill. + * + * @remarks + * This method allows you to reply to an activity. + * + * This is slightly different from sendToConversation(). + * - sendToConversation(conversationId) - will append the activity to the end + * of the conversation according to the timestamp or semantics of the channel. + * - replyToActivity(conversationId,ActivityId) - adds the activity as a reply + * to another activity, if the channel supports it. If the channel does not + * support nested replies, replyToActivity falls back to sendToConversation. + * + * Use replyToActivity when replying to a specific activity in the conversation. + * + * Use sendToConversation in all other cases. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param conversationId Conversation ID. + * @param activityId activityId the reply is to. + * @param activity Activity to send. + * @returns A Promise with a ResourceResponse. + */ + onReplyToActivity(claimsIdentity, conversationId, activityId, activity) { + return this.inner.onReplyToActivity(claimsIdentity, conversationId, activityId, activity); + } + /** + * + * UpdateActivity() API for Skill. + * + * @remarks + * Edit an existing activity. + * + * Some channels allow you to edit an existing activity to reflect the new + * state of a bot conversation. + * + * For example, you can remove buttons after someone has clicked "Approve" button. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param conversationId Conversation ID. + * @param activityId activityId to update. + * @param activity replacement Activity. + * @returns a promise resolving to the underlying resource response + */ + onUpdateActivity(claimsIdentity, conversationId, activityId, activity) { + return this.inner.onUpdateActivity(claimsIdentity, conversationId, activityId, activity); + } + /** + * DeleteActivity() API for Skill. + * + * @remarks + * Delete an existing activity. + * + * Some channels allow you to delete an existing activity, and if successful + * this method will remove the specified activity. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param conversationId Conversation ID. + * @param activityId activityId to delete. + * @returns a promise representing the async operation + */ + onDeleteActivity(claimsIdentity, conversationId, activityId) { + return __awaiter2(this, void 0, void 0, function* () { + return this.inner.onDeleteActivity(claimsIdentity, conversationId, activityId); + }); + } + /** + * getConversationMember() API for Skill. + * + * @remarks + * Get the account of a single conversation member. + * + * This REST API takes a ConversationId and UserId and returns the ChannelAccount + * object representing the member of the conversation. + * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim. + * @param userId User ID. + * @param conversationId Conversation ID. + * @returns The ChannelAccount object representing the member of the conversation. + */ + onGetConversationMember(claimsIdentity, userId, conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + return this.inner.onGetMember(claimsIdentity, userId, conversationId); + }); + } + }; + exports2.CloudSkillHandler = CloudSkillHandler; + } +}); + +// node_modules/botbuilder/lib/skills/index.js +var require_skills2 = __commonJS({ + "node_modules/botbuilder/lib/skills/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CloudSkillHandler = void 0; + __exportStar2(require_skillHandler(), exports2); + __exportStar2(require_skillHttpClient(), exports2); + var cloudSkillHandler_1 = require_cloudSkillHandler(); + Object.defineProperty(exports2, "CloudSkillHandler", { enumerable: true, get: function() { + return cloudSkillHandler_1.CloudSkillHandler; + } }); + } +}); + +// node_modules/botbuilder/lib/teams/teamsSSOTokenExchangeMiddleware.js +var require_teamsSSOTokenExchangeMiddleware = __commonJS({ + "node_modules/botbuilder/lib/teams/teamsSSOTokenExchangeMiddleware.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TeamsSSOTokenExchangeMiddleware = void 0; + var z = __importStar2(require_zod()); + var botbuilder_core_1 = require_lib10(); + function getStorageKey(context) { + var _a; + const activity = context.activity; + const channelId = activity.channelId; + if (!channelId) { + throw new Error("invalid activity. Missing channelId"); + } + const conversationId = (_a = activity.conversation) === null || _a === void 0 ? void 0 : _a.id; + if (!conversationId) { + throw new Error("invalid activity. Missing conversation.id"); + } + const value = activity.value; + if (!(value === null || value === void 0 ? void 0 : value.id)) { + throw new Error("Invalid signin/tokenExchange. Missing activity.value.id."); + } + return `${channelId}/${conversationId}/${value.id}`; + } + function sendInvokeResponse(context, body = null, status = botbuilder_core_1.StatusCodes.OK) { + return __awaiter2(this, void 0, void 0, function* () { + yield context.sendActivity({ + type: botbuilder_core_1.ActivityTypes.InvokeResponse, + value: { body, status } + }); + }); + } + var ExchangeToken = z.custom((val) => typeof val.exchangeToken === "function", { message: "ExtendedUserTokenProvider" }); + var TeamsSSOTokenExchangeMiddleware = class { + /** + * Initializes a new instance of the TeamsSSOTokenExchangeMiddleware class. + * + * @param storage The [Storage](xref:botbuilder-core.Storage) to use for deduplication + * @param oAuthConnectionName The connection name to use for the single sign on token exchange + */ + constructor(storage, oAuthConnectionName) { + this.storage = storage; + this.oAuthConnectionName = oAuthConnectionName; + if (!storage) { + throw new TypeError("`storage` parameter is required"); + } + if (!oAuthConnectionName) { + throw new TypeError("`oAuthConnectionName` parameter is required"); + } + } + /** + * Called each time the bot receives a new request. + * + * @param context Context for current turn of conversation with the user. + * @param next Function to call to continue execution to the next step in the middleware chain. + */ + onTurn(context, next) { + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.channelId === botbuilder_core_1.Channels.Msteams && context.activity.name === botbuilder_core_1.tokenExchangeOperationName) { + if (!(yield this.exchangedToken(context))) { + return; + } + if (!(yield this.deduplicatedTokenExchangeId(context))) { + return; + } + } + yield next(); + }); + } + deduplicatedTokenExchangeId(context) { + var _a, _b; + return __awaiter2(this, void 0, void 0, function* () { + const storeItem = { + eTag: (_a = context.activity.value) === null || _a === void 0 ? void 0 : _a.id + }; + try { + yield this.storage.write({ + [getStorageKey(context)]: storeItem + }); + } catch (err) { + const message = (_b = err.message) === null || _b === void 0 ? void 0 : _b.toLowerCase(); + if (message.includes("etag conflict") || message.includes("precondition is not met")) { + yield sendInvokeResponse(context); + return false; + } + throw err; + } + return true; + }); + } + exchangedToken(context) { + return __awaiter2(this, void 0, void 0, function* () { + let tokenExchangeResponse; + const tokenExchangeRequest = context.activity.value; + try { + const userTokenClient = context.turnState.get(context.adapter.UserTokenClientKey); + const exchangeToken = ExchangeToken.safeParse(context.adapter); + if (userTokenClient) { + tokenExchangeResponse = yield userTokenClient.exchangeToken(context.activity.from.id, this.oAuthConnectionName, context.activity.channelId, { token: tokenExchangeRequest.token }); + } else if (exchangeToken.success) { + tokenExchangeResponse = yield exchangeToken.data.exchangeToken(context, this.oAuthConnectionName, context.activity.from.id, { token: tokenExchangeRequest.token }); + } else { + new Error("Token Exchange is not supported by the current adapter."); + } + } catch (_err) { + } + if (!(tokenExchangeResponse === null || tokenExchangeResponse === void 0 ? void 0 : tokenExchangeResponse.token)) { + const invokeResponse = { + id: tokenExchangeRequest.id, + connectionName: this.oAuthConnectionName, + failureDetail: "The bot is unable to exchange token. Proceed with regular login." + }; + yield sendInvokeResponse(context, invokeResponse, botbuilder_core_1.StatusCodes.PRECONDITION_FAILED); + return false; + } + return true; + }); + } + }; + exports2.TeamsSSOTokenExchangeMiddleware = TeamsSSOTokenExchangeMiddleware; + } +}); + +// node_modules/botbuilder/lib/teams/index.js +var require_teams4 = __commonJS({ + "node_modules/botbuilder/lib/teams/index.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TeamsSSOTokenExchangeMiddleware = void 0; + var teamsSSOTokenExchangeMiddleware_1 = require_teamsSSOTokenExchangeMiddleware(); + Object.defineProperty(exports2, "TeamsSSOTokenExchangeMiddleware", { enumerable: true, get: function() { + return teamsSSOTokenExchangeMiddleware_1.TeamsSSOTokenExchangeMiddleware; + } }); + } +}); + +// node_modules/botbuilder/lib/cloudAdapter.js +var require_cloudAdapter = __commonJS({ + "node_modules/botbuilder/lib/cloudAdapter.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.CloudAdapter = void 0; + var z = __importStar2(require_zod()); + var botbuilder_core_1 = require_lib10(); + var streaming_1 = require_streaming(); + var azureCoreHttpCompat_1 = require_azureCoreHttpCompat(); + var zod_1 = require_zod2(); + var interfaces_1 = require_interfaces3(); + var botFrameworkAdapter_1 = require_botFrameworkAdapter(); + var botbuilder_stdlib_1 = require_lib5(); + var activityValidator_1 = require_activityValidator(); + var botframework_connector_1 = require_lib9(); + var botframework_streaming_1 = require_lib18(); + var ActivityT = z.custom((val) => z.record(z.unknown()).safeParse(val).success, { message: "Activity" }); + var CloudAdapter = class extends botbuilder_core_1.CloudAdapterBase { + /** + * Initializes a new instance of the [CloudAdapter](xref:botbuilder:CloudAdapter) class. + * + * @param botFrameworkAuthentication Optional [BotFrameworkAuthentication](xref:botframework-connector.BotFrameworkAuthentication) instance + */ + constructor(botFrameworkAuthentication = botframework_connector_1.BotFrameworkAuthenticationFactory.create()) { + super(botFrameworkAuthentication); + } + /** + * @internal + */ + process(req, resOrSocket, logicOrHead, maybeLogic) { + var _a, _b, _c, _d; + return __awaiter2(this, void 0, void 0, function* () { + if (maybeLogic) { + const socket = zod_1.INodeSocketT.parse(resOrSocket); + const head = zod_1.INodeBufferT.parse(logicOrHead); + const logic2 = zod_1.LogicT.parse(maybeLogic); + return this.connect(req, socket, head, logic2); + } + const res = interfaces_1.ResponseT.parse(resOrSocket); + const logic = zod_1.LogicT.parse(logicOrHead); + const end = (status, body) => { + res.status(status); + if (body) { + res.send(body); + } + res.end(); + }; + if (req.method !== "POST") { + return end(botbuilder_core_1.StatusCodes.METHOD_NOT_ALLOWED); + } + if (!z.record(z.unknown()).safeParse(req.body).success) { + return end(botbuilder_core_1.StatusCodes.BAD_REQUEST, "`req.body` not an object, make sure you are using middleware to parse incoming requests."); + } + const activity = (0, activityValidator_1.validateAndFixActivity)(ActivityT.parse(req.body)); + if (!activity.type) { + console.warn("BadRequest: Missing activity or activity type."); + return end(botbuilder_core_1.StatusCodes.BAD_REQUEST); + } + const authHeader = z.string().parse((_b = (_a = req.headers.Authorization) !== null && _a !== void 0 ? _a : req.headers.authorization) !== null && _b !== void 0 ? _b : ""); + try { + const invokeResponse = yield this.processActivity(authHeader, activity, logic); + return end((_c = invokeResponse === null || invokeResponse === void 0 ? void 0 : invokeResponse.status) !== null && _c !== void 0 ? _c : botbuilder_core_1.StatusCodes.OK, invokeResponse === null || invokeResponse === void 0 ? void 0 : invokeResponse.body); + } catch (err) { + console.error(err); + return end(err instanceof botframework_connector_1.AuthenticationError ? botbuilder_core_1.StatusCodes.UNAUTHORIZED : botbuilder_core_1.StatusCodes.INTERNAL_SERVER_ERROR, (_d = err.message) !== null && _d !== void 0 ? _d : err); + } + }); + } + /** + * Asynchronously process an activity running the provided logic function. + * + * @param authorization The authorization header in the format: "Bearer [longString]" or the AuthenticateRequestResult for this turn. + * @param activity The activity to process. + * @param logic The logic function to apply. + * @returns a promise representing the asynchronous operation. + */ + processActivityDirect(authorization, activity, logic) { + return __awaiter2(this, void 0, void 0, function* () { + try { + yield this.processActivity(authorization, activity, logic); + } catch (err) { + throw new Error(`CloudAdapter.processActivityDirect(): ERROR + ${err.stack}`); + } + }); + } + /** + * Used to connect the adapter to a named pipe. + * + * @param pipeName Pipe name to connect to (note: yields two named pipe servers by appending ".incoming" and ".outgoing" to this name) + * @param logic The logic function to call for resulting bot turns. + * @param appId The Bot application ID + * @param audience The audience to use for outbound communication. The will vary by cloud environment. + * @param callerId Optional, the caller ID + * @param retryCount Optional, the number of times to retry a failed connection (defaults to 7) + */ + connectNamedPipe(pipeName, logic, appId, audience, callerId, retryCount = 7) { + return __awaiter2(this, void 0, void 0, function* () { + z.object({ + pipeName: z.string(), + logic: zod_1.LogicT, + appId: z.string(), + audience: z.string(), + callerId: z.string().optional() + }).parse({ pipeName, logic, appId, audience, callerId }); + const authenticateRequestResult = { + audience, + callerId, + claimsIdentity: appId ? this.createClaimsIdentity(appId) : new botframework_connector_1.ClaimsIdentity([]) + }; + const requestHandler = new StreamingRequestHandler(authenticateRequestResult, (authenticateRequestResult2, activity) => this.processActivity(authenticateRequestResult2, activity, logic)); + const server2 = new botframework_streaming_1.NamedPipeServer(pipeName, requestHandler); + requestHandler.server = server2; + yield (0, botbuilder_stdlib_1.retry)(() => server2.start(), retryCount); + }); + } + connect(req, socket, head, logic) { + var _a, _b; + return __awaiter2(this, void 0, void 0, function* () { + const authHeader = z.string().parse((_b = (_a = req.headers.Authorization) !== null && _a !== void 0 ? _a : req.headers.authorization) !== null && _b !== void 0 ? _b : ""); + const channelIdHeader = z.string().optional().parse(req.headers.channelid); + const authenticateRequestResult = yield this.botFrameworkAuthentication.authenticateStreamingRequest(authHeader, channelIdHeader); + const requestHandler = new StreamingRequestHandler(authenticateRequestResult, (authenticateRequestResult2, activity) => this.processActivity(authenticateRequestResult2, activity, logic)); + const server2 = new botframework_streaming_1.WebSocketServer(yield new botframework_streaming_1.NodeWebSocketFactory().createWebSocket(req, socket, head), requestHandler); + requestHandler.server = server2; + yield server2.start(); + }); + } + }; + exports2.CloudAdapter = CloudAdapter; + var StreamingRequestHandler = class extends botframework_streaming_1.RequestHandler { + // Note: `processActivity` lambda is to work around the fact that CloudAdapterBase#processActivity + // is protected, and we can't get around that by defining classes inside of other classes + constructor(authenticateRequestResult, processActivity) { + super(); + this.authenticateRequestResult = authenticateRequestResult; + this.processActivity = processActivity; + this.authenticateRequestResult.connectorFactory = new StreamingConnectorFactory(this); + } + processRequest(request) { + var _a, _b; + return __awaiter2(this, void 0, void 0, function* () { + const response = new botframework_streaming_1.StreamingResponse(); + const end = (statusCode, body) => { + response.statusCode = statusCode; + if (body) { + response.setBody(body); + } + return response; + }; + if (!request) { + return end(botbuilder_core_1.StatusCodes.BAD_REQUEST, "No request provided."); + } + if (!request.verb || !request.path) { + return end(botbuilder_core_1.StatusCodes.BAD_REQUEST, `Request missing verb and/or path. Verb: ${request.verb}, Path: ${request.path}`); + } + if (request.verb.toUpperCase() !== streaming_1.POST && request.verb.toUpperCase() !== streaming_1.GET) { + return end(botbuilder_core_1.StatusCodes.METHOD_NOT_ALLOWED, `Invalid verb received. Only GET and POST are accepted. Verb: ${request.verb}`); + } + if (request.path.toLowerCase() === streaming_1.VERSION_PATH) { + if (request.verb.toUpperCase() === streaming_1.GET) { + return end(botbuilder_core_1.StatusCodes.OK, { UserAgent: botFrameworkAdapter_1.USER_AGENT }); + } else { + return end(botbuilder_core_1.StatusCodes.METHOD_NOT_ALLOWED, `Invalid verb received for path: ${request.path}. Only GET is accepted. Verb: ${request.verb}`); + } + } + const [activityStream, ...attachmentStreams] = request.streams; + let activity; + try { + activity = (0, activityValidator_1.validateAndFixActivity)(ActivityT.parse(yield activityStream.readAsJson())); + activity.attachments = yield Promise.all(attachmentStreams.map((attachmentStream) => __awaiter2(this, void 0, void 0, function* () { + const contentType = attachmentStream.contentType; + const content = contentType === "application/json" ? yield attachmentStream.readAsJson() : yield attachmentStream.readAsString(); + return { contentType, content }; + }))); + } catch (err) { + return end(botbuilder_core_1.StatusCodes.BAD_REQUEST, `Request body missing or malformed: ${err}`); + } + try { + const invokeResponse = yield this.processActivity(this.authenticateRequestResult, activity); + return end((_a = invokeResponse === null || invokeResponse === void 0 ? void 0 : invokeResponse.status) !== null && _a !== void 0 ? _a : botbuilder_core_1.StatusCodes.OK, invokeResponse === null || invokeResponse === void 0 ? void 0 : invokeResponse.body); + } catch (err) { + return end(botbuilder_core_1.StatusCodes.INTERNAL_SERVER_ERROR, (_b = err.message) !== null && _b !== void 0 ? _b : err); + } + }); + } + }; + var StreamingConnectorFactory = class { + constructor(requestHandler) { + this.requestHandler = requestHandler; + } + create(serviceUrl, _audience) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + (_a = this.serviceUrl) !== null && _a !== void 0 ? _a : this.serviceUrl = serviceUrl; + if (serviceUrl !== this.serviceUrl) { + throw new Error("This is a streaming scenario, all connectors from this factory must all be for the same url."); + } + const httpClient = new StreamingHttpClient(this.requestHandler); + return new botframework_connector_1.ConnectorClient(botframework_connector_1.MicrosoftAppCredentials.Empty, { httpClient }); + }); + } + }; + var StreamingHttpClient = class { + constructor(requestHandler) { + this.requestHandler = requestHandler; + } + sendRequest(httpRequest) { + var _a; + return __awaiter2(this, void 0, void 0, function* () { + const streamingRequest = this.createStreamingRequest(httpRequest); + const receiveResponse = yield (_a = this.requestHandler.server) === null || _a === void 0 ? void 0 : _a.send(streamingRequest); + return this.createHttpResponse(receiveResponse, httpRequest); + }); + } + createStreamingRequest(httpRequest) { + const verb = httpRequest.method.toString(); + const path3 = httpRequest.url.slice(httpRequest.url.indexOf("/v3")); + const request = botframework_streaming_1.StreamingRequest.create(verb, path3); + request.setBody(httpRequest.body); + return request; + } + createHttpResponse(receiveResponse, httpRequest) { + var _a, _b, _c; + return __awaiter2(this, void 0, void 0, function* () { + const [bodyAsText] = (_c = yield Promise.all((_b = (_a = receiveResponse.streams) === null || _a === void 0 ? void 0 : _a.map((stream) => stream.readAsString())) !== null && _b !== void 0 ? _b : [])) !== null && _c !== void 0 ? _c : []; + return { + bodyAsText, + headers: new azureCoreHttpCompat_1.HttpHeaders(), + request: httpRequest, + status: receiveResponse.statusCode + }; + }); + } + }; + } +}); + +// node_modules/botbuilder/lib/teamsInfo.js +var require_teamsInfo = __commonJS({ + "node_modules/botbuilder/lib/teamsInfo.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TeamsInfo = void 0; + var botbuilder_core_1 = require_lib10(); + var botframework_connector_1 = require_lib9(); + var cloudAdapter_1 = require_cloudAdapter(); + var teamsActivityHelpers_1 = require_teamsActivityHelpers(); + var TeamsInfo = class { + /** + * Gets the meeting participant for the given meeting id and participant id. This only works in + * teams scoped meeting conversations. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param meetingId The meeting ID to fetch + * @param participantId The participant ID to fetch + * @param tenantId The tenant ID to use when scoping the request + * @returns The [TeamsMeetingParticipant](xref:botbuilder-core.TeamsMeetingParticipant) fetched + */ + static getMeetingParticipant(context, meetingId, participantId, tenantId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context) { + throw new Error("context is required."); + } + const activity = context.activity; + if (meetingId == null) { + const meeting = (0, teamsActivityHelpers_1.teamsGetTeamMeetingInfo)(activity); + meetingId = meeting === null || meeting === void 0 ? void 0 : meeting.id; + } + if (!meetingId) { + throw new Error("meetingId is required."); + } + if (participantId == null) { + const from = activity.from; + participantId = from === null || from === void 0 ? void 0 : from.aadObjectId; + } + if (!participantId) { + throw new Error("participantId is required."); + } + if (tenantId === void 0) { + const tenant = (0, teamsActivityHelpers_1.teamsGetTenant)(activity); + tenantId = tenant === null || tenant === void 0 ? void 0 : tenant.id; + } + return this.getTeamsConnectorClient(context).teams.fetchMeetingParticipant(meetingId, participantId, { + tenantId + }); + }); + } + /** + * Gets the information for the given meeting id. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param meetingId The BASE64-encoded id of the Teams meeting. + * @returns The [MeetingInfo](xref:botframework-schema.MeetingInfo) fetched + */ + static getMeetingInfo(context, meetingId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context) { + throw new Error("context is required."); + } + const activity = context.activity; + if (meetingId == null) { + const meeting = (0, teamsActivityHelpers_1.teamsGetTeamMeetingInfo)(activity); + meetingId = meeting === null || meeting === void 0 ? void 0 : meeting.id; + } + if (!meetingId) { + throw new Error("meetingId or TurnContext containing meetingId is required."); + } + return this.getTeamsConnectorClient(context).teams.fetchMeetingInfo(meetingId); + }); + } + /** + * Gets the details for the given team id. This only works in teams scoped conversations. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param teamId The id of the Teams team. + * @returns The [TeamDetails](xref:botbuilder-core.TeamDetails) fetched + */ + static getTeamDetails(context, teamId) { + return __awaiter2(this, void 0, void 0, function* () { + const t = teamId || this.getTeamId(context); + if (!t) { + throw new Error("This method is only valid within the scope of a MS Teams Team."); + } + return yield this.getTeamsConnectorClient(context).teams.fetchTeamDetails(t); + }); + } + /** + * Creates a new thread in a Teams chat and sends an [Activity](xref:botframework-schema.Activity) to that new thread. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param activity The [Activity](xref:botframework-schema.Activity) to send. + * @param teamsChannelId The Team's Channel ID, note this is distinct from the Bot Framework activity property with same name. + * @param botAppId The bot's appId. This is only used when context.adapter is an instance of CloudAdapter. + * @returns The [ConversationReference](xref:botframework-schema.ConversationReference) and the id of the [Activity](xref:botframework-schema.Activity) (if sent). + */ + static sendMessageToTeamsChannel(context, activity, teamsChannelId, botAppId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!context) { + throw new Error("TurnContext cannot be null"); + } + if (!activity) { + throw new Error("Activity cannot be null"); + } + if (!teamsChannelId || !teamsChannelId) { + throw new Error("The teamsChannelId cannot be null or empty"); + } + const convoParams = { + isGroup: true, + channelData: { + channel: { + id: teamsChannelId + } + }, + activity + }; + let conversationReference; + let newActivityId; + if (botAppId && context.adapter instanceof cloudAdapter_1.CloudAdapter) { + yield context.adapter.createConversationAsync(botAppId, botbuilder_core_1.Channels.Msteams, context.activity.serviceUrl, null, convoParams, (turnContext) => __awaiter2(this, void 0, void 0, function* () { + conversationReference = botbuilder_core_1.TurnContext.getConversationReference(turnContext.activity); + newActivityId = turnContext.activity.id; + })); + } else { + const connectorClient = context.adapter.createConnectorClient(context.activity.serviceUrl); + const conversationResourceResponse = yield connectorClient.conversations.createConversation(convoParams); + conversationReference = botbuilder_core_1.TurnContext.getConversationReference(context.activity); + conversationReference.conversation.id = conversationResourceResponse.id; + newActivityId = conversationResourceResponse.activityId; + } + return [conversationReference, newActivityId]; + }); + } + /** + * Returns a list of channels in a Team. This only works in teams scoped conversations. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param teamId ID of the Teams team. + * @returns The list of [ChannelInfo](xref:botframework-schema.ChannelInfo) objects with the conversations. + */ + static getTeamChannels(context, teamId) { + return __awaiter2(this, void 0, void 0, function* () { + const t = teamId || this.getTeamId(context); + if (!t) { + throw new Error("This method is only valid within the scope of a MS Teams Team."); + } + const channelList = yield this.getTeamsConnectorClient(context).teams.fetchChannelList(t); + return channelList.conversations; + }); + } + /** + * Gets the conversation members of a one-on-one or group chat. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @returns The list of [TeamsChannelAccount](xref:botframework-schema.TeamsChannelAccount). + * @deprecated Use `getPagedTeamMembers` instead. + */ + static getMembers(context) { + return __awaiter2(this, void 0, void 0, function* () { + const teamId = this.getTeamId(context); + if (teamId) { + return yield this.getTeamMembers(context, teamId); + } else { + const conversation = context.activity.conversation; + const conversationId = conversation && conversation.id ? conversation.id : void 0; + return yield this.getMembersInternal(this.getConnectorClient(context), conversationId); + } + }); + } + /** + * Gets a pagined list of members of one-on-one, group, or team conversation. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param pageSize Suggested number of entries on a page. + * @param continuationToken A continuation token. + * @returns The [TeamsPagedMembersResult](xref:botframework-schema.TeamsPagedMembersResult) with the list of members. + */ + static getPagedMembers(context, pageSize, continuationToken) { + return __awaiter2(this, void 0, void 0, function* () { + const teamId = this.getTeamId(context); + const options = { + continuationToken, + pageSize + }; + if (teamId) { + return yield this.getPagedTeamMembers(context, teamId, pageSize, continuationToken); + } else { + const conversation = context.activity.conversation; + const conversationId = conversation && conversation.id ? conversation.id : void 0; + return yield this.getPagedMembersInternal(this.getConnectorClient(context), conversationId, options); + } + }); + } + /** + * Gets the account of a single conversation member. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param userId ID of the user in question. + * @returns The [TeamsChannelAccount](xref:botframework-schema.TeamsChannelAccount) of the member. + */ + static getMember(context, userId) { + return __awaiter2(this, void 0, void 0, function* () { + const teamId = this.getTeamId(context); + if (teamId) { + return yield this.getTeamMember(context, teamId, userId); + } else { + const conversation = context.activity.conversation; + const conversationId = conversation && conversation.id ? conversation.id : void 0; + return yield this.getMemberInternal(this.getConnectorClient(context), conversationId, userId); + } + }); + } + /** + * Gets the list of [TeamsChannelAccount](xref:botframework-schema.TeamsChannelAccount) within a team. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param teamId ID of the Teams team. + * @returns The list of [TeamsChannelAccount](xref:botframework-schema.TeamsChannelAccount) of the members. + * @deprecated Use `getPagedTeamMembers` instead. + */ + static getTeamMembers(context, teamId) { + return __awaiter2(this, void 0, void 0, function* () { + const t = teamId || this.getTeamId(context); + if (!t) { + throw new Error("This method is only valid within the scope of a MS Teams Team."); + } + return yield this.getMembersInternal(this.getConnectorClient(context), t); + }); + } + /** + * Gets a paginated list of members of a team. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param teamId ID of the Teams team. + * @param pageSize The number of entries on the page. + * @param continuationToken The continuationToken token. + * @returns A [TeamsPagedMembersResult](xref:botframework-schema.TeamsPagedMembersResult) with the list of members. + */ + static getPagedTeamMembers(context, teamId, pageSize, continuationToken) { + return __awaiter2(this, void 0, void 0, function* () { + const t = teamId || this.getTeamId(context); + if (!t) { + throw new Error("This method is only valid within the scope of a MS Teams Team."); + } + const options = { + continuationToken, + pageSize + }; + return yield this.getPagedMembersInternal(this.getConnectorClient(context), t, options); + }); + } + /** + * Gets the account of a member in a teams scoped conversation. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param teamId ID of the Teams team. + * @param userId ID of the Teams user. + * @returns The [TeamsChannelAccount](xref:botframework-schema.TeamsChannelAccount) of the member. + */ + static getTeamMember(context, teamId, userId) { + return __awaiter2(this, void 0, void 0, function* () { + const t = teamId || this.getTeamId(context); + if (!t) { + throw new Error("This method is only valid within the scope of a MS Teams Team."); + } + return yield this.getMemberInternal(this.getConnectorClient(context), t, userId); + }); + } + /** + * Sends a meeting notification to specific users in a Teams meeting. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param notification The meeting notification payload. + * @param meetingId Id of the Teams meeting. + * @returns Promise with either an empty object if notifications were successfully sent to all recipients or + * [MeetingNotificationResponse](xref:botframework-schema.MeetingNotificationResponse) if notifications + * were sent to some but not all recipients. + */ + static sendMeetingNotification(context, notification, meetingId) { + return __awaiter2(this, void 0, void 0, function* () { + const activity = context.activity; + if (meetingId == null) { + const meeting = (0, teamsActivityHelpers_1.teamsGetTeamMeetingInfo)(activity); + meetingId = meeting === null || meeting === void 0 ? void 0 : meeting.id; + } + if (!meetingId) { + throw new Error("meetingId is required."); + } + return yield this.getTeamsConnectorClient(context).teams.sendMeetingNotification(meetingId, notification); + }); + } + /** + * Sends a message to the provided users in the list of Teams members. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param activity The activity to send. + * @param tenantId The tenant ID. + * @param members The list of users recipients for the message. + * @returns Promise with operationId. + */ + static sendMessageToListOfUsers(context, activity, tenantId, members) { + return __awaiter2(this, void 0, void 0, function* () { + if (!activity) { + throw new Error("activity is required."); + } + if (!tenantId) { + throw new Error("tenantId is required."); + } + if (!members || members.length == 0) { + throw new Error("members list is required."); + } + return yield this.getTeamsConnectorClient(context).teams.sendMessageToListOfUsers(activity, tenantId, members); + }); + } + /** + * Sends a message to all the users in a tenant. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param activity The activity to send. + * @param tenantId The tenant ID. + * @returns Promise with operationId. + */ + static sendMessageToAllUsersInTenant(context, activity, tenantId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!activity) { + throw new Error("activity is required."); + } + if (!tenantId) { + throw new Error("tenantId is required."); + } + return yield this.getTeamsConnectorClient(context).teams.sendMessageToAllUsersInTenant(activity, tenantId); + }); + } + /** + * Sends a message to all the users in a team. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param activity The activity to send. + * @param tenantId The tenant ID. + * @param teamId The team ID. + * @returns Promise with operationId. + */ + static sendMessageToAllUsersInTeam(context, activity, tenantId, teamId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!activity) { + throw new Error("activity is required."); + } + if (!tenantId) { + throw new Error("tenantId is required."); + } + if (!teamId) { + throw new Error("teamId is required."); + } + return yield this.getTeamsConnectorClient(context).teams.sendMessageToAllUsersInTeam(activity, tenantId, teamId); + }); + } + /** + * Sends a message to the provided list of Teams channels. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param activity The activity to send. + * @param tenantId The tenant ID. + * @param members The list of channels recipients for the message. + * @returns Promise with operationId. + */ + static sendMessageToListOfChannels(context, activity, tenantId, members) { + return __awaiter2(this, void 0, void 0, function* () { + if (!activity) { + throw new Error("activity is required."); + } + if (!tenantId) { + throw new Error("tenantId is required."); + } + if (!members || members.length == 0) { + throw new Error("members list is required."); + } + return yield this.getTeamsConnectorClient(context).teams.sendMessageToListOfChannels(activity, tenantId, members); + }); + } + /** + * Gets the operation state. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param operationId The operationId to get the state of. + * @returns Promise with The state and responses of the operation. + */ + static getOperationState(context, operationId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!operationId) { + throw new Error("operationId is required."); + } + return yield this.getTeamsConnectorClient(context).teams.getOperationState(operationId); + }); + } + /** + * Gets the failed entries of an executed operation. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param operationId The operationId to get the failed entries of. + * @returns Promise with the list of failed entries of the operation. + */ + static getFailedEntries(context, operationId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!operationId) { + throw new Error("operationId is required."); + } + return yield this.getTeamsConnectorClient(context).teams.getOperationFailedEntries(operationId); + }); + } + /** + * Cancels a pending operation. + * + * @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn. + * @param operationId The id of the operation to cancel. + * @returns Promise representing the asynchronous operation. + */ + static cancelOperation(context, operationId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!operationId) { + throw new Error("operationId is required."); + } + return yield this.getTeamsConnectorClient(context).teams.cancelOperation(operationId); + }); + } + /** + * @private + */ + static getMembersInternal(connectorClient, conversationId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!conversationId) { + throw new Error("The getMembers operation needs a valid conversationId."); + } + const teamMembers = yield connectorClient.conversations.getConversationMembers(conversationId); + teamMembers.forEach((member) => { + member.aadObjectId = member.objectId; + }); + return teamMembers; + }); + } + /** + * @private + */ + static getPagedMembersInternal(connectorClient, conversationId, options) { + return __awaiter2(this, void 0, void 0, function* () { + if (!conversationId) { + throw new Error("The getPagedMembers operation needs a valid conversationId."); + } + const pagedMembersResult = yield connectorClient.conversations.getConversationPagedMembers(conversationId, options); + const teamsPagedMembersResult = { + continuationToken: pagedMembersResult.continuationToken, + members: pagedMembersResult.members + }; + return teamsPagedMembersResult; + }); + } + /** + * @private + */ + static getMemberInternal(connectorClient, conversationId, userId) { + return __awaiter2(this, void 0, void 0, function* () { + if (!conversationId) { + throw new Error("The getMember operation needs a valid conversationId."); + } + if (!userId) { + throw new Error("The getMember operation needs a valid userId."); + } + const teamMember = yield connectorClient.conversations.getConversationMember(conversationId, userId); + return teamMember; + }); + } + /** + * @private + */ + static getTeamId(context) { + if (!context) { + throw new Error("Missing context parameter"); + } + if (!context.activity) { + throw new Error("Missing activity on context"); + } + const channelData = context.activity.channelData; + const team = channelData && channelData.team ? channelData.team : void 0; + const teamId = team && typeof team.id === "string" ? team.id : void 0; + return teamId; + } + /** + * @private + */ + static getConnectorClient(context) { + var _a; + const client = context.adapter && "createConnectorClient" in context.adapter ? context.adapter.createConnectorClient(context.activity.serviceUrl) : (_a = context.turnState) === null || _a === void 0 ? void 0 : _a.get(context.adapter.ConnectorClientKey); + if (!client) { + throw new Error("This method requires a connector client."); + } + return client; + } + /** + * @private + */ + static getTeamsConnectorClient(context) { + const connectorClient = this.getConnectorClient(context); + return new botframework_connector_1.TeamsConnectorClient(connectorClient.credentials, { baseUri: context.activity.serviceUrl }); + } + }; + exports2.TeamsInfo = TeamsInfo; + } +}); + +// node_modules/botbuilder/lib/teamsActivityHandler.js +var require_teamsActivityHandler = __commonJS({ + "node_modules/botbuilder/lib/teamsActivityHandler.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TeamsActivityHandler = void 0; + var botbuilder_core_1 = require_lib10(); + var botframework_connector_1 = require_lib9(); + var teamsInfo_1 = require_teamsInfo(); + var z = __importStar2(require_zod()); + var TeamsMeetingStartT = z.object({ + Id: z.string(), + JoinUrl: z.string(), + MeetingType: z.string(), + Title: z.string(), + StartTime: z.string() + }).nonstrict(); + var TeamsMeetingEndT = z.object({ + Id: z.string(), + JoinUrl: z.string(), + MeetingType: z.string(), + Title: z.string(), + EndTime: z.string() + }).nonstrict(); + var TeamsActivityHandler = class extends botbuilder_core_1.ActivityHandler { + /** + * Invoked when an invoke activity is received from the connector. + * Invoke activities can be used to communicate many different things. + * + * @param context A context object for this turn. + * @returns An Invoke Response for the activity. + */ + onInvokeActivity(context) { + const _super = Object.create(null, { + onInvokeActivity: { get: () => super.onInvokeActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + let runEvents = true; + try { + if (!context.activity.name && context.activity.channelId === "msteams") { + return yield this.handleTeamsCardActionInvoke(context); + } else { + switch (context.activity.name) { + case "config/fetch": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsConfigFetch(context, context.activity.value)); + case "config/submit": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsConfigSubmit(context, context.activity.value)); + case "fileConsent/invoke": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsFileConsent(context, context.activity.value)); + case "actionableMessage/executeAction": + yield this.handleTeamsO365ConnectorCardAction(context, context.activity.value); + return botbuilder_core_1.ActivityHandler.createInvokeResponse(); + case "composeExtension/queryLink": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsAppBasedLinkQuery(context, context.activity.value)); + case "composeExtension/anonymousQueryLink": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsAnonymousAppBasedLinkQuery(context, context.activity.value)); + case "composeExtension/query": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsMessagingExtensionQuery(context, context.activity.value)); + case "composeExtension/selectItem": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsMessagingExtensionSelectItem(context, context.activity.value)); + case "composeExtension/submitAction": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsMessagingExtensionSubmitActionDispatch(context, context.activity.value)); + case "composeExtension/fetchTask": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsMessagingExtensionFetchTask(context, context.activity.value)); + case "composeExtension/querySettingUrl": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsMessagingExtensionConfigurationQuerySettingUrl(context, context.activity.value)); + case "composeExtension/setting": + yield this.handleTeamsMessagingExtensionConfigurationSetting(context, context.activity.value); + return botbuilder_core_1.ActivityHandler.createInvokeResponse(); + case "composeExtension/onCardButtonClicked": + yield this.handleTeamsMessagingExtensionCardButtonClicked(context, context.activity.value); + return botbuilder_core_1.ActivityHandler.createInvokeResponse(); + case "task/fetch": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsTaskModuleFetch(context, context.activity.value)); + case "task/submit": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsTaskModuleSubmit(context, context.activity.value)); + case "tab/fetch": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsTabFetch(context, context.activity.value)); + case "tab/submit": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.handleTeamsTabSubmit(context, context.activity.value)); + default: + runEvents = false; + return _super.onInvokeActivity.call(this, context); + } + } + } catch (err) { + if (err.message === "NotImplemented") { + return { status: 501 }; + } else if (err.message === "BadRequest") { + return { status: 400 }; + } + throw err; + } finally { + if (runEvents) { + this.defaultNextEvent(context)(); + } + } + }); + } + /** + * Handles a Teams Card Action Invoke activity. + * + * @param _context A context object for this turn. + * @returns An Invoke Response for the activity. + */ + handleTeamsCardActionInvoke(_context) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Handles a config/fetch invoke activity. + * + * @param _context A context object for this turn. + * @param _configData The object representing the configuration. + * @returns A Config Response for the activity. + */ + handleTeamsConfigFetch(_context, _configData) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Handles a config/submit invoke activity. + * + * @param _context A context object for this turn. + * @param _configData The object representing the configuration. + * @returns A Config Response for the activity. + */ + handleTeamsConfigSubmit(_context, _configData) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'fileConsent/invoke'. Handlers registered here run before + * `handleTeamsFileConsentAccept` and `handleTeamsFileConsentDecline`. + * Developers are not passed a pointer to the next `handleTeamsFileConsent` handler because the _wrapper_ around + * the handler will call `onDialogs` handlers after delegating to `handleTeamsFileConsentAccept` or `handleTeamsFileConsentDecline`. + * + * @param context A context object for this turn. + * @param fileConsentCardResponse Represents the value of the invoke activity sent when the user acts on a file consent card. + * @returns A promise that represents the work queued. + */ + handleTeamsFileConsent(context, fileConsentCardResponse) { + return __awaiter2(this, void 0, void 0, function* () { + switch (fileConsentCardResponse.action) { + case "accept": + return yield this.handleTeamsFileConsentAccept(context, fileConsentCardResponse); + case "decline": + return yield this.handleTeamsFileConsentDecline(context, fileConsentCardResponse); + default: + throw new Error("BadRequest"); + } + }); + } + /** + * Receives invoke activities with Activity name of 'fileConsent/invoke' with confirmation from user + * + * @remarks + * This type of invoke activity occur during the File Consent flow. + * @param _context A context object for this turn. + * @param _fileConsentCardResponse Represents the value of the invoke activity sent when the user acts on a file consent card. + * @returns A promise that represents the work queued. + */ + handleTeamsFileConsentAccept(_context, _fileConsentCardResponse) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'fileConsent/invoke' with decline from user + * + * @remarks + * This type of invoke activity occur during the File Consent flow. + * @param _context A context object for this turn. + * @param _fileConsentCardResponse Represents the value of the invoke activity sent when the user acts on a file consent card. + * @returns A promise that represents the work queued. + */ + handleTeamsFileConsentDecline(_context, _fileConsentCardResponse) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'actionableMessage/executeAction'. + * + * @param _context A context object for this turn. + * @param _query The O365 connector card HttpPOST invoke query. + * @returns A promise that represents the work queued. + */ + handleTeamsO365ConnectorCardAction(_context, _query) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Invoked when a signIn invoke activity is received from the connector. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onSignInInvoke(context) { + return __awaiter2(this, void 0, void 0, function* () { + switch (context.activity.name) { + case botbuilder_core_1.verifyStateOperationName: + return yield this.handleTeamsSigninVerifyState(context, context.activity.value); + case botbuilder_core_1.tokenExchangeOperationName: + return yield this.handleTeamsSigninTokenExchange(context, context.activity.value); + } + }); + } + /** + * Receives invoke activities with Activity name of 'signin/verifyState'. + * + * @param _context A context object for this turn. + * @param _query Signin state (part of signin action auth flow) verification invoke query. + * @returns A promise that represents the work queued. + */ + handleTeamsSigninVerifyState(_context, _query) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'signin/tokenExchange' + * + * @param _context A context object for this turn. + * @param _query Signin state (part of signin action auth flow) verification invoke query + * @returns A promise that represents the work queued. + */ + handleTeamsSigninTokenExchange(_context, _query) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'composeExtension/onCardButtonClicked' + * + * @param _context A context object for this turn. + * @param _cardData Object representing the card data. + * @returns A promise that represents the work queued. + */ + handleTeamsMessagingExtensionCardButtonClicked(_context, _cardData) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'task/fetch' + * + * @param _context A context object for this turn. + * @param _taskModuleRequest The task module invoke request value payload. + * @returns A Task Module Response for the request. + */ + handleTeamsTaskModuleFetch(_context, _taskModuleRequest) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'task/submit' + * + * @param _context A context object for this turn. + * @param _taskModuleRequest The task module invoke request value payload. + * @returns A Task Module Response for the request. + */ + handleTeamsTaskModuleSubmit(_context, _taskModuleRequest) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'tab/fetch' + * + * @param _context A context object for this turn. + * @param _tabRequest The tab invoke request value payload. + * @returns A Tab Response for the request. + */ + handleTeamsTabFetch(_context, _tabRequest) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'tab/submit' + * + * @param _context A context object for this turn. + * @param _tabSubmit The tab submit invoke request value payload. + * @returns A Tab Response for the request. + */ + handleTeamsTabSubmit(_context, _tabSubmit) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'composeExtension/queryLink' + * + * @remarks + * Used in creating a Search-based Message Extension. + * @param _context A context object for this turn. + * @param _query he invoke request body type for app-based link query. + * @returns The Messaging Extension Response for the query. + */ + handleTeamsAppBasedLinkQuery(_context, _query) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with Activity name of 'composeExtension/anonymousQueryLink' + * + * @remarks + * Used in creating a Search-based Message Extension. + * @param _context A context object for this turn. + * @param _query he invoke request body type for app-based link query. + * @returns The Messaging Extension Response for the query. + */ + handleTeamsAnonymousAppBasedLinkQuery(_context, _query) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with the name 'composeExtension/query'. + * + * @remarks + * Used in creating a Search-based Message Extension. + * @param _context A context object for this turn. + * @param _query The query for the search command. + * @returns The Messaging Extension Response for the query. + */ + handleTeamsMessagingExtensionQuery(_context, _query) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with the name 'composeExtension/selectItem'. + * + * @remarks + * Used in creating a Search-based Message Extension. + * @param _context A context object for this turn. + * @param _query The object representing the query. + * @returns The Messaging Extension Response for the query. + */ + handleTeamsMessagingExtensionSelectItem(_context, _query) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with the name 'composeExtension/submitAction' and dispatches to botMessagePreview-flows as applicable. + * + * @remarks + * A handler registered through this method does not dispatch to the next handler (either `handleTeamsMessagingExtensionSubmitAction`, `handleTeamsMessagingExtensionBotMessagePreviewEdit`, or `handleTeamsMessagingExtensionBotMessagePreviewSend`). + * This method exists for developers to optionally add more logic before the TeamsActivityHandler routes the activity to one of the + * previously mentioned handlers. + * @param context A context object for this turn. + * @param action The messaging extension action. + * @returns The Messaging Extension Action Response for the action. + */ + handleTeamsMessagingExtensionSubmitActionDispatch(context, action) { + return __awaiter2(this, void 0, void 0, function* () { + if (action.botMessagePreviewAction) { + switch (action.botMessagePreviewAction) { + case "edit": + return yield this.handleTeamsMessagingExtensionBotMessagePreviewEdit(context, action); + case "send": + return yield this.handleTeamsMessagingExtensionBotMessagePreviewSend(context, action); + default: + throw new Error("BadRequest"); + } + } else { + return yield this.handleTeamsMessagingExtensionSubmitAction(context, action); + } + }); + } + /** + * Receives invoke activities with the name 'composeExtension/submitAction'. + * + * @param _context A context object for this turn. + * @param _action The messaging extension action. + * @returns The Messaging Extension Action Response for the action. + */ + handleTeamsMessagingExtensionSubmitAction(_context, _action) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with the name 'composeExtension/submitAction' with the 'botMessagePreview' property present on activity.value. + * The value for 'botMessagePreview' is 'edit'. + * + * @param _context A context object for this turn. + * @param _action The messaging extension action. + * @returns The Messaging Extension Action Response for the action. + */ + handleTeamsMessagingExtensionBotMessagePreviewEdit(_context, _action) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with the name 'composeExtension/submitAction' with the 'botMessagePreview' property present on activity.value. + * The value for 'botMessagePreview' is 'send'. + * + * @param _context A context object for this turn. + * @param _action The messaging extension action. + * @returns The Messaging Extension Action Response for the action. + */ + handleTeamsMessagingExtensionBotMessagePreviewSend(_context, _action) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with the name 'composeExtension/fetchTask' + * + * @param _context A context object for this turn. + * @param _action The messaging extension action. + * @returns The Messaging Extension Action Response for the action. + */ + handleTeamsMessagingExtensionFetchTask(_context, _action) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with the name 'composeExtension/querySettingUrl' + * + * @param _context A context object for this turn. + * @param _query The Messaging extension query. + * @returns The Messaging Extension Action Response for the query. + */ + handleTeamsMessagingExtensionConfigurationQuerySettingUrl(_context, _query) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Receives invoke activities with the name 'composeExtension/setting' + * + * @param _context A context object for this turn. + * @param _settings Object representing the configuration settings. + */ + handleTeamsMessagingExtensionConfigurationSetting(_context, _settings) { + throw new Error("NotImplemented"); + } + /** + * Override this method to change the dispatching of ConversationUpdate activities. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + dispatchConversationUpdateActivity(context) { + const _super = Object.create(null, { + dispatchConversationUpdateActivity: { get: () => super.dispatchConversationUpdateActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.channelId == "msteams") { + const channelData = context.activity.channelData; + if (context.activity.membersAdded && context.activity.membersAdded.length > 0) { + return yield this.onTeamsMembersAdded(context); + } + if (context.activity.membersRemoved && context.activity.membersRemoved.length > 0) { + return yield this.onTeamsMembersRemoved(context); + } + if (!channelData || !channelData.eventType) { + return yield _super.dispatchConversationUpdateActivity.call(this, context); + } + switch (channelData.eventType) { + case "channelCreated": + return yield this.onTeamsChannelCreated(context); + case "channelDeleted": + return yield this.onTeamsChannelDeleted(context); + case "channelRenamed": + return yield this.onTeamsChannelRenamed(context); + case "teamArchived": + return yield this.onTeamsTeamArchived(context); + case "teamDeleted": + return yield this.onTeamsTeamDeleted(context); + case "teamHardDeleted": + return yield this.onTeamsTeamHardDeleted(context); + case "channelRestored": + return yield this.onTeamsChannelRestored(context); + case "teamRenamed": + return yield this.onTeamsTeamRenamed(context); + case "teamRestored": + return yield this.onTeamsTeamRestored(context); + case "teamUnarchived": + return yield this.onTeamsTeamUnarchived(context); + default: + return yield _super.dispatchConversationUpdateActivity.call(this, context); + } + } else { + return yield _super.dispatchConversationUpdateActivity.call(this, context); + } + }); + } + /** + * Override this method to change the dispatching of MessageUpdate activities. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + dispatchMessageUpdateActivity(context) { + const _super = Object.create(null, { + dispatchMessageUpdateActivity: { get: () => super.dispatchMessageUpdateActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.channelId == "msteams") { + const channelData = context.activity.channelData; + switch (channelData.eventType) { + case "undeleteMessage": + return yield this.onTeamsMessageUndelete(context); + case "editMessage": + return yield this.onTeamsMessageEdit(context); + default: + return _super.dispatchMessageUpdateActivity.call(this, context); + } + } else { + return yield _super.dispatchMessageUpdateActivity.call(this, context); + } + }); + } + /** + * Override this method to change the dispatching of MessageDelete activities. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + dispatchMessageDeleteActivity(context) { + const _super = Object.create(null, { + dispatchMessageDeleteActivity: { get: () => super.dispatchMessageDeleteActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.channelId == "msteams") { + const channelData = context.activity.channelData; + switch (channelData.eventType) { + case "softDeleteMessage": + return yield this.onTeamsMessageSoftDelete(context); + default: + return _super.dispatchMessageDeleteActivity.call(this, context); + } + } else { + return yield _super.dispatchMessageDeleteActivity.call(this, context); + } + }); + } + /** + * Called in `dispatchMessageUpdateActivity()` to trigger the `'TeamsMessageUndelete'` handlers. + * Override this in a derived class to provide logic for when a deleted message in a conversation is undeleted. + * For example, when the user decides to "undo" a deleted message. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMessageUndelete(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsMessageUndelete", this.defaultNextEvent(context)); + }); + } + /** + * Called in `dispatchMessageUpdateActivity()` to trigger the `'TeamsMessageEdit'` handlers. + * Override this in a derived class to provide logic for when a message in a conversation is edited. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMessageEdit(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsMessageEdit", this.defaultNextEvent(context)); + }); + } + /** + * Called in `dispatchMessageDeleteActivity()` to trigger the `'TeamsMessageEdit'` handlers. + * Override this in a derived class to provide logic for when a message in a conversation is soft deleted. + * This means that the message as the option of being undeleted. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMessageSoftDelete(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "onTeamsMessageSoftDelete", this.defaultNextEvent(context)); + }); + } + /** + * Called in `dispatchConversationUpdateActivity()` to trigger the `'TeamsMembersAdded'` handlers. + * Override this in a derived class to provide logic for when members other than the bot + * join the channel, such as your bot's welcome logic. + * + * @remarks + * If no handlers are registered for the `'TeamsMembersAdded'` event, the `'MembersAdded'` handlers will run instead. + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMembersAdded(context) { + return __awaiter2(this, void 0, void 0, function* () { + if ("TeamsMembersAdded" in this.handlers && this.handlers["TeamsMembersAdded"].length > 0) { + if (!context.activity || !context.activity.membersAdded) { + throw new Error("OnTeamsMemberAdded: context.activity is undefined"); + } + for (let i = 0; i < context.activity.membersAdded.length; i++) { + const channelAccount = context.activity.membersAdded[i]; + if ("givenName" in channelAccount || "surname" in channelAccount || "email" in channelAccount || "userPrincipalName" in channelAccount || context.activity.recipient.id === channelAccount.id) { + continue; + } + try { + context.activity.membersAdded[i] = yield teamsInfo_1.TeamsInfo.getMember(context, channelAccount.id); + } catch (err) { + const errCode = err.body && err.body.error && err.body.error.code; + if (errCode === "ConversationNotFound") { + const teamsChannelAccount = { + id: channelAccount.id, + name: channelAccount.name, + aadObjectId: channelAccount.aadObjectId, + role: channelAccount.role + }; + context.activity.membersAdded[i] = teamsChannelAccount; + } else { + throw err; + } + } + } + yield this.handle(context, "TeamsMembersAdded", this.defaultNextEvent(context)); + } else { + yield this.handle(context, "MembersAdded", this.defaultNextEvent(context)); + } + }); + } + /** + * Called in `dispatchConversationUpdateActivity()` to trigger the `'TeamsMembersRemoved'` handlers. + * Override this in a derived class to provide logic for when members other than the bot + * leave the channel, such as your bot's good-bye logic. + * + * @remarks + * If no handlers are registered for the `'TeamsMembersRemoved'` event, the `'MembersRemoved'` handlers will run instead. + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMembersRemoved(context) { + return __awaiter2(this, void 0, void 0, function* () { + if ("TeamsMembersRemoved" in this.handlers && this.handlers["TeamsMembersRemoved"].length > 0) { + yield this.handle(context, "TeamsMembersRemoved", this.defaultNextEvent(context)); + } else { + yield this.handle(context, "MembersRemoved", this.defaultNextEvent(context)); + } + }); + } + /** + * Invoked when a Channel Created event activity is received from the connector. + * Channel Created corresponds to the user creating a new channel. + * Override this in a derived class to provide logic for when a channel is created. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsChannelCreated(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsChannelCreated", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Channel Deleted event activity is received from the connector. + * Channel Deleted corresponds to the user deleting a channel. + * Override this in a derived class to provide logic for when a channel is deleted. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsChannelDeleted(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsChannelDeleted", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Channel Renamed event activity is received from the connector. + * Channel Renamed corresponds to the user renaming a new channel. + * Override this in a derived class to provide logic for when a channel is renamed. + * + * @param context A context object for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsChannelRenamed(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsChannelRenamed", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Team Archived event activity is received from the connector. + * Team Archived corresponds to the user archiving a team. + * Override this in a derived class to provide logic for when a team is archived. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsTeamArchived(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsTeamArchived", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Team Deleted event activity is received from the connector. + * Team Deleted corresponds to the user deleting a team. + * Override this in a derived class to provide logic for when a team is deleted. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsTeamDeleted(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsTeamDeleted", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Team Hard Deleted event activity is received from the connector. + * Team Hard Deleted corresponds to the user hard-deleting a team. + * Override this in a derived class to provide logic for when a team is hard-deleted. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsTeamHardDeleted(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsTeamHardDeleted", this.defaultNextEvent(context)); + }); + } + /** + * + * Invoked when a Channel Restored event activity is received from the connector. + * Channel Restored corresponds to the user restoring a previously deleted channel. + * Override this in a derived class to provide logic for when a channel is restored. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsChannelRestored(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsChannelRestored", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Team Renamed event activity is received from the connector. + * Team Renamed corresponds to the user renaming a team. + * Override this in a derived class to provide logic for when a team is renamed. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsTeamRenamed(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsTeamRenamed", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Team Restored event activity is received from the connector. + * Team Restored corresponds to the user restoring a team. + * Override this in a derived class to provide logic for when a team is restored. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsTeamRestored(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsTeamRestored", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Team Unarchived event activity is received from the connector. + * Team Unarchived corresponds to the user unarchiving a team. + * Override this in a derived class to provide logic for when a team is unarchived. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsTeamUnarchived(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsTeamUnarchived", this.defaultNextEvent(context)); + }); + } + /** + * Registers a handler for TeamsMessageUndelete events, such as for when a message in a conversation that is + * observed by the bot goes from a soft delete state to the normal state. + * + * @param handler A callback to handle the teams undelete message event. + * @returns A promise that represents the work queued. + */ + onTeamsMessageUndeleteEvent(handler) { + return this.on("TeamsMessageUndelete", (context, next) => __awaiter2(this, void 0, void 0, function* () { + yield handler(context, next); + })); + } + /** + * Registers a handler for TeamsMessageEdit events, such as for when a message in a conversation that is + * observed by the bot is edited. + * + * @param handler A callback to handle the teams edit message event. + * @returns A promise that represents the work queued. + */ + onTeamsMessageEditEvent(handler) { + return this.on("TeamsMessageEdit", (context, next) => __awaiter2(this, void 0, void 0, function* () { + yield handler(context, next); + })); + } + /** + * Registers a handler for TeamsMessageSoftDelete events, such as for when a message in a conversation that is + * observed by the bot is soft deleted. This means that the deleted message, up to a certain time period, + * can be undoed. + * + * @param handler A callback to handle the teams edit message event. + * @returns A promise that represents the work queued. + */ + onTeamsMessageSoftDeleteEvent(handler) { + return this.on("onTeamsMessageSoftDelete", (context, next) => __awaiter2(this, void 0, void 0, function* () { + yield handler(context, next); + })); + } + /** + * Registers a handler for TeamsMembersAdded events, such as for when members other than the bot + * join the channel, such as your bot's welcome logic. + * + * @param handler A callback to handle the teams members added event. + * @returns A promise that represents the work queued. + */ + onTeamsMembersAddedEvent(handler) { + return this.on("TeamsMembersAdded", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(context.activity.membersAdded, teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsMembersRemoved events, such as for when members other than the bot + * leave the channel, such as your bot's good-bye logic. + * + * @param handler A callback to handle the teams members removed event. + * @returns A promise that represents the work queued. + */ + onTeamsMembersRemovedEvent(handler) { + return this.on("TeamsMembersRemoved", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(context.activity.membersRemoved, teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsChannelCreated events, such as for when a channel is created. + * + * @param handler A callback to handle the teams channel created event. + * @returns A promise that represents the work queued. + */ + onTeamsChannelCreatedEvent(handler) { + return this.on("TeamsChannelCreated", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.channel, teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsChannelDeleted events, such as for when a channel is deleted. + * + * @param handler A callback to handle the teams channel deleted event. + * @returns A promise that represents the work queued. + */ + onTeamsChannelDeletedEvent(handler) { + return this.on("TeamsChannelDeleted", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.channel, teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsChannelRenamed events, such as for when a channel is renamed. + * + * @param handler A callback to handle the teams channel renamed event. + * @returns A promise that represents the work queued. + */ + onTeamsChannelRenamedEvent(handler) { + return this.on("TeamsChannelRenamed", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.channel, teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsTeamArchived events, such as for when a team is archived. + * + * @param handler A callback to handle the teams team archived event. + * @returns A promise that represents the work queued. + */ + onTeamsTeamArchivedEvent(handler) { + return this.on("TeamsTeamArchived", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsTeamDeleted events, such as for when a team is deleted. + * + * @param handler A callback to handle the teams team deleted event. + * @returns A promise that represents the work queued. + */ + onTeamsTeamDeletedEvent(handler) { + return this.on("TeamsTeamDeleted", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsTeamHardDeleted events, such as for when a team is hard-deleted. + * + * @param handler A callback to handle the teams team hard deleted event. + * @returns A promise that represents the work queued. + */ + onTeamsTeamHardDeletedEvent(handler) { + return this.on("TeamsTeamHardDeleted", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsChannelRestored events, such as for when a channel is restored. + * + * @param handler A callback to handle the teams channel restored event. + * @returns A promise that represents the work queued. + */ + onTeamsChannelRestoredEvent(handler) { + return this.on("TeamsChannelRestored", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.channel, teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsTeamRenamed events, such as for when a team is renamed. + * + * @param handler A callback to handle the teams team renamed event. + * @returns A promise that represents the work queued. + */ + onTeamsTeamRenamedEvent(handler) { + return this.on("TeamsTeamRenamed", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsTeamRestored events, such as for when a team is restored. + * + * @param handler A callback to handle the teams team restored event. + * @returns A promise that represents the work queued. + */ + onTeamsTeamRestoredEvent(handler) { + return this.on("TeamsTeamRestored", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.team, context, next); + })); + } + /** + * Registers a handler for TeamsTeamUnarchived events, such as for when a team is unarchived. + * + * @param handler A callback to handle the teams team unarchived event. + * @returns A promise that represents the work queued. + */ + onTeamsTeamUnarchivedEvent(handler) { + return this.on("TeamsTeamUnarchived", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const teamsChannelData = context.activity.channelData; + yield handler(teamsChannelData.team, context, next); + })); + } + /** + * Runs the _event_ sub-type handlers, as appropriate, and then continues the event emission process. + * + * @param context The context object for the current turn. + * @returns A promise that represents the work queued. + * @remarks + * Override this method to support channel-specific behavior across multiple channels or to add + * custom event sub-type events. + */ + dispatchEventActivity(context) { + const _super = Object.create(null, { + dispatchEventActivity: { get: () => super.dispatchEventActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.channelId === botbuilder_core_1.Channels.Msteams) { + switch (context.activity.name) { + case "application/vnd.microsoft.readReceipt": + return this.onTeamsReadReceipt(context); + case "application/vnd.microsoft.meetingStart": + return this.onTeamsMeetingStart(context); + case "application/vnd.microsoft.meetingEnd": + return this.onTeamsMeetingEnd(context); + case "application/vnd.microsoft.meetingParticipantJoin": + return this.onTeamsMeetingParticipantsJoin(context); + case "application/vnd.microsoft.meetingParticipantLeave": + return this.onTeamsMeetingParticipantsLeave(context); + } + } + return _super.dispatchEventActivity.call(this, context); + }); + } + /** + * Invoked when a Meeting Started event activity is received from the connector. + * Override this in a derived class to provide logic for when a meeting is started. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMeetingStart(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsMeetingStart", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Meeting End event activity is received from the connector. + * Override this in a derived class to provide logic for when a meeting is ended. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMeetingEnd(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsMeetingEnd", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a read receipt for a previously sent message is received from the connector. + * Override this in a derived class to provide logic for when the bot receives a read receipt event. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsReadReceipt(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsReadReceipt", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Meeting Participant Join event activity is received from the connector. + * Override this in a derived class to provide logic for when a meeting participant is joined. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMeetingParticipantsJoin(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsMeetingParticipantsJoin", this.defaultNextEvent(context)); + }); + } + /** + * Invoked when a Meeting Participant Leave event activity is received from the connector. + * Override this in a derived class to provide logic for when a meeting participant is left. + * + * @param context The context for this turn. + * @returns A promise that represents the work queued. + */ + onTeamsMeetingParticipantsLeave(context) { + return __awaiter2(this, void 0, void 0, function* () { + yield this.handle(context, "TeamsMeetingParticipantsLeave", this.defaultNextEvent(context)); + }); + } + /** + * Registers a handler for when a Teams meeting starts. + * + * @param handler A callback that handles Meeting Start events. + * @returns A promise that represents the work queued. + */ + onTeamsMeetingStartEvent(handler) { + return this.on("TeamsMeetingStart", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const meeting = TeamsMeetingStartT.parse(context.activity.value); + yield handler({ + id: meeting.Id, + joinUrl: meeting.JoinUrl, + meetingType: meeting.MeetingType, + startTime: new Date(meeting.StartTime), + title: meeting.Title + }, context, next); + })); + } + /** + * Registers a handler for when a Teams meeting ends. + * + * @param handler A callback that handles Meeting End events. + * @returns A promise that represents the work queued. + */ + onTeamsMeetingEndEvent(handler) { + return this.on("TeamsMeetingEnd", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const meeting = TeamsMeetingEndT.parse(context.activity.value); + yield handler({ + id: meeting.Id, + joinUrl: meeting.JoinUrl, + meetingType: meeting.MeetingType, + endTime: new Date(meeting.EndTime), + title: meeting.Title + }, context, next); + })); + } + /** + * Registers a handler for when a Read Receipt is sent. + * + * @param handler A callback that handles Read Receipt events. + * @returns A promise that represents the work queued. + */ + onTeamsReadReceiptEvent(handler) { + return this.on("TeamsReadReceipt", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const receiptInfo = context.activity.value; + yield handler(new botframework_connector_1.ReadReceiptInfo(receiptInfo.lastReadMessageId), context, next); + })); + } + /** + * Registers a handler for when a Teams meeting participant join. + * + * @param handler A callback that handles Meeting Participant Join events. + * @returns A promise that represents the work queued. + */ + onTeamsMeetingParticipantsJoinEvent(handler) { + return this.on("TeamsMeetingParticipantsJoin", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const meeting = context.activity.value; + yield handler({ + members: meeting === null || meeting === void 0 ? void 0 : meeting.members + }, context, next); + })); + } + /** + * Registers a handler for when a Teams meeting participant leave. + * + * @param handler A callback that handles Meeting Participant Leave events. + * @returns A promise that represents the work queued. + */ + onTeamsMeetingParticipantsLeaveEvent(handler) { + return this.on("TeamsMeetingParticipantsLeave", (context, next) => __awaiter2(this, void 0, void 0, function* () { + const meeting = context.activity.value; + yield handler({ + members: meeting === null || meeting === void 0 ? void 0 : meeting.members + }, context, next); + })); + } + }; + exports2.TeamsActivityHandler = TeamsActivityHandler; + } +}); + +// node_modules/botbuilder/lib/routeConstants.js +var require_routeConstants = __commonJS({ + "node_modules/botbuilder/lib/routeConstants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RouteConstants = void 0; + var RouteConstants = class { + }; + exports2.RouteConstants = RouteConstants; + RouteConstants.Conversations = "/v3/conversations"; + RouteConstants.ConversationHistory = "/v3/conversations/:conversationId/activities/history"; + RouteConstants.ConversationMembers = "/v3/conversations/:conversationId/members"; + RouteConstants.ConversationPagedMembers = "/v3/conversations/:conversationId/pagedmembers"; + RouteConstants.ConversationMember = "/v3/conversations/:conversationId/members/:memberId"; + RouteConstants.Attachments = "/v3/conversations/:conversationId/attachments"; + RouteConstants.Activities = "/v3/conversations/:conversationId/activities"; + RouteConstants.Activity = "/v3/conversations/:conversationId/activities/:activityId"; + RouteConstants.ActivityMembers = "/v3/conversations/:conversationId/activities/:activityId/members"; + } +}); + +// node_modules/botbuilder/lib/channelServiceRoutes.js +var require_channelServiceRoutes = __commonJS({ + "node_modules/botbuilder/lib/channelServiceRoutes.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ChannelServiceRoutes = void 0; + var botbuilder_core_1 = require_lib10(); + var statusCodeError_1 = require_statusCodeError(); + var activityValidator_1 = require_activityValidator(); + var routeConstants_1 = require_routeConstants(); + var ChannelServiceRoutes = class _ChannelServiceRoutes { + /** + * @param channelServiceHandler The channel service handler. + */ + constructor(channelServiceHandler) { + this.channelServiceHandler = channelServiceHandler; + } + /** + * Registers all Channel Service paths on the provided WebServer. + * + * @param server WebServer + * @param basePath Optional basePath which is appended before the service's REST API is configured on the WebServer. + */ + register(server2, basePath = "") { + server2.post(basePath + routeConstants_1.RouteConstants.Activities, this.processSendToConversation.bind(this)); + server2.post(basePath + routeConstants_1.RouteConstants.Activity, this.processReplyToActivity.bind(this)); + server2.put(basePath + routeConstants_1.RouteConstants.Activity, this.processUpdateActivity.bind(this)); + server2.get(basePath + routeConstants_1.RouteConstants.ActivityMembers, this.processGetActivityMembers.bind(this)); + server2.post(basePath + routeConstants_1.RouteConstants.Conversations, this.processCreateConversation.bind(this)); + server2.get(basePath + routeConstants_1.RouteConstants.Conversations, this.processGetConversations.bind(this)); + server2.get(basePath + routeConstants_1.RouteConstants.ConversationMembers, this.processGetConversationMembers.bind(this)); + server2.get(basePath + routeConstants_1.RouteConstants.ConversationMember, this.processGetConversationMember.bind(this)); + server2.get(basePath + routeConstants_1.RouteConstants.ConversationPagedMembers, this.processGetConversationPagedMembers.bind(this)); + server2.post(basePath + routeConstants_1.RouteConstants.ConversationHistory, this.processSendConversationHistory.bind(this)); + server2.post(basePath + routeConstants_1.RouteConstants.Attachments, this.processUploadAttachment.bind(this)); + if (typeof server2.delete === "function") { + server2.delete(basePath + routeConstants_1.RouteConstants.ConversationMember, this.processDeleteConversationMember.bind(this)); + server2.delete(basePath + routeConstants_1.RouteConstants.Activity, this.processDeleteActivity.bind(this)); + } else if (typeof server2.del === "function") { + server2.del(basePath + routeConstants_1.RouteConstants.ConversationMember, this.processDeleteConversationMember.bind(this)); + server2.del(basePath + routeConstants_1.RouteConstants.Activity, this.processDeleteActivity.bind(this)); + } + } + /** + * @private + */ + processSendToConversation(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + _ChannelServiceRoutes.readActivity(req).then((activity) => { + this.channelServiceHandler.handleSendToConversation(authHeader, req.params.conversationId, activity).then((resourceResponse) => { + res.status(200); + if (resourceResponse) { + res.send(resourceResponse); + } + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processReplyToActivity(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + _ChannelServiceRoutes.readActivity(req).then((activity) => { + this.channelServiceHandler.handleReplyToActivity(authHeader, req.params.conversationId, req.params.activityId, activity).then((resourceResponse) => { + res.status(200); + if (resourceResponse) { + res.send(resourceResponse); + } + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processUpdateActivity(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + _ChannelServiceRoutes.readActivity(req).then((activity) => { + this.channelServiceHandler.handleUpdateActivity(authHeader, req.params.conversationId, req.params.activityId, activity).then((resourceResponse) => { + res.status(200); + if (resourceResponse) { + res.send(resourceResponse); + } + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processDeleteActivity(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + this.channelServiceHandler.handleDeleteActivity(authHeader, req.params.conversationId, req.params.activityId).then(() => { + res.status(200); + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processGetActivityMembers(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + this.channelServiceHandler.handleGetActivityMembers(authHeader, req.params.conversationId, req.params.activityId).then((channelAccounts) => { + if (channelAccounts) { + res.send(channelAccounts); + } + res.status(200); + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processCreateConversation(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + _ChannelServiceRoutes.readBody(req).then((conversationParameters) => { + this.channelServiceHandler.handleCreateConversation(authHeader, conversationParameters).then((conversationResourceResponse) => { + if (conversationResourceResponse) { + res.send(conversationResourceResponse); + } + res.status(201); + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + }); + } + /** + * @private + */ + processGetConversations(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + this.channelServiceHandler.handleGetConversations(authHeader, req.params.conversationId, req.query.continuationToken).then((conversationsResult) => { + if (conversationsResult) { + res.send(conversationsResult); + } + res.status(200); + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processGetConversationMembers(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + this.channelServiceHandler.handleGetConversationMembers(authHeader, req.params.conversationId).then((channelAccounts) => { + res.status(200); + if (channelAccounts) { + res.send(channelAccounts); + } + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processGetConversationMember(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + this.channelServiceHandler.handleGetConversationMember(authHeader, req.params.memberId, req.params.conversationId).then((channelAccount) => { + res.status(200); + if (channelAccount) { + res.send(channelAccount); + } + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processGetConversationPagedMembers(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + let pageSize = parseInt(req.query.pageSize); + if (isNaN(pageSize)) { + pageSize = void 0; + } + this.channelServiceHandler.handleGetConversationPagedMembers(authHeader, req.params.conversationId, pageSize, req.query.continuationToken).then((pagedMembersResult) => { + res.status(200); + if (pagedMembersResult) { + res.send(pagedMembersResult); + } + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processDeleteConversationMember(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + this.channelServiceHandler.handleDeleteConversationMember(authHeader, req.params.conversationId, req.params.memberId).then(() => { + res.status(200); + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processSendConversationHistory(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + _ChannelServiceRoutes.readBody(req).then((transcript) => { + this.channelServiceHandler.handleSendConversationHistory(authHeader, req.params.conversationId, transcript).then((resourceResponse) => { + if (resourceResponse) { + res.send(resourceResponse); + } + res.status(200); + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + processUploadAttachment(req, res, next) { + const authHeader = req.headers.authorization || req.headers.Authorization || ""; + _ChannelServiceRoutes.readBody(req).then((attachmentData) => { + this.channelServiceHandler.handleUploadAttachment(authHeader, req.params.conversationId, attachmentData).then((resourceResponse) => { + if (resourceResponse) { + res.send(resourceResponse); + } + res.status(200); + res.end(); + return next(); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + }).catch((err) => { + _ChannelServiceRoutes.handleError(err, res); + }); + } + /** + * @private + */ + static readActivity(req) { + return new Promise((resolve, reject) => { + if (req.body) { + try { + const activity = (0, activityValidator_1.validateAndFixActivity)(req.body); + resolve(activity); + } catch (err) { + reject(new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.BAD_REQUEST, err.message)); + } + } else { + let requestData = ""; + req.on("data", (chunk) => { + requestData += chunk; + }); + req.on("end", () => { + try { + const body = JSON.parse(requestData); + const activity = (0, activityValidator_1.validateAndFixActivity)(body); + resolve(activity); + } catch (err) { + reject(new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.BAD_REQUEST, err.message)); + } + }); + } + }); + } + /** + * @private + */ + static readBody(req) { + return new Promise((resolve, reject) => { + if (req.body) { + try { + resolve(req.body); + } catch (err) { + reject(new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.BAD_REQUEST, err.message)); + } + } else { + let requestData = ""; + req.on("data", (chunk) => { + requestData += chunk; + }); + req.on("end", () => { + try { + const body = JSON.parse(requestData); + resolve(body); + } catch (err) { + reject(new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.BAD_REQUEST, err.message)); + } + }); + } + }); + } + /** + * @private + */ + static handleError(err, res) { + res.status(typeof (err === null || err === void 0 ? void 0 : err.statusCode) === "number" ? err.statusCode : 500); + if (err instanceof Error) { + res.send(err.message); + } else { + res.send("An error occurred while processing the request."); + console.error(err); + } + res.end(); + } + }; + exports2.ChannelServiceRoutes = ChannelServiceRoutes; + } +}); + +// node_modules/dayjs/dayjs.min.js +var require_dayjs_min = __commonJS({ + "node_modules/dayjs/dayjs.min.js"(exports2, module2) { + !(function(t, e) { + "object" == typeof exports2 && "undefined" != typeof module2 ? module2.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + })(exports2, (function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: function t2(e2, n2) { + if (e2.date() < n2.date()) return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = "$isDayjsObject", S = function(t2) { + return t2 instanceof _ || !(!t2 || !t2[p]); + }, w = function t2(e2, n2, r2) { + var i2; + if (!e2) return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, O = function(t2, e2) { + if (S(t2)) return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, b = v; + b.l = w, b.i = S, b.w = function(t2, e2) { + return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = (function() { + function M2(t2) { + this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; + } + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = (function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) return /* @__PURE__ */ new Date(NaN); + if (b.u(e2)) return /* @__PURE__ */ new Date(); + if (e2 instanceof Date) return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + })(t2), this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return b; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = O(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return O(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < O(t2); + }, m2.$g = function(t2, e2, n2) { + return b.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) { + var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, $2 = function(t3, e3) { + return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (f2) { + case h: + return r2 ? l2(1, 0) : l2(31, 11); + case c: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === c || o2 === h) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[b.p(t2)](); + }, m2.add = function(r2, f2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = b.p(f2), y2 = function(t2) { + var e2 = O(l2); + return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }; + if ($2 === c) return this.set(c, this.$M + r2); + if ($2 === h) return this.set(h, this.$y + r2); + if ($2 === a) return y2(1); + if ($2 === o) return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return b.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, d2 = function(t3) { + return b.s(s2 % 12 || 12, t3, "0"); + }, $2 = f2 || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }; + return r2.replace(y, (function(t3, r3) { + return r3 || (function(t4) { + switch (t4) { + case "YY": + return String(e2.$y).slice(-2); + case "YYYY": + return b.s(e2.$y, 4, "0"); + case "M": + return a2 + 1; + case "MM": + return b.s(a2 + 1, 2, "0"); + case "MMM": + return h2(n2.monthsShort, a2, c2, 3); + case "MMMM": + return h2(c2, a2); + case "D": + return e2.$D; + case "DD": + return b.s(e2.$D, 2, "0"); + case "d": + return String(e2.$W); + case "dd": + return h2(n2.weekdaysMin, e2.$W, o2, 2); + case "ddd": + return h2(n2.weekdaysShort, e2.$W, o2, 3); + case "dddd": + return o2[e2.$W]; + case "H": + return String(s2); + case "HH": + return b.s(s2, 2, "0"); + case "h": + return d2(1); + case "hh": + return d2(2); + case "a": + return $2(s2, u2, true); + case "A": + return $2(s2, u2, false); + case "m": + return String(u2); + case "mm": + return b.s(u2, 2, "0"); + case "s": + return String(e2.$s); + case "ss": + return b.s(e2.$s, 2, "0"); + case "SSS": + return b.s(e2.$ms, 3, "0"); + case "Z": + return i2; + } + return null; + })(t3) || i2.replace(":", ""); + })); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() { + return b.m(y2, m3); + }; + switch (M3) { + case h: + $2 = D2() / 12; + break; + case c: + $2 = D2(); + break; + case f: + $2 = D2() / 3; + break; + case o: + $2 = (g2 - v2) / 6048e5; + break; + case a: + $2 = (g2 - v2) / 864e5; + break; + case u: + $2 = g2 / n; + break; + case s: + $2 = g2 / e; + break; + case i: + $2 = g2 / t; + break; + default: + $2 = g2; + } + return l2 ? $2 : b.a($2); + }, m2.daysInMonth = function() { + return this.endOf(c).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) return this.$L; + var n2 = this.clone(), r2 = w(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return b.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + })(), k = _.prototype; + return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach((function(t2) { + k[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + })), O.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, O), t2.$i = true), O; + }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { + return O(1e3 * t2); + }, O.en = D[g], O.Ls = D, O.p = {}, O; + })); + } +}); + +// node_modules/dayjs/plugin/timezone.js +var require_timezone = __commonJS({ + "node_modules/dayjs/plugin/timezone.js"(exports2, module2) { + !(function(t, e) { + "object" == typeof exports2 && "undefined" != typeof module2 ? module2.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e(); + })(exports2, (function() { + "use strict"; + var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {}; + return function(n, i, o) { + var r, a = function(t2, n2, i2) { + void 0 === i2 && (i2 = {}); + var o2 = new Date(t2), r2 = (function(t3, n3) { + void 0 === n3 && (n3 = {}); + var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3]; + return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3; + })(n2, i2); + return r2.formatToParts(o2); + }, u = function(e2, n2) { + for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) { + var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2]; + c >= 0 && (r2[c] = parseInt(m, 10)); + } + var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2; + return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4; + }, f = i.prototype; + f.tz = function(t2, e2) { + void 0 === t2 && (t2 = r); + var n2, i2 = this.utcOffset(), a2 = this.toDate(), u2 = a2.toLocaleString("en-US", { timeZone: t2 }), f2 = Math.round((a2 - new Date(u2)) / 1e3 / 60), s2 = 15 * -Math.round(a2.getTimezoneOffset() / 15) - f2; + if (!Number(s2)) n2 = this.utcOffset(0, e2); + else if (n2 = o(u2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(s2, true), e2) { + var m = n2.utcOffset(); + n2 = n2.add(i2 - m, "minute"); + } + return n2.$x.$timezone = t2, n2; + }, f.offsetName = function(t2) { + var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find((function(t3) { + return "timezonename" === t3.type.toLowerCase(); + })); + return n2 && n2.value; + }; + var s = f.startOf; + f.startOf = function(t2, e2) { + if (!this.$x || !this.$x.$timezone) return s.call(this, t2, e2); + var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L }); + return s.call(n2, t2, e2).tz(this.$x.$timezone, true); + }, o.tz = function(t2, e2, n2) { + var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2); + if ("string" != typeof t2) return o(t2).tz(a2); + var s2 = (function(t3, e3, n3) { + var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3); + if (e3 === o2) return [i3, e3]; + var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3); + return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)]; + })(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c); + return d.$x.$timezone = a2, d; + }, o.tz.guess = function() { + return Intl.DateTimeFormat().resolvedOptions().timeZone; + }, o.tz.setDefault = function(t2) { + r = t2; + }; + }; + })); + } +}); + +// node_modules/botbuilder/lib/handoffEventNames.js +var require_handoffEventNames = __commonJS({ + "node_modules/botbuilder/lib/handoffEventNames.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.HandoffEventNames = void 0; + var HandoffEventNames = class { + }; + exports2.HandoffEventNames = HandoffEventNames; + HandoffEventNames.InitiateHandoff = "handoff.initiate"; + HandoffEventNames.HandoffStatus = "handoff.status"; + } +}); + +// node_modules/botbuilder/lib/eventFactory.js +var require_eventFactory = __commonJS({ + "node_modules/botbuilder/lib/eventFactory.js"(exports2) { + "use strict"; + var __importDefault2 = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.EventFactory = void 0; + var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports)); + var botbuilder_core_1 = require_lib10(); + var dayjs_1 = __importDefault2(require_dayjs_min()); + var timezone_1 = __importDefault2(require_timezone()); + dayjs_1.default.extend(timezone_1.default); + var handoffEventNames_1 = require_handoffEventNames(); + var EventFactory = class { + /** + * Create handoff initiation event. + * + * @param context The context object for the turn. + * @param handoffContext Agent hub-specific context. + * @param transcript Transcript of the conversation. + * @returns The handoff event activity. + */ + static createHandoffInitiation(context, handoffContext, transcript) { + if (!context) { + throw new TypeError("EventFactory.createHandoffInitiation(): Missing context."); + } + const handoffEvent = this.createHandoffEvent(handoffEventNames_1.HandoffEventNames.InitiateHandoff, handoffContext, context.activity.conversation); + handoffEvent.from = context.activity.from; + handoffEvent.relatesTo = botbuilder_core_1.TurnContext.getConversationReference(context.activity); + handoffEvent.replyToId = context.activity.id; + handoffEvent.serviceUrl = context.activity.serviceUrl; + handoffEvent.channelId = context.activity.channelId; + if (transcript) { + const attachment = { + content: transcript, + contentType: "application/json", + name: "Transcript" + }; + handoffEvent.attachments.push(attachment); + } + return handoffEvent; + } + /** + * Create handoff status event. + * + * @param conversation Conversation being handed over. + * @param state State, possible values are: "accepted", "failed", "completed". + * @param message Additional message for failed handoff. + * @returns The handoff event activity. + */ + static createHandoffStatus(conversation, state, message) { + if (!conversation) { + throw new TypeError("EventFactory.createHandoffStatus(): missing conversation."); + } + if (!state) { + throw new TypeError("EventFactory.createHandoffStatus(): missing state."); + } + return this.createHandoffEvent(handoffEventNames_1.HandoffEventNames.HandoffStatus, { state, message }, conversation); + } + /** + * @private + */ + static createHandoffEvent(name, value, conversation) { + const handoffEvent = { type: botbuilder_core_1.ActivityTypes.Event }; + handoffEvent.name = name; + handoffEvent.value = value; + handoffEvent.id = (0, uuid_1.v4)(); + handoffEvent.timestamp = new Date(Date.now()); + handoffEvent.localTimezone = dayjs_1.default.tz.guess(); + handoffEvent.conversation = conversation; + handoffEvent.attachments = []; + handoffEvent.entities = []; + return handoffEvent; + } + }; + exports2.EventFactory = EventFactory; + } +}); + +// node_modules/botbuilder/lib/sharepoint/sharePointActivityHandler.js +var require_sharePointActivityHandler = __commonJS({ + "node_modules/botbuilder/lib/sharepoint/sharePointActivityHandler.js"(exports2) { + "use strict"; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SharePointActivityHandler = void 0; + var botbuilder_core_1 = require_lib10(); + var SharePointActivityHandler = class extends botbuilder_core_1.ActivityHandler { + /** + * Invoked when an invoke activity is received from the connector. + * Invoke activities can be used to communicate many different things. + * Invoke activities communicate programmatic commands from a client or channel to a bot. + * + * @param context A strongly-typed context object for this turn + * @returns A task that represents the work queued to execute + */ + onInvokeActivity(context) { + const _super = Object.create(null, { + onInvokeActivity: { get: () => super.onInvokeActivity } + }); + return __awaiter2(this, void 0, void 0, function* () { + try { + if (!context.activity.name && context.activity.channelId === "sharepoint") { + throw new Error("NotImplemented"); + } else { + switch (context.activity.name) { + case "cardExtension/getCardView": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.onSharePointTaskGetCardViewAsync(context, context.activity.value)); + case "cardExtension/getQuickView": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.onSharePointTaskGetQuickViewAsync(context, context.activity.value)); + case "cardExtension/getPropertyPaneConfiguration": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.onSharePointTaskGetPropertyPaneConfigurationAsync(context, context.activity.value)); + case "cardExtension/setPropertyPaneConfiguration": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.onSharePointTaskSetPropertyPaneConfigurationAsync(context, context.activity.value)); + case "cardExtension/handleAction": + return botbuilder_core_1.ActivityHandler.createInvokeResponse(yield this.onSharePointTaskHandleActionAsync(context, context.activity.value)); + case "cardExtension/token": + yield this.onSignInInvoke(context); + return botbuilder_core_1.ActivityHandler.createInvokeResponse(); + default: + return _super.onInvokeActivity.call(this, context); + } + } + } catch (err) { + if (err.message === "NotImplemented") { + return { status: 501 }; + } else if (err.message === "BadRequest") { + return { status: 400 }; + } + throw err; + } + }); + } + /** + * Override this in a derived class to provide logic for when a card view is fetched + * + * @param _context - A strongly-typed context object for this turn + * @param _aceRequest - The Ace invoke request value payload + * @returns A Card View Response for the request + */ + onSharePointTaskGetCardViewAsync(_context, _aceRequest) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Override this in a derived class to provide logic for when a quick view is fetched + * + * @param _context - A strongly-typed context object for this turn + * @param _aceRequest - The Ace invoke request value payload + * @returns A Quick View Response for the request + */ + onSharePointTaskGetQuickViewAsync(_context, _aceRequest) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Override this in a derived class to provide logic for getting configuration pane properties. + * + * @param _context - A strongly-typed context object for this turn + * @param _aceRequest - The Ace invoke request value payload + * @returns A Property Pane Configuration Response for the request + */ + onSharePointTaskGetPropertyPaneConfigurationAsync(_context, _aceRequest) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Override this in a derived class to provide logic for setting configuration pane properties. + * + * @param _context - A strongly-typed context object for this turn + * @param _aceRequest - The Ace invoke request value payload + * @returns A Card view or no-op action response + */ + onSharePointTaskSetPropertyPaneConfigurationAsync(_context, _aceRequest) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Override this in a derived class to provide logic for handling ACE action. + * + * @param _context - A strongly-typed context object for this turn + * @param _aceRequest - The Ace invoke request value payload + * @returns A handle action response + */ + onSharePointTaskHandleActionAsync(_context, _aceRequest) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + /** + * Override this method to support channel-specific behavior across multiple channels. + * + * @param _context - A strongly-typed context object for this turn + */ + onSignInInvoke(_context) { + return __awaiter2(this, void 0, void 0, function* () { + throw new Error("NotImplemented"); + }); + } + }; + exports2.SharePointActivityHandler = SharePointActivityHandler; + } +}); + +// node_modules/botbuilder/lib/sharepoint/sharePointSSOTokenExchangeMiddleware.js +var require_sharePointSSOTokenExchangeMiddleware = __commonJS({ + "node_modules/botbuilder/lib/sharepoint/sharePointSSOTokenExchangeMiddleware.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __setModuleDefault2 = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }); + var __importStar2 = exports2 && exports2.__importStar || function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SharePointSSOTokenExchangeMiddleware = void 0; + var z = __importStar2(require_zod()); + var botbuilder_core_1 = require_lib10(); + function getStorageKey(context) { + var _a; + const activity = context.activity; + const channelId = activity.channelId; + if (!channelId) { + throw new Error("invalid activity. Missing channelId"); + } + const conversationId = (_a = activity.conversation) === null || _a === void 0 ? void 0 : _a.id; + if (!conversationId) { + throw new Error("invalid activity. Missing conversation.id"); + } + const value = activity.value; + if (!(value === null || value === void 0 ? void 0 : value.id)) { + throw new Error("Invalid signin/tokenExchange. Missing activity.value.id."); + } + return `${channelId}/${conversationId}/${value.id}`; + } + function sendInvokeResponse(context, body = null, status = botbuilder_core_1.StatusCodes.OK) { + return __awaiter2(this, void 0, void 0, function* () { + yield context.sendActivity({ + type: botbuilder_core_1.ActivityTypes.InvokeResponse, + value: { body, status } + }); + }); + } + var ExchangeToken = z.custom((val) => typeof val.exchangeToken === "function", { message: "ExtendedUserTokenProvider" }); + var SharePointSSOTokenExchangeMiddleware = class { + /** + * Initializes a new instance of the SharePointSSOTokenExchangeMiddleware class. + * + * @param storage The [Storage](xref:botbuilder-core.Storage) to use for deduplication + * @param oAuthConnectionName The connection name to use for the single sign on token exchange + */ + constructor(storage, oAuthConnectionName) { + this.storage = storage; + this.oAuthConnectionName = oAuthConnectionName; + if (!storage) { + throw new TypeError("`storage` parameter is required"); + } + if (!oAuthConnectionName) { + throw new TypeError("`oAuthConnectionName` parameter is required"); + } + } + /** + * Called each time the bot receives a new request. + * + * @param context Context for current turn of conversation with the user. + * @param _next Function to call to continue execution to the next step in the middleware chain. + */ + onTurn(context, _next) { + return __awaiter2(this, void 0, void 0, function* () { + if (context.activity.channelId === botbuilder_core_1.Channels.M365 && context.activity.name === botbuilder_core_1.sharePointTokenExchange) { + if (!(yield this.exchangedToken(context))) { + return; + } + if (!(yield this.deduplicatedTokenExchangeId(context))) { + return; + } + } + return; + }); + } + deduplicatedTokenExchangeId(context) { + var _a, _b; + return __awaiter2(this, void 0, void 0, function* () { + const storeItem = { + eTag: (_a = context.activity.value) === null || _a === void 0 ? void 0 : _a.id + }; + try { + yield this.storage.write({ + [getStorageKey(context)]: storeItem + }); + } catch (err) { + const message = (_b = err.message) === null || _b === void 0 ? void 0 : _b.toLowerCase(); + if (message.includes("etag conflict") || message.includes("precondition is not met")) { + yield sendInvokeResponse(context); + return false; + } + throw err; + } + return true; + }); + } + exchangedToken(context) { + return __awaiter2(this, void 0, void 0, function* () { + let tokenExchangeResponse; + const aceRequest = context.activity.value; + try { + const userTokenClient = context.turnState.get(context.adapter.UserTokenClientKey); + const exchangeToken = ExchangeToken.safeParse(context.adapter); + if (userTokenClient) { + tokenExchangeResponse = yield userTokenClient.exchangeToken(context.activity.from.id, this.oAuthConnectionName, context.activity.channelId, { token: aceRequest.data }); + } else if (exchangeToken.success) { + tokenExchangeResponse = yield exchangeToken.data.exchangeToken(context, this.oAuthConnectionName, context.activity.from.id, { token: aceRequest.data }); + } else { + new Error("Token Exchange is not supported by the current adapter."); + } + } catch (_err) { + } + if (!(tokenExchangeResponse === null || tokenExchangeResponse === void 0 ? void 0 : tokenExchangeResponse.token)) { + const invokeResponse = { + id: "FAKE ID", + connectionName: this.oAuthConnectionName, + failureDetail: "The bot is unable to exchange token. Proceed with regular login." + }; + yield sendInvokeResponse(context, invokeResponse, botbuilder_core_1.StatusCodes.PRECONDITION_FAILED); + return false; + } + return true; + }); + } + }; + exports2.SharePointSSOTokenExchangeMiddleware = SharePointSSOTokenExchangeMiddleware; + } +}); + +// node_modules/botbuilder/lib/index.js +var require_lib19 = __commonJS({ + "node_modules/botbuilder/lib/index.js"(exports2) { + "use strict"; + var __createBinding2 = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar2 = exports2 && exports2.__exportStar || function(m, exports3) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding2(exports3, m, p); + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SharePointSSOTokenExchangeMiddleware = exports2.SharePointActivityHandler = exports2.TokenResolver = exports2.StreamingHttpClient = exports2.StatusCodeError = exports2.HandoffEventNames = exports2.EventFactory = exports2.CloudAdapter = exports2.ChannelServiceRoutes = exports2.ChannelServiceHandlerBase = exports2.ChannelServiceHandler = exports2.BotFrameworkHttpClient = exports2.BotFrameworkAdapter = void 0; + __exportStar2(require_lib10(), exports2); + __exportStar2(require_fileTranscriptStore(), exports2); + __exportStar2(require_inspectionMiddleware(), exports2); + __exportStar2(require_setSpeakMiddleware(), exports2); + __exportStar2(require_skills2(), exports2); + __exportStar2(require_teams4(), exports2); + __exportStar2(require_teamsActivityHandler(), exports2); + __exportStar2(require_teamsActivityHelpers(), exports2); + __exportStar2(require_teamsInfo(), exports2); + var botFrameworkAdapter_1 = require_botFrameworkAdapter(); + Object.defineProperty(exports2, "BotFrameworkAdapter", { enumerable: true, get: function() { + return botFrameworkAdapter_1.BotFrameworkAdapter; + } }); + var botFrameworkHttpClient_1 = require_botFrameworkHttpClient(); + Object.defineProperty(exports2, "BotFrameworkHttpClient", { enumerable: true, get: function() { + return botFrameworkHttpClient_1.BotFrameworkHttpClient; + } }); + var channelServiceHandler_1 = require_channelServiceHandler(); + Object.defineProperty(exports2, "ChannelServiceHandler", { enumerable: true, get: function() { + return channelServiceHandler_1.ChannelServiceHandler; + } }); + var channelServiceHandlerBase_1 = require_channelServiceHandlerBase(); + Object.defineProperty(exports2, "ChannelServiceHandlerBase", { enumerable: true, get: function() { + return channelServiceHandlerBase_1.ChannelServiceHandlerBase; + } }); + var channelServiceRoutes_1 = require_channelServiceRoutes(); + Object.defineProperty(exports2, "ChannelServiceRoutes", { enumerable: true, get: function() { + return channelServiceRoutes_1.ChannelServiceRoutes; + } }); + var cloudAdapter_1 = require_cloudAdapter(); + Object.defineProperty(exports2, "CloudAdapter", { enumerable: true, get: function() { + return cloudAdapter_1.CloudAdapter; + } }); + var eventFactory_1 = require_eventFactory(); + Object.defineProperty(exports2, "EventFactory", { enumerable: true, get: function() { + return eventFactory_1.EventFactory; + } }); + var handoffEventNames_1 = require_handoffEventNames(); + Object.defineProperty(exports2, "HandoffEventNames", { enumerable: true, get: function() { + return handoffEventNames_1.HandoffEventNames; + } }); + var statusCodeError_1 = require_statusCodeError(); + Object.defineProperty(exports2, "StatusCodeError", { enumerable: true, get: function() { + return statusCodeError_1.StatusCodeError; + } }); + var streaming_1 = require_streaming(); + Object.defineProperty(exports2, "StreamingHttpClient", { enumerable: true, get: function() { + return streaming_1.StreamingHttpClient; + } }); + Object.defineProperty(exports2, "TokenResolver", { enumerable: true, get: function() { + return streaming_1.TokenResolver; + } }); + var sharePointActivityHandler_1 = require_sharePointActivityHandler(); + Object.defineProperty(exports2, "SharePointActivityHandler", { enumerable: true, get: function() { + return sharePointActivityHandler_1.SharePointActivityHandler; + } }); + var sharePointSSOTokenExchangeMiddleware_1 = require_sharePointSSOTokenExchangeMiddleware(); + Object.defineProperty(exports2, "SharePointSSOTokenExchangeMiddleware", { enumerable: true, get: function() { + return sharePointSSOTokenExchangeMiddleware_1.SharePointSSOTokenExchangeMiddleware; + } }); + } +}); + +// server/models/adaptiveCard.js +var require_adaptiveCard = __commonJS({ + "server/models/adaptiveCard.js"(exports2, module2) { + var adaptiveCardForTabStageView = (baseUrlForOpenUrl) => ({ + $schema: "http://adaptivecards.io/schemas/adaptive-card.json", + body: [ + { + type: "TextBlock", + size: "Medium", + weight: "Bolder", + text: "Click the button to open the url in tab stage view" + }, + { + type: "ActionSet", + actions: [ + { + type: "Action.Submit", + title: "View via card", + data: { + msteams: { + type: "invoke", + value: { + type: "tab/tabInfoAction", + tabInfo: { + contentUrl: process.env.BaseUrl + "/content", + websiteUrl: process.env.BaseUrl + "/content", + name: "Stage view", + entityId: "entityId" + } + } + } + } + }, + { + type: "Action.OpenUrl", + title: "View via Deep Link", + url: "https://teams.microsoft.com/l/stage/" + process.env.TeamsAppId + "/0?context=%7B%22contentUrl%22%3A%22https%3A%2F%2F" + baseUrlForOpenUrl + "%2Fcontent%22%2C%22websiteUrl%22%3A%22https%3A%2F%2F" + baseUrlForOpenUrl + "%2Fcontent%22%2C%22name%22%3A%22DemoStageView%22%7D" + } + ] + } + ], + type: "AdaptiveCard", + version: "1.4" + }); + module2.exports = { + adaptiveCardForTabStageView + }; + } +}); + +// server/models/adaptiveCardUnfurling.js +var require_adaptiveCardUnfurling = __commonJS({ + "server/models/adaptiveCardUnfurling.js"(exports2, module2) { + var adaptiveCardForTabStageView = () => ({ + $schema: "http://adaptivecards.io/schemas/adaptive-card.json", + body: [ + { + type: "TextBlock", + size: "Medium", + weight: "Bolder", + text: "Click the button to open the url in tab stage view" + }, + { + type: "ActionSet", + actions: [ + { + type: "Action.Submit", + title: "View via card", + data: { + msteams: { + type: "invoke", + value: { + type: "tab/tabInfoAction", + tabInfo: { + contentUrl: process.env.BaseUrl + "/content", + websiteUrl: process.env.BaseUrl + "/content", + name: "Stage view", + entityId: "entityId" + } + } + } + } + } + ] + } + ], + type: "AdaptiveCard", + version: "1.4" + }); + module2.exports = { + adaptiveCardForTabStageView + }; + } +}); + +// server/bot/botActivityHandler.js +var require_botActivityHandler = __commonJS({ + "server/bot/botActivityHandler.js"(exports2, module2) { + var { TeamsActivityHandler, CardFactory, MessageFactory } = require_lib19(); + var adaptiveCards = require_adaptiveCard(); + var adaptiveCardUnfurling = require_adaptiveCardUnfurling(); + var BotActivityHandler = class extends TeamsActivityHandler { + constructor() { + super(); + this.onMessage(async (context, next) => { + const baseUrl = process.env.baseUrl ? process.env.baseUrl.split(":")[1] : ""; + await context.sendActivity({ attachments: [CardFactory.adaptiveCard(adaptiveCards.adaptiveCardForTabStageView(baseUrl))] }); + await next(); + }); + this.onMembersAdded(async (context, next) => { + const welcomeText = "Hello and welcome!, Please type any bot command to see the stage view feature"; + await context.sendActivity(MessageFactory.text(welcomeText)); + await next(); + }); + } + // invoked when an app based link query activity is received + handleTeamsAppBasedLinkQuery(context, query) { + const attachment = CardFactory.adaptiveCard(adaptiveCardUnfurling.adaptiveCardForTabStageView()); + const result = { + attachmentLayout: "list", + type: "result", + attachments: [attachment], + responseType: "composeExtension" + }; + const response = { + composeExtension: result + }; + return response; + } + }; + module2.exports.BotActivityHandler = BotActivityHandler; + } +}); + +// server/api/botController.js +var require_botController = __commonJS({ + "server/api/botController.js"(exports2, module2) { + var { + CloudAdapter, + ConfigurationBotFrameworkAuthentication + } = require_lib19(); + var { BotActivityHandler } = require_botActivityHandler(); + var botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env); + var adapter = new CloudAdapter(botFrameworkAuthentication); + adapter.onTurnError = async (context, error) => { + console.error(` + [onTurnError] unhandled error: ${error}`); + await context.sendTraceActivity( + "OnTurnError Trace", + `${error}`, + "https://www.botframework.com/schemas/error", + "TurnError" + ); + }; + var botActivityHandler = new BotActivityHandler(); + var botHandler = async (req, res) => { + await adapter.process(req, res, (context) => botActivityHandler.run(context)); + }; + module2.exports = botHandler; + } +}); + +// server/api/index.js +var require_api = __commonJS({ + "server/api/index.js"(exports2, module2) { + var express2 = require_express2(); + var router = express2.Router(); + router.post("/messages", require_botController()); + module2.exports = router; + } +}); + +// server/index.js +var path2 = require("path"); +var express = require_express2(); +var cors = require_lib3(); +var ENV_FILE = path2.join(__dirname, "../.env"); +require_main().config({ path: ENV_FILE }); +var PORT = process.env.PORT || 3978; +var server = express(); +server.use(cors()); +server.use(express.json()); +server.use(express.urlencoded({ + extended: true +})); +server.engine(".html", require_ejs().renderFile); +server.set("views", __dirname); +server.set("view engine", "ejs"); +server.use("/api", require_api()); +server.get("/content", (req, res) => { + res.sendFile("views/content-tab.html", { root: __dirname }); +}); +server.get("/tab", (req, res) => { + res.render("./views/sampleTab", { teamsAppId: process.env.TeamsAppId, baseUrl: process.env.BaseUrl }); +}); +server.get("*", (req, res) => { + res.json({ error: "Route not found" }); +}); +server.listen(PORT, () => { + console.log("Server listening on port: " + PORT); +}); +/*! Bundled license information: + +depd/index.js: + (*! + * depd + * Copyright(c) 2014-2018 Douglas Christopher Wilson + * MIT Licensed + *) + +bytes/index.js: + (*! + * bytes + * Copyright(c) 2012-2014 TJ Holowaychuk + * Copyright(c) 2015 Jed Watson + * MIT Licensed + *) + +content-type/index.js: + (*! + * content-type + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + *) + +statuses/index.js: + (*! + * statuses + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + *) + +toidentifier/index.js: + (*! + * toidentifier + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + *) + +http-errors/index.js: + (*! + * http-errors + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + *) + +destroy/index.js: + (*! + * destroy + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015-2022 Douglas Christopher Wilson + * MIT Licensed + *) + +unpipe/index.js: + (*! + * unpipe + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + *) + +raw-body/index.js: + (*! + * raw-body + * Copyright(c) 2013-2014 Jonathan Ong + * Copyright(c) 2014-2022 Douglas Christopher Wilson + * MIT Licensed + *) + +ee-first/index.js: + (*! + * ee-first + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + *) + +on-finished/index.js: + (*! + * on-finished + * Copyright(c) 2013 Jonathan Ong + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + *) + +body-parser/lib/read.js: +body-parser/lib/types/raw.js: +body-parser/lib/types/text.js: +body-parser/index.js: + (*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + *) + +media-typer/index.js: + (*! + * media-typer + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + *) + +mime-db/index.js: + (*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015-2022 Douglas Christopher Wilson + * MIT Licensed + *) + +mime-types/index.js: + (*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + *) + +type-is/index.js: + (*! + * type-is + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + *) + +body-parser/lib/types/json.js: +body-parser/lib/types/urlencoded.js: + (*! + * body-parser + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + *) + +merge-descriptors/index.js: + (*! + * merge-descriptors + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + *) + +encodeurl/index.js: + (*! + * encodeurl + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + *) + +escape-html/index.js: + (*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + *) + +parseurl/index.js: + (*! + * parseurl + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2017 Douglas Christopher Wilson + * MIT Licensed + *) + +finalhandler/index.js: + (*! + * finalhandler + * Copyright(c) 2014-2022 Douglas Christopher Wilson + * MIT Licensed + *) + +express/lib/router/layer.js: +express/lib/router/route.js: +express/lib/router/index.js: +express/lib/middleware/init.js: +express/lib/middleware/query.js: +express/lib/view.js: +express/lib/application.js: +express/lib/request.js: +express/lib/express.js: +express/index.js: + (*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + *) + +methods/index.js: + (*! + * methods + * Copyright(c) 2013-2014 TJ Holowaychuk + * Copyright(c) 2015-2016 Douglas Christopher Wilson + * MIT Licensed + *) + +safe-buffer/index.js: + (*! safe-buffer. MIT License. Feross Aboukhadijeh *) + +content-disposition/index.js: + (*! + * content-disposition + * Copyright(c) 2014-2017 Douglas Christopher Wilson + * MIT Licensed + *) + +etag/index.js: + (*! + * etag + * Copyright(c) 2014-2016 Douglas Christopher Wilson + * MIT Licensed + *) + +fresh/index.js: + (*! + * fresh + * Copyright(c) 2012 TJ Holowaychuk + * Copyright(c) 2016-2017 Douglas Christopher Wilson + * MIT Licensed + *) + +range-parser/index.js: + (*! + * range-parser + * Copyright(c) 2012-2014 TJ Holowaychuk + * Copyright(c) 2015-2016 Douglas Christopher Wilson + * MIT Licensed + *) + +send/index.js: + (*! + * send + * Copyright(c) 2012 TJ Holowaychuk + * Copyright(c) 2014-2022 Douglas Christopher Wilson + * MIT Licensed + *) + +forwarded/index.js: + (*! + * forwarded + * Copyright(c) 2014-2017 Douglas Christopher Wilson + * MIT Licensed + *) + +proxy-addr/index.js: + (*! + * proxy-addr + * Copyright(c) 2014-2016 Douglas Christopher Wilson + * MIT Licensed + *) + +express/lib/utils.js: +express/lib/response.js: + (*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + *) + +negotiator/index.js: + (*! + * negotiator + * Copyright(c) 2012 Federico Romero + * Copyright(c) 2012-2014 Isaac Z. Schlueter + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + *) + +accepts/index.js: + (*! + * accepts + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + *) + +cookie/index.js: + (*! + * cookie + * Copyright(c) 2012-2014 Roman Shtylman + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + *) + +vary/index.js: + (*! + * vary + * Copyright(c) 2014-2017 Douglas Christopher Wilson + * MIT Licensed + *) + +serve-static/index.js: + (*! + * serve-static + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2014-2016 Douglas Christopher Wilson + * MIT Licensed + *) + +object-assign/index.js: + (* + object-assign + (c) Sindre Sorhus + @license MIT + *) + +ejs/lib/ejs.js: + (** + * @file Embedded JavaScript templating engine. {@link http://ejs.co} + * @author Matthew Eernisse + * @author Tiancheng "Timothy" Gu + * @project EJS + * @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0} + *) + +axios/dist/node/axios.cjs: + (*! Axios v1.15.0 Copyright (c) 2026 Matt Zabriskie and contributors *) + +@azure/msal-node/lib/msal-node.cjs: + (*! @azure/msal-node v2.16.3 2025-08-05 *) + (*! @azure/msal-common v14.16.1 2025-08-05 *) + +@azure/msal-node/lib/msal-node.cjs: + (*! @azure/msal-node v5.1.2 2026-04-01 *) + (*! @azure/msal-common v16.4.1 2026-04-01 *) +*/ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/env/.env.local b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/env/.env.local new file mode 100644 index 0000000000..ef1cabe7de --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/env/.env.local @@ -0,0 +1,21 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +MICROSOFT_APP_TYPE= +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/infra/azure.bicep b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/infra/azure.bicep new file mode 100644 index 0000000000..c3ce051b3d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/infra/azure.bicep @@ -0,0 +1,44 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string + +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' +param microsoftAppType string +param microsoftAppTenantId string + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: microsoftAppType + msaAppTenantId: microsoftAppType == 'SingleTenant' ? microsoftAppTenantId : '' + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/infra/azure.parameters.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/infra/azure.parameters.json new file mode 100644 index 0000000000..0c8b50260d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/infra/azure.parameters.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "tab-stage-view" + }, + "microsoftAppType": { + "value": "${{MICROSOFT_APP_TYPE}}" + }, + "microsoftAppTenantId": { + "value": "${{MICROSOFT_APP_TENANT_ID}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/m365agents.local.yml b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/m365agents.local.yml new file mode 100644 index 0000000000..46218a6f44 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/m365agents.local.yml @@ -0,0 +1,100 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-stage-view-nodejs + +provision: + - uses: aadApp/create # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + with: + name: tab-stage-view-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # SingleTenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-stage-view${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: script + with: + run: + echo "::set-teamsfx-env MICROSOFT_APP_TYPE=SingleTenant"; + echo "::set-teamsfx-env MICROSOFT_APP_TENANT_ID=${{AAD_APP_TENANT_ID}}"; + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select or create resource grouop if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Teams Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Run npm command + - uses: cli/runNpmCommand + with: + args: install --no-audit + + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + MicrosoftAppType: SingleTenant + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} + BaseUrl: ${{BOT_ENDPOINT}} + TeamsAppId: ${{TEAMS_APP_ID}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/m365agents.yml b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/m365agents.yml new file mode 100644 index 0000000000..d7564c8df7 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-stage-view-nodejs + +environmentFolderPath: ./env \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/package.json b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/package.json new file mode 100644 index 0000000000..291787cade --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/package.json @@ -0,0 +1,36 @@ +{ + "name": "tab-stage-view", + "version": "1.0.0", + "description": "Microsoft Teams tab sample app for stage view", + "main": "server/index.js", + "scripts": { + "dev:teamsfx": "npm run dev", + "dev": "nodemon --inspect=9239 --signal SIGINT server/index.js", + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server/index.js", + "watch": "nodemon server/index.js", + "build": "node build.js", + "lint": "eslint .", + "server": "npm install && node server/index.js", + "manifest": "del \"appManifest\\appManifest.zip\" 2> nul && powershell Compress-Archive appManifest/* appManifest/appManifest.zip" + }, + "keywords": [], + "author": "Microsoft", + "license": "MIT", + "dependencies": { + "botbuilder": "^4.23.3", + "cors": "^2.8.5", + "dotenv": "^16.6.1", + "ejs": "^3.1.10", + "express": "^4.21.2", + "nodemon": "^3.1.14" + }, + "devDependencies": { + "eslint": "^8.57.1", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-promise": "^6.6.0", + "esbuild": "^0.25.0" + } +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/api/botController.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/api/botController.js new file mode 100644 index 0000000000..006cccd5d3 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/api/botController.js @@ -0,0 +1,37 @@ +const { + CloudAdapter, + ConfigurationBotFrameworkAuthentication +} = require('botbuilder'); +const { BotActivityHandler } = require('../bot/botActivityHandler'); + +const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env); + +const adapter = new CloudAdapter(botFrameworkAuthentication); + +adapter.onTurnError = async (context, error) => { + // This check writes out errors to console log .vs. server insights. + // NOTE: In production environment, you should consider logging this to Azure + // serverlication insights. + console.error(`\n [onTurnError] unhandled error: ${ error }`); + + // Send a trace activity, which will be displayed in Bot Framework Emulator + await context.sendTraceActivity( + 'OnTurnError Trace', + `${ error }`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); + + // Uncomment below commented line for local debugging. + // await context.sendActivity(`Sorry, it looks like something went wrong. Exception Caught: ${error}`); + +}; + +// Create bot handlers +const botActivityHandler = new BotActivityHandler(); +const botHandler = async (req, res) => { + // Route received a request to adapter for processing + await adapter.process(req, res, (context) => botActivityHandler.run(context)); +}; + +module.exports = botHandler; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/api/index.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/api/index.js new file mode 100644 index 0000000000..b7405d6a53 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/api/index.js @@ -0,0 +1,6 @@ +const express = require('express'); +const router = express.Router(); + +router.post('/messages', require('./botController')); + +module.exports = router; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/bot/botActivityHandler.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/bot/botActivityHandler.js new file mode 100644 index 0000000000..8a38226351 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/bot/botActivityHandler.js @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { TeamsActivityHandler , CardFactory, MessageFactory } = require('botbuilder'); +const adaptiveCards = require('../models/adaptiveCard'); +const adaptiveCardUnfurling = require('../models/adaptiveCardUnfurling'); + +class BotActivityHandler extends TeamsActivityHandler { + constructor() { + super(); + + this.onMessage(async (context, next) => { + // Base url without protocol to be used in OpenUrl encoded deeplink + const baseUrl = process.env.BaseUrl ? process.env.BaseUrl.split(':')[1] : ''; + await context.sendActivity({ attachments: [CardFactory.adaptiveCard(adaptiveCards.adaptiveCardForTabStageView(baseUrl))] }); + await next(); + }); + + this.onMembersAdded(async (context, next) => { + const welcomeText = "Hello and welcome!, Please type any bot command to see the stage view feature"; + await context.sendActivity(MessageFactory.text(welcomeText)); + await next(); + }); + } + + // invoked when an app based link query activity is received + handleTeamsAppBasedLinkQuery(context, query) { + const attachment = CardFactory.adaptiveCard(adaptiveCardUnfurling.adaptiveCardForTabStageView()); + const result = { + attachmentLayout: 'list', + type: 'result', + attachments: [attachment], + responseType: "composeExtension" + }; + + const response = { + composeExtension: result + }; + + return response; + } + +} + +module.exports.BotActivityHandler = BotActivityHandler; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/index.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/index.js new file mode 100644 index 0000000000..1e8ecffd4d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/index.js @@ -0,0 +1,33 @@ +const path = require('path'); +const express = require('express'); +const cors = require('cors'); +const ENV_FILE = path.join(__dirname, '../.env'); +require('dotenv').config({ path: ENV_FILE }); + +const PORT = process.env.PORT || 3978; +const server = express(); + +server.use(cors()); +server.use(express.json()); +server.use(express.urlencoded({ + extended: true +})); +server.set('views', __dirname); +server.set('view engine', 'ejs'); +server.use('/api', require('./api')); + +server.get('/content', (req, res) => { + res.sendFile('views/content-tab.html', { root: __dirname }); +}); + +server.get('/tab', (req, res) => { + res.render('./views/sampleTab', { teamsAppId: process.env.TeamsAppId, baseUrl: process.env.BaseUrl }); +}); + +server.get('*', (req, res) => { + res.json({ error: 'Route not found' }); +}); + +server.listen(PORT, () => { + console.log('Server listening on port: ' + PORT); +}); diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/models/adaptiveCard.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/models/adaptiveCard.js new file mode 100644 index 0000000000..031d154502 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/models/adaptiveCard.js @@ -0,0 +1,46 @@ +// Adaptive Card for tab to show in stage view +const adaptiveCardForTabStageView = (baseUrlForOpenUrl) => ({ + $schema: 'http://adaptivecards.io/schemas/adaptive-card.json', + body: [ + { + type: 'TextBlock', + size: 'Medium', + weight: 'Bolder', + text: 'Click the button to open the url in tab stage view' + }, + { + type: 'ActionSet', + actions: [ + { + type: "Action.Submit", + title: "View via card", + data: { + msteams: { + type: "invoke", + value: { + type: "tab/tabInfoAction", + tabInfo: { + contentUrl: process.env.BaseUrl + "/content", + websiteUrl: process.env.BaseUrl + "/content", + name: "Stage view", + entityId: "entityId" + } + } + } + } + }, + { + type: "Action.OpenUrl", + title: "View via Deep Link", + url: "https://teams.microsoft.com/l/stage/"+process.env.TeamsAppId+"/0?context=%7B%22contentUrl%22%3A%22https%3A%2F%2F"+baseUrlForOpenUrl+"%2Fcontent%22%2C%22websiteUrl%22%3A%22https%3A%2F%2F"+baseUrlForOpenUrl+"%2Fcontent%22%2C%22name%22%3A%22DemoStageView%22%7D" + } + ] + } + ], + type: 'AdaptiveCard', + version: '1.4' +}); + +module.exports = { + adaptiveCardForTabStageView, +}; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/models/adaptiveCardUnfurling.js b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/models/adaptiveCardUnfurling.js new file mode 100644 index 0000000000..bbf20d9714 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/models/adaptiveCardUnfurling.js @@ -0,0 +1,41 @@ +// Adaptive Card for link unfurling to show in stage view +const adaptiveCardForTabStageView = () => ({ + $schema: 'http://adaptivecards.io/schemas/adaptive-card.json', + body: [ + { + type: 'TextBlock', + size: 'Medium', + weight: 'Bolder', + text: 'Click the button to open the url in tab stage view' + }, + { + type: 'ActionSet', + actions: [ + { + type: "Action.Submit", + title: "View via card", + data: { + msteams: { + type: "invoke", + value: { + type: "tab/tabInfoAction", + tabInfo: { + contentUrl: process.env.BaseUrl + "/content", + websiteUrl: process.env.BaseUrl + "/content", + name: "Stage view", + entityId: "entityId" + } + } + } + } + }, + ] + } + ], + type: 'AdaptiveCard', + version: '1.4' +}); + +module.exports = { + adaptiveCardForTabStageView, +}; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/views/content-tab.html b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/views/content-tab.html new file mode 100644 index 0000000000..1bcca90a65 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/views/content-tab.html @@ -0,0 +1,30 @@ + + + + + + + +
+

Tab in Stage View

+

Learn about building Web apps with ASP.NET Core.

+ +
+ + + + diff --git a/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/views/sampleTab.ejs b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/views/sampleTab.ejs new file mode 100644 index 0000000000..e69249a8ab --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/nodejs/server/views/sampleTab.ejs @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+
+
+ Click on the button to view the stage view from deeplink: + +
+
+
+ + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/.env b/samples/TeamsSDK/Archived/tab-stage-view/python/.env new file mode 100644 index 0000000000..972a8ecf08 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/.env @@ -0,0 +1,4 @@ +MicrosoftAppId= +MicrosoftAppPassword= +TeamsAppId= +BaseUrl= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/.gitignore b/samples/TeamsSDK/Archived/tab-stage-view/python/.gitignore new file mode 100644 index 0000000000..3144f60181 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/.gitignore @@ -0,0 +1,12 @@ +# TeamsFx files +env/.env.*.user +appManifest/build/ + +# python virtual environment +.venv/ + +# misc +.deployment/ + +# tmp files +__pycache__/ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/extensions.json b/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/extensions.json new file mode 100644 index 0000000000..bf8c33db9c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension", + "ms-python.python", + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/launch.json b/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/launch.json new file mode 100644 index 0000000000..6d66d8beb8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/launch.json @@ -0,0 +1,69 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch App (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Launch App (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Python: Run App Locally" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Python: Run App Locally", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/app.py", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal" + } + ], + "compounds": [ + { + "name": "Debug (Edge)", + "configurations": [ + "Launch App (Edge)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug (Chrome)", + "configurations": [ + "Launch App (Chrome)", + "Python: Run App Locally" + ], + "preLaunchTask": "Prepare Teams App Resources", + "presentation": { + "group": "all", + "order": 2 + }, + "stopAll": true + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/settings.json b/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/settings.json new file mode 100644 index 0000000000..40ea4c3290 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "debug.onTaskErrors": "abort", + "python-envs.defaultEnvManager": "ms-python.python:system", + "python-envs.pythonProjects": [] +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/tasks.json b/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/tasks.json new file mode 100644 index 0000000000..643dd9b802 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/.vscode/tasks.json @@ -0,0 +1,78 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Prepare Teams App Resources", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the sideloading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978, // app service port + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT + "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/1.Install.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/1.Install.png new file mode 100644 index 0000000000..a08502c3e3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/1.Install.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/AppOffice.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/AppOffice.png new file mode 100644 index 0000000000..61491e2555 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/AppOutlook.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/AppOutlook.png new file mode 100644 index 0000000000..eaf7f6e445 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/InstallOffice.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/InstallOffice.png new file mode 100644 index 0000000000..eb6449d7d5 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/InstallOutlook.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/InstallOutlook.png new file mode 100644 index 0000000000..0328041f5e Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OpenAppIcon.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OpenAppIcon.png new file mode 100644 index 0000000000..53a44c14e3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OpenAppIcon.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OpenNewMail.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OpenNewMail.png new file mode 100644 index 0000000000..e1e768258d Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OpenNewMail.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OutlookUnfurling.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OutlookUnfurling.png new file mode 100644 index 0000000000..dbd12892bf Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/OutlookUnfurling.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/StageViewTab.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/StageViewTab.png new file mode 100644 index 0000000000..8e2de548aa Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/StageViewTab.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/TabDeepLink.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/TabDeepLink.png new file mode 100644 index 0000000000..fda6537aba Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/TabDeepLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/TabStageView.gif b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/TabStageView.gif new file mode 100644 index 0000000000..3c74dec834 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/TabStageView.gif differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/ViewViaCard.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/ViewViaCard.png new file mode 100644 index 0000000000..7a10bffa41 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/ViewViaCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/ViewViaDeepLink.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/ViewViaDeepLink.png new file mode 100644 index 0000000000..2ba23372f3 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/ViewViaDeepLink.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/Images/WelcomeMessage.png b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/WelcomeMessage.png new file mode 100644 index 0000000000..2ba065a78e Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/Images/WelcomeMessage.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/README.md b/samples/TeamsSDK/Archived/tab-stage-view/python/README.md new file mode 100644 index 0000000000..15d718f663 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/README.md @@ -0,0 +1,164 @@ +--- +page_type: sample +description: This sample app demonstrates the use of Teams tab in stage view using Python, featuring collaborative elements and interactive capabilities. +products: +- office-teams +- office +- office-365 +languages: +- python +extensions: + contentType: samples + createdDate: "12/06/2025" +urlFragment: officedev-microsoft-teams-samples-tab-stage-view-python +--- + +# Tab Stage View + +This sample app showcases the capabilities of Microsoft Teams tabs in stage view using Python. It demonstrates collaborative features such as multi-window support and interactive elements, allowing users to engage dynamically through adaptive cards and deep linking for a richer experience in Teams. + +For reference, see [Tabs link unfurling and Stage View](https://docs.microsoft.com/microsoftteams/platform/tabs/tabs-link-unfurling). + +## Included Features +* Bots +* Stage View (tabs) +* Collaborative Stageview + +## Interaction with app + +![Tab Stage ViewGif](Images/TabStageView.gif) + +## Prerequisites + +- Microsoft Teams is installed and you have an account +- [Python SDK](https://www.python.org/downloads/) min version 3.6 +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunneling solution + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) and [Python Extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Press **CTRL+Shift+P** to open the command box and enter **Python: Create Environment** to create and activate your desired virtual environment. Remember to select `requirements.txt` as dependencies to install when creating the virtual environment. +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. + +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Run the app (Manually Uploading to Teams) + +> Note these instructions are for running the sample on your local machine, the tunneling solution is required because the Teams service needs to call into the bot. + +1) Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +2) Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +3) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose the **supported account types** (any account type will work) + * Leave **Redirect URI** empty. + * Choose **Register**. +3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the appsettings.json. +4. Navigate to **API Permissions**, and make sure to add the follow permissions: + * Select Add a permission + * Select Microsoft Graph -> Delegated permissions. + * `User.Read` (enabled by default) + * Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + +4) Create [Azure Bot resource](https://docs.microsoft.com/azure/bot-service/bot-service-quickstart-registration) in Azure + - Use the current `https` URL you were given by running the tunneling application. Append with the path `/api/messages` used by this sample + - Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + - __*If you don't have an Azure account*__ you can use this [Azure free account here](https://azure.microsoft.com/free/) + +5) In a terminal, go to `samples/tab-stage-view/python` + +6) Activate your desired virtual environment + +7) Install dependencies by running ```pip install -r requirements.txt``` in the project folder. + +8) Update the `config.py` configuration for the bot to use the Microsoft App Id and App Password from the Bot Framework registration. (Note the App Password is referred to as the "client secret" in the azure portal and you can always create a new client secret anytime.) + +9) __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the `appManifest` folder to replace your Microsoft App Id (that was created when you registered your bot earlier) *everywhere* you see the place holder string `${{AAD_APP_CLIENT_ID}}` and `${{TEAMS_APP_ID}}` + - **Zip** up the contents of the `appManifest` folder to create a `manifest.zip` + - **Upload** the `manifest.zip` to Teams (in the Apps view click "Upload a custom app") + +10) Run your bot with `python app.py` + +## Running the sample + +- From Teams left side bar, select the ellipses ●●● and choose your app from the list. + +**Install App:** +![InstallApp](Images/1.Install.png) + +**Welcome message with feature explanation and Adaptive Card with actions:** +![Welcome Message](Images/WelcomeMessage.png) + +**Click view via card action:** +![Stage View in tab](Images/ViewViaCard.png) + +**Click view via deeplink:** +![Tab View](Images/ViewViaDeepLink.png) + +**Tab with execute deeplink action to open stage view:** +![Tab View](Images/StageViewTab.png) + +**Click execute deep-link:** +![Tab View](Images/TabDeepLink.png) + +- To view your app in Outlook on the web, go to [Outlook on the web](https://outlook.office.com/mail/) and sign in using your dev tenant account. +- On the side bar, select More Apps. Your sideloaded app title appears among your installed apps + +![InstallOutlook](Images/InstallOutlook.png) +![AppOutlook](Images/AppOutlook.png) + +## Office on the web + +- Log into office.com with test tenant credentials +- Select the Apps icon on the side bar. Your sideloaded app title appears among your installed apps + +![InstallOffice](Images/InstallOffice.png) +![AppOffice](Images/AppOffice.png) + +**After opening Outlook web, click the "New mail" button.** +![Open New Mail](Images/OpenNewMail.png) + +**On the tool bar on top, select Apps icon. Your sideloaded app title appears among your installed apps** +![OpenAppIcon](Images/OpenAppIcon.png) + +**Opening stage view from unfurling link. If you copy and paste a link from https://tabstageview.com/card into the compose message area the link will unfurl.** +![Outlook Unfurling](Images/OutlookUnfurling.png) + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Tabs](https://learn.microsoft.com/microsoftteams/platform/tabs/what-are-tabs) +- [Stage view](https://learn.microsoft.com/microsoftteams/platform/tabs/tabs-link-unfurling#stage-view) + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/api/bot_controller.py b/samples/TeamsSDK/Archived/tab-stage-view/python/api/bot_controller.py new file mode 100644 index 0000000000..588aeb3d53 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/api/bot_controller.py @@ -0,0 +1,42 @@ +# api/bot_controller.py + +import sys +import traceback +from aiohttp.web import Request, Response +from botbuilder.core import ( + TurnContext, +) +from botbuilder.integration.aiohttp import CloudAdapter, ConfigurationBotFrameworkAuthentication +from botbuilder.schema import Activity +from bots.bot_activity_handler import BotActivityHandler + +from config import DefaultConfig +CONFIG = DefaultConfig() +# Adapter settings using environment variables +ADAPTER = CloudAdapter(ConfigurationBotFrameworkAuthentication(CONFIG)) + +# Error handler +async def on_error(context: TurnContext, error: Exception): + print(f"\n[on_turn_error] unhandled error: {error}", file=sys.stderr) + traceback.print_exc() + + await context.send_activity("The bot encountered an error or bug.") + await context.send_activity("To continue, please fix the bot source code.") + + # Send a trace activity (for Emulator) + await context.send_trace_activity( + name="OnTurnError Trace", + value=str(error), + value_type="https://www.botframework.com/schemas/error", + label="TurnError" + ) + +ADAPTER.on_turn_error = on_error + +# Instantiate the bot +bot = BotActivityHandler() + +# Main request handler for /api/messages +async def messages(request: Request) -> Response: + + return await ADAPTER.process(request, bot) diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/api/routes.py b/samples/TeamsSDK/Archived/tab-stage-view/python/api/routes.py new file mode 100644 index 0000000000..f0ebc10ee3 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/api/routes.py @@ -0,0 +1,11 @@ +# api/routes.py + +from aiohttp import web +from .bot_controller import messages + +# Define aiohttp routes +api_routes = web.RouteTableDef() + +@api_routes.post('/api/messages') +async def messages_handler(request): + return await messages(request) diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/app.py b/samples/TeamsSDK/Archived/tab-stage-view/python/app.py new file mode 100644 index 0000000000..e2371dd9af --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/app.py @@ -0,0 +1,43 @@ +import os +import sys +import traceback +from pathlib import Path +from aiohttp import web +from dotenv import load_dotenv +from api.routes import api_routes + +load_dotenv() + +PORT = int(os.getenv("PORT", 3978)) +BASE_DIR = Path(__file__).parent +VIEWS_DIR = BASE_DIR / "views" + +app = web.Application() + +async def content_handler(request): + return web.FileResponse(VIEWS_DIR / "content-tab.html") + +async def tab_handler(request): + return web.FileResponse(VIEWS_DIR / "sampleTab.html") + +async def config_api(request): + return web.json_response({ + "BaseUrl": os.getenv("BaseUrl"), + "teamsAppId": os.getenv("TeamsAppId") + }) + +async def handle_404(request): + return web.json_response({"error": "Route not found"}, status=404) + +app.router.add_get("/content", content_handler) +app.router.add_get("/tab", tab_handler) +app.router.add_get("/api/config", config_api) +app.add_routes(api_routes) +app.router.add_route("*", "/{tail:.*}", handle_404) + +if __name__ == "__main__": + try: + web.run_app(app, port=PORT) + except Exception as e: + print("Error starting server:", e, file=sys.stderr) + traceback.print_exc() diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/color.png b/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/manifest.json b/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/manifest.json new file mode 100644 index 0000000000..27b67763f0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/manifest.json @@ -0,0 +1,90 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.microsoft.com", + "privacyUrl": "https://www.microsoft.com/privacy", + "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + }, + "name": { + "short": "Tab SV_Python", + "full": "Tab in stage view" + }, + "description": { + "short": "Microsoft Teams tab sample app showcasing stage view functionality.", + "full": "This sample app demonstrates the use of Teams tab in stage view using python, featuring collaborative elements and interactive capabilities." + }, + "icons": { + "outline": "outline.png", + "color": "color.png" + }, + "staticTabs": [ + { + "entityId": "stageViewTask", + "scopes": [ + "personal" + ], + "context": [ + "personalTab", + "channelTab" + ], + "name": "Stage View", + "contentUrl": "https://${{BOT_DOMAIN}}/tab", + "websiteUrl": "https://${{BOT_DOMAIN}}/tab", + "searchUrl": "https://${{BOT_DOMAIN}}/tab" + } + ], + "bots": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "scopes": [ + "team", + "personal", + "groupChat" + ], + "isNotificationOnly": false + } + ], + "accentColor": "#60A18E", + "composeExtensions": [ + { + "botId": "${{AAD_APP_CLIENT_ID}}", + "commands": [ + { + "id": "searchQuery", + "context": [ "commandBox" ], + "description": "Test command to run query", + "title": "Search Command", + "type": "query", + "parameters": [ + { + "name": "searchQuery", + "title": "Search Query", + "description": "Your search query", + "inputType": "text" + } + ] + } + ], + "messageHandlers": [ + { + "type": "link", + "value": { + "domains": [ + "tabstageview.com/card", + "${{BOT_DOMAIN}}" + ] + } + } + ] + } + ], + "permissions": [ "identity", "messageTeamMembers" ], + "validDomains": [ + "${{BOT_DOMAIN}}", + "token.botframework.com" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/outline.png b/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-stage-view/python/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/assets/sample.json b/samples/TeamsSDK/Archived/tab-stage-view/python/assets/sample.json new file mode 100644 index 0000000000..00ea1cc204 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-tab-stage-view-python", + "source": "officeDev", + "title": "Stage View", + "shortDescription": "This sample app demonstrates the use of Teams tab in stage view using python, featuring collaborative elements and interactive capabilities.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-stage-view/python", + "longDescription": [ + "The Stage View sample app illustrates the functionality of Microsoft Teams tabs in stage view with a python implementation, highlighting features like multi-window support and collaborative interactions. Users can engage through adaptive cards and deep links, enhancing their experience within Teams." + ], + "creationDateTime": "2025-06-12", + "updateDateTime": "2025-06-12", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "python" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "python" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab,bot" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/tab-stage-view/python/Images/TabStageView.gif", + "alt": "Solution UX showing stage view" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/bots/bot_activity_handler.py b/samples/TeamsSDK/Archived/tab-stage-view/python/bots/bot_activity_handler.py new file mode 100644 index 0000000000..1e9c21cd0a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/bots/bot_activity_handler.py @@ -0,0 +1,44 @@ +import os +from botbuilder.core import TurnContext, MessageFactory +from botbuilder.schema import Activity, ActivityTypes +from botbuilder.core.teams import TeamsActivityHandler +from botbuilder.schema.teams import AppBasedLinkQuery, MessagingExtensionResult, MessagingExtensionAttachment, MessagingExtensionResponse +from botbuilder.schema import Attachment + +from models import adaptive_card, adaptive_card_unfurling + + +class BotActivityHandler(TeamsActivityHandler): + async def on_message_activity(self, turn_context: TurnContext): + base_url = os.getenv("BaseUrl", "") + base_url = base_url.split("://")[-1] if "://" in base_url else base_url + + card = adaptive_card.adaptive_card_for_tab_stage_view(base_url) + attachment = Attachment( + content_type="application/vnd.microsoft.card.adaptive", + content=card + ) + + await turn_context.send_activity(Activity( + type=ActivityTypes.message, + attachments=[attachment] + )) + + async def on_members_added_activity(self, members_added, turn_context: TurnContext): + welcome_text = "Hello and welcome! Please type any bot command to see the stage view feature" + await turn_context.send_activity(MessageFactory.text(welcome_text)) + + async def on_teams_app_based_link_query(self, turn_context: TurnContext, query: AppBasedLinkQuery): + card = adaptive_card_unfurling.adaptive_card_for_tab_stage_view() + attachment = MessagingExtensionAttachment( + content_type="application/vnd.microsoft.card.adaptive", + content=card + ) + + result = MessagingExtensionResult( + type="result", + attachment_layout="list", + attachments=[attachment] + ) + + return MessagingExtensionResponse(compose_extension=result) diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/config.py b/samples/TeamsSDK/Archived/tab-stage-view/python/config.py new file mode 100644 index 0000000000..7ad775f627 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/config.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os + +""" Bot Configuration """ + + +class DefaultConfig: + """ Bot Configuration """ + + PORT = 3978 + APP_TYPE = os.environ.get("MicrosoftAppType", "SingleTenant") + APP_ID = os.environ.get("MicrosoftAppId", "") + APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "") + APP_TENANTID = os.environ.get("MicrosoftAppTenantId", "") + BOT_ENDPOINT = os.environ.get("BaseUrl", "<>") + TEAMS_APP_ID = os.environ.get("TeamsAppId", "<>") \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/env/.env.local b/samples/TeamsSDK/Archived/tab-stage-view/python/env/.env.local new file mode 100644 index 0000000000..502b7d8cd8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/env/.env.local @@ -0,0 +1,22 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. If you're adding a secret value, add SECRET_ prefix to the name so Teams Toolkit can handle them properly +BOT_ENDPOINT= +BOT_DOMAIN= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +MICROSOFT_APP_TYPE= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +MICROSOFT_APP_TENANT_ID= +RESOURCE_SUFFIX= +AZURE_SUBSCRIPTION_ID= +AZURE_RESOURCE_GROUP_NAME= +APP_NAME_SUFFIX=local \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/infra/azure.bicep b/samples/TeamsSDK/Archived/tab-stage-view/python/infra/azure.bicep new file mode 100644 index 0000000000..5593c83681 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/infra/azure.bicep @@ -0,0 +1,42 @@ +@maxLength(20) +@minLength(4) +@description('Used to generate names for all resources in this file') +param resourceBaseName string + +@description('Required when create Azure Bot service') +param botAadAppClientId string + +param botAppDomain string +param botAadAppTenantId string +@maxLength(42) +param botDisplayName string + +param botServiceName string = resourceBaseName +param botServiceSku string = 'F0' + +// Register your web service as a bot with the Bot Framework +resource botService 'Microsoft.BotService/botServices@2021-03-01' = { + kind: 'azurebot' + location: 'global' + name: botServiceName + properties: { + displayName: botDisplayName + endpoint: 'https://${botAppDomain}/api/messages' + msaAppId: botAadAppClientId + msaAppType: 'SingleTenant' + msaAppTenantId: botAadAppTenantId + } + sku: { + name: botServiceSku + } +} + +// Connect the bot service to Microsoft Teams +resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { + parent: botService + location: 'global' + name: 'MsTeamsChannel' + properties: { + channelName: 'MsTeamsChannel' + } +} diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/infra/azure.parameters.json b/samples/TeamsSDK/Archived/tab-stage-view/python/infra/azure.parameters.json new file mode 100644 index 0000000000..d73eebee50 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/infra/azure.parameters.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceBaseName": { + "value": "bot${{RESOURCE_SUFFIX}}" + }, + "botAadAppClientId": { + "value": "${{AAD_APP_CLIENT_ID}}" + }, + "botAadAppTenantId": { + "value": "${{AAD_APP_TENANT_ID}}" + }, + "botAppDomain": { + "value": "${{BOT_DOMAIN}}" + }, + "botDisplayName": { + "value": "tab-stage-view" + } + } + } \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/m365agents.local.yml b/samples/TeamsSDK/Archived/tab-stage-view/python/m365agents.local.yml new file mode 100644 index 0000000000..3d4daffe63 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/m365agents.local.yml @@ -0,0 +1,82 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-stage-view-python + +provision: + # Creates a new Azure Active Directory (AAD) app to authenticate users if the environment variable that stores clientId is empty + - uses: aadApp/create + with: + name: tab-stage-view-aad # Note: when you run aadApp/update, the AAD app name will be updated based on the definition in manifest. If you don't want to change the name, make sure the name in AAD manifest is the same with the name defined here. + generateClientSecret: true # If the value is false, the action will not generate client secret for you + signInAudience: "AzureADMyOrg" # SingleTenant + writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). + clientId: AAD_APP_CLIENT_ID + clientSecret: SECRET_AAD_APP_CLIENT_SECRET # Environment variable that starts with `SECRET_` will be stored to the .env.{envName}.user environment file + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-stage-view${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + - uses: arm/deploy # Deploy given ARM templates parallelly. + with: + subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you to select one subscription if its value is empty. You're free to reference other environment variable here, but TeamsFx will not ask you to select subscription if it's empty in this case. + resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}} # The AZURE_RESOURCE_GROUP_NAME is a built-in environment variable. TeamsFx will ask you to select or create one resource group if its value is empty. You're free to reference other environment variable here, but TeamsFx will not ask you to select or create resource group if it's empty in this case. + templates: + - path: ./infra/azure.bicep + parameters: ./infra/azure.parameters.json + deploymentName: Create-resources-for-bot + bicepCliVersion: v0.9.1 # Microsoft 365 Agents Toolkit will download this bicep CLI version from github for you, will use bicep CLI in PATH if you remove this config. + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + +deploy: + # Generate runtime environment variables + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env + envs: + MicrosoftAppType: SingleTenant + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + TeamsAppId: ${{TEAMS_APP_ID}} + BaseUrl: ${{BOT_ENDPOINT}} + MicrosoftAppTenantId: ${{AAD_APP_TENANT_ID}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/m365agents.yml b/samples/TeamsSDK/Archived/tab-stage-view/python/m365agents.yml new file mode 100644 index 0000000000..f67c545cc4 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-stage-view-python + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/models/adaptive_card.py b/samples/TeamsSDK/Archived/tab-stage-view/python/models/adaptive_card.py new file mode 100644 index 0000000000..2adf5dc650 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/models/adaptive_card.py @@ -0,0 +1,47 @@ +import os + +def adaptive_card_for_tab_stage_view(base_url_for_open_url: str) -> dict: + base_url = os.getenv("BaseUrl", "") + teams_app_id = os.getenv("TeamsAppId", "") + + return { + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.4", + "body": [ + { + "type": "TextBlock", + "size": "Medium", + "weight": "Bolder", + "text": "Click the button to open the url in tab stage view" + }, + { + "type": "ActionSet", + "actions": [ + { + "type": "Action.Submit", + "title": "View via card", + "data": { + "msteams": { + "type": "invoke", + "value": { + "type": "tab/tabInfoAction", + "tabInfo": { + "contentUrl": f"{base_url}/content", + "websiteUrl": f"{base_url}/content", + "name": "Stage view", + "entityId": "stageViewTask" + } + } + } + } + }, + { + "type": "Action.OpenUrl", + "title": "View via Deep Link", + "url": f"https://teams.microsoft.com/l/stage/{teams_app_id}/0?context=%7B%22contentUrl%22%3A%22https%3A%2F%2F{base_url_for_open_url}%2Fcontent%22%2C%22websiteUrl%22%3A%22https%3A%2F%2F{base_url_for_open_url}%2Fcontent%22%2C%22name%22%3A%22DemoStageView%22%7D" + } + ] + } + ] + } diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/models/adaptive_card_unfurling.py b/samples/TeamsSDK/Archived/tab-stage-view/python/models/adaptive_card_unfurling.py new file mode 100644 index 0000000000..90ce048197 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/models/adaptive_card_unfurling.py @@ -0,0 +1,40 @@ +import os + +def adaptive_card_for_tab_stage_view() -> dict: + base_url = os.getenv("BaseUrl", "") + return { + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.4", + "body": [ + { + "type": "TextBlock", + "size": "Medium", + "weight": "Bolder", + "text": "Click the button to open the url in tab stage view" + }, + { + "type": "ActionSet", + "actions": [ + { + "type": "Action.Submit", + "title": "View via card", + "data": { + "msteams": { + "type": "invoke", + "value": { + "type": "tab/tabInfoAction", + "tabInfo": { + "contentUrl": f"{base_url}/content", + "websiteUrl": f"{base_url}/content", + "name": "Stage view", + "entityId": "stageViewTask" + } + } + } + } + } + ] + } + ] + } diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/requirements.txt b/samples/TeamsSDK/Archived/tab-stage-view/python/requirements.txt new file mode 100644 index 0000000000..5f7eeb9a56 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/requirements.txt @@ -0,0 +1,3 @@ +aiohttp>=3.13.5 +python-dotenv>=1.2.2 +botbuilder-integration-aiohttp>=4.17.1 \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/views/content-tab.html b/samples/TeamsSDK/Archived/tab-stage-view/python/views/content-tab.html new file mode 100644 index 0000000000..a19f3715e2 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/views/content-tab.html @@ -0,0 +1,27 @@ + + + + + + + +
+

Tab in Stage View

+

Learn about building Web apps with ASP.NET Core.

+ +
+ + + + diff --git a/samples/TeamsSDK/Archived/tab-stage-view/python/views/sampleTab.html b/samples/TeamsSDK/Archived/tab-stage-view/python/views/sampleTab.html new file mode 100644 index 0000000000..de021a5954 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-stage-view/python/views/sampleTab.html @@ -0,0 +1,53 @@ + + + + + + + + + +
+
+
+ + Click on the button to view the stage view from deeplink: + +
+
+
+ + diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/M365Agent.ttkproj b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/M365Agent.ttkproj new file mode 100644 index 0000000000..aac958923a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/M365Agent.ttkproj @@ -0,0 +1,13 @@ + + + + beb78e4a-bea1-4c26-953c-a3f8ac413232 + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/aad.manifest.json b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/aad.manifest.json new file mode 100644 index 0000000000..d2f2c8dc8c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/aad.manifest.json @@ -0,0 +1,101 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "tab-staggered-permission-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMyOrg", + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "oauth2Permissions": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ], + "identifierUris": [ + "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}" + ], + "replyUrlsWithType": [ + { + "url": "${{TAB_ENDPOINT}}/auth-end", + "type": "Spa" + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/color.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/manifest.json b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/manifest.json new file mode 100644 index 0000000000..947c082566 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/manifest.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.1", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.teams.com", + "privacyUrl": "https://www.teams.com/privacy", + "termsOfUseUrl": "https://www.teams.com/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Staggered permission", + "full": "App to get staggered permissions" + }, + "description": { + "short": "Demo app to request staggered Graph API permissions in Teams tabs.", + "full": "This sample demonstrates how to obtain staggered Graph API permissions in a Microsoft Teams tab, prompting users for permissions only when specific features are accessed." + }, + "accentColor": "#235EA5", + "staticTabs": [ + { + "entityId": "Staggered permission", + "name": "tab", + "contentUrl": "https://${{TAB_DOMAIN}}/tab", + "websiteUrl": "https://${{TAB_DOMAIN}}/tab", + "scopes": [ + "personal" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "*.ngrok-free.app", + "${{TAB_DOMAIN}}" + ], + "webApplicationInfo": { + "id": "${{AAD_APP_CLIENT_ID}}", + "resource": "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/outline.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/appPackage/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/env/.env.local b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/env/.env.local new file mode 100644 index 0000000000..69ebf4a486 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/env/.env.local @@ -0,0 +1,23 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. +TEAMS_APP_ID= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_OAUTH2_PERMISSION_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY_HOST= +AAD_APP_OAUTH_AUTHORITY= +TAB_ENDPOINT= + +APP_NAME_SUFFIX=local +TAB_DOMAIN= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= + +M365_TITLE_ID= +M365_APP_ID= +TEAMSFX_M365_USER_NAME= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/launchSettings.json b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/launchSettings.json new file mode 100644 index 0000000000..92a69083e6 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/launchSettings.json @@ -0,0 +1,19 @@ +{ + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + }, + "Outlook (browser)": { + "commandName": "Project", + "launchUrl": "https://outlook.office.com/host/${{M365_APP_ID}}?login_hint=${{TEAMSFX_M365_USER_NAME}}" + }, + // Launch project within Teams without prepare app dependencies + "Microsoft Teams (browser) (skip update app)": { + "commandName": "Project", + "environmentVariables": { "UPDATE_TEAMS_APP": "false" }, + "launchUrl": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/m365agents.local.yml b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/m365agents.local.yml new file mode 100644 index 0000000000..74a03ab968 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/m365agents.local.yml @@ -0,0 +1,105 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-staggered-permission-csharp + +provision: + # Creates a new Azure Active Directory (AAD) app to authenticate users if + # the environment variable that stores clientId is empty + - uses: aadApp/create + with: + # Note: when you run aadApp/update, the AAD app name will be updated + # based on the definition in manifest. If you don't want to change the + # name, make sure the name in AAD manifest is the same with the name + # defined here. + name: tab-staggered-permission-aad + # If the value is false, the action will not generate client secret for you + generateClientSecret: true + # Authenticate users with a Microsoft work or school account in your + # organization's Azure AD tenant (for example, single tenant). + signInAudience: AzureADMyOrg + # Write the information of created resources into environment file for the + # specified environment variable(s). + writeToEnvironmentFile: + clientId: AAD_APP_CLIENT_ID + # Environment variable that starts with `SECRET_` will be stored to the + # .env.{envName}.user environment file + clientSecret: SECRET_AAD_APP_CLIENT_SECRET + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Set TAB_DOMAIN and TAB_ENDPOINT for local launch + - uses: script + with: + run: + echo "::set-teamsfx-env TAB_DOMAIN=localhost:44302"; + echo "::set-teamsfx-env TAB_ENDPOINT=https://localhost:44302"; + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-staggered-permission${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ../StaggeredPermission/appsettings.json + content: + AzureAd: + ClientId: ${{AAD_APP_CLIENT_ID}} + AppSecret: ${{SECRET_AAD_APP_CLIENT_SECRET}} + ApplicationIdURI: api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}} + + # Apply the AAD manifest to an existing AAD app. Will use the object id in + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appPackage/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Extend your Teams app to Outlook and the Microsoft 365 app + - uses: teamsApp/extendToM365 + with: + # Relative path to the build app package. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + titleId: M365_TITLE_ID + appId: M365_APP_ID \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/m365agents.yml b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/m365agents.yml new file mode 100644 index 0000000000..edc751a5fe --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/M365Agent/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-staggered-permission-csharp + +environmentFolderPath: ./env \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/README.md b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/README.md new file mode 100644 index 0000000000..bf350f75b4 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/README.md @@ -0,0 +1,219 @@ +--- +page_type: sample +description: This sample demonstrates how to obtain staggered Graph API permissions in a Microsoft Teams tab, prompting users for permissions only when specific features are accessed. +products: +- office-teams +- office +- office-365 +languages: +- csharp +extensions: + contentType: samples + createdDate: "03/17/2022 12:00:00 AM" +urlFragment: officedev-microsoft-teams-samples-tab-staggered-permission-csharp +--- + +# Staggered Permission sample + +This sample app showcases a robust approach to managing Graph API permissions within a Microsoft Teams tab, utilizing staggered permission requests to enhance user experience. By only prompting users for the necessary permissions when they attempt to access specific features—like photos or emails—the app ensures a seamless interaction while maintaining security and privacy. + + +## Included Features +* Teams SSO (tabs) +* MSAL.js 2.0 support +* Graph API + +## Interaction with app + +![Staggered Module](StaggeredPermission/Images/StaggeredModule.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app manifest (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Staggered Permission sample:** [Manifest](/samples/tab-staggered-permission/csharp/demo-manifest/tab-staggered-permission.zip) + +## Prerequisites + +- [.NET SDK](https://dotnet.microsoft.com/download) version 10.0 + + determine dotnet version + ```bash + dotnet --version + ``` +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [Ngrok](https://ngrok.com/download) (For local environment testing) latest version (any other tunneling software can also be used) + +- [Teams](https://teams.microsoft.com) Microsoft Teams is installed and you have an account + +- [Microsoft 365 Agents Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.14 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Microsoft 365 Agents Toolkit for Visual Studio [Microsoft 365 Agents Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In the debug dropdown menu of Visual Studio, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel. +1. Right-click the 'M365Agent' project in Solution Explorer and select **Microsoft 365 Agents Toolkit > Select Microsoft 365 Account** +1. Sign in to Microsoft 365 Agents Toolkit with a **Microsoft 365 work or school account** +1. Set `Startup Item` as `Microsoft Teams (browser)`. +1. Press F5, or select Debug > Start Debugging menu in Visual Studio to start your app +
![image](https://raw.githubusercontent.com/OfficeDev/TeamsFx/dev/docs/images/visualstudio/debug/debug-button.png) +1. In the opened web browser, select Add button to install the app in Teams +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. + - Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose **Accounts in this organizational directory only (Single tenant)**. + * Leave **Redirect URI** empty. + * Choose **Register**. + - On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You’ll need those later when updating your Teams application manifest and in the appsettings.json. + - Under **Manage**, select **Expose an API**. + - Select the **Set** link to generate the Application ID URI in the form of `api://{AppID}`. Insert your fully qualified domain name (with a forward slash "/" appended to the end) between the double forward slashes and the GUID. The entire ID should have the form of: `api://fully-qualified-domain-name/{AppID}` + * ex: `api://%ngrokDomain%.ngrok-free.app/00000000-0000-0000-0000-000000000000`. + - Select the **Add a scope** button. In the panel that opens, enter `access_as_user` as the **Scope name**. + - Set **Who can consent?** to `Admins and users` + - Fill in the fields for configuring the admin and user consent prompts with values that are appropriate for the `access_as_user` scope: + * **Admin consent title:** Teams can access the user’s profile. + * **Admin consent description**: Allows Teams to call the app’s web APIs as the current user. + * **User consent title**: Teams can access the user profile and make requests on the user's behalf. + * **User consent description:** Enable Teams to call this app’s APIs with the same rights as the user. + - Ensure that **State** is set to **Enabled** + - Select **Add scope** + * The domain part of the **Scope name** displayed just below the text field should automatically match the **Application ID** URI set in the previous step, with `/access_as_user` appended to the end: + * `api://[ngrokDomain].ngrok-free.app/00000000-0000-0000-0000-000000000000/access_as_user. +- In the **Authorized client applications** section, identify the applications that you want to authorize for your app’s web application. Each of the following IDs needs to be entered: + * `1fec8e78-bce4-4aaf-ab1b-5451cc387264` (Teams mobile/desktop application) + * `5e3ce6c0-2b1f-4285-8d4b-75ee78787346` (Teams web application) +**Note** If you want to test or extend your Teams apps across Office and Outlook, kindly add below client application identifiers while doing Azure AD app registration in your tenant: + * `4765445b-32c6-49b0-83e6-1d93765276ca` (Office web) + * `0ec893e0-5785-4de6-99da-4ed124e5296c` (Office desktop) + * `bc59ab01-8403-45c6-8796-ac3ef710b3e3` (Outlook web) + * `d3590ed6-52b3-4102-aeff-aad2292ab01c` (Outlook desktop) + - Navigate to **API Permissions**, and make sure to add the follow permissions: + - Select Add a permission + -  Select Microsoft Graph -\> Delegated permissions. + - `User.Read` (enabled by default) + - Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + - Navigate to **Authentication** + If an app hasn't been granted IT admin consent, users will have to provide consent the first time they use an app. + Set a redirect URI: + * Select **Add a platform**. + * Select **Single Page Application**. + * Enter the **redirect URI** for the app in the following format: `https://{Base_Url}/auth-end`. + - Navigate to the **Certificates & secrets**. In the Client secrets section, click on "+ New client secret". Add a description(Name of the secret) for the secret and select “Never” for Expires. Click "Add". Once the client secret is created, copy its value, it need to be placed in the appsettings.json. +- Ensure that you've [enabled the Teams Channel](https://learn.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) + +2. Setup NGROK + - Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +3. Setup for code + +- Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + +- Modify the `/appsettings.json` and fill in the following details: + - `{{MicrosoftAppId}}` - Generated from Step 1 while doing Microsoft Entra ID app registration in Azure portal. + - `{{MicrosoftAppPassword}}` - Generated from Step 1, also referred to as Client secret + - `{{ ApplicationBaseUrl }}` - Your application's base url. E.g. https://12345.ngrok-free.app if you are using ngrok and if you are using dev tunnels, your URL will be like: https://12345.devtunnels.ms. + - `{{ ApplicationIdURI }}` - Your application's ApplicationIdURI. * ex: `api:///00000000-0000-0000-0000-000000000000`.. + - `{{TenantId}}` - Generated from Step 1(Directory (tenant) ID) is the tenant id + +- Open the code in Visual Studio + - File -> Open -> Project/Solution + - Navigate to folder where repository is cloned then `samples/tab-staggered-permission/csharp/StaggeredPermission.sln` + - Press `F5` to run the project + +4. Setup Manifest for Teams +- __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the ./appPackage folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `{{Microsoft-App-Id}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` and replace `{{domain-name}}` with base Url of your domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Edit** the `manifest.json` for `webApplicationInfo` resource `"api://{{domain-name}}/{{Microsoft-App-Id}}"` with MicrosoftAppId. E.g. `"api://ngrok-free.app/00000000-0000-0000-0000-000000000000"` + - **Note:** If you want to test your app across multi hub like: Outlook/Office.com, please update the `manifest.json` in the `tab-staggered-permission\csharp\StaggeredPermission\AppManifest_Hub` folder with the required values. + - **Zip** up the contents of the `Manifest` folder to create a `Manifest.zip` or `AppManifest_Hub` folder to create a `AppManifest_Hub.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appPackage folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your app is uploaded to Teams. + +## Running the sample + + - User basic + +![user info card](StaggeredPermission/Images/user-info.png) + + - User photo + +![User mails](StaggeredPermission/Images/user-photo.png) + +- User emails + +![User mails](StaggeredPermission/Images/user-mails.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**On the side bar, select More Apps. Your uploaded app title appears among your installed apps** + +![InstallOutlook](StaggeredPermission/Images/InstallOutlook.png) + +**Select your app icon to launch and preview your app running in Outlook on the web** + +![AppOutlook](StaggeredPermission/Images/AppOutlook.png) + +**User Info** + +![UserDetailsOutlook](StaggeredPermission/Images/UserDetailsOutlook.png) + +**Note:** Similarly, you can test your application in the Outlook desktop app as well. + +## Office on the web + +- To preview your app running in Office on the web. + +- Log into office.com with test tenant credentials + +**Select the Apps icon on the side bar. Your uploaded app title appears among your installed apps** + +![InstallOffice](StaggeredPermission/Images/InstallOffice.png) + +**Select your app icon to launch your app in Office on the web** + +![AppOffice](StaggeredPermission/Images/AppOffice.png) + +**User Info** + +![UserDetailsOffice](StaggeredPermission/Images/UserDetailsOffice.png) + +**Note:** Similarly, you can test your application in the Office 365 desktop app as well. + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Tabs](https://learn.microsoft.com/microsoftteams/platform/tabs/what-are-tabs) +- [Authentication basics](https://docs.microsoft.com/microsoftteams/platform/concepts/authentication/authentication) +- [Extend Teams apps across Microsoft 365](https://learn.microsoft.com/microsoftteams/platform/m365-apps/overview) + + diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission.sln b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission.sln new file mode 100644 index 0000000000..995e24de23 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.34814.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StaggeredPermission", "StaggeredPermission\StaggeredPermission.csproj", "{BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}" +EndProject +Project("{A9E3F50B-275E-4AF7-ADCE-8BE12D41E305}") = "M365Agent", "M365Agent\M365Agent.ttkproj", "{BEB78E4A-BEA1-4C26-953C-A3F8AC413232}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{472FC046-929F-4413-B64A-BA177C23C0A8}" + ProjectSection(SolutionItems) = preProject + StaggeredPermission.slnLaunch.user = StaggeredPermission.slnLaunch.user + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEE3FB6B-5F07-491F-9669-23B0C1CA4A30}.Release|Any CPU.Build.0 = Release|Any CPU + {BEB78E4A-BEA1-4C26-953C-A3F8AC413232}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEB78E4A-BEA1-4C26-953C-A3F8AC413232}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEB78E4A-BEA1-4C26-953C-A3F8AC413232}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {BEB78E4A-BEA1-4C26-953C-A3F8AC413232}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEB78E4A-BEA1-4C26-953C-A3F8AC413232}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4D7C6DCC-3A5C-42E6-B6E8-2E80E5342C91} + EndGlobalSection +EndGlobal diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/.gitignore b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/.gitignore new file mode 100644 index 0000000000..4596bae4d8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +appPackage/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/color.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/manifest.json b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/manifest.json new file mode 100644 index 0000000000..c3b1b3e401 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/manifest.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.1", + "id": "{{Microsoft-App-Id}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.teams.com", + "privacyUrl": "https://www.teams.com/privacy", + "termsOfUseUrl": "https://www.teams.com/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Staggered permission", + "full": "App to get staggered permissions" + }, + "description": { + "short": "App to get staggered permissions", + "full": "This sample demos to get staggered graph api permissions" + }, + "accentColor": "#235EA5", + "staticTabs": [ + { + "entityId": "Staggered permission", + "name": "tab", + "contentUrl": "https://{{domain-name}}/tab", + "websiteUrl": "https://{{domain-name}}/tab", + "scopes": [ + "personal" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "{{domain-name}}" + ], + "webApplicationInfo": { + "id": "{{Microsoft-App-Id}}", + "resource": "api://{{domain-name}}/{{Microsoft-App-Id}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/outline.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/AppManifest_Hub/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Controllers/TabController.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Controllers/TabController.cs new file mode 100644 index 0000000000..1594b31f7c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Controllers/TabController.cs @@ -0,0 +1,134 @@ +using StaggeredPermission.helper; +using StaggeredPermission.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Threading.Tasks; + +namespace StaggeredPermission.Controllers +{ + public class TabController : Controller + { + public readonly IConfiguration _configuration; + + public TabController(IConfiguration configuration) + { + _configuration = configuration; + } + + // Get user's profile photo. + [HttpPost] + [Route("GetUserPhoto")] + public async Task GetUserPhoto(string idToken) + { + try + { + var bearerToken = await AuthHelper.GetAccessTokenOnBehalfUserAsync(_configuration, idToken); + var client = new SimpleGraphClient(bearerToken); + var photo = await client.GetPhotoAsync(); + + var userInfo = new UserData() + { + Photo = photo + }; + + var jsonString = JsonConvert.SerializeObject(userInfo); + return Json(jsonString); + } + catch (Exception ex) + { + Console.WriteLine(ex); + Response.StatusCode = StatusCodes.Status500InternalServerError; + return Json(JsonConvert.SerializeObject(new { error = "Unable to fetch user photo.", details = ex.Message })); + } + } + + // Get user's mails. + [HttpPost] + [Route("GetUserMails")] + public async Task GetUserMails(string idToken) + { + try + { + var bearerToken = await AuthHelper.GetAccessTokenOnBehalfUserAsync(_configuration, idToken); + var emails = new List(); + var client = new SimpleGraphClient(bearerToken); + + var mails = await client.GetMailsAsync(); + + foreach (var mail in mails) + { + if (mail.Sender != null && + mail.ToRecipients?.Any() == true && + !string.IsNullOrEmpty(mail.Subject)) + { + var userEntity = new UserEmail + { + FromMail = mail.Sender.EmailAddress?.Address, + ToMail = mail.ToRecipients.FirstOrDefault()?.EmailAddress?.Address, + Subject = mail.Subject, + Time = mail.SentDateTime?.ToString() + }; + + emails.Add(userEntity); + } + } + + var userInfo = new UserData() + { + Details = emails + }; + + var jsonString = JsonConvert.SerializeObject(userInfo); + return Json(jsonString); + } + catch (Exception ex) + { + Console.WriteLine(ex); + Response.StatusCode = StatusCodes.Status500InternalServerError; + return Json(JsonConvert.SerializeObject(new { error = "Unable to fetch user mails.", details = ex.Message })); + } + } + + // Get user details based on jwt id token. + [HttpPost] + [Route("decodeToken")] + public JsonResult DecodeToken(string accessToken) + { + try + { + object nameObj = null, emailObj = null; + var handler = new JwtSecurityTokenHandler(); + var decodedValue = handler.ReadJwtToken(accessToken); + if (decodedValue.Payload.ContainsKey("name")) + { + decodedValue.Payload.TryGetValue("name", out nameObj); + } + + if (decodedValue.Payload.ContainsKey("preferred_username")) + { + decodedValue.Payload.TryGetValue("preferred_username", out emailObj); + } + + var userInfo = new UserData() + { + Name = nameObj?.ToString(), + Email = emailObj?.ToString() + }; + + var jsonString = JsonConvert.SerializeObject(userInfo); + return Json(jsonString); + } + catch (Exception ex) + { + Console.WriteLine(ex); + Response.StatusCode = StatusCodes.Status500InternalServerError; + return Json(JsonConvert.SerializeObject(new { error = "Unable to decode token.", details = ex.Message })); + } + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/AppOffice.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/AppOffice.png new file mode 100644 index 0000000000..e19e9fb1ce Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/AppOutlook.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/AppOutlook.png new file mode 100644 index 0000000000..697860bfb1 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/InstallOffice.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/InstallOffice.png new file mode 100644 index 0000000000..e1a33b0bbc Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/InstallOutlook.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/InstallOutlook.png new file mode 100644 index 0000000000..3bf9f3db35 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/StaggeredModule.gif b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/StaggeredModule.gif new file mode 100644 index 0000000000..8646f09d8f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/StaggeredModule.gif differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/TabStaggeredPermissionGif.gif b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/TabStaggeredPermissionGif.gif new file mode 100644 index 0000000000..c622e786c4 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/TabStaggeredPermissionGif.gif differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/UserDetailsOffice.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/UserDetailsOffice.png new file mode 100644 index 0000000000..7c8753e1aa Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/UserDetailsOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/UserDetailsOutlook.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/UserDetailsOutlook.png new file mode 100644 index 0000000000..8388c2d1fe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/UserDetailsOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/consent-popup.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/consent-popup.png new file mode 100644 index 0000000000..a4d744320f Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/consent-popup.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/install.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/install.png new file mode 100644 index 0000000000..3c38fde127 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/install.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-info.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-info.png new file mode 100644 index 0000000000..701c6d4715 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-info.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-mails.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-mails.png new file mode 100644 index 0000000000..47709ce88c Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-mails.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-photo.png b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-photo.png new file mode 100644 index 0000000000..4956aedcf4 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Images/user-photo.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/Token.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/Token.cs new file mode 100644 index 0000000000..ef489bf376 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/Token.cs @@ -0,0 +1,14 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +namespace StaggeredPermission.Models +{ + /// + /// Token state model class. + /// + public class Token + { + public string AccessToken { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/UserData.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/UserData.cs new file mode 100644 index 0000000000..001a4d375c --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/UserData.cs @@ -0,0 +1,22 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +using System.Collections.Generic; + +namespace StaggeredPermission.Models +{ + /// + /// User data model class. + /// + public class UserData + { + public string Photo { get; set; } + + public string Name { get; set; } + + public string Email { get; set; } + + public List Details { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/UserEmail.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/UserEmail.cs new file mode 100644 index 0000000000..3b85776710 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Models/UserEmail.cs @@ -0,0 +1,20 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// + +namespace StaggeredPermission.Models +{ + /// + /// User email model class. + /// + public class UserEmail + { + public string FromMail { get; set; } + + public string ToMail { get; set; } + + public string Subject { get; set; } + + public string Time { get; set; } + } +} diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml new file mode 100644 index 0000000000..63230c2b66 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml @@ -0,0 +1,47 @@ +@page +@model StaggeredPermission.Pages.authEnd +@{ +} + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml.cs new file mode 100644 index 0000000000..8c68326141 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.Configuration; + +namespace StaggeredPermission.Pages +{ + public class authEnd : PageModel + { + /// + /// IConfiguration instance for fetching app settings. + /// + private readonly IConfiguration _configuration; + + /// + /// Model entity for storing clientId of the app. + /// + public string ClientId { get; set; } + + /// + /// Initialize the AuthEnd Class. + /// + public authEnd(IConfiguration configuration) + { + _configuration = configuration; + } + + /// + /// Handler method called when get request is made to auth-end page. + /// + public void OnGet() + { + ClientId = _configuration["AzureAd:ClientId"]; + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml new file mode 100644 index 0000000000..d57d484eac --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml @@ -0,0 +1,60 @@ +@page +@model StaggeredPermission.Pages.authStart +@{ + Layout = null; +} + + + + + + + + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml.cs new file mode 100644 index 0000000000..e84bb569e5 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.Configuration; + +namespace StaggeredPermission.Pages +{ + public class authStart : PageModel + { + /// + /// IConfiguration instance for fetching app settings. + /// + private readonly IConfiguration _configuration; + + /// + /// Model entity for storing clientId of the app. + /// + public string ClientId { get; set; } + + /// + /// Initialize the AuthStart Class. + /// + public authStart(IConfiguration configuration) + { + _configuration = configuration; + } + + /// + /// Handler method called when get request is made to auth-start page. + /// + public void OnGet() + { + ClientId = _configuration["AzureAd:ClientId"]; + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/tab.cshtml b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/tab.cshtml new file mode 100644 index 0000000000..537a6bf953 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/tab.cshtml @@ -0,0 +1,243 @@ +@page +@model StaggeredPermission.Pages.tabModel +@{ +} + + + + + + + + + + + +
+
+
+ +
+
+ Avatar +
+ Name:
+ Email:
+ Work: +
+ + + +
+
+
+
+
+ + + + + + + + + + +
Sr No.FromToSubjectReceived DateTime
+
+
+ \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/tab.cshtml.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/tab.cshtml.cs new file mode 100644 index 0000000000..5921f845c0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Pages/tab.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace StaggeredPermission.Pages +{ + public class tabModel : PageModel + { + public void OnGet() + { + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Program.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Program.cs new file mode 100644 index 0000000000..e7729a6c8d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Program.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.IdentityModel.Tokens; +using Newtonsoft.Json.Serialization; +using StaggeredPermission.helper; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers() + .AddNewtonsoftJson(options => + { + options.SerializerSettings.ContractResolver = new DefaultContractResolver(); + }); + +builder.Services.AddRazorPages(); + +builder.Services.AddAuthentication(options => +{ + options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; +}) +.AddJwtBearer(options => +{ + var tenantId = builder.Configuration["AzureAd:TenantId"]; + var instance = builder.Configuration["AzureAd:Instance"]; + options.Authority = $"{instance}{tenantId}/v2.0"; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidAudiences = AuthHelper.GetValidAudiences(builder.Configuration), + ValidIssuers = AuthHelper.GetValidIssuers(builder.Configuration), + AudienceValidator = AuthHelper.AudienceValidator + }; +}); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +} + +app.UseDefaultFiles(); +app.UseStaticFiles(); +app.UseRouting(); +app.UseAuthentication(); +app.UseAuthorization(); +app.MapControllers(); +app.MapRazorPages(); + +app.Run(); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Properties/launchSettings.json b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Properties/launchSettings.json new file mode 100644 index 0000000000..9b9feeee56 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "Start Project": { + "commandName": "Project", + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:44302;http://localhost:2544", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/SimpleGraphClient.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/SimpleGraphClient.cs new file mode 100644 index 0000000000..1827ecadba --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/SimpleGraphClient.cs @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Graph; +using Microsoft.Graph.Models; +using Microsoft.Kiota.Abstractions.Authentication; + +namespace StaggeredPermission +{ + // This class is a wrapper for the Microsoft Graph API + // See: https://developer.microsoft.com/en-us/graph + public class SimpleGraphClient + { + private readonly string _token; + + public SimpleGraphClient(string token) + { + if (string.IsNullOrWhiteSpace(token)) + { + throw new ArgumentNullException(nameof(token)); + } + + _token = token; + } + + // Get information about the user's mails. + public async Task> GetMailsAsync() + { + var graphClient = GetAuthenticatedClient(); + var response = await graphClient.Me.Messages.GetAsync(); + return response?.Value; + } + + // Gets the user's photo + public async Task GetPhotoAsync() + { + var graphClient = GetAuthenticatedClient(); + var photo = await graphClient.Me.Photo.Content.GetAsync(); + if (photo == null) + { + return string.Empty; + } + + using var memoryStream = new MemoryStream(); + await photo.CopyToAsync(memoryStream); + var buffers = memoryStream.ToArray(); + return $"data:image/png;base64,{Convert.ToBase64String(buffers)}"; + } + + // Get an Authenticated Microsoft Graph client using the token issued to the user. + private sealed class SimpleAccessTokenProvider : IAccessTokenProvider + { + private readonly string _accessToken; + + public SimpleAccessTokenProvider(string accessToken) + { + _accessToken = accessToken; + } + + public Task GetAuthorizationTokenAsync(Uri uri, Dictionary context = null, CancellationToken cancellationToken = default) + { + return Task.FromResult(_accessToken); + } + + public AllowedHostsValidator AllowedHostsValidator => new AllowedHostsValidator(); + } + + private GraphServiceClient GetAuthenticatedClient() + { + var tokenProvider = new SimpleAccessTokenProvider(_token); + var authProvider = new BaseBearerTokenAuthenticationProvider(tokenProvider); + + return new GraphServiceClient(authProvider); + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/StaggeredPermission.csproj b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/StaggeredPermission.csproj new file mode 100644 index 0000000000..544bbb7c4d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/StaggeredPermission.csproj @@ -0,0 +1,23 @@ + + + + net10.0 + latest + enable + + + + + + + + + + + + + Always + + + + diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/appsettings.Development.json b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/appsettings.Development.json new file mode 100644 index 0000000000..b49abfc201 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } + } diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/appsettings.json b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/appsettings.json new file mode 100644 index 0000000000..8cf1089961 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/appsettings.json @@ -0,0 +1,11 @@ +{ + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "TenantId": "{{TenantId}}", + "ClientId": "{{MicrosoftClientId}}", + "AppSecret": "{{MicrosoftAppPassword}}", + "ApplicationIdURI": "api://{{ApplicationBaseUrl}}/{{MicrosoftClientId}}", + "AuthUrl": "/oauth2/v2.0/token", + "ValidIssuers": "https://login.microsoftonline.com/{{TenantId}}/v2.0,https://sts.windows.net/{{TenantId}}/" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/helper/AuthHelper.cs b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/helper/AuthHelper.cs new file mode 100644 index 0000000000..4e46959b8a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/helper/AuthHelper.cs @@ -0,0 +1,170 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Identity.Client; +using Microsoft.IdentityModel.Tokens; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace StaggeredPermission.helper +{ + public class AuthHelper + { + /// + /// Retrieve Valid Audiences. + /// + /// IConfiguration instance. + /// Valid Audiences. + public static IEnumerable GetValidAudiences(IConfiguration configuration) + { + var clientId = configuration["AzureAd:ClientId"]; + var applicationIdUri = configuration["AzureAd:ApplicationIdURI"]; + var validAudiences = new List { clientId, applicationIdUri.ToLowerInvariant() }; + return validAudiences; + } + /// + /// Retrieve Valid Issuers. + /// + /// IConfiguration instance. + /// Valid Issuers. + public static IEnumerable GetValidIssuers(IConfiguration configuration) + { + var tenantId = configuration["AzureAd:TenantId"]; + var validIssuers = GetSettings(configuration); + validIssuers = validIssuers.Select(validIssuer => validIssuer.Replace("tenantId", tenantId)); + return validIssuers; + } + + /// + /// Audience Validator. + /// + /// Token audiences. + /// Security token. + /// Validation parameters. + /// Audience validator status. + public static bool AudienceValidator( + IEnumerable tokenAudiences, + SecurityToken securityToken, + TokenValidationParameters validationParameters) + { + if (tokenAudiences == null || tokenAudiences.Count() == 0) + { + throw new ApplicationException("No audience defined in token!"); + } + + var validAudiences = validationParameters.ValidAudiences; + + if (validAudiences == null || validAudiences.Count() == 0) + { + throw new ApplicationException("No valid audiences defined in validationParameters!"); + } + + foreach (var tokenAudience in tokenAudiences) + { + if (validAudiences.Any(validAudience => validAudience.Equals(tokenAudience, StringComparison.OrdinalIgnoreCase))) + { + return true; + } + } + + return false; + } + + /// + /// Get token using on-behalf-of flow. + /// + /// IConfiguration instance. + /// The id token from the client. + /// App access token on behalf of user. + public static async Task GetAccessTokenOnBehalfUserAsync(IConfiguration configuration, IHttpClientFactory httpClientFactory, IHttpContextAccessor httpContextAccessor, string idToken) + { + try + { + var tenantId = configuration["AzureAd:TenantId"]; + var instance = configuration["AzureAd:Instance"]; + + if (string.IsNullOrWhiteSpace(instance)) + { + instance = "https://login.microsoftonline.com/"; + } + + if (!instance.EndsWith("/", StringComparison.Ordinal)) + { + instance += "/"; + } + + if (string.IsNullOrWhiteSpace(tenantId) || tenantId.Contains("{{", StringComparison.Ordinal) || tenantId.Contains("}}", StringComparison.Ordinal)) + { + tenantId = "common"; + } + + var authority = new Uri(new Uri(instance), tenantId).ToString(); + + IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(configuration["AzureAd:ClientId"]) + .WithClientSecret(configuration["AzureAd:AppSecret"]) + .WithAuthority(authority) + .Build(); + + UserAssertion assert = new UserAssertion(idToken); + var scopes = new List { "https://graph.microsoft.com/User.Read" }; + var responseToken = await app.AcquireTokenOnBehalfOf(scopes, assert).ExecuteAsync(); + + return responseToken.AccessToken; + } + catch + { + throw; + } + } + + /// + /// Get token using on-behalf-of flow. (Overload for backward compatibility) + /// + /// IConfiguration instance. + /// The id token from the client. + /// App access token on behalf of user. + public static async Task GetAccessTokenOnBehalfUserAsync(IConfiguration configuration, string idToken) + { + var tenantId = configuration["AzureAd:TenantId"]; + IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(configuration["AzureAd:ClientId"]) + .WithClientSecret(configuration["AzureAd:AppSecret"]) + .WithAuthority($"https://login.microsoftonline.com/{tenantId}") + .Build(); + + try + { + UserAssertion assert = new UserAssertion(idToken); + List scopes = new List(); + scopes.Add("https://graph.microsoft.com/User.Read"); + var responseToken = await app.AcquireTokenOnBehalfOf(scopes, assert).ExecuteAsync(); + + return responseToken.AccessToken.ToString(); + } + catch (Exception ex) + { + return ex.Message; + } + } + + /// + /// Retrieve Settings. + /// + /// IConfiguration instance. + /// Configuration settings for valid issuers. + private static IEnumerable GetSettings(IConfiguration configuration) + { + var configurationSettingsValue = configuration["AzureAd:ValidIssuers"]; + var settings = configurationSettingsValue + ?.Split([';', ','], StringSplitOptions.RemoveEmptyEntries) + ?.Select(p => p.Trim()); + + if (settings == null) + { + throw new ApplicationException($"AzureAd:ValidIssuers does not contain a valid value in the configuration file."); + } + + return settings; + } + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/wwwroot/default.html b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/wwwroot/default.html new file mode 100644 index 0000000000..a7556f7576 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/StaggeredPermission/wwwroot/default.html @@ -0,0 +1,11 @@ + + + + + + Staggered Permission + + +
Sample app for staggered permission
+ + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/assets/sample.json b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/assets/sample.json new file mode 100644 index 0000000000..4558dc138d --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-tab-staggered-permission-csharp", + "source": "officeDev", + "title": "Staggered Permission sample", + "shortDescription": "This sample demonstrates how to obtain staggered Graph API permissions in a Microsoft Teams tab, prompting users for permissions only when specific features are accessed.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-staggered-permission/csharp", + "longDescription": [ + "The Staggered Permission sample app illustrates a C# implementation that retrieves Graph API permissions in a staggered manner within Microsoft Teams. Users are only prompted for permissions, such as access to photos or emails, when they attempt to use those features, enhancing the user experience by minimizing unnecessary consent requests." + ], + "creationDateTime": "2022-03-17", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "csharp" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "net" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/tab-staggered-permission/csharp/StaggeredPermission/Images/StaggeredModule.gif", + "alt": "Solution UX showing staggered permission sample" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/demo-manifest/tab-staggered-permission.zip b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/demo-manifest/tab-staggered-permission.zip new file mode 100644 index 0000000000..37424bc4cb Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/csharp/demo-manifest/tab-staggered-permission.zip differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.env b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.env new file mode 100644 index 0000000000..28d993252e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.env @@ -0,0 +1,3 @@ +MicrosoftAppId= +MicrosoftAppPassword= +TenantId= diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.gitignore b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.gitignore new file mode 100644 index 0000000000..64bbc01865 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.gitignore @@ -0,0 +1,109 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +*.zip + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# Distributables +dist/ +manifest/ +build/ + +############# + +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appManifest/build +/build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store + +# build +lib/ + diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/extensions.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/extensions.json new file mode 100644 index 0000000000..2d88dee21b --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension" + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/launch.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/launch.json new file mode 100644 index 0000000000..3f4a94ca48 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/launch.json @@ -0,0 +1,181 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to Frontend in Teams (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Frontend in Teams (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Frontend in Outlook (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://outlook.office.com/host/${{local:M365_APP_ID}}?${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Frontend in Outlook (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://outlook.office.com/host/${{local:M365_APP_ID}}?${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Frontend in the Microsoft 365 app (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://www.office.com/m365apps/${{local:M365_APP_ID}}?auth=2&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Frontend in the Microsoft 365 app (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://www.office.com/m365apps/${{local:M365_APP_ID}}?auth=2&${account-hint}", + "cascadeTerminateToConfigurations": [ + "Attach to Local Service" + ], + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Attach to Local Service", + "type": "node", + "request": "attach", + "port": 9239, + "restart": true, + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen" + } + ], + "compounds": [ + { + "name": "Debug in Teams (Edge)", + "configurations": [ + "Attach to Frontend in Teams (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "group 1: Teams", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug in Teams (Chrome)", + "configurations": [ + "Attach to Frontend in Teams (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "group 1: Teams", + "order": 2 + }, + "stopAll": true + }, + { + "name": "Debug in Outlook (Edge)", + "configurations": [ + "Attach to Frontend in Outlook (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "group 2: Outlook", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug in Outlook (Chrome)", + "configurations": [ + "Attach to Frontend in Outlook (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "group 2: Outlook", + "order": 2 + }, + "stopAll": true + }, + { + "name": "Debug in the Microsoft 365 app (Edge)", + "configurations": [ + "Attach to Frontend in the Microsoft 365 app (Edge)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "group 3: the Microsoft 365 app", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Debug in the Microsoft 365 app (Chrome)", + "configurations": [ + "Attach to Frontend in the Microsoft 365 app (Chrome)", + "Attach to Local Service" + ], + "preLaunchTask": "Start Teams App Locally", + "presentation": { + "group": "group 3: the Microsoft 365 app", + "order": 2 + }, + "stopAll": true + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/settings.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/settings.json new file mode 100644 index 0000000000..4299620253 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ] +} diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/tasks.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/tasks.json new file mode 100644 index 0000000000..2889b849af --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/.vscode/tasks.json @@ -0,0 +1,108 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Teams App Locally", + "dependsOn": [ + "Validate prerequisites", + "Start local tunnel", + "Provision", + "Deploy", + "Start application" + ], + "dependsOrder": "sequence" + }, + { + // Check all required prerequisites. + // See https://aka.ms/teamsfx-tasks/check-prerequisites to know the details and how to customize the args. + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "nodejs", // Validate if Node.js is installed. + "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the uploading permission. + "portOccupancy" // Validate available ports to ensure those debug ones are not occupied. + ], + "portOccupancy": [ + 3978// tab service port + ] + } + }, + { + // Start the local tunnel service to forward public URL to local port and inspect traffic. + // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. + "label": "Start local tunnel", + "type": "teamsfx", + "command": "debug-start-local-tunnel", + "args": { + "type": "dev-tunnel", + "ports": [ + { + "portNumber": 3978, + "protocol": "http", + "access": "public", + "writeToEnvironmentFile": { + "endpoint": "TAB_ENDPOINT", // output tunnel endpoint as TAB_ENDPOINT + "domain": "TAB_DOMAIN" // output tunnel domain as TAB_DOMAIN + } + } + ], + "env": "local" + }, + "isBackground": true, + "problemMatcher": "$teamsfx-local-tunnel-watch" + }, + { + // Create the debug resources. + // See https://aka.ms/teamsfx-tasks/provision to know the details and how to customize the args. + "label": "Provision", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + // Build project. + // See https://aka.ms/teamsfx-tasks/deploy to know the details and how to customize the args. + "label": "Deploy", + "type": "teamsfx", + "command": "deploy", + "args": { + "env": "local" + } + }, + { + "label": "Start application", + "dependsOn": [ + "Start frontend" + ] + }, + { + "label": "Start frontend", + "type": "shell", + "command": "npm run dev:teamsfx", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": { + "pattern": { + "regexp": "^.*$", + "file": 0, + "location": 1, + "message": 2 + }, + "background": { + "activeOnStart": true, + "beginsPattern": ".*", + "endsPattern": "Server listening on http://localhost:" + } + } + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/AppOffice.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/AppOffice.png new file mode 100644 index 0000000000..331299ceb0 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/AppOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/AppOutlook.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/AppOutlook.png new file mode 100644 index 0000000000..9c86f19641 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/AppOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/ConsentPopup.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/ConsentPopup.png new file mode 100644 index 0000000000..b887c34e02 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/ConsentPopup.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallApp.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallApp.png new file mode 100644 index 0000000000..ebaaa95f5e Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallApp.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallOffice.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallOffice.png new file mode 100644 index 0000000000..bea12a6f56 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallOutlook.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallOutlook.png new file mode 100644 index 0000000000..5405ac909a Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/InstallOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/TabStaggeredPermissionGif.gif b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/TabStaggeredPermissionGif.gif new file mode 100644 index 0000000000..c622e786c4 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/TabStaggeredPermissionGif.gif differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserDetailsOffice.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserDetailsOffice.png new file mode 100644 index 0000000000..ba817c5d51 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserDetailsOffice.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserDetailsOutlook.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserDetailsOutlook.png new file mode 100644 index 0000000000..d11ce71535 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserDetailsOutlook.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCard.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCard.png new file mode 100644 index 0000000000..58eb1bb22b Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCard.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCardGetPhoto.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCardGetPhoto.png new file mode 100644 index 0000000000..d2371a02bc Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCardGetPhoto.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCardGetPhotoAndUserMail.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCardGetPhotoAndUserMail.png new file mode 100644 index 0000000000..6ec9f621f4 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserInformationCardGetPhotoAndUserMail.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserMails.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserMails.png new file mode 100644 index 0000000000..cb09eb43ef Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/Images/UserMails.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/README.md b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/README.md new file mode 100644 index 0000000000..84832fdf7a --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/README.md @@ -0,0 +1,239 @@ +--- +page_type: sample +description: This sample demonstrates how to request staggered Graph API permissions in a Microsoft Teams tab, prompting users only when specific features are accessed. +products: +- office-teams +- office +- office-365 +languages: +- nodejs +- javascript +extensions: + contentType: samples + createdDate: "03/07/2022 00:15:13 AM" +urlFragment: officedev-microsoft-teams-samples-tab-staggered-permission-nodejs +--- + +# Staggered permission sample + +This sample app illustrates an effective way to manage Graph API permissions within a Microsoft Teams tab using Node.js. By employing staggered permission requests, the app enhances user experience by only prompting for necessary permissions when users interact with specific features, such as photos or emails, thus minimizing consent fatigue and promoting a seamless interaction. + +## Included Features +* Teams SSO (tabs) +* MSAL.js 2.0 support +* Graph API + +## Interaction with app + +![Tab Staggered PermissionGif](Images/TabStaggeredPermissionGif.gif) + +## Try it yourself - experience the App in your Microsoft Teams client +Please find below demo manifest which is deployed on Microsoft Azure and you can try it yourself by uploading the app package (.zip file link below) to your teams and/or as a personal app. (Uploading must be enabled for your tenant, [see steps here](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant#enable-custom-teams-apps-and-turn-on-custom-app-uploading)). + +**Staggered Permission sample:** [Manifest](/samples/tab-staggered-permission/csharp/demo-manifest/tab-staggered-permission.zip) + +## Prerequisites + +- Microsoft Teams is installed and you have an account (not a guest account) +- To test locally, [NodeJS](https://nodejs.org/en/download/) must be installed on your development machine (version 16.14.2 or higher). +- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/download) latest version or equivalent tunneling solution +- [M365 developer account](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the appropriate permissions to install an app. +- [Microsoft 365 Agents Toolkit for VS Code](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) or [TeamsFx CLI](https://learn.microsoft.com/microsoftteams/platform/toolkit/teamsfx-cli?pivots=version-one) + +## Run the app (Using Microsoft 365 Agents Toolkit for Visual Studio Code) + +The simplest way to run this sample in Teams is to use Microsoft 365 Agents Toolkit for Visual Studio Code. + +1. Ensure you have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/docs/setup/setup-overview) +1. Install the [Microsoft 365 Agents Toolkit extension](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) +1. Select **File > Open Folder** in VS Code and choose this samples directory from the repo +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps +1. Select **Debug > Start Debugging** or **F5** to run the app in a Teams web client. +1. In the browser that launches, select the **Add** button to install the app to Teams. +> If you do not have permission to upload custom apps (uploading), Microsoft 365 Agents Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + +## Setup + +1) Setup for Bot +- In Azure portal, create a [Azure Bot resource](https://docs.microsoft.com/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp%2Caadv2). +- Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0) +- If you are using Ngrok to test locally, you'll need [Ngrok](https://ngrok.com/) installed on your development machine. +Make sure you've downloaded and installed Ngrok on your local machine. ngrok will tunnel requests from the Internet to your local computer and terminate the SSL connection from Teams. + +2) App Registration + +### Register your application with Azure AD + +1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. +2. Select **New Registration** and on the *register an application page*, set following values: + * Set **name** to your app name. + * Choose **Accounts in this organizational directory only (Single tenant)**. + * Leave **Redirect URI** empty. + * Choose **Register**. + - On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You’ll need those later when updating your Teams application manifest and in the appsettings.json. + - Under **Manage**, select **Expose an API**. + - Select the **Set** link to generate the Application ID URI in the form of `api://{AppID}`. Insert your fully qualified domain name (with a forward slash "/" appended to the end) between the double forward slashes and the GUID. The entire ID should have the form of: `api://fully-qualified-domain-name/{AppID}` + * ex: `api://%ngrokDomain%.ngrok-free.app/00000000-0000-0000-0000-000000000000`. + - Select the **Add a scope** button. In the panel that opens, enter `access_as_user` as the **Scope name**. + - Set **Who can consent?** to `Admins and users` + - Fill in the fields for configuring the admin and user consent prompts with values that are appropriate for the `access_as_user` scope: + * **Admin consent title:** Teams can access the user’s profile. + * **Admin consent description**: Allows Teams to call the app’s web APIs as the current user. + * **User consent title**: Teams can access the user profile and make requests on the user's behalf. + * **User consent description:** Enable Teams to call this app’s APIs with the same rights as the user. + - Ensure that **State** is set to **Enabled** + - Select **Add scope** + * The domain part of the **Scope name** displayed just below the text field should automatically match the **Application ID** URI set in the previous step, with `/access_as_user` appended to the end: + * `api://[ngrokDomain].ngrok-free.app/00000000-0000-0000-0000-000000000000/access_as_user. +- In the **Authorized client applications** section, identify the applications that you want to authorize for your app’s web application. Each of the following IDs needs to be entered: + * `1fec8e78-bce4-4aaf-ab1b-5451cc387264` (Teams mobile/desktop application) + * `5e3ce6c0-2b1f-4285-8d4b-75ee78787346` (Teams web application) +**Note** If you want to test or extend your Teams apps across Office and Outlook, kindly add below client application identifiers while doing Azure AD app registration in your tenant: + * `4765445b-32c6-49b0-83e6-1d93765276ca` (Office web) + * `0ec893e0-5785-4de6-99da-4ed124e5296c` (Office desktop) + * `bc59ab01-8403-45c6-8796-ac3ef710b3e3` (Outlook web) + * `d3590ed6-52b3-4102-aeff-aad2292ab01c` (Outlook desktop) + - Navigate to **API Permissions**, and make sure to add the follow permissions: + - Select Add a permission + -  Select Microsoft Graph -\> Delegated permissions. + - `User.Read` (enabled by default) + - Click on Add permissions. Please make sure to grant the admin consent for the required permissions. + - Navigate to **Authentication** + If an app hasn't been granted IT admin consent, users will have to provide consent the first time they use an app. + Set a redirect URI: + * Select **Add a platform**. + * Select **Single Page Application**. + * Enter the **redirect URI** for the app in the following format: `https://{Base_Url}/auth-end`. + + - Navigate to the **Certificates & secrets**. In the Client secrets section, click on "+ New client secret". Add a description(Name of the secret) for the secret and select “Never” for Expires. Click "Add". Once the client secret is created, copy its value, it need to be placed in the appsettings.json. + +3) Setup NGROK + - Run ngrok - point to port 3978 + + ```bash + ngrok http 3978 --host-header="localhost:3978" + ``` + + Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below: + + ```bash + devtunnel host -p 3978 --allow-anonymous + ``` + +4) Setup for code + - Clone the repository + + ```bash + git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git + ``` + + - In the folder where repository is cloned navigate to `samples\tab-staggered-permission\nodejs` + + -Update the `.env` configuration for the bot to use the `MicrosoftAppId`, `MicrosoftAppPassword` and `TenantId` (Note the MicrosoftAppId is the AppId created in step 1 (Setup for Bot), the MicrosoftAppPassword is referred to as the "client secret" in step 1 (Setup for Bot) and you can always create a new client secret anytime. TenantId is the id of the tenant where app is registered.) + + - Install node modules + + Inside node js folder, open your local terminal and run the below command to install node modules. You can do the same in Visual studio code terminal by opening the project in Visual studio code + + ```bash + npm install + ``` + + - Run your app + + ```bash + npm start + ``` + +5) Setup Manifest for Teams +- __*This step is specific to Teams.*__ + - **Edit** the `manifest.json` contained in the ./appManifest folder to replace your Microsoft App Id (that was created when you registered your app registration earlier) *everywhere* you see the place holder string `{{Microsoft-App-Id}}` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`) + - **Edit** the `manifest.json` for `validDomains` and replace `{{domain-name}}` with base Url of your domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`. + - **Edit** the `manifest.json` for `webApplicationInfo` resource `"api://{{domain-name}}/{{Microsoft-App-Id}}"` with MicrosoftAppId. E.g. `"api://ngrok-free.app/00000-0000-0000"` + - **Note:** If you want to test your app across multi hub like: Outlook/Office.com, please update the `manifest.json` in the `tab-staggered-permission\nodejs\appManifest_Hub` folder with the required values. + - **Zip** up the contents of the `appManifest` folder to create a `Manifest.zip` or `appManifest_Hub` folder to create a `appManifest_Hub.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package) + +- Upload the manifest.zip to Teams (in the Apps view click "Upload a custom app") + - Go to Microsoft Teams. From the lower left corner, select Apps + - From the lower left corner, choose Upload a custom App + - Go to your project directory, the ./appManifest folder, select the zip folder, and choose Open. + - Select Add in the pop-up dialog box. Your app is uploaded to Teams. + +## Running the sample + +**Install App:** + +![user info card](Images/InstallApp.png) + +**Tab:** + +![user info card](Images/UserInformationCard.png) + +**Consent popup for staggered permission:** + +![consent popup](Images/ConsentPopup.png) + +**User emails:** + +![User mails](Images/UserMails.png) + +**Get photo:** + +![User Information Card GetPhoto](Images/UserInformationCardGetPhoto.png) + +**Get photo and User emails:** + +![User Information Card Get PhotoAndUserMail](Images/UserInformationCardGetPhotoAndUserMail.png) + +## Outlook on the web + +- To view your app in Outlook on the web. + +- Go to [Outlook on the web](https://outlook.office.com/mail/)and sign in using your dev tenant account. + +**On the side bar, select More Apps. Your uploaded app title appears among your installed apps** + +![InstallOutlook](Images/InstallOutlook.png) + +**Select your app icon to launch and preview your app running in Outlook on the web** + +![AppOutlook](Images/AppOutlook.png) + +**User Info** + +![UserDetailsOutlook](Images/UserDetailsOutlook.png) + +**Note:** Similarly, you can test your application in the Outlook desktop app as well. + +## Office on the web + +- To preview your app running in Office on the web. + +- Log into office.com with test tenant credentials + +**Select the Apps icon on the side bar. Your uploaded app title appears among your installed apps** + +![InstallOffice](Images/InstallOffice.png) + +**Select your app icon to launch your app in Office on the web** + +![AppOffice](Images/AppOffice.png) + +**User Info** + +![UserDetailsOffice](Images/UserDetailsOffice.png) + +**Note:** Similarly, you can test your application in the Office 365 desktop app as well. + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Tabs](https://learn.microsoft.com/microsoftteams/platform/tabs/what-are-tabs) +- [Authentication basics](https://docs.microsoft.com/microsoftteams/platform/concepts/authentication/authentication) +- [Extend Teams apps across Microsoft 365](https://learn.microsoft.com/microsoftteams/platform/m365-apps/overview) + + + diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/aad.manifest.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/aad.manifest.json new file mode 100644 index 0000000000..37411239e0 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/aad.manifest.json @@ -0,0 +1,101 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "tab-staggered-permission-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMyOrg", + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "oauth2Permissions": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ], + "identifierUris": [ + "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}" + ], + "replyUrlsWithType": [ + { + "url": "${{TAB_ENDPOINT}}/auth-end", + "type": "Spa" + } + ] +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/color.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/manifest.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/manifest.json new file mode 100644 index 0000000000..561d65a4aa --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/manifest.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.1", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.teams.com", + "privacyUrl": "https://www.teams.com/privacy", + "termsOfUseUrl": "https://www.teams.com/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Staggered permission", + "full": "App to get staggered permissions" + }, + "description": { + "short": "Demo app to obtain staggered Graph API permissions in Teams tabs.", + "full": "This sample demonstrates how to request staggered Graph API permissions in a Microsoft Teams tab, prompting users only when specific features are accessed." + }, + "accentColor": "#235EA5", + "staticTabs": [ + { + "entityId": "Staggered permission", + "name": "tab", + "contentUrl": "https://${{TAB_DOMAIN}}/tab", + "websiteUrl": "https://${{TAB_DOMAIN}}/tab", + "scopes": [ + "personal" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "${{TAB_DOMAIN}}" + ], + "webApplicationInfo": { + "id": "${{AAD_APP_CLIENT_ID}}", + "resource": "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/outline.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/color.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/color.png new file mode 100644 index 0000000000..b8cf81afbe Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/color.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/manifest.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/manifest.json new file mode 100644 index 0000000000..9506dbe924 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/manifest.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", + "manifestVersion": "1.19", + "version": "1.0.1", + "id": "{{Microsoft-App-Id}}", + "developer": { + "name": "Microsoft", + "websiteUrl": "https://www.teams.com", + "privacyUrl": "https://www.teams.com/privacy", + "termsOfUseUrl": "https://www.teams.com/termsofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "Staggered permission", + "full": "App to get staggered permissions" + }, + "description": { + "short": "App to get staggered permissions", + "full": "This sample demos to get staggered graph api permissions" + }, + "accentColor": "#235EA5", + "staticTabs": [ + { + "entityId": "Staggered permission", + "name": "tab", + "contentUrl": "https://{{domain-name}}/tab", + "websiteUrl": "https://{{domain-name}}/tab", + "scopes": [ + "personal" + ] + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [ + "{{domain-name}}" + ], + "webApplicationInfo": { + "id": "{{Microsoft-App-Id}}", + "resource": "api://{{domain-name}}/{{Microsoft-App-Id}}" + } +} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/outline.png b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/outline.png new file mode 100644 index 0000000000..2c3bf6fa65 Binary files /dev/null and b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/appManifest_Hub/outline.png differ diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/assets/sample.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/assets/sample.json new file mode 100644 index 0000000000..2a4415a7e8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/assets/sample.json @@ -0,0 +1,68 @@ +[ + { + "name": "officedev-microsoft-teams-samples-tab-staggered-permission-nodejs", + "source": "officeDev", + "title": "Staggered permission sample", + "shortDescription": "This sample demonstrates how to request staggered Graph API permissions in a Microsoft Teams tab, prompting users only when specific features are accessed.", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-staggered-permission/nodejs", + "longDescription": [ + "The Staggered Permission sample app provides a Node.js implementation to manage Graph API permissions in a staggered fashion within Microsoft Teams. Users are prompted for permissions—such as accessing photos or emails—only when they attempt to use those features, streamlining the consent process and enhancing user experience." + ], + "creationDateTime": "2022-07-03", + "updateDateTime": "2024-10-15", + "products": [ + "Teams" + ], + "metadata": [ + { + "key": "TEAMS-SAMPLE-SOURCE", + "value": "OfficeDev" + }, + { + "key": "TEAMS-SERVER-LANGUAGE", + "value": "javascript" + }, + { + "key": "TEAMS-SERVER-PLATFORM", + "value": "express" + }, + { + "key": "TEAMS-FEATURES", + "value": "tab" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/tab-staggered-permission/nodejs/Images/TabStaggeredPermissionGif.gif", + "alt": "Solution UX showing staggered permission sample" + } + ], + "authors": [ + { + "gitHubAccount": "OfficeDev", + "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4", + "name": "OfficeDev" + } + ], + "references": [ + { + "name": "Teams developer documentation", + "url": "https://aka.ms/TeamsPlatformDocs" + }, + { + "name": "Teams developer questions", + "url": "https://aka.ms/TeamsPlatformFeedback" + }, + { + "name": "Teams development videos from Microsoft", + "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft" + }, + { + "name": "Teams development videos from the community", + "url": "https://aka.ms/community/videos/m365powerplatform" + } + ] + } +] \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/build.js b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/build.js new file mode 100644 index 0000000000..a59684a045 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/build.js @@ -0,0 +1,14 @@ +const esbuild = require('esbuild'); +esbuild.build({ + entryPoints: ['index.js'], + bundle: true, + platform: 'node', + outfile: 'dist/index.js' +}) + .then((r) => { + console.log(`Build succeeded.`); + }) + .catch((e) => { + console.log("Error building:", e.message); + process.exit(1); + }); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/env/.env.local b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/env/.env.local new file mode 100644 index 0000000000..c339a95fe8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/env/.env.local @@ -0,0 +1,18 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. +TAB_DOMAIN= +TAB_ENDPOINT= +TEAMS_APP_ID= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY= +AAD_APP_OAUTH_AUTHORITY_HOST= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= +TEAMS_APP_TENANT_ID= +M365_TITLE_ID= +M365_APP_ID= \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/index.js b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/index.js new file mode 100644 index 0000000000..14f042fce8 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/index.js @@ -0,0 +1,138 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const path = require('path'); +const msal = require('@azure/msal-node'); +const express = require('express'); +const cors = require('cors'); +const { SimpleGraphClient } = require('./simpleGraphClient'); + +// Load environment variables. +const ENV_FILE = path.join(__dirname, '.env'); +require('dotenv').config({ path: ENV_FILE }); +const PORT = process.env.PORT || 3978; +const server = express(); + +const configuredTenantId = process.env.TenantId; + +const scopes = ["https://graph.microsoft.com/User.Read"]; + +let msalClient; + +function getMsalClient() { + if (!msalClient) { + msalClient = new msal.ConfidentialClientApplication({ + auth: { + clientId: process.env.MicrosoftAppId, + clientSecret: process.env.MicrosoftAppPassword, + authority: `https://login.microsoftonline.com/${process.env.TenantId}` + } + }); + } + return msalClient; +} + +server.use(cors()); +server.use(express.json()); +server.use(express.urlencoded({ + extended: true +})); +server.set('view engine', 'ejs'); +server.set('views', __dirname); + +// Create HTTP server. +server.listen(PORT, () => { + console.log(`Server listening on http://localhost:${PORT}`); +}); + +// Endpoint to fetch Auth tab page. +server.get('/tab', (req, res) => { + res.render('./views/tab'); +}); + +// Pop-up dialog to ask for additional permissions, redirects to AAD page. +server.get('/auth-start', (req, res) => { + const scope = req.query.scope; + const data = { + clientId: process.env.MicrosoftAppId, + tenantId: configuredTenantId, + scope: scope + }; + res.render('./views/auth-start', { data: JSON.stringify(data) }); +}); + +// End of the pop-up dialog auth flow, returns the results back to parent window. +server.get('/auth-end', (req, res) => { + const data = { + clientId: process.env.MicrosoftAppId, + tenantId: configuredTenantId + }; + res.render('./views/auth-end', { data: JSON.stringify(data) }); +}); + +// Exchange the id token with access token. +const getDelegateAccessToken = async (token) => { + try { + const result = await getMsalClient().acquireTokenOnBehalfOf({ + authority: `https://login.microsoftonline.com/${configuredTenantId}`, + oboAssertion: token, + scopes: scopes, + skipCache: true + }); + return result.accessToken; + } catch (error) { + console.log("Error occurred: " + error); + throw error; + } +}; + +function getIdTokenFromRequest(req) { + const token = req.body?.idToken; + if (!token) { + throw new Error('Missing idToken in request body.'); + } + return token; +} + +// Get user photo. +server.post('/GetUserPhoto', async (req, res) => { + try { + const idToken = getIdTokenFromRequest(req); + const accessToken = await getDelegateAccessToken(idToken); + const client = new SimpleGraphClient(accessToken); + const userImage = await client.getUserPhoto(); + const result = await userImage.arrayBuffer(); + const imageString = Buffer.from(result).toString('base64'); + res.json({ image: "data:image/png;base64," + imageString }); + } catch (error) { + console.log("Error getting user photo: " + error); + res.status(500).json({ error: "Failed to get user photo" }); + } +}); + +// Get user mails. +server.post('/GetUserMails', async (req, res) => { + try { + const idToken = getIdTokenFromRequest(req); + const accessToken = await getDelegateAccessToken(idToken); + const client = new SimpleGraphClient(accessToken); + const userMails = await client.getMailAsync(); + res.json(userMails.value); + } catch (error) { + console.log("Error getting user mails: " + error); + res.status(500).json({ error: "Failed to get user mails" }); + } +}); + +// Decode JWT token. +server.post('/decodeToken', (req, res) => { + const token = req.body.idToken; + if (token !== null && token !== undefined) { + const base64String = token.split('.')[1]; + const decodedValue = JSON.parse(Buffer.from(base64String, + 'base64url').toString('utf8')); + res.json(decodedValue); + } else { + res.status(400).json({ error: "Invalid token" }); + } +}); \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/m365agents.local.yml b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/m365agents.local.yml new file mode 100644 index 0000000000..345485e17b --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/m365agents.local.yml @@ -0,0 +1,107 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-staggered-permission-nodejs + +provision: + # Creates a new Azure Active Directory (AAD) app to authenticate users if + # the environment variable that stores clientId is empty + - uses: aadApp/create + with: + # Note: when you run aadApp/update, the AAD app name will be updated + # based on the definition in manifest. If you don't want to change the + # name, make sure the name in AAD manifest is the same with the name + # defined here. + name: tab-staggered-permission + # If the value is false, the action will not generate client secret for you + generateClientSecret: true + # Authenticate users with a Microsoft work or school account in your + # organization's Azure AD tenant (for example, single tenant). + signInAudience: AzureADMyOrg + # Write the information of created resources into environment file for the + # specified environment variable(s). + writeToEnvironmentFile: + clientId: AAD_APP_CLIENT_ID + # Environment variable that starts with `SECRET_` will be stored to the + # .env.{envName}.user environment file + clientSecret: SECRET_AAD_APP_CLIENT_SECRET + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-staggered-permission${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + + # Apply the AAD manifest to an existing AAD app. Will use the object id in + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appManifest/manifest.json + outputZipPath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./appManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Apply the Teams app manifest to an existing Teams app in + # Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + + # Extend your Teams app to Outlook and the Microsoft 365 app + - uses: teamsApp/extendToM365 + with: + # Relative path to the build app package. + appPackagePath: ./appManifest/build/appManifest.${{TEAMSFX_ENV}}.zip + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + titleId: M365_TITLE_ID + appId: M365_APP_ID + +deploy: + # Run npm command + - uses: cli/runNpmCommand + with: + workingDirectory: . + args: install --no-audit + + - uses: file/createOrUpdateEnvironmentFile + with: + target: ./.env # Required. The relative path of settings file + envs: + MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + TenantId: ${{AAD_APP_TENANT_ID}} \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/m365agents.yml b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/m365agents.yml new file mode 100644 index 0000000000..13c67357aa --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/m365agents.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-staggered-permission-nodejs + +environmentFolderPath: ./env diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/package-lock.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/package-lock.json new file mode 100644 index 0000000000..dc930b57be --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/package-lock.json @@ -0,0 +1,1912 @@ +{ + "name": "tab-staggered-permission", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tab-staggered-permission", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@azure/msal-node": "^5.1.4", + "@microsoft/microsoft-graph-client": "^3.0.7", + "cors": "^2.8.6", + "dotenv": "^17.4.2", + "ejs": "^5.0.2", + "express": "^5.2.1" + }, + "devDependencies": { + "esbuild": "^0.28.0", + "nodemon": "^3.1.14" + } + }, + "node_modules/@azure/msal-common": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.5.1.tgz", + "integrity": "sha512-WS9w9SfI8SEYO7mTnxGeZ3UwQfhAVYCWglYF2/7GNx3ioHiAs2gPkl9eSwVs8cPrmiGh+zi9ai/OOKoq4cyzDw==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-5.1.4.tgz", + "integrity": "sha512-G4LXGGggok1QC48uKu64/SV2DPRDlddmV8EieK8pflsNYMj9/Zz+Y9OHoEBhT15h+zpdwXXLYA/7PJCR/yZ8aw==", + "license": "MIT", + "dependencies": { + "@azure/msal-common": "16.5.1", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@microsoft/microsoft-graph-client": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@microsoft/microsoft-graph-client/-/microsoft-graph-client-3.0.7.tgz", + "integrity": "sha512-/AazAV/F+HK4LIywF9C+NYHcJo038zEnWkteilcxC1FM/uK/4NVGDKGrxx7nNq1ybspAroRKT4I1FHfxQzxkUw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependenciesMeta": { + "@azure/identity": { + "optional": true + }, + "@azure/msal-browser": { + "optional": true + }, + "buffer": { + "optional": true + }, + "stream-browserify": { + "optional": true + } + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-5.0.2.tgz", + "integrity": "sha512-IpbUaI/CAW86l3f+T8zN0iggSc0LmMZLcIW5eRVStLVNCoTXkE0YlncbbH50fp8Cl6zHIky0sW2uUbhBqGw0Jw==", + "license": "Apache-2.0", + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.12.18" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz", + "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^10.2.1", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/package.json b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/package.json new file mode 100644 index 0000000000..42389abf59 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/package.json @@ -0,0 +1,31 @@ +{ + "name": "tab-staggered-permission", + "version": "1.0.0", + "description": "Microsoft Teams tab sample demonstrating staggered Graph API permissions", + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev:teamsfx": "npm run start", + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "build": "node build.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples.git" + }, + "dependencies": { + "@azure/msal-node": "^5.1.4", + "@microsoft/microsoft-graph-client": "^3.0.7", + "cors": "^2.8.6", + "dotenv": "^17.4.2", + "ejs": "^5.0.2", + "express": "^5.2.1" + }, + "devDependencies": { + "nodemon": "^3.1.14", + "esbuild": "^0.28.0" + } +} diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/simpleGraphClient.js b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/simpleGraphClient.js new file mode 100644 index 0000000000..06e12a4974 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/simpleGraphClient.js @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { Client } = require('@microsoft/microsoft-graph-client'); + +/** +* This class is a wrapper for the Microsoft Graph API. +* See: https://developer.microsoft.com/en-us/graph for more information. +*/ +class SimpleGraphClient { + constructor(token) { + if (!token || !token.trim()) { + throw new Error('SimpleGraphClient: Invalid token received.'); + } + + this._token = token; + + // Get an Authenticated Microsoft Graph client using the token issued to the user. + this.graphClient = Client.init({ + authProvider: (done) => { + done(null, this._token); // First parameter takes an error if you can't get an access token. + } + }); + } + + // Get user photo. + async getUserPhoto() { + return await this.graphClient.api('/me/photo/$value').get(); + } + + // Get user mails. + async getMailAsync(){ + return await this.graphClient.api('/me/messages').get(); + } +} + +exports.SimpleGraphClient = SimpleGraphClient; \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/auth-end.ejs b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/auth-end.ejs new file mode 100644 index 0000000000..375841c10e --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/auth-end.ejs @@ -0,0 +1,43 @@ + + + \ No newline at end of file diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/auth-start.ejs b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/auth-start.ejs new file mode 100644 index 0000000000..aee7859927 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/auth-start.ejs @@ -0,0 +1,49 @@ + + + + + + + diff --git a/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/tab.ejs b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/tab.ejs new file mode 100644 index 0000000000..f2aefc56c3 --- /dev/null +++ b/samples/TeamsSDK/Archived/tab-staggered-permission/nodejs/views/tab.ejs @@ -0,0 +1,232 @@ + + + + + + + + + + +
+
+
+ +
+
+ Avatar +
+ Name:
+ Email:
+
+ + + +
+
+
+
+
+ + + + + + + + + + +
Sr No.FromToSubjectReceived DateTime
+
+
+ \ No newline at end of file