From 36f595767ffd2aea5b525f4a4a56945cf6d7616d Mon Sep 17 00:00:00 2001
From: Gil Megidish <136448141+gmegidish-saucelabs@users.noreply.github.com>
Date: Wed, 12 Jun 2024 12:56:09 +0200
Subject: [PATCH 001/148] App distribution updates (#2801)
* Added App Center Alternatives
* Added App Expiration
* Moved items around
* Moved TestFairy items around
* Moved TestFairy items around
* Added "Beta Testing" to top nav bar
---
docs/mobile-apps/ms-app-center.md | 4 +-
docs/testfairy/acct-mgmt/acct-mgmt.md | 6 -
docs/testfairy/acct-mgmt/sso.md | 6 -
docs/testfairy/app-center-alternative.md | 33 +++
.../app-distribution/app-expiration.md | 86 +++++++
.../app-distribution/managing-dist.md | 2 +-
.../bug-tracking/github.md | 0
.../bug-tracking/jira-cloud.md | 0
.../bug-tracking/jira-server.md | 2 +-
.../bug-tracking/tf-connect.md | 0
.../bug-tracking/trello.md | 0
.../bug-tracking}/using-bug-tracking.md | 11 +-
docs/testfairy/sdk/ios/ad-hoc-ipa.md | 2 +-
.../{security => sdk}/private-cloud-int.md | 0
.../{ => sdk}/security/data-encryption.md | 0
.../{ => sdk}/security/hiding-data.md | 0
docs/testfairy/sdk/supported-platforms.md | 6 +-
.../feedback.md => sdk/user-feedback.md} | 6 +-
.../{acct-mgmt => security}/acct-settings.md | 2 +-
.../{acct-mgmt => security}/sso/azure.md | 0
.../{acct-mgmt => security}/sso/google.md | 0
.../{acct-mgmt => security}/sso/okta.md | 0
.../{acct-mgmt => security}/sso/onelogin.md | 0
.../{acct-mgmt => security}/sso/ping-id.md | 0
.../{acct-mgmt => security}/sso/sso-intro.md | 16 +-
.../testers/building-testers-app.md | 0
.../testers/managing-testers.md | 0
.../testers/reg-ios-device.md | 0
.../testers/testers-dashboard.md | 0
.../testers/testing-android-apps.md | 0
docs/testfairy/testfairy.md | 6 +-
.../bug-tracking/micro-focus.md | 40 ----
.../testing-an-app/testers/user-feedback.md | 28 ---
.../testfairy/testing-an-app/using-testers.md | 9 -
docusaurus.config.js | 5 +
sidebars.js | 220 +++++++++---------
36 files changed, 258 insertions(+), 232 deletions(-)
delete mode 100644 docs/testfairy/acct-mgmt/acct-mgmt.md
delete mode 100644 docs/testfairy/acct-mgmt/sso.md
create mode 100644 docs/testfairy/app-center-alternative.md
create mode 100644 docs/testfairy/app-distribution/app-expiration.md
rename docs/testfairy/{testing-an-app => sdk}/bug-tracking/github.md (100%)
rename docs/testfairy/{testing-an-app => sdk}/bug-tracking/jira-cloud.md (100%)
rename docs/testfairy/{testing-an-app => sdk}/bug-tracking/jira-server.md (98%)
rename docs/testfairy/{testing-an-app => sdk}/bug-tracking/tf-connect.md (100%)
rename docs/testfairy/{testing-an-app => sdk}/bug-tracking/trello.md (100%)
rename docs/testfairy/{testing-an-app => sdk/bug-tracking}/using-bug-tracking.md (67%)
rename docs/testfairy/{security => sdk}/private-cloud-int.md (100%)
rename docs/testfairy/{ => sdk}/security/data-encryption.md (100%)
rename docs/testfairy/{ => sdk}/security/hiding-data.md (100%)
rename docs/testfairy/{testing-an-app/feedback.md => sdk/user-feedback.md} (98%)
rename docs/testfairy/{acct-mgmt => security}/acct-settings.md (98%)
rename docs/testfairy/{acct-mgmt => security}/sso/azure.md (100%)
rename docs/testfairy/{acct-mgmt => security}/sso/google.md (100%)
rename docs/testfairy/{acct-mgmt => security}/sso/okta.md (100%)
rename docs/testfairy/{acct-mgmt => security}/sso/onelogin.md (100%)
rename docs/testfairy/{acct-mgmt => security}/sso/ping-id.md (100%)
rename docs/testfairy/{acct-mgmt => security}/sso/sso-intro.md (80%)
rename docs/testfairy/{testing-an-app => }/testers/building-testers-app.md (100%)
rename docs/testfairy/{testing-an-app => }/testers/managing-testers.md (100%)
rename docs/testfairy/{testing-an-app => }/testers/reg-ios-device.md (100%)
rename docs/testfairy/{testing-an-app => }/testers/testers-dashboard.md (100%)
rename docs/testfairy/{testing-an-app => }/testers/testing-android-apps.md (100%)
delete mode 100644 docs/testfairy/testing-an-app/bug-tracking/micro-focus.md
delete mode 100644 docs/testfairy/testing-an-app/testers/user-feedback.md
delete mode 100644 docs/testfairy/testing-an-app/using-testers.md
diff --git a/docs/mobile-apps/ms-app-center.md b/docs/mobile-apps/ms-app-center.md
index c0e6331f01..98be13df5b 100644
--- a/docs/mobile-apps/ms-app-center.md
+++ b/docs/mobile-apps/ms-app-center.md
@@ -21,13 +21,13 @@ We recommend using the Upload API method to enable the Jenkins plugin, Gradle pl
TestFairy offers enterprise-grade app distribution capabilities, allowing companies to easily and securely distribute the right apps to the right users. The platform allows admins to enforce corporate security policies during testing, and has the capability to automatically update apps to new versions or revoke access to installed apps or users.
-For more information, see [Managing Testers](/testfairy/testing-an-app/testers/managing-testers/).
+For more information, see [Managing Testers](/testfairy/testers/managing-testers/).
## Security
TestFairy is available as a private cloud or an on-premise installation and can integrate with any SAML single sign-on service. TestFairy is the only platform that provides end-to-end data encryption using your private/public keys, so your data remains private.
-For more information, see [End to End Data Encryption](/testfairy/security/data-encryption/).
+For more information, see [End to End Data Encryption](/testfairy/sdk/security/data-encryption/).
:::tip
Use the [TestFairy](/testfairy/api-reference/upload-api/) API to upload, or retrieve your mobile applications.
diff --git a/docs/testfairy/acct-mgmt/acct-mgmt.md b/docs/testfairy/acct-mgmt/acct-mgmt.md
deleted file mode 100644
index 21b1eff9f7..0000000000
--- a/docs/testfairy/acct-mgmt/acct-mgmt.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-id: acct-mgmt
-title: Using Account and Management
-sidebar_label: Using Account and Management
-hide_table_of_contents: true
----
diff --git a/docs/testfairy/acct-mgmt/sso.md b/docs/testfairy/acct-mgmt/sso.md
deleted file mode 100644
index b14b428d82..0000000000
--- a/docs/testfairy/acct-mgmt/sso.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-id: sso
-title: Single Sign On
-sidebar_label: Single Sign On
-hide_table_of_contents: true
----
diff --git a/docs/testfairy/app-center-alternative.md b/docs/testfairy/app-center-alternative.md
new file mode 100644
index 0000000000..f9a20bb9e0
--- /dev/null
+++ b/docs/testfairy/app-center-alternative.md
@@ -0,0 +1,33 @@
+---
+id: app-center-alternative
+title: App Center Alternative
+sidebar_label: App Center Alternative
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+Welcome to TestFairy, the App Center distribution alternative! Use our enterprise-grade app distribution capabilities to migrate from App Center before March 31, 2025!
+
+## Distribute App to Testers
+
+TestFairy offers enterprise-grade app distribution capabilities, allowing companies to easily and securely distribute the right apps to the right users. The platform allows admins to enforce corporate security policies during testing, and has the capability to automatically update apps to new versions or revoke access to installed apps or users.
+
+For more information, see [Managing Testers](/testfairy/testers/managing-testers/).
+
+## Analyze User Behavior
+
+TestFairy provides mobile teams with videos showing exactly what happened during a mobile device test, before a crash, or before something went wrong, which ensures that bugs are fixed quickly.
+
+For more information, see [Adding the TestFairy SDK](/testfairy/sdk/adding-tf-sdk/).
+
+## Collect Feedback
+
+TestFairy's feedback features help users provide feedback by shaking their device or taking a screenshot. A report can automatically be posted to Jira along with the session video recording, logs, metrics, and crash reports.
+
+For more information, see [Getting Feedback](/testfairy/sdk/user-feedback/).
+
+## Security
+
+TestFairy is available as a private cloud or an on-premise installation and can integrate with any SAML single sign-on service. TestFairy is the only platform that provides end-to-end data encryption using your private/public keys, so your data remains private.
+
+For more information, see [End to End Data Encryption](/testfairy/sdk/security/data-encryption/).
diff --git a/docs/testfairy/app-distribution/app-expiration.md b/docs/testfairy/app-distribution/app-expiration.md
new file mode 100644
index 0000000000..7ca3dfe940
--- /dev/null
+++ b/docs/testfairy/app-distribution/app-expiration.md
@@ -0,0 +1,86 @@
+---
+id: app-expiration
+title: Invalidating Apps After Distribution
+sidebar_label: Invalidating Apps
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+There comes a time after distribution that you want to invalidate the app.
+
+Some cases for invalidation include:
+- Releasing a final version, and beta version should stop working
+- A specific version should no longer be used, and new one should be downloaded
+- A terrible fault has been found, and current version should no longer run
+
+## Disabling Distribution
+
+To disable a distribution of an App or a specific Build of an App, please follow the instructions for [Stopping Distribution](/testfairy/app-distribution/managing-dist/#stopping-distribution)
+
+After app distribution has been disabled, it could no longer be downloaded. However, in certain cases, you would
+want to programmatically detect distribution status, and notify the end-user what they need to do next.
+
+For example:
+- App detects distribution has been disabled, then present an popup message on screen and stop the process.
+- App detects distribution has been disabled and opens browser to [Internal App Store](https://mobile.saucelabs.com/my) page.
+
+## Programmatically Detecting Distribution Status
+
+Sauce Labs' App Distribution provides a simple API to receive the distribution status as
+set in the Build Settings page.
+
+To fetch the status of a specific version, use
+```jsx title="Sample Request"
+curl -XPOST \
+ "https://mobile.saucelabs.com/services/?method=testfairy.session.getDistributionStatus" \
+ -F token=$TESTFAIRY_APP_TOKEN \
+ -F platform=0 \
+ -F bundleIdentifier=com.saucelabs.mydemoapp.android \
+ -F bundleVersion=22 \
+ -F bundleShortVersion=2.0.1
+```
+
+
+
+
+ token |
+ TestFairy App Token |
+
+
+ platform |
+ Mobile OS to query (0 for Android, 1 for iOS) |
+
+
+ bundleIdentifier |
+ Bundle Identifier (iOS) or Package Name (Android) |
+
+
+ bundleVersion |
+ bundleVersion (iOS) or versionCode (Android) of build to query |
+
+
+ bundleShortVersion |
+ bundleShortVersion (iOS) or versionName (Android) of build to query |
+
+
+
+
+:::note Important
+App Distribution is using a Token. This is not your Sauce Labs' username and access key. The token
+itself is not private and can be used only to query status. It cannot be used to access any other
+data in your account.
+:::
+
+Upon response, the API will return a json with `status` equal to either `enabled` or `disabled`. For example:
+```json
+{"status":"enabled"}
+```
+
+If a Build cannot be found on App Distribution platform, it is assumed deleted, and the result will be `disabled`.
+
+## Sample Code
+
+For reference, please visit the [My Demo App](https://github.com/saucelabs/my-demo-app-android/) sample application. A method called [checkVersionIsStillSupported](https://github.com/saucelabs/my-demo-app-android/blob/main/app/src/main/java/com/saucelabs/mydemoapp/android/view/activities/MainActivity.java#L617) calls the API and will display an AlertDialog if version has expired.
+
diff --git a/docs/testfairy/app-distribution/managing-dist.md b/docs/testfairy/app-distribution/managing-dist.md
index e74839c786..6d9523a18f 100644
--- a/docs/testfairy/app-distribution/managing-dist.md
+++ b/docs/testfairy/app-distribution/managing-dist.md
@@ -59,7 +59,7 @@ The **Testers Dashboard** is where a tester can view the apps they were invited
Permissions manage app distribution to groups of testers/users and are defined for each app (including all its builds). This means all testers within a group can access all builds of the app.
-Permissions are based on defined groups of testers (see [Managing Testers](/testfairy/testing-an-app/testers/managing-testers)).
+Permissions are based on defined groups of testers (see [Managing Testers](/testfairy/testers/managing-testers)).
Once groups are defined, they will appear on the **Permissions** page.
diff --git a/docs/testfairy/testing-an-app/bug-tracking/github.md b/docs/testfairy/sdk/bug-tracking/github.md
similarity index 100%
rename from docs/testfairy/testing-an-app/bug-tracking/github.md
rename to docs/testfairy/sdk/bug-tracking/github.md
diff --git a/docs/testfairy/testing-an-app/bug-tracking/jira-cloud.md b/docs/testfairy/sdk/bug-tracking/jira-cloud.md
similarity index 100%
rename from docs/testfairy/testing-an-app/bug-tracking/jira-cloud.md
rename to docs/testfairy/sdk/bug-tracking/jira-cloud.md
diff --git a/docs/testfairy/testing-an-app/bug-tracking/jira-server.md b/docs/testfairy/sdk/bug-tracking/jira-server.md
similarity index 98%
rename from docs/testfairy/testing-an-app/bug-tracking/jira-server.md
rename to docs/testfairy/sdk/bug-tracking/jira-server.md
index 70b26fa963..a173aea0fa 100644
--- a/docs/testfairy/testing-an-app/bug-tracking/jira-server.md
+++ b/docs/testfairy/sdk/bug-tracking/jira-server.md
@@ -11,7 +11,7 @@ import TabItem from '@theme/TabItem';
This documentation provides step-by-step instructions on how to integrate TestFairy Connect with Jira Server for bug tracking. By following these guidelines, you can seamlessly connect TestFairy to your on-premise Jira Server either using basic authentication (user/password token) or OAuth.
:::note
-To connect TestFairy to Jira Server that is installed on-prem, start by installing [TestFairy Connect](/testfairy/testing-an-app/bug-tracking/tf-connect/).
+To connect TestFairy to Jira Server that is installed on-prem, start by installing [TestFairy Connect](/testfairy/sdk/bug-tracking/tf-connect/).
:::
diff --git a/docs/testfairy/testing-an-app/bug-tracking/tf-connect.md b/docs/testfairy/sdk/bug-tracking/tf-connect.md
similarity index 100%
rename from docs/testfairy/testing-an-app/bug-tracking/tf-connect.md
rename to docs/testfairy/sdk/bug-tracking/tf-connect.md
diff --git a/docs/testfairy/testing-an-app/bug-tracking/trello.md b/docs/testfairy/sdk/bug-tracking/trello.md
similarity index 100%
rename from docs/testfairy/testing-an-app/bug-tracking/trello.md
rename to docs/testfairy/sdk/bug-tracking/trello.md
diff --git a/docs/testfairy/testing-an-app/using-bug-tracking.md b/docs/testfairy/sdk/bug-tracking/using-bug-tracking.md
similarity index 67%
rename from docs/testfairy/testing-an-app/using-bug-tracking.md
rename to docs/testfairy/sdk/bug-tracking/using-bug-tracking.md
index f0fe49286e..bb8de8dea7 100644
--- a/docs/testfairy/testing-an-app/using-bug-tracking.md
+++ b/docs/testfairy/sdk/bug-tracking/using-bug-tracking.md
@@ -13,12 +13,11 @@ Bug tracking is an essential part of the software development process to identif
Before utilizing the bug-tracking features in TestFairy, ensure that you connect your TestFairy account to your preferred bug-tracking platform. TestFairy supports the following bug-tracking integrations:
-- [JIRA Cloud](/testfairy/testing-an-app/bug-tracking/jira-cloud/)
-- [JIRA Server](/testfairy/testing-an-app/bug-tracking/jira-server/)
-- [GitHub] (/testfairy/testing-an-app/bug-tracking/github/)
-- [Trello] (/testfairy/testing-an-app/bug-tracking/trello/)
-- [Connect (TFC)](/testfairy/testing-an-app/bug-tracking/tf-connect/)
-- [Micro Focus ALM Octane](/testfairy/testing-an-app/bug-tracking/micro-focus/)
+- [JIRA Cloud](/testfairy/sdk/bug-tracking/jira-cloud/)
+- [JIRA Server](/testfairy/sdk/bug-tracking/jira-server/)
+- [GitHub](/testfairy/sdk/bug-tracking/github/)
+- [Trello](/testfairy/sdk/bug-tracking/trello/)
+- [Connect (TFC)](/testfairy/sdk/bug-tracking/tf-connect/)
Ensure that you follow the relevant documentation to establish a secure and authenticated connection between TestFairy and your bug-tracking platform.
diff --git a/docs/testfairy/sdk/ios/ad-hoc-ipa.md b/docs/testfairy/sdk/ios/ad-hoc-ipa.md
index fb2b739125..b94ecbf52c 100644
--- a/docs/testfairy/sdk/ios/ad-hoc-ipa.md
+++ b/docs/testfairy/sdk/ios/ad-hoc-ipa.md
@@ -16,7 +16,7 @@ Apple allows app distribution for testing on registered devices using an **Ad-Ho
## Prerequisites
Before proceeding with the steps below, ensure that you have completed the following:
-1. **Register Test Devices** Register all the test devices on which you intend to install and test your app. You can follow the instructions in the [Registering Your iOS Device UDID Number](https://docs.saucelabs.com/testfairy/testing-an-app/testers/reg-ios-device/) to complete this step.
+1. **Register Test Devices** Register all the test devices on which you intend to install and test your app. You can follow the instructions in the [Registering Your iOS Device UDID Number](https://docs.saucelabs.com/testfairy/testers/reg-ios-device/) to complete this step.
2. **Create Ad Hoc Provisioning Profile** - Make sure you have created an Ad Hoc provisioning profile on the Apple Developer Portal. This provisioning profile should specify an App ID that matches your app, a list of test devices, and a single distribution certificate.
3. **Archive Your App** - Create an archive of your app using Xcode. This archive will be used to generate the Ad Hoc IPA file.
diff --git a/docs/testfairy/security/private-cloud-int.md b/docs/testfairy/sdk/private-cloud-int.md
similarity index 100%
rename from docs/testfairy/security/private-cloud-int.md
rename to docs/testfairy/sdk/private-cloud-int.md
diff --git a/docs/testfairy/security/data-encryption.md b/docs/testfairy/sdk/security/data-encryption.md
similarity index 100%
rename from docs/testfairy/security/data-encryption.md
rename to docs/testfairy/sdk/security/data-encryption.md
diff --git a/docs/testfairy/security/hiding-data.md b/docs/testfairy/sdk/security/hiding-data.md
similarity index 100%
rename from docs/testfairy/security/hiding-data.md
rename to docs/testfairy/sdk/security/hiding-data.md
diff --git a/docs/testfairy/sdk/supported-platforms.md b/docs/testfairy/sdk/supported-platforms.md
index 7f668ea463..cb1f7d7a21 100644
--- a/docs/testfairy/sdk/supported-platforms.md
+++ b/docs/testfairy/sdk/supported-platforms.md
@@ -27,7 +27,7 @@ Along with native Android and iOS development, TestFairy supports a number of ot
## React Native
- [Adding the SDK to your App](/testfairy/platforms/react-native)
-- [Hiding Sensitive Data](/testfairy/security/hiding-data)
+- [Hiding Sensitive Data](/testfairy/sdk/security/hiding-data)
- [Identifying your Users](/testfairy/sdk/identifying-users)
- [Session Attributes](/testfairy/sdk/session-attributes)
- [Remote Logging](/testfairy/sdk/remote-logging)
@@ -35,7 +35,7 @@ Along with native Android and iOS development, TestFairy supports a number of ot
## Nativescript
- [Adding the SDK to your App](/testfairy/platforms/nativescript)
-- [Hiding Sensitive Data](/testfairy/security/hiding-data)
+- [Hiding Sensitive Data](/testfairy/sdk/security/hiding-data)
- [Identifying your Users](/testfairy/sdk/identifying-users)
- [Session Attributes](/testfairy/sdk/session-attributes)
- [Remote Logging](/testfairy/sdk/remote-logging)
@@ -50,7 +50,7 @@ Along with native Android and iOS development, TestFairy supports a number of ot
## Xamarin
- [Adding the SDK to your App](/testfairy/platforms/xamarin)
-- [Hiding Sensitive Data](/testfairy/security/hiding-data)
+- [Hiding Sensitive Data](/testfairy/sdk/security/hiding-data)
- [Identifying your Users](/testfairy/sdk/identifying-users)
- [Session Attributes](/testfairy/sdk/session-attributes)
- [Remote Logging](/testfairy/sdk/remote-logging)
diff --git a/docs/testfairy/testing-an-app/feedback.md b/docs/testfairy/sdk/user-feedback.md
similarity index 98%
rename from docs/testfairy/testing-an-app/feedback.md
rename to docs/testfairy/sdk/user-feedback.md
index b5021eacb3..a417144d0e 100644
--- a/docs/testfairy/testing-an-app/feedback.md
+++ b/docs/testfairy/sdk/user-feedback.md
@@ -1,7 +1,7 @@
---
-id: feedback
-title: Getting Feedback
-sidebar_label: Getting Feedback
+id: user-feedback
+title: Submitting User Feedback
+sidebar_label: Submitting User Feedback
---
import useBaseUrl from '@docusaurus/useBaseUrl';
diff --git a/docs/testfairy/acct-mgmt/acct-settings.md b/docs/testfairy/security/acct-settings.md
similarity index 98%
rename from docs/testfairy/acct-mgmt/acct-settings.md
rename to docs/testfairy/security/acct-settings.md
index a191dff752..88160d42af 100644
--- a/docs/testfairy/acct-mgmt/acct-settings.md
+++ b/docs/testfairy/security/acct-settings.md
@@ -66,7 +66,7 @@ To ensure testers first login to their tester accounts before downloading your a
### SAML/Single Sign-On
-Add the SSO metadata definitions file here. When you add SAML/Single Sign-On, the file contains your ID, URL, and X.509 certificate. See [SSO](/testfairy/acct-mgmt/sso/sso-intro) for more information.
+Add the SSO metadata definitions file here. When you add SAML/Single Sign-On, the file contains your ID, URL, and X.509 certificate. See [SSO](/testfairy/security/sso/sso-intro) for more information.
## Account
diff --git a/docs/testfairy/acct-mgmt/sso/azure.md b/docs/testfairy/security/sso/azure.md
similarity index 100%
rename from docs/testfairy/acct-mgmt/sso/azure.md
rename to docs/testfairy/security/sso/azure.md
diff --git a/docs/testfairy/acct-mgmt/sso/google.md b/docs/testfairy/security/sso/google.md
similarity index 100%
rename from docs/testfairy/acct-mgmt/sso/google.md
rename to docs/testfairy/security/sso/google.md
diff --git a/docs/testfairy/acct-mgmt/sso/okta.md b/docs/testfairy/security/sso/okta.md
similarity index 100%
rename from docs/testfairy/acct-mgmt/sso/okta.md
rename to docs/testfairy/security/sso/okta.md
diff --git a/docs/testfairy/acct-mgmt/sso/onelogin.md b/docs/testfairy/security/sso/onelogin.md
similarity index 100%
rename from docs/testfairy/acct-mgmt/sso/onelogin.md
rename to docs/testfairy/security/sso/onelogin.md
diff --git a/docs/testfairy/acct-mgmt/sso/ping-id.md b/docs/testfairy/security/sso/ping-id.md
similarity index 100%
rename from docs/testfairy/acct-mgmt/sso/ping-id.md
rename to docs/testfairy/security/sso/ping-id.md
diff --git a/docs/testfairy/acct-mgmt/sso/sso-intro.md b/docs/testfairy/security/sso/sso-intro.md
similarity index 80%
rename from docs/testfairy/acct-mgmt/sso/sso-intro.md
rename to docs/testfairy/security/sso/sso-intro.md
index 11bc17715e..15ded6fd69 100644
--- a/docs/testfairy/acct-mgmt/sso/sso-intro.md
+++ b/docs/testfairy/security/sso/sso-intro.md
@@ -1,7 +1,7 @@
---
id: sso-intro
title: SSO
-sidebar_label: SSO
+sidebar_label: Getting Started
---
import useBaseUrl from '@docusaurus/useBaseUrl';
@@ -14,12 +14,12 @@ Single Sign-on (SSO) enables you to manage users and testers outside of TestFair
To integrate TestFairy with your preferred SAML/SSO provider, refer to our integration guides for each supported provider below. These guides provide detailed instructions on configuring TestFairy with Okta, OneLogin, Ping, Oracle, IBM, and Azure ADFS, respectively :
-| | |
-| :---------------------------------------------------------------------------------------------------------------: | -------------------------------------------------------- |
-|
| [OKTA](/testfairy/acct-mgmt/sso/okta) |
-|
| [OneLogin](/testfairy/acct-mgmt/sso/onelogin) |
-|
| [Azure Active Directory](/testfairy/acct-mgmt/sso/azure) |
-|
| [Google Apps](/testfairy/acct-mgmt/sso/google) |
-|
| [Ping Identity](/testfairy/acct-mgmt/sso/ping-id) |
+| | |
+| :---------------------------------------------------------------------------------------------------------------: |---------------------------------------------------------|
+|
| [OKTA](/testfairy/security/sso/okta) |
+|
| [OneLogin](/testfairy/security/sso/onelogin) |
+|
| [Azure Active Directory](/testfairy/security/sso/azure) |
+|
| [Google Apps](/testfairy/security/sso/google) |
+|
| [Ping Identity](/testfairy/security/sso/ping-id) |
Once SSO is properly configured, the TestFairy login page will be replaced with a **Login with SSO** button. This button serves as the entry point to authenticate via your SSO provider and gain access to TestFairy.
diff --git a/docs/testfairy/testing-an-app/testers/building-testers-app.md b/docs/testfairy/testers/building-testers-app.md
similarity index 100%
rename from docs/testfairy/testing-an-app/testers/building-testers-app.md
rename to docs/testfairy/testers/building-testers-app.md
diff --git a/docs/testfairy/testing-an-app/testers/managing-testers.md b/docs/testfairy/testers/managing-testers.md
similarity index 100%
rename from docs/testfairy/testing-an-app/testers/managing-testers.md
rename to docs/testfairy/testers/managing-testers.md
diff --git a/docs/testfairy/testing-an-app/testers/reg-ios-device.md b/docs/testfairy/testers/reg-ios-device.md
similarity index 100%
rename from docs/testfairy/testing-an-app/testers/reg-ios-device.md
rename to docs/testfairy/testers/reg-ios-device.md
diff --git a/docs/testfairy/testing-an-app/testers/testers-dashboard.md b/docs/testfairy/testers/testers-dashboard.md
similarity index 100%
rename from docs/testfairy/testing-an-app/testers/testers-dashboard.md
rename to docs/testfairy/testers/testers-dashboard.md
diff --git a/docs/testfairy/testing-an-app/testers/testing-android-apps.md b/docs/testfairy/testers/testing-android-apps.md
similarity index 100%
rename from docs/testfairy/testing-an-app/testers/testing-android-apps.md
rename to docs/testfairy/testers/testing-android-apps.md
diff --git a/docs/testfairy/testfairy.md b/docs/testfairy/testfairy.md
index b2a7690f0e..b3cff92df1 100644
--- a/docs/testfairy/testfairy.md
+++ b/docs/testfairy/testfairy.md
@@ -12,7 +12,7 @@ Welcome to TestFairy, the App Center distribution alternative! Use our enterpris
TestFairy offers enterprise-grade app distribution capabilities, allowing companies to easily and securely distribute the right apps to the right users. The platform allows admins to enforce corporate security policies during testing, and has the capability to automatically update apps to new versions or revoke access to installed apps or users.
-For more information, see [Managing Testers](/testfairy/testing-an-app/testers/managing-testers/).
+For more information, see [Managing Testers](/testfairy/testers/managing-testers/).
## Analyze User Behavior
@@ -24,10 +24,10 @@ For more information, see [Adding the TestFairy SDK](/testfairy/sdk/adding-tf-sd
TestFairy's feedback features help users provide feedback by shaking their device or taking a screenshot. A report can automatically be posted to Jira along with the session video recording, logs, metrics, and crash reports.
-For more information, see [Getting Feedback](/testfairy/testing-an-app/feedback/).
+For more information, see [Getting Feedback](/testfairy/sdk/user-feedback/).
## Security
TestFairy is available as a private cloud or an on-premise installation and can integrate with any SAML single sign-on service. TestFairy is the only platform that provides end-to-end data encryption using your private/public keys, so your data remains private.
-For more information, see [End to End Data Encryption](/testfairy/security/data-encryption/).
+For more information, see [End to End Data Encryption](/testfairy/sdk/security/data-encryption/).
diff --git a/docs/testfairy/testing-an-app/bug-tracking/micro-focus.md b/docs/testfairy/testing-an-app/bug-tracking/micro-focus.md
deleted file mode 100644
index 57ba9949c9..0000000000
--- a/docs/testfairy/testing-an-app/bug-tracking/micro-focus.md
+++ /dev/null
@@ -1,40 +0,0 @@
----
-id: micro-focus
-title: Connecting Micro Focus ALM Octane to TestFairy
-sidebar_label: Micro Focus ALM Octane
----
-
-import useBaseUrl from '@docusaurus/useBaseUrl';
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-
-Micro Focus ALM Octane a web-based application lifecycle management and quality management solution designed to streamline software delivery and testing processes. By integrating Micro Focus ALM Octane with TestFairy, you can efficiently manage your testing processes, streamline bug tracking, and ensure a smooth collaboration between development and testing teams.
-
-## Integration Steps
-
-1. Go to your [Integrations](https://app.testfairy.com/settings/integrations/) page.
-
-2. Scoll the list to the **Micro Focus ALM Octane** and press the **Add Integration**.
-
-
-3. Next, go to your `ALM Octane` workspace and navigate to the **API ACCESS**. You can use an existing API Access if you have its `API key(Client ID)` and `API password (Client secret)` or create a new one.
-
-
-4. Copy the `API key(Client ID)` and `API password (Client secret)` from your workspace to the Bug System Configuration screen fields.
-
-
-5. Copy your workspace number (you can find it in the workspace URL after `?admin&p=`).
- The link in the URL field should be: `https://almoctane-eur.saas.microfocus.com/api/shared_spaces/[INSERT WORKSPACE NUMBER HERE]/`.
-
-6. Press **Save** to save the configuration.
-
-
-7. Scroll down and press **Activate** for the app you want to connect to a workspace.
-
-8. In the window, select the target workspace for your issues in the `Project Key` field and **Save Changes**.
-
-
-9. When you return to the apps screen, the workspace is mapped to the app.
-
-
-Congratulations! You have successfully integrated Micro Focus ALM Octane with TestFairy, and you can now manage your testing processes and issues more efficiently.
\ No newline at end of file
diff --git a/docs/testfairy/testing-an-app/testers/user-feedback.md b/docs/testfairy/testing-an-app/testers/user-feedback.md
deleted file mode 100644
index 3fda8472a8..0000000000
--- a/docs/testfairy/testing-an-app/testers/user-feedback.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-id: user-feedback
-title: Submitting User Feedback
-sidebar_label: Submitting User Feedback
----
-
-import useBaseUrl from '@docusaurus/useBaseUrl';
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-
-
-TestFairy offers a convenient "Shake to Feedback" feature that allows users to provide feedback easily while using your application. By shaking their device, users can trigger an email pop up containing comprehensive feedback, along with an attached screenshot that users can scribble on. The feedback message is then sent to designated destinations such as your developer's dashboard, JIRA, Slack, etc., including the user's input, a video recording of the session, and all relevant data collected during the session.
-
-## Using Shake to Feedback
-
-By default, the User Feedback feature is activated by shaking the device. When the TestFairy SDK is integrated, users can shake their device to prompt the feedback issue creation.
-When the shake gesture is detected, a feedback form will appear on the screen. Users can fill in details like their email address and a description of the issue they encountered.
-
-The feedback issue will automatically include a screenshot of the app at the moment the user initiated the shake gesture. This screenshot provides valuable context for developers to understand the reported issue. Users can annotate the screenshot to highlight specific areas or provide additional context. Annotating the screenshot can help communicate the issue more effectively.
-
-## Enabling Shake to Feedback in Your Build Settings
-
-To enable the Shake to Feedback feature for your application, follow these steps:
-
-1. Go to Apps and select the app from the list and click Settings.
-
-2. Enable the **In-App Bug Reporting** and click **Save Changes**.
-
\ No newline at end of file
diff --git a/docs/testfairy/testing-an-app/using-testers.md b/docs/testfairy/testing-an-app/using-testers.md
deleted file mode 100644
index 823d9684c0..0000000000
--- a/docs/testfairy/testing-an-app/using-testers.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-id: using-testers
-title: Using Testers
-sidebar_label: Using Testers
----
-
-import useBaseUrl from '@docusaurus/useBaseUrl';
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
diff --git a/docusaurus.config.js b/docusaurus.config.js
index e9d249f293..aa87f39dcd 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -90,6 +90,11 @@ const docusaurusConfig = {
position: 'left',
to: '/visual-testing',
},
+ {
+ label: 'Beta Testing',
+ position: 'left',
+ to: '/testfairy',
+ },
{
label: 'Error Reporting',
position: 'left',
diff --git a/sidebars.js b/sidebars.js
index 55d8104076..f2ee1193dd 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -1161,78 +1161,7 @@ module.exports = {
'testfairy/using-testfairy/insights',
],
},
- {
- type: 'category',
- label: 'Account and Management',
- collapsed: true,
- items: [
- 'testfairy/acct-mgmt/acct-settings',
- {
- type: 'category',
- label: 'Single Sign On',
- collapsed: true,
- items: [
- 'testfairy/acct-mgmt/sso/sso-intro',
- 'testfairy/acct-mgmt/sso/azure',
- 'testfairy/acct-mgmt/sso/google',
- 'testfairy/acct-mgmt/sso/okta',
- 'testfairy/acct-mgmt/sso/onelogin',
- 'testfairy/acct-mgmt/sso/ping-id',
- ],
- },
- ],
- },
- {
- type: 'category',
- label: 'Security',
- collapsed: true,
- items: [
- 'testfairy/security/data-encryption',
- 'testfairy/security/gdpr',
- 'testfairy/security/hiding-data',
- 'testfairy/security/private-cloud-int',
- ],
- },
- {
- type: 'category',
- label: 'SDK',
- collapsed: true,
- items: [
- {
- type: 'category',
- label: 'Android',
- collapsed: true,
- items: [
- 'testfairy/sdk/android/integrating-android',
- ],
- },
- {
- type: 'category',
- label: 'iOS',
- collapsed: true,
- items: [
- 'testfairy/sdk/ios/ad-hoc-ipa',
- 'testfairy/sdk/ios/adding-udids',
- 'testfairy/sdk/ios/custom-ent-apps',
- 'testfairy/sdk/ios/dsyms',
- 'testfairy/sdk/ios/hiding-webview',
- 'testfairy/sdk/ios/integrating-ios',
- 'testfairy/sdk/ios/log-network',
- ],
- },
- 'testfairy/sdk/adding-tf-sdk',
- 'testfairy/sdk/options',
- 'testfairy/sdk/logging',
- 'testfairy/sdk/tf-production',
- 'testfairy/sdk/crash-handler-testing',
- 'testfairy/sdk/identifying-users',
- 'testfairy/sdk/remote-logging',
- 'testfairy/sdk/session-attributes',
- 'testfairy/sdk/supported-platforms',
- 'testfairy/sdk/tf-crash-handler',
- 'testfairy/sdk/map-locations',
- ],
- },
+ 'testfairy/app-center-alternative',
{
type: 'category',
label: 'App Distribution',
@@ -1242,61 +1171,43 @@ module.exports = {
'testfairy/app-distribution/app-versioning',
'testfairy/app-distribution/landing-pages',
'testfairy/app-distribution/auto-update',
+ 'testfairy/app-distribution/app-expiration',
'testfairy/app-distribution/release-notes',
'testfairy/app-distribution/tags',
],
},
{
type: 'category',
- label: 'Testing Your App',
+ label: 'Beta Testers',
collapsed: true,
items: [
- {
- type: 'category',
- label: 'Testers',
- collapsed: true,
- items: [
- 'testfairy/testing-an-app/testers/building-testers-app',
- 'testfairy/testing-an-app/testers/testing-android-apps',
- 'testfairy/testing-an-app/testers/managing-testers',
- 'testfairy/testing-an-app/testers/reg-ios-device',
- 'testfairy/testing-an-app/testers/user-feedback',
- 'testfairy/testing-an-app/testers/testers-dashboard',
- ],
- },
- {
- type: 'category',
- label: 'Bug Tracking',
- collapsed: true,
- items: [
- 'testfairy/testing-an-app/using-bug-tracking',
- 'testfairy/testing-an-app/bug-tracking/github',
- 'testfairy/testing-an-app/bug-tracking/jira-cloud',
- 'testfairy/testing-an-app/bug-tracking/jira-server',
- 'testfairy/testing-an-app/bug-tracking/micro-focus',
- 'testfairy/testing-an-app/bug-tracking/tf-connect',
- 'testfairy/testing-an-app/bug-tracking/trello',
- ],
- },
- 'testfairy/testing-an-app/feedback',
+ 'testfairy/testers/managing-testers',
+ 'testfairy/testers/building-testers-app',
+ 'testfairy/testers/testing-android-apps',
+ 'testfairy/testers/reg-ios-device',
+ 'testfairy/testers/testers-dashboard',
],
},
{
type: 'category',
- label: 'Platforms',
+ label: 'Security',
collapsed: true,
items: [
- 'testfairy/platforms/cordova',
- 'testfairy/platforms/expo',
- 'testfairy/platforms/flutter',
- 'testfairy/platforms/ionic',
- 'testfairy/platforms/lumberyard',
- 'testfairy/platforms/nativescript',
- 'testfairy/platforms/neptune',
- 'testfairy/platforms/react-native',
- 'testfairy/platforms/titanium',
- 'testfairy/platforms/unity',
- 'testfairy/platforms/xamarin',
+ {
+ type: 'category',
+ label: 'Single Sign On',
+ collapsed: true,
+ items: [
+ 'testfairy/security/sso/sso-intro',
+ 'testfairy/security/sso/azure',
+ 'testfairy/security/sso/google',
+ 'testfairy/security/sso/okta',
+ 'testfairy/security/sso/onelogin',
+ 'testfairy/security/sso/ping-id',
+ ],
+ },
+ 'testfairy/security/acct-settings',
+ 'testfairy/security/gdpr',
],
},
{
@@ -1310,7 +1221,6 @@ module.exports = {
'testfairy/integrations/smtp-gmail',
'testfairy/integrations/splunk',
'testfairy/integrations/zendesk',
- 'testfairy/integrations/intercom',
'testfairy/integrations/ms-teams',
'testfairy/integrations/google-cloud',
'testfairy/integrations/apple-uploading',
@@ -1339,6 +1249,88 @@ module.exports = {
'testfairy/api-reference/rest-api',
'testfairy/api-reference/upload-api',
'testfairy/api-reference/webhooks',
+ {
+ type: 'category',
+ label: 'SDK',
+ collapsed: true,
+ items: [
+ {
+ type: 'category',
+ label: 'Android',
+ collapsed: true,
+ items: [
+ 'testfairy/sdk/android/integrating-android',
+ ],
+ },
+ {
+ type: 'category',
+ label: 'iOS',
+ collapsed: true,
+ items: [
+ 'testfairy/sdk/ios/ad-hoc-ipa',
+ 'testfairy/sdk/ios/adding-udids',
+ 'testfairy/sdk/ios/custom-ent-apps',
+ 'testfairy/sdk/ios/dsyms',
+ 'testfairy/sdk/ios/hiding-webview',
+ 'testfairy/sdk/ios/integrating-ios',
+ 'testfairy/sdk/ios/log-network',
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Platforms',
+ collapsed: true,
+ items: [
+ 'testfairy/platforms/cordova',
+ 'testfairy/platforms/expo',
+ 'testfairy/platforms/flutter',
+ 'testfairy/platforms/ionic',
+ 'testfairy/platforms/lumberyard',
+ 'testfairy/platforms/nativescript',
+ 'testfairy/platforms/neptune',
+ 'testfairy/platforms/react-native',
+ 'testfairy/platforms/titanium',
+ 'testfairy/platforms/unity',
+ 'testfairy/platforms/xamarin',
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Bug Tracking',
+ collapsed: true,
+ items: [
+ 'testfairy/sdk/bug-tracking/using-bug-tracking',
+ 'testfairy/sdk/bug-tracking/github',
+ 'testfairy/sdk/bug-tracking/jira-cloud',
+ 'testfairy/sdk/bug-tracking/jira-server',
+ 'testfairy/sdk/bug-tracking/tf-connect',
+ 'testfairy/sdk/bug-tracking/trello',
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Security',
+ collapsed: true,
+ items: [
+ 'testfairy/sdk/security/data-encryption',
+ 'testfairy/sdk/security/hiding-data',
+ ],
+ },
+ 'testfairy/sdk/adding-tf-sdk',
+ 'testfairy/sdk/options',
+ 'testfairy/sdk/logging',
+ 'testfairy/sdk/private-cloud-int',
+ 'testfairy/sdk/user-feedback',
+ 'testfairy/sdk/tf-production',
+ 'testfairy/sdk/crash-handler-testing',
+ 'testfairy/sdk/identifying-users',
+ 'testfairy/sdk/remote-logging',
+ 'testfairy/sdk/session-attributes',
+ 'testfairy/sdk/supported-platforms',
+ 'testfairy/sdk/tf-crash-handler',
+ 'testfairy/sdk/map-locations',
+ ],
+ },
],
},
],
From a32ef146742194958f560a59bd7dcc4b85e82345 Mon Sep 17 00:00:00 2001
From: Logan Graham
Date: Wed, 12 Jun 2024 08:44:55 -0400
Subject: [PATCH 002/148] remove last enterprise note / warning (#2803)
document skipping visual test execution
Co-authored-by: Logan Graham
---
docs/visual-testing.md | 8 --------
docs/visual-testing/integrations/nightwatch.md | 7 +++++++
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/docs/visual-testing.md b/docs/visual-testing.md
index d3cb657053..f9fc51a528 100644
--- a/docs/visual-testing.md
+++ b/docs/visual-testing.md
@@ -3,14 +3,6 @@ title: Sauce Visual Testing
sidebar_label: Overview
---
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-import useBaseUrl from '@docusaurus/useBaseUrl';
-
-:::note Important
-Access to this feature is currently limited to Enterprise customers as part of our commitment to providing tailored solutions. We are excited to announce that self-service access is under development and will be released shortly. Stay tuned!
-:::
-
Get clear and instant visibility into the impact of code changes on your UI across browsers, devices, and operating systems with our automated visual testing solution, which generates side-by-side comparisons of your UI versions with DOM diffs inspection.
Know exactly where and what has changed so that you can deliver a consistent and intuitive user experience.
diff --git a/docs/visual-testing/integrations/nightwatch.md b/docs/visual-testing/integrations/nightwatch.md
index 34d987381b..f82853fc36 100644
--- a/docs/visual-testing/integrations/nightwatch.md
+++ b/docs/visual-testing/integrations/nightwatch.md
@@ -355,6 +355,13 @@ module.exports = {
};
```
+### Skip Execution of Visual Tests
+
+In the event you're running / debugging tests locally and would like to disable the Sauce Visual integration temporarily, you can use the `SAUCE_VISUAL_SKIP` environment variable with any truthy value. When provided, we'll skip build creation, taking snapshots, and all snapshot based assertions will be marked as successful.
+
+Available in `@saucelabs/nightwatch-sauce-visual-service@0.6.0` and later.
+
+
## Example
An example project is available [here](https://github.com/saucelabs/visual-examples/tree/main/nightwatch).
From 47d0f1ec51af7bbda42bdcc3423c0110a34efb1d Mon Sep 17 00:00:00 2001
From: Mykola Mokhnach
Date: Wed, 12 Jun 2024 19:02:37 +0200
Subject: [PATCH 003/148] Update the tutorial for pre-run executables and File
Storage interactions (#2802)
---
docs/dev/api/storage.md | 7 +-
.../selenium/pre-run-executables.md | 178 ++++++------------
2 files changed, 60 insertions(+), 125 deletions(-)
diff --git a/docs/dev/api/storage.md b/docs/dev/api/storage.md
index 0a5aec0b49..6441b19df4 100644
--- a/docs/dev/api/storage.md
+++ b/docs/dev/api/storage.md
@@ -658,7 +658,12 @@ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" \
POST /v1/storage/upload
-Uploads an app file to Sauce Storage for the purpose of mobile app testing and returns a unique file ID assigned to the app. Sauce Storage supports app files in \*.apk, \*.aab, \*.ipa, or \*.zip format, up to 4GB.
+Uploads an app file to Sauce Storage for the purpose of mobile app testing or generic files
+to be used as [Pre-Run Executables](/web-apps/automated-testing/selenium/pre-run-executables/)
+and returns a unique file ID assigned to the uploaded file.
+Sauce Storage supports mobile app packages in \*.apk, \*.aab, \*.ipa, or \*.zip
+format as well as any other file format.
+The maximum size of a single file is limited to 4GB.
#### Parameters
diff --git a/docs/web-apps/automated-testing/selenium/pre-run-executables.md b/docs/web-apps/automated-testing/selenium/pre-run-executables.md
index e6b92a0d76..5b128d239a 100644
--- a/docs/web-apps/automated-testing/selenium/pre-run-executables.md
+++ b/docs/web-apps/automated-testing/selenium/pre-run-executables.md
@@ -48,7 +48,7 @@ When creating your executable file, take into account the operating system you'l
### Storing a Configuration Script
-Your script can be stored in GitHub or in [App Storage](/mobile-apps/app-storage/) (for more information see [Common Error Messages](https://docs.saucelabs.com/dev/error-messages/#failed-to-download-mobile-application)). You can also use [Gist](https://gist.github.com/) to easily host your executable file. Make sure to use the link containing the raw file contents.
+Your script can be stored in GitHub or in [File Storage](/mobile-apps/app-storage/) (for more information see [Common Error Messages](https://docs.saucelabs.com/dev/error-messages/#failed-to-download-mobile-application)). You can also use [Gist](https://gist.github.com/) to easily host your executable file. Make sure to use the link containing the raw file contents.
### Set the `prerun` Capability
@@ -61,7 +61,7 @@ desired_capabilities['prerun'] = {
}
```
-This example accesses the same script from App Storage:
+This example accesses the same script from [App Storage](#upload-files-with-the-rest-api):
```
desired_capabilities['prerun'] = {
@@ -206,7 +206,7 @@ Editing the Host file of the virtual machine will not work if [Sauce Connect Pro
An example of configuring a Sauce Labs virtual machine with a pre-run executable is editing the host file in the virtual machine, so when the driver tries to access a particular domain, like google.com, it will be redirected to a new IP address, for example 162.222.75.243 ([saucelabs.com](http://saucelabs.com/)). As with other `prerun` configurations, the basic steps are:
1. Write a script with the URL redirect to the new IP address.
-1. Upload the script to a publicly accessible location, like GitHub or App Storage.
+1. Upload the script to a publicly accessible location, like GitHub or [File Storage](/dev/api/storage).
1. Set the [`prerun` capability](/dev/test-configuration-options#pre-run-executables) in your test script to load the script as host file in the Sauce Labs virtual machine.
### Host File Script
@@ -310,7 +310,7 @@ The 64bit version of AutoIT works on IE11, and not on IE9. The 32bit version wor
### Upload Files with the REST API
-Below are some examples of how to use the Sauce Labs REST API to upload your mobile file to Sauce Storage. If you do not have a file to test, consider using the [Sauce Labs Swag Labs sample app](https://github.com/saucelabs/sample-app-mobile) for validating this process.
+Below are some examples of how to use the [Sauce Labs REST API](/dev/api/storage) to upload your files to Sauce Storage.
#### REST API Authentication
@@ -329,7 +329,8 @@ For specific instructions on how to set environment variables visit the followin
#### Accepted File Types
-App Storage recognizes certain file types for different platforms and generic use cases. Here are the accepted file types:
+File Storage recognizes certain file types for different platforms.
+Here are the accepted file types for the mobile app testing scenarios:
**Android Apps (APK):** .apk files are recognized as Android apps.
@@ -337,7 +338,11 @@ App Storage recognizes certain file types for different platforms and generic us
**iOS Apps (APP Bundle):** A .zip file will be parsed to determine whether a valid .app bundle exists, and if found, it will be accepted as an iOS app.
-For generic use, you can upload and store other file types like pre-run executables, packages, or binaries. Some of the accepted formats for this type of use case include:
+Mobile apps could be uploaded and managed through the [File Storage API](/dev/api/storage/)
+as well as through the [App Management](https://app.saucelabs.com/app-management) section of the SauceLabs web site.
+
+For the generic use cases, you could upload and store any other file types
+like pre-run executables, packages or binaries, for example:
- .js
- .py
@@ -345,27 +350,27 @@ For generic use, you can upload and store other file types like pre-run executab
- .zip
- .sh
- .bat
+- .exe
+
+Generic files could be uploaded and managed **only** through the [File Storage API](/dev/api/storage/).
+Any file which is not recognized as a valid mobile app won't be shown in the
+[App Management](https://app.saucelabs.com/app-management) section of the SauceLabs web site.
#### Organization Management Sync
-App Storage utilizes a Organization Management sync feature that enables user permission schemes. In other words, a Sauce Labs administrator, whether an organization admin or a team admin, can regulate access to individual application files or specific binary/script files. By default, the system shares all uploaded files with the team to which the user belongs. As a user, you can only access files shared with the team in which you contribute/participate unless you hold the role of an organization admin; in this case, you have access to all files in your organization.
+File Storage utilizes a Organization Management sync feature that enables user permission schemes. In other words, a Sauce Labs administrator, whether an organization admin or a team admin, can regulate access to individual application files or specific binary/script files. By default, the system shares all uploaded files with the team to which the user belongs. As a user, you can only access files shared with the team in which you contribute/participate unless you hold the role of an organization admin; in this case, you have access to all files in your organization.
To manage access to your organization, navigate to **Account** > **Organization Management**.
#### Storage API Endpoints
-There are two main contexts/branches for the storage API:
-
-- One for working with separate application builds (individual builds, application files, etc.)
-- One for working with apps (groups of application builds with the same unique identifier, belonging to the same platform and team)
-
For the full list of the available endpoints, see [Storage API](/dev/api/storage/)
-### Using Application Storage with Automated Test Builds
+### Using File Storage with Pre-run Executables
-After successfully uploading your file to application storage, you need to reference the unique app Identifier (file_id) in your test code to retrieve and use your app for automated tests.
+After successfully uploading your file to the file storage, you need to reference the unique file Identifier (file_id) in your test code to retrieve and use your file for automated tests.
-For example, let's assume you've updated a new version of your app using the [/upload](/dev/api/storage/#upload-file-to-app-storage) endpoint. The JSON response would be something like below:
+For example, let's assume you've updated a new version of your file using the [/upload](/dev/api/storage/#upload-file-to-app-storage) endpoint. The JSON response would be something like below:
```json
{
@@ -375,33 +380,25 @@ For example, let's assume you've updated a new version of your app using the [/u
"id":"286c0fbb0cb644c4a012d505b8a0a1ac",
"org_id":"c064890612424e34a12fca98ce4f32c6"
},
- "name":"Android.SauceLabs.Mobile.Sample.app.2.3.0.apk",
+ "name":"script.sh",
"upload_timestamp":1593450387,
"etag":"0cf189b1c4c17a56656ada5e2d75cd51",
- "kind":"android",
+ "kind":"other",
"group_id":2807,
- "metadata":{
- "identifier":"com.swaglabsmobileapp",
- "name":"Swag Labs Mobile App",
- "version":"2.3.0",
- "icon":"",
- "version_code":13,
- "min_sdk":16,
- "target_sdk":28
- },
+ "metadata":null,
...
}
}
}
```
-Then the file_id would be "id":"379c301a-199c-4b40-ad45-4a95e5f30a3a". If you're unsure of the id of an existing app, you can use the [endpoint](/dev/api/storage/#get-app-storage-files), along with the necessary parameters to find the desired application.
+Then the file_id would be "id":"379c301a-199c-4b40-ad45-4a95e5f30a3a". If you're unsure of the id of an existing file, you can use the [endpoint](/dev/api/storage/#get-app-storage-files), along with the necessary parameters to find the desired file.
:::tip File Name instead of File ID
-You can also use the app `name` field from the storage API in the `app` capability. This approach is particularly useful if you uploaded your build to Application Storage via a CI pipeline, and you either don't know the `id`, or you do not wish to perform JSON parsing in order to retrieve the `id`. The `filename` field also includes [any supported file that can be uploaded to application storage](#accepted-file-types).
+You can also use the file `name` field from the storage API in the `app` capability. This approach is particularly useful if you uploaded your build to the File Storage via a CI pipeline, and you either don't know the `id`, or you do not wish to perform JSON parsing in order to retrieve the `id`. The `filename` field also includes [any supported file that can be uploaded to file storage](#accepted-file-types).
-Example of uploading an Android .apk file:
+Example of using a shell script (.sh) file that has been uploaded to the [File Storage](/dev/api/storage/):
```java
-caps.setCapability("app", "storage:filename=.apk");
+caps.setCapability("prerun", "storage:filename=.sh");
```
@@ -425,7 +422,7 @@ caps.setCapability("app", "storage:filename=.apk");
```js
-caps['app'] = 'storage:filename=.apk';
+caps['prerun'] = 'storage:filename=.sh';
```
@@ -433,7 +430,7 @@ caps['app'] = 'storage:filename=.apk';
```python
-caps['app'] = "storage:filename=.apk"
+caps['prerun'] = "storage:filename=.sh"
```
@@ -441,7 +438,7 @@ caps['app'] = "storage:filename=.apk"
```ruby
-caps['app'] = 'storage:filename=.apk'
+caps['prerun'] = 'storage:filename=.sh'
```
@@ -449,7 +446,7 @@ caps['app'] = 'storage:filename=.apk'
```csharp
-caps.SetCapability("app","storage:filename=.apk");
+caps.SetCapability("prerun","storage:filename=.sh");
```
@@ -459,14 +456,14 @@ caps.SetCapability("app","storage:filename=.apk");
**Limitations**:
- File names are **NOT** unique, therefore they will always default to the latest version.
-- Currently you cannot specify the version of the app using this feature.
+- Currently you cannot specify the version of the file using this feature.
- `build` capability not supported in VDC at this time.
:::
#### Updating WebDriver Capabilities
-If you were previously using application stored in sauce-storage, you can convert your existing test capabilities by replacing `sauce-storage:myapp` with `storage:`.
+If you were previously using a file stored in sauce-storage, you can convert your existing test capabilities by replacing `sauce-storage:myfile` with `storage:`.
##### Example Code Snippets
@@ -488,13 +485,13 @@ values={[
**Before**
```java
-caps.setCapability("app", "sauce-storage:some-app.apk");
+caps.setCapability("prerun", "sauce-storage:some-file.sh");
```
**After**
```java
-caps.setCapability("app", "storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882");
+caps.setCapability("prerun", "storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882");
```
@@ -504,13 +501,13 @@ caps.setCapability("app", "storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882");
**Before**
```js
-caps['app'] = 'sauce-storage:my_app.apk';
+caps['prerun'] = 'sauce-storage:my_file.sh';
```
**After**
```js
-caps['app'] = 'storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882';
+caps['prerun'] = 'storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882';
```
@@ -520,13 +517,13 @@ caps['app'] = 'storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882';
**Before**
```python
-caps['app'] = "sauce-storage:my_app.apk"
+caps['prerun'] = "sauce-storage:my_file.sh"
```
**After**
```python
-caps['app'] = "storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882"
+caps['prerun'] = "storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882"
```
@@ -535,14 +532,14 @@ caps['app'] = "storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882"
**Before**
-```ruby
-caps['app'] = 'sauce-storage:my_app.apk'
+```prerun
+caps['prerun'] = 'sauce-storage:my_file.sh'
```
**After**
```ruby
-caps['app'] = 'storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882'
+caps['prerun'] = 'storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882'
```
@@ -552,13 +549,13 @@ caps['app'] = 'storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882'
**Before**
```csharp
-caps.SetCapability("app","sauce-storage:my_app.apk");
+caps.SetCapability("prerun","sauce-storage:my_file.sh");
```
**After**
```csharp
-caps.SetCapability("app","storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882");
+caps.SetCapability("prerun","storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882");
```
@@ -567,14 +564,13 @@ caps.SetCapability("app","storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882");
### Uploading to a Remote Location
-There may be situations where you want to install an application from a downloadable remote location (AWS S3 bucket, a GitHub repository, etc.).
+There may be situations where you want to download the file from a downloadable remote location (AWS S3 bucket, a GitHub repository, etc.).
-Review the following guidelines below before uploading your application:
+Review the following guidelines below before uploading your file:
-1. Make sure your application meets the [requirements](/mobile-apps/supported-devices/) for Android and iOS Mobile Application Testing.
-2. Upload your application to the hosting location.
-3. Ensure Sauce Labs has READ access to the app URL.
-4. In your test script, enter the URL for the application as the `app` desired capability. Below are some example snippets:
+1. Upload your file to the hosting location.
+2. Ensure Sauce Labs has READ access to the file URL.
+3. In your test script, enter the URL for the file as the `prerun` desired capability. Below are some example snippets:
```java
-caps.setCapability("app", "https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip);
+caps.setCapability("prerun", "https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip);
```
@@ -598,7 +594,7 @@ caps.setCapability("app", "https://github.com/saucelabs/sample-app-mobile/releas
```js
-app: 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip',
+caps.prerun = 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip',
```
@@ -606,7 +602,7 @@ app: 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS
```python
-'app': 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip',
+caps['prerun'] = 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip',
```
@@ -614,7 +610,7 @@ app: 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS
```ruby
-app: 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip'
+caps['prerun'] = 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip'
```
@@ -622,73 +618,7 @@ app: 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS
```csharp
-caps.SetCapability("app", "https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip");
-```
-
-
-
-
-
-### Uploading to Legacy Sauce Storage
-
-Sauce Storage is our legacy private storage space for apps. Files uploaded will expire seven days after upload, and be removed. You can upload the app you want to test to Sauce Storage using our REST API, and then access it for testing by specifying `sauce-storage:myapp` for the `app` capability in your test script. You upload apps using the [upload file method](/dev/api/storage/#upload-file-to-app-storage) of the Sauce Labs REST API.
-
-You can use any REST client; [cURL](https://curl.haxx.se/docs/manpage.html) is a convenient command-line option.
-
-
-
-
-
-**US West**
-
-```curl
-$ curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY -X POST -H "Content-Type: application/octet-stream" \
-"https://saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/$APP_NAME?overwrite=true" --data-binary @path/to/your_file_name
-```
-
-**US East**
-
-```curl
-$ curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY -X POST -H "Content-Type: application/octet-stream" \
-"https://us-east-1.saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/$APP_NAME?overwrite=true" --data-binary @path/to/your_file_name
-```
-
-**EU Central**
-
-```curl
-$ curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY -X POST -H "Content-Type: application/octet-stream" \
-"https://eu-central-1.saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/$APP_NAME?overwrite=true" --data-binary @path/to/your_file_name
-```
-
-
-
-
-
-**US West**
-
-```curl
-> curl -u %SAUCE_USERNAME%:%SAUCE_ACCESS_KEY% -X POST -H "Content-Type: application/octet-stream" \
-"https://saucelabs.com/rest/v1/storage/%SAUCE_USERNAME%/%APP_NAME%?overwrite=true" --data-binary @path\to\your_file_name
-```
-
-**US East**
-
-```curl
-> curl -u %SAUCE_USERNAME%:%SAUCE_ACCESS_KEY% -X POST -H "Content-Type: application/octet-stream" \
-"https://us-east-1.saucelabs.com/rest/v1/storage/%SAUCE_USERNAME%/%APP_NAME%?overwrite=true" --data-binary @path\to\your_file_name
-```
-
-**EU Central**
-
-```curl
-> curl -u %SAUCE_USERNAME%:%SAUCE_ACCESS_KEY% -X POST -H "Content-Type: application/octet-stream" \
-"https://eu-central-1.saucelabs.com/rest/v1/storage/%SAUCE_USERNAME%/%APP_NAME%?overwrite=true" --data-binary @path\to\your_file_name
+caps.SetCapability("prerun", "https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip");
```
From f31feb8e0e92277838302c1756f576a6c9910499 Mon Sep 17 00:00:00 2001
From: kristofmuhi
Date: Thu, 13 Jun 2024 13:09:19 +0200
Subject: [PATCH 004/148] new passcode capability exposure (#2806)
* Update live-cross-browser-testing.md
* Update live-mobile-app-testing.md
* Add files via upload
* Update live-mobile-app-testing.md
---
.../live-testing/live-mobile-app-testing.md | 3 ++-
.../live-testing/live-cross-browser-testing.md | 2 +-
static/img/live-testing/passcode.png | Bin 0 -> 5058 bytes
3 files changed, 3 insertions(+), 2 deletions(-)
create mode 100644 static/img/live-testing/passcode.png
diff --git a/docs/mobile-apps/live-testing/live-mobile-app-testing.md b/docs/mobile-apps/live-testing/live-mobile-app-testing.md
index a451f700b3..3bbd7791c9 100644
--- a/docs/mobile-apps/live-testing/live-mobile-app-testing.md
+++ b/docs/mobile-apps/live-testing/live-mobile-app-testing.md
@@ -64,7 +64,7 @@ To view your recent configurations, click **Recents**.
| Device Language | Use the dropdown to select the device language. The language selector will tell your application that the locale of the device and region is set to the selected parameter. You won't need to change the language of the OS manually during a session inside iOS/Android settings. For more information about the locale setting, see the documentation for [iOS](https://developer.apple.com/documentation/foundation/locale) and [Android](https://developer.android.com/reference/java/util/Locale). |
| Device Orientation | Use the dropdown to set the device orientation (Landscape or Portrait). |
| Proxy | Enable/disable the use of a proxy. Enter the **Hostname** and **Port** and then click **Update**. |
-| Device Passcode
Real Devices Only
| Enable/disable the device passcode for your apps. If your app requires a device passcode/screenlock to launch, you can enable this setting to run your tests on a passcode-protected device. On Android we are setting 000000, on iOS 089675 as passcode. |
+| Device Passcode
Real Devices Only
| Enable/disable the device passcode for your apps. If your app requires a device passcode/screenlock to launch, you can enable this setting to run your tests on a passcode-protected device. On Android we are setting 000000, on iOS 089675 as passcode. This is available during Live Testing sessions, see it below in the [Live Testing interface section](/mobile-apps/live-testing/live-mobile-app-testing/#live-test-interface). |
| Instrumentation | Enable/disable device instrumentation. Enabling allows you to use advanced features when testing your app in the real device cloud, like image injection and taking screenshots of secure views. |
| Image Injection | Enable/disable image injection. Image injection allows you to mimic camera behavior when testing apps by letting you upload an image and present it to the app as if it were read by the device camera. |
| Bypass Screenshot Restriction
Android Only
| Enable/disable Bypass Screenshot Restriction (not supported on apps uploaded to the legacy sauce storage). If you're testing Android mobile apps on Sauce Labs and see a black screen in your live testing session, you might need to enable the Bypass Screenshot Restriction. This allows Sauce Labs to work around a setting on those apps that prevents screenshots or videos from being taken. However, there are other details to keep in mind. To effectively test apps that have this setting, see [Bypass Screenshot Restriction](/mobile-apps/features/bypass-screenshot). |
@@ -216,6 +216,7 @@ This feature has a constraint on the maximum allowable length of the test name,
|
| Install Dependency | Opens the **Install Dependent App** window. |
|
| Developer Options | Opens the **Developer Options** panel, which includes the **Device Log** and **Dev Tools** tabs. |
|
| Mute/Unmute | Mutes or unmutes audio for your testing session. |
+|
| Passcode - Android Only | If your app requires a device passcode/screenlock to launch, you can enable this setting to run your tests on a passcode-protected device. On Android we are setting 000000. |
### Device Log
diff --git a/docs/web-apps/live-testing/live-cross-browser-testing.md b/docs/web-apps/live-testing/live-cross-browser-testing.md
index 84db446c33..d9d3668458 100644
--- a/docs/web-apps/live-testing/live-cross-browser-testing.md
+++ b/docs/web-apps/live-testing/live-cross-browser-testing.md
@@ -95,7 +95,7 @@ When you are done testing, [you can opt to select an outcome and enter a name fo
|
| Take Screenshot | Takes a screenshot of the current device screen. The image downloads automatically as a .png file. |
|
| Rotate Device | Rotates the device between portrait and landscape. |
|
| Restart App | Restarts the app. |
-|
| Device Settings | **Language** - Enables you to choose a different language from the default one.
**WiFi** - Turns On/Off the Wifi.
**Animations** - Turns On/Off the animations.
**Audio** - Turns On/Off the audio.
**Performance mode On/Off** - Enables you to increase frame rate per second, or switch back to lower frame rate video streaming, when your network connection or VPN is restrictive and you experience blurred screen. |
+|
| Device Settings | **Language** - Enables you to choose a different language from the default one.
**WiFi** - Turns On/Off the Wifi.
**Animations** - Turns On/Off the animations.
**Audio** - Turns On/Off the audio.
**Performance mode On/Off** - Enables you to increase frame rate per second, or switch back to lower frame rate video streaming, when your network connection or VPN is restrictive and you experience blurred screen.
**Passcode - Android Only** - If your app requires a device passcode/screenlock to launch, you can enable this setting to run your tests on a passcode-protected device. On Android we are setting 000000. |
|
| Tools | **ADB Shell** - Opens a window to execute an ADB Command.
**Set GPS Location** - Set the GPS location using coordinates or by dropping a pin on the map.
**Upload file to SD Card** - Uploads a file to SD Card.
**Copy to clipboard** - Opens the Paste Content Into Device window. |
#### Device Log
diff --git a/static/img/live-testing/passcode.png b/static/img/live-testing/passcode.png
new file mode 100644
index 0000000000000000000000000000000000000000..5101f0a21ab4823c3002e9f6d7c90f07f0e2575a
GIT binary patch
literal 5058
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
Date: Wed, 12 Jun 2024 08:24:19 +0200
Subject: [PATCH 005/148] delete billing docs
---
docs/basics/acct-team-mgmt-hub.md | 11 ------
.../acct-team-mgmt/managing-subscription.md | 36 -------------------
docs/basics/acct-team-mgmt/plan-details.md | 27 --------------
.../basics/acct-team-mgmt/updating-billing.md | 28 ---------------
sidebars.js | 11 ------
tests/sauce-docs-checker/map.conf | 5 ---
6 files changed, 118 deletions(-)
delete mode 100644 docs/basics/acct-team-mgmt/managing-subscription.md
delete mode 100644 docs/basics/acct-team-mgmt/plan-details.md
delete mode 100644 docs/basics/acct-team-mgmt/updating-billing.md
diff --git a/docs/basics/acct-team-mgmt-hub.md b/docs/basics/acct-team-mgmt-hub.md
index cb8dbfdb84..bad9e099c6 100644
--- a/docs/basics/acct-team-mgmt-hub.md
+++ b/docs/basics/acct-team-mgmt-hub.md
@@ -18,15 +18,4 @@ The Account area in Sauce Labs provides several options for you to configure you
-
-
-
Billing and Subscriptions
-
Sauce Labs offers several options for managing your billing and subscription information.
-
-
-
diff --git a/docs/basics/acct-team-mgmt/managing-subscription.md b/docs/basics/acct-team-mgmt/managing-subscription.md
deleted file mode 100644
index 7151f088f4..0000000000
--- a/docs/basics/acct-team-mgmt/managing-subscription.md
+++ /dev/null
@@ -1,36 +0,0 @@
----
-id: managing-subscription
-title: Managing Your Subscription
-sidebar_label: Managing Your Subscription
----
-
-import useBaseUrl from '@docusaurus/useBaseUrl';
-
-## Canceling Your Subscription
-
-You can cancel your subscription plan at any time from the **Billing** page.
-
-:::note
-If you want to cancel an Enterprise plan, contact your Sauce Labs account executive.
-:::
-
-1. On Sauce Labs, click **ACCOUNT** and then click **Billing**.
-
-
-
-2. On the **SELECT PLAN** tab, click **Cancel Your Subscription**.
-
-
-
-## Upgrading Your Subscription
-
-If you need more concurrent VMs, concurrent devices, or more minutes, you can upgrade your subscription plan on the **Organization Management** page. You can also enter redemption codes for upgrades and free minutes on the same page.
-
-:::note
-If you want to upgrade an Enterprise plan, contact your Sauce Labs account executive.
-:::
-
-1. On Sauce Labs, click **ACCOUNT** and then click **Billing**.
-2. On the **SELECT PLAN** tab, update the relevant settings and then click **Update Plan**.
-
-
diff --git a/docs/basics/acct-team-mgmt/plan-details.md b/docs/basics/acct-team-mgmt/plan-details.md
deleted file mode 100644
index c6a0f62c6a..0000000000
--- a/docs/basics/acct-team-mgmt/plan-details.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-id: plan-details
-title: Viewing Plan Details
-sidebar_label: Viewing Plan Details
----
-
-import useBaseUrl from '@docusaurus/useBaseUrl';
-
-You can view the number of concurrent VMs, concurrent devices, and minutes allowed under your plan.
-
-1. On Sauce Labs, click **ACCOUNT** and then click **Billing**.
-
-
-
-2. Your plan type (for example, Enterprise or Subscription) is displayed at the bottom of the **Select Plan** tab.
-
-## Viewing Plan Usage
-
-You can view usage information for your account on the **Organization Management** page.
-
-1. On Sauce Labs, click **ACCOUNT** and then click **Billing**.
-
-2. Next to **Usage**, select a user to view their usage statistics for the current 30 days as compared with the previous 30 days.
-
-:::note
-You can view usage statistics for your entire team or yourself only.
-:::
diff --git a/docs/basics/acct-team-mgmt/updating-billing.md b/docs/basics/acct-team-mgmt/updating-billing.md
deleted file mode 100644
index 14f7eb99a1..0000000000
--- a/docs/basics/acct-team-mgmt/updating-billing.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-id: updating-billing
-title: Updating Your Billing Information
-sidebar_label: Updating Your Billing Information
----
-
-import useBaseUrl from '@docusaurus/useBaseUrl';
-
-You can update your plan billing information at any time for our online plans.
-
-:::note
-If you want to update the billing information for an Enterprise plan, contact your Sauce Labs account executive.
-:::
-
-## Virtual Device Cloud Billing
-
-1. On Sauce Labs, click **ACCOUNT**, and then click **Billing**.
-
-
-
-2. On the Billing page, click **Billing Information**.
-3. Update cardholder details (if required).
-4. To update the card on file, click **Replace Existing Card**.
-5. Click **UPDATE INFORMATION**.
-
-:::note
-For your reference, the URL for this page is **https://app.saucelabs.com/billing/my-account**.
-:::
diff --git a/sidebars.js b/sidebars.js
index f2ee1193dd..020138694f 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -912,17 +912,6 @@ module.exports = {
'basics/acct-team-mgmt/sauce-connect-proxy-tunnels',
],
},
- 'basics/acct-team-mgmt/private-device-mgmt',
- {
- type: 'category',
- label: 'Billing and Subscriptions',
- collapsed: true,
- items: [
- 'basics/acct-team-mgmt/managing-subscription',
- 'basics/acct-team-mgmt/updating-billing',
- 'basics/acct-team-mgmt/plan-details',
- ],
- },
],
},
{
diff --git a/tests/sauce-docs-checker/map.conf b/tests/sauce-docs-checker/map.conf
index 24b2886050..8ae5ccb729 100644
--- a/tests/sauce-docs-checker/map.conf
+++ b/tests/sauce-docs-checker/map.conf
@@ -78,11 +78,6 @@ map $request_uri $new_uri {
/display/DOCS/User+Account+Types docs.saucelabs.com/basics/acct-team-mgmt/managing-user-info/;
/display/DOCS/Viewing+and+Exporting+Usage+Data docs.saucelabs.com/basics/acct-team-mgmt/assigning-removing-users-teams/;
/display/DOCS/Sharing+Sauce+Connect+Proxy+Tunnels+-+Extended+Team+Management docs.saucelabs.com/basics/acct-team-mgmt/sauce-connect-proxy-tunnels/;
- /display/DOCS/Canceling+Your+Subscription+Plan docs.saucelabs.com/basics/acct-team-mgmt/managing-subscription/;
- /display/DOCS/Upgrading+Your+Subscription+Plan docs.saucelabs.com/basics/acct-team-mgmt/managing-subscription/;
- /display/DOCS/Updating+Your+Plan+Billing+Information docs.saucelabs.com/basics/acct-team-mgmt/updating-billing/;
- /display/DOCS/Viewing+Plan+Details docs.saucelabs.com/basics/acct-team-mgmt/plan-details/;
- /display/DOCS/Viewing+Plan+Usage+Details+for+Your+Accounts docs.saucelabs.com/basics/acct-team-mgmt/plan-details/;
/display/DOCS/Account+and+Team+Management+for+Real+Devices docs.saucelabs.com/basics/acct-team-mgmt/real-devices/;
/display/DOCS/Setting+Up+Single+Sign-On docs.saucelabs.com/basics/sso/setting-up-single-sign-on/;
/display/DOCS/Configuring+Active+Directory+Federated+Service+for+Sauce+Labs+SSO docs.saucelabs.com/basics/sso/config-adfs/;
From a6b03a5cc2717f1637535478abdf2e3535115794 Mon Sep 17 00:00:00 2001
From: aga-szczepanska
Date: Wed, 12 Jun 2024 13:23:27 +0200
Subject: [PATCH 006/148] bring back basics/acct-team-mgmt/private-device-mgmt
link
---
sidebars.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/sidebars.js b/sidebars.js
index 020138694f..1561098b70 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -912,6 +912,7 @@ module.exports = {
'basics/acct-team-mgmt/sauce-connect-proxy-tunnels',
],
},
+ 'basics/acct-team-mgmt/private-device-mgmt',
],
},
{
From 4058fe62b44b0e050a5dbb4f1d9bb33a38880152 Mon Sep 17 00:00:00 2001
From: Alex Plischke
Date: Thu, 13 Jun 2024 13:20:30 -0700
Subject: [PATCH 007/148] docs: add known limitations (#2805)
---
docs/web-apps/automated-testing/cypress.md | 1 +
docs/web-apps/automated-testing/playwright.md | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/docs/web-apps/automated-testing/cypress.md b/docs/web-apps/automated-testing/cypress.md
index 9c42ef2818..ff4c085fe3 100644
--- a/docs/web-apps/automated-testing/cypress.md
+++ b/docs/web-apps/automated-testing/cypress.md
@@ -201,3 +201,4 @@ Cypress does not currently work with Microsoft Edge 120+ on Windows.
- Cypress only supports launching Webkit with a fixed resolution of 1280x720.
- Cypress 12.6.0 does not work on Windows with Webkit browser.
- Cypress 12+ does not work on macOS 11 with Webkit browser.
+- Cypress 13.10.0+ does not work on macOS 12 with Webkit browser.
diff --git a/docs/web-apps/automated-testing/playwright.md b/docs/web-apps/automated-testing/playwright.md
index b87314310d..9c45d47ed1 100644
--- a/docs/web-apps/automated-testing/playwright.md
+++ b/docs/web-apps/automated-testing/playwright.md
@@ -179,9 +179,13 @@ We recommend that you avoid the use of special characters when naming your tests
When using Sauce-Connect, Webkit browser is unable to load any website that is hosted on the Internet.
Local websites can still be loaded.
+### macOS 12 + Playwright 1.44+ + Webkit
+
+Webkit is not working on macOS 12 since Playwright 1.44.0.
+
### macOS 11 + Playwright 1.29+ + Webkit
-Webkit is not working on macOS 11 since Playwright 1.29.0
+Webkit is not working on macOS 11 since Playwright 1.29.0.
### Playwright HTML Reporter + Trace Viewer
From 3031b609e94a359820c4eee0842aa8df79abd17b Mon Sep 17 00:00:00 2001
From: Yu Yi Yang
Date: Fri, 14 Jun 2024 10:51:44 +0200
Subject: [PATCH 008/148] add device management api base
---
.../acct-team-mgmt/private-device-mgmt.md | 4 ++
docs/dev/api/rdc.md | 52 ++++++++++++++++++-
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/docs/basics/acct-team-mgmt/private-device-mgmt.md b/docs/basics/acct-team-mgmt/private-device-mgmt.md
index ec1b3b209c..0f82a97b28 100644
--- a/docs/basics/acct-team-mgmt/private-device-mgmt.md
+++ b/docs/basics/acct-team-mgmt/private-device-mgmt.md
@@ -133,3 +133,7 @@ Please send us a support ticket to set up Confirm with AssistiveTouch on your de
This feature **requires** setting the Account Allow List.
Please see [Testing Apple Pay](/mobile-apps/live-testing/testing-apple-pay) for more information.
:::
+
+## Private Device Management API
+Easily manage your private real devices with our [Device Management API endpoints](/dev/api/rdc/#private-real-device-management)
+to obtain device information, assign devices to a specific team, and update device settings efficiently.
diff --git a/docs/dev/api/rdc.md b/docs/dev/api/rdc.md
index 98256fe55a..b954d6291d 100644
--- a/docs/dev/api/rdc.md
+++ b/docs/dev/api/rdc.md
@@ -8,10 +8,17 @@ description: Retrieve information related to real device availability, device/pl
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
-Use the Real Device Cloud (RDC) API methods to look up device types and availability in your data center and view current activity on those devices.
+The Real Device Cloud (RDC) API allows you to manage real devices and jobs in your data center. Use the RDC API methods to:
+* Look up device types and availability
+* View current device activity
+* Manage real device jobs by stopping, deleting, or updating job details
+* Assign a private device to a team
+* Update private device settings
Refer to [Getting Started](/dev/api) for Authentication and Server information.
+## Real Devices
+
### Get Devices
@@ -568,6 +575,8 @@ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
---
+## Jobs
+
### Get Real Device Jobs
@@ -1322,3 +1331,44 @@ No payload is returned with the successful deletion.
---
+
+## Private Real Device Management
+
+Learn more about how to [manage your private devices](/basics/acct-team-mgmt/private-device-mgmt).
+
+### Get Private Devices
+
+GET /v1/rdc/deviceManagement/devices
+
+
+Get a list of private devices with their device information and settings.
+
+
+
+### Assign Device to a Team
+
+PUT /v1/rdc/deviceManagement/{device_descriptor_id}/team
+
+
+Assign a private device to a specific team.
+
+
+
+### Remove Device Assignment from Team
+
+DELETE /v1/rdc/deviceManagement/{device_descriptor_id}/team
+
+
+Remove the private device assignment from a team.
+
+
+
+### Update Device Settings
+
+PUT /v1/rdc/deviceManagement/{device_descriptor_id}/settings
+
+
+Update device settings to allow apps, system apps, and accounts to persist between sessions. Check out the
+[available device settings](/basics/acct-team-management/#app-allow-list) for more information on each setting.
+
+
\ No newline at end of file
From 8ee3fb89a598e24a08606d090c7fee818ad6795a Mon Sep 17 00:00:00 2001
From: Yu Yi Yang
Date: Fri, 14 Jun 2024 14:09:17 +0200
Subject: [PATCH 009/148] remove link to private device management API until it
is merged first
---
docs/basics/acct-team-mgmt/private-device-mgmt.md | 4 ----
docs/dev/api/rdc.md | 12 ++++++++++++
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/docs/basics/acct-team-mgmt/private-device-mgmt.md b/docs/basics/acct-team-mgmt/private-device-mgmt.md
index 0f82a97b28..ec1b3b209c 100644
--- a/docs/basics/acct-team-mgmt/private-device-mgmt.md
+++ b/docs/basics/acct-team-mgmt/private-device-mgmt.md
@@ -133,7 +133,3 @@ Please send us a support ticket to set up Confirm with AssistiveTouch on your de
This feature **requires** setting the Account Allow List.
Please see [Testing Apple Pay](/mobile-apps/live-testing/testing-apple-pay) for more information.
:::
-
-## Private Device Management API
-Easily manage your private real devices with our [Device Management API endpoints](/dev/api/rdc/#private-real-device-management)
-to obtain device information, assign devices to a specific team, and update device settings efficiently.
diff --git a/docs/dev/api/rdc.md b/docs/dev/api/rdc.md
index b954d6291d..fb0a7c072d 100644
--- a/docs/dev/api/rdc.md
+++ b/docs/dev/api/rdc.md
@@ -1343,6 +1343,9 @@ Learn more about how to [manage your private devices](/basics/acct-team-mgmt/pri
Get a list of private devices with their device information and settings.
+#### Parameters
+#### Responses
+
### Assign Device to a Team
@@ -1352,6 +1355,9 @@ Get a list of private devices with their device information and settings.
Assign a private device to a specific team.
+#### Parameters
+#### Responses
+
### Remove Device Assignment from Team
@@ -1361,6 +1367,9 @@ Assign a private device to a specific team.
Remove the private device assignment from a team.
+#### Parameters
+#### Responses
+
### Update Device Settings
@@ -1371,4 +1380,7 @@ Remove the private device assignment from a team.
Update device settings to allow apps, system apps, and accounts to persist between sessions. Check out the
[available device settings](/basics/acct-team-management/#app-allow-list) for more information on each setting.
+#### Parameters
+#### Responses
+
\ No newline at end of file
From a78d6928cdd5d70a3f9f2652fd892738508946ed Mon Sep 17 00:00:00 2001
From: Przemyslaw Zukowski
Date: Fri, 14 Jun 2024 14:45:15 +0200
Subject: [PATCH 010/148] update docs on auxiliary service providers
---
docs/basics/sso/setting-up-sso-special-cases.md | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/docs/basics/sso/setting-up-sso-special-cases.md b/docs/basics/sso/setting-up-sso-special-cases.md
index efa10aba88..4358749175 100644
--- a/docs/basics/sso/setting-up-sso-special-cases.md
+++ b/docs/basics/sso/setting-up-sso-special-cases.md
@@ -27,10 +27,6 @@ The `contact_email` must be an email address not used by any other user in Sauce
## Single Identity Provider and Multiple Organizations at Sauce Labs
-:::note
-Integrating more than two Sauce Labs organizations with the same Identity Provider is not supported. If you have more than two organizations that you need integration with the same Identity Provider, contact your Customer Success Manager or [Sauce Labs Support](mailto:help@saucelabs.com).
-:::
-
### Problem Description
Some identity providers do not allow creating more than one SAML integration with the same service provider. In other words, they require one unique entity ID for a service provider.
@@ -42,8 +38,14 @@ If your Identity Provider has this limitation and you have two organizations at
2. [Integrate the SAML SSO application](/basics/sso/setting-up-sso/#integrating-with-sauce-labs-service-provider) that you created in the previous step with one of your Sauce Labs organizations.
3. In your Identity Provider set up another SAML SSO integration/application with the auxiliary Sauce Labs Service Provider. You cannot use a preconfigured Sauce Labs SAML application from your identity provider's catalog for this purpose. Instead, you must create a custom SAML application, as it requires different metadata than the preconfigured one.
- - You have to use [different Sauce Labs metadata](https://accounts.saucelabs.com/am/sso/metadata/https%3A%2F%2Faccounts.saucelabs.com%2Fsp1).
- - The metadata contains different entity ID and different ACS URLs (`sp1` instead of `sp`):
+ - You have to use different Sauce Labs metadata. Sauce Labs provides four auxiliary Service Providers with different entity IDs. You can find the metadata for each auxiliary Service Provider below:
+ - [sp1 metadata](https://accounts.saucelabs.com/am/sso/metadata/https%3A%2F%2Faccounts.saucelabs.com%2Fsp1)
+ - [sp2 metadata](https://accounts.saucelabs.com/am/sso/metadata/https%3A%2F%2Faccounts.saucelabs.com%2Fsp2)
+ - [sp3 metadata](https://accounts.saucelabs.com/am/sso/metadata/https%3A%2F%2Faccounts.saucelabs.com%2Fsp3)
+ - [sp4 metadata](https://accounts.saucelabs.com/am/sso/metadata/https%3A%2F%2Faccounts.saucelabs.com%2Fsp4)
+ - The metadata contains different entity ID and different ACS URLs (`spX` instead of `sp`), where `X` is a number from 1 to 4.
+ - In this tutorial we will use the metadata for the auxiliary SP with entity ID `sp1`. But if you for example want to use the auxiliary **SP3, remember to put `sp3` in all places in the configuration in your IdP instead of `sp1`**.
+ - Here is an example of the attributes for the auxiliary Sauce Labs SP with entity ID `sp1` that differ from the standard setup with `sp`:
| Setting | Value |
| -------------------------- | ----------------------------------------------------------------------- |
From 63148841ae7f15c49e1416dcb3a2a82f6985eb62 Mon Sep 17 00:00:00 2001
From: Tony Knight
Date: Fri, 14 Jun 2024 09:41:15 -0400
Subject: [PATCH 011/148] Stadia was shut down January 18th, 2023.
---
.../platform-integrations/overview.md | 1 -
.../platform-integrations/stadia.md | 72 -------------------
sidebars.js | 1 -
3 files changed, 74 deletions(-)
delete mode 100644 docs/error-reporting/platform-integrations/stadia.md
diff --git a/docs/error-reporting/platform-integrations/overview.md b/docs/error-reporting/platform-integrations/overview.md
index 11ee11c5a6..e2c95465fd 100644
--- a/docs/error-reporting/platform-integrations/overview.md
+++ b/docs/error-reporting/platform-integrations/overview.md
@@ -27,7 +27,6 @@ Integrate Backtrace in your games and apps across languages and platforms with o
Unity
Unreal Engine
CryEngine
- Stadia
Switch
PlayStation 4
PlayStation 5
diff --git a/docs/error-reporting/platform-integrations/stadia.md b/docs/error-reporting/platform-integrations/stadia.md
deleted file mode 100644
index e8890d93be..0000000000
--- a/docs/error-reporting/platform-integrations/stadia.md
+++ /dev/null
@@ -1,72 +0,0 @@
----
-id: stadia
-title: Stadia Integration Guide
-sidebar_label: Stadia
-description: Backtrace supports ingesting crash reports from Google Stadia.
----
-
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-import useBaseUrl from '@docusaurus/useBaseUrl';
-
-Backtrace supports the ingestion of crash reports from Google Stadia.
-
-This integration guide provides instructions using the Google Cloud Console, Google Cloud Shell, or command-line tools (gcloud, gsutil, ggp).
-
-## What You'll Need
-
-- Google Cloud Console access and the ability to use the web console or command-line tools.
-- Google Cloud project_id, cloud storage bucket name, Pub/Sub name, and your Service Account Key JSON file. These can be configured through the user interface, but this guide provides command-line invocations for convenience.
-- A Backtrace instance to which Stadia game crashes are pushed.
-
-## Setup and Installation
-
-The following are detailed setup instructions.
-
-### 1. Configure Stadia Title to Route Crashes to Google Cloud Storage
-
-Follow the instructions in the Google Cloud Develop Stadia [Get Crash Reports documentation](https://developers.google.com/stadia/1.37/docs/develop/debug-and-test/crash-reports) to create or use an existing Cloud Storage Bucket. Retrieve the `project_id` (shown in the screenshot below) and the bucket name in use. Make a note of this information for later reference.
-
-
-
-### 2. Configure Google Cloud Storage Topic
-
-Use the `gsutil` command-line tool to set up a new Topic where Cloud Storage posts a notification for every new object created (finalized) in the Cloud Storage bucket. Use the command below to create a bucket:
-
-```
-gsutil notification create -t -f json -e OBJECT_FINALIZE gs://[/]
-```
-
-Use the `gcloud pubsub` command to create a Pub/Sub subscription for the topic. See the invocation below:
-
-```
-gcloud pubsub subscriptions create --topic=
-```
-
-Remember the Pub/Sub Subscription name you specified and make a note of it for later reference.
-
-### 3. Create a Service Account Key Credential in Google Cloud
-
-Navigate to **API & Services** > **Credentials UI** > **Create Credentials** > **Service Account Key** in the Google Cloud Console to start the process. Choose **New service account** and specify a `Service account name`. Select the following roles: **Storage** > **Storage Admin Pub/Sub** > **Pub/Sub Subscriber Pub/Sub** > **Pub/Sub Viewer**.
-
-Specify the Key type as JSON and click on **Create**. Google saves a .json file to your desktop. Remember the location of this file as you will need it in the next step.
-
-### 4. Configure Backtrace Data Source with the Recorded Information
-
-1. Go to **Project Settings** > **Error Submission** > **Data Sources** in Backtrace.
-
-2. Upload the .JSON file so that the Backtrace system can properly authenticate it.
-
-3. Fill in the `project_id`, `bucket_name`, and `subscription_name` that were created in the previous steps.
-
-4. Save the data source, and Backtrace ingests any new crashes received. You can also use the Data Source to download historical data.
-
-## Investigating an Error in Backtrace
-
-Once errors are reported to your Backtrace instance, you can view them in the Triage and Web Debugger views. See the screenshot below for the Triage view.
-
-
-
-When debugging an error, you can choose to view more details of the exception. You can use the **View Latest Trace** action to see more details in the Backtrace Web Debugger. The Web Debugger provides a list of all attributes submitted with a report, the call stack and details of the selected frame, system environment details, and more to assist with the investigation.
-
-
diff --git a/sidebars.js b/sidebars.js
index 1561098b70..0d7cb7d9fa 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -427,7 +427,6 @@ module.exports = {
],
},
'error-reporting/platform-integrations/cryengine',
- 'error-reporting/platform-integrations/stadia',
'error-reporting/platform-integrations/nintendo',
'error-reporting/platform-integrations/ps4',
'error-reporting/platform-integrations/ps5',
From ed9bbe741ded10e1857841e317f251b53620af29 Mon Sep 17 00:00:00 2001
From: Mykola Mokhnach
Date: Mon, 17 Jun 2024 14:46:51 +0200
Subject: [PATCH 012/148] Update component versions for the "latest" snapshot
released at 15.06.2024 (#2814)
---
.../automated-testing/appium/appium-versions.md | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/docs/mobile-apps/automated-testing/appium/appium-versions.md b/docs/mobile-apps/automated-testing/appium/appium-versions.md
index ccd40c8d62..c932adfacb 100644
--- a/docs/mobile-apps/automated-testing/appium/appium-versions.md
+++ b/docs/mobile-apps/automated-testing/appium/appium-versions.md
@@ -184,8 +184,8 @@ The following list of custom Appium plugins are supported:
This is a collection of drivers that were released in this version
-
- appium-uiautomator2-driver
: 3.5.2
+
+ appium-uiautomator2-driver
: 3.5.4
-
- appium-xcuitest-driver
: 7.16.2
+
+ appium-xcuitest-driver
: 7.17.5
From 5dbddd23ee219808243aef739f905eac794ac737 Mon Sep 17 00:00:00 2001
From: Rick Foster <115846221+rick-bt@users.noreply.github.com>
Date: Mon, 17 Jun 2024 13:50:56 -0700
Subject: [PATCH 013/148] Adding ProGuard rule to de-obfuscate Java classes
(#2813)
* Adding ProGuard rule to de-obfuscate Java classes
* Added usage of backtraceClient.UseProguard, and addition 'keep' line
* Update docs/error-reporting/platform-integrations/unity/configuration.md
Co-authored-by: Konrad Dysput
* Update docs/error-reporting/platform-integrations/unity/configuration.md
Co-authored-by: Konrad Dysput
---------
Co-authored-by: Konrad Dysput
---
.../android/proguard-deobfuscation.md | 3 +++
.../unity/configuration.md | 20 +++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/docs/error-reporting/platform-integrations/android/proguard-deobfuscation.md b/docs/error-reporting/platform-integrations/android/proguard-deobfuscation.md
index 5a01804f9c..0cf82babc5 100644
--- a/docs/error-reporting/platform-integrations/android/proguard-deobfuscation.md
+++ b/docs/error-reporting/platform-integrations/android/proguard-deobfuscation.md
@@ -28,6 +28,9 @@ To do this, you need to upload the ProGuard mapping file corresponding to the bu
```
-keep class com.google.gson.**.* { *; }
-keep class backtraceio.library.**.* { *; }
+
+ # Add this line for Unity projects:
+ -keep class backtraceio.unity.* { *; }
```
1. Enable ProGuard mode in the `BacktraceClient`.
diff --git a/docs/error-reporting/platform-integrations/unity/configuration.md b/docs/error-reporting/platform-integrations/unity/configuration.md
index 575d89cfd4..e84186273f 100644
--- a/docs/error-reporting/platform-integrations/unity/configuration.md
+++ b/docs/error-reporting/platform-integrations/unity/configuration.md
@@ -124,6 +124,26 @@ For more information about other data that is captured, see [Attributes](/error-
| Enable client-side unwinding | Enables callstack unwinding. If you're unable to upload all debug symbols for your app, you can use this setting to get debug information. Available only for supported versions of Android (NDK 19; Unity 2019+).
You can also enable this setting via the [`BacktraceConfiguration`](/error-reporting/platform-integrations/unity/configuration/#backtraceclient) object and the `.ClientSideUnwinding = true;` option. | Boolean | False |
| Symbols upload token | Required to automatically upload debug symbols to Backtrace.
To generate a symbol upload token, in Backtrace go to Project Settings > Symbols > Access tokens > and select + to generate a new token. | String |
+#### ProGuard Rules
+ProGuard obfuscation prevents the reflection used to invoke Java code from the Unity bridge. The ProGuard symbolication id must be passed to BacktraceClient, and additional ProGuard rules must be added to allow Backtrace to identify Java classes.
+
+Symbolication id is a UUID identifier created by the user. The same identifier value must be sent when uploading the source map and must be accessible in the game's runtime environment.
+
+
+Please follow [this guide](/error-reporting/platform-integrations/android/proguard-deobfuscation/) to enable ProGuard, and add the following:
+
+- Pass your ProGuard symbolication id to BacktraceClient:
+ ```java
+ var backtraceClient = GameObject.Find("manager name").GetComponent();
+ var symbolicationId = "f6c3e8d4-8626-4051-94ec-53e6daccce25";
+ backtraceClient.UseProguard(symbolicationId);
+ ```
+- Use these rules in proguard_rules.pro:
+ ```
+ -keep class backtraceio.unity.* { *; }
+ -keep class backtraceio.library.**.* { *; }
+ ```
+
#### Uploading Debug Symbols
You can configure the Backtrace client to automatically upload debug symbols in IL2CPP builds for Android apps.
From b1404eac8d13aea8bbe41f253fd641b755d34367 Mon Sep 17 00:00:00 2001
From: Yu Yi <58987452+yuyi-sl@users.noreply.github.com>
Date: Tue, 18 Jun 2024 12:05:27 +0200
Subject: [PATCH 014/148] add pretty name to network profiles and add link to
demo repo (#2807)
---
docs/dev/test-configuration-options.md | 4 ++--
docs/mobile-apps/features/network-throttling.md | 15 +++++++++++++++
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/docs/dev/test-configuration-options.md b/docs/dev/test-configuration-options.md
index c30671543a..1515ddd00f 100644
--- a/docs/dev/test-configuration-options.md
+++ b/docs/dev/test-configuration-options.md
@@ -1554,7 +1554,7 @@ capabilities.setCapability("sauce:options", sauceOptions);
### `networkProfile`
-| OPTIONAL | STRING | Real Devices Only | iOS BETA |
+| OPTIONAL | STRING | Real Devices Only | BETA |
Set a network profile with predefined network conditions at the beginning of the session.
Please refer to the [list of network profiles](https://docs.saucelabs.com/mobile-apps/features/network-throttling/#predefined-network-profiles) for more information about each profile's network conditions.
@@ -1571,7 +1571,7 @@ capabilities.setCapability("sauce:options", sauceOptions);
### `networkConditions`
-| OPTIONAL | OBJECT | Real Devices Only | iOS BETA |
+| OPTIONAL | OBJECT | Real Devices Only | BETA |
Set custom network conditions for `downloadSpeed`, `uploadSpeed`, `latency` or `loss` at the beginning of the session.
Not all parameters need to be specified and only the ones specified will have conditioning applied.
diff --git a/docs/mobile-apps/features/network-throttling.md b/docs/mobile-apps/features/network-throttling.md
index 540a988768..512bf75be1 100644
--- a/docs/mobile-apps/features/network-throttling.md
+++ b/docs/mobile-apps/features/network-throttling.md
@@ -28,24 +28,29 @@ The following table shows the allowed range of supported network condition param
Network Condition |
+ Parameter |
Range |
Download speed |
+ downloadSpeed |
0 - 50000 kbps |
Upload speed |
+ uploadSpeed |
0 - 50000 kbps |
Latency |
+ latency |
0 - 3000 ms |
Packet loss |
+ loss |
0 - 100 % |
@@ -61,6 +66,7 @@ The following table shows the predefined network profiles along with their corre
Network Profile |
+ ID |
Download Speed (kbps) |
Upload Speed (kbps) |
Latency (ms) |
@@ -69,6 +75,7 @@ The following table shows the predefined network profiles along with their corre
+ No Throttling |
no-throttling |
- |
- |
@@ -76,6 +83,7 @@ The following table shows the predefined network profiles along with their corre
- |
+ No Network |
no-network |
- |
- |
@@ -83,6 +91,7 @@ The following table shows the predefined network profiles along with their corre
100 |
+ 2G Packet Loss |
2G-packet-loss |
100 |
50 |
@@ -90,6 +99,7 @@ The following table shows the predefined network profiles along with their corre
10 |
+ 2G |
2G |
200 |
100 |
@@ -97,6 +107,7 @@ The following table shows the predefined network profiles along with their corre
1 |
+ 3G Slow |
3G-slow |
500 |
250 |
@@ -104,6 +115,7 @@ The following table shows the predefined network profiles along with their corre
1 |
+ 3G Fast |
3G-fast |
7000 |
2500 |
@@ -111,6 +123,7 @@ The following table shows the predefined network profiles along with their corre
- |
+ 4G Slow |
4G-slow |
8000 |
4000 |
@@ -118,6 +131,7 @@ The following table shows the predefined network profiles along with their corre
- |
+ 4G Fast |
4G-fast |
25000 |
15000 |
@@ -154,3 +168,4 @@ to apply one of the predefined network profiles to your session.
## More Information
- Use [Network Capture](https://docs.saucelabs.com/mobile-apps/features/network-capture/) to debug the failures in the app.
+- Check out the [Java Appium examples](https://github.com/saucelabs-training/demo-java/tree/main/appium/appium-app/appium-app-examples/src/test/java/com/examples/network_throttling) for iOS and Android.
From 6b7e338581733f643898374b3c2b8f76b8e2540b Mon Sep 17 00:00:00 2001
From: Hubert Grochowski
Date: Tue, 18 Jun 2024 16:12:01 +0200
Subject: [PATCH 015/148] sauce-connect-5(installation): bump version to 5.1.1
---
.../sauce-connect-5/installation.md | 20 +++++++++----------
.../sauce-connect-5/installation/docker.md | 4 ++--
.../sauce-connect-5/installation/linux.md | 12 +++++------
.../sauce-connect-5/installation/macos.md | 2 +-
.../sauce-connect-5/installation/windows.md | 4 ++--
5 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/docs/secure-connections/sauce-connect-5/installation.md b/docs/secure-connections/sauce-connect-5/installation.md
index f6797c5481..f71302cd17 100644
--- a/docs/secure-connections/sauce-connect-5/installation.md
+++ b/docs/secure-connections/sauce-connect-5/installation.md
@@ -17,7 +17,7 @@ Visit the following pages for installation instructions for your platform:
If you prefer to do custom installation, you can download Sauce Connect binaries from the following links.
-SHA256 checksums are available [here](https://saucelabs.com/downloads/sauce-connect/5.1.0/checksums).
+SHA256 checksums are available [here](https://saucelabs.com/downloads/sauce-connect/5.1.1/checksums).
diff --git a/docs/secure-connections/sauce-connect-5/installation/docker.md b/docs/secure-connections/sauce-connect-5/installation/docker.md
index 28114886fe..a608bacc62 100644
--- a/docs/secure-connections/sauce-connect-5/installation/docker.md
+++ b/docs/secure-connections/sauce-connect-5/installation/docker.md
@@ -26,11 +26,11 @@ Here are some benefits/use cases for using containerized Sauce Connect Proxy:
```
- To use a specific version, add it as a tag:
```bash
- $ docker pull saucelabs/sauce-connect:5.1.0-amd64
+ $ docker pull saucelabs/sauce-connect:5.1.1-amd64
```
Supported tags
- - 5, 5.1, 5.1.0
+ - 5, 5.1, 5.1.1
2. To run the Sauce Connect Proxy Docker image, modify and run the script below.
diff --git a/docs/secure-connections/sauce-connect-5/installation/linux.md b/docs/secure-connections/sauce-connect-5/installation/linux.md
index a2a604517e..be9eeab0d4 100644
--- a/docs/secure-connections/sauce-connect-5/installation/linux.md
+++ b/docs/secure-connections/sauce-connect-5/installation/linux.md
@@ -24,7 +24,7 @@ defaultValue="ARM64"
```bash
-curl -L -o sauce-connect.deb https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect_5.1.0.linux_arm64.deb
+curl -L -o sauce-connect.deb https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect_5.1.1.linux_arm64.deb
sudo dpkg -i sauce-connect.deb
```
@@ -32,7 +32,7 @@ sudo dpkg -i sauce-connect.deb
```bash
-curl -L -o sauce-connect.deb https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect_5.1.0.linux_amd64.deb
+curl -L -o sauce-connect.deb https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect_5.1.1.linux_amd64.deb
sudo dpkg -i sauce-connect.deb
```
@@ -75,14 +75,14 @@ defaultValue="ARM64"
```bash
-sudo rpm -i https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect-5.1.0_linux.aarch64.rpm
+sudo rpm -i https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect-5.1.1_linux.aarch64.rpm
```
```bash
-sudo rpm -i https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect-5.1.0_linux.x86_64.rpm
+sudo rpm -i https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect-5.1.1_linux.x86_64.rpm
```
@@ -120,7 +120,7 @@ defaultValue="ARM64"
```bash
-curl -L -o sauce-connect.tar.gz https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect-5.1.0_linux.aarch64.tar.gz
+curl -L -o sauce-connect.tar.gz https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect-5.1.1_linux.aarch64.tar.gz
sudo mkdir -p /opt/sauce-connect
sudo tar -C /opt/sauce-connect -xzf sauce-connect.tar.gz
```
@@ -129,7 +129,7 @@ sudo tar -C /opt/sauce-connect -xzf sauce-connect.tar.gz
```bash
-curl -L -o sauce-connect.tar.gz https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect-5.1.0_linux.x86_64.tar.gz
+curl -L -o sauce-connect.tar.gz https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect-5.1.1_linux.x86_64.tar.gz
sudo mkdir -p /opt/sauce-connect
sudo tar -C /opt/sauce-connect -xzf sauce-connect.tar.gz
```
diff --git a/docs/secure-connections/sauce-connect-5/installation/macos.md b/docs/secure-connections/sauce-connect-5/installation/macos.md
index 3798382f22..6aa75331e5 100644
--- a/docs/secure-connections/sauce-connect-5/installation/macos.md
+++ b/docs/secure-connections/sauce-connect-5/installation/macos.md
@@ -41,7 +41,7 @@ Sauce Connect provides `.zip` package with a signed binary that can be used on a
### Unpack the zip file
```bash
-curl -L -o sauce-connect.zip https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect-5.1.0_darwin.all.zip
+curl -L -o sauce-connect.zip https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect-5.1.1_darwin.all.zip
sudo mkdir -p /opt/sauce-connect
sudo unzip -d /opt/sauce-connect sauce-connect.zip
```
diff --git a/docs/secure-connections/sauce-connect-5/installation/windows.md b/docs/secure-connections/sauce-connect-5/installation/windows.md
index 992c55ae0d..115ae58ba1 100644
--- a/docs/secure-connections/sauce-connect-5/installation/windows.md
+++ b/docs/secure-connections/sauce-connect-5/installation/windows.md
@@ -20,7 +20,7 @@ defaultValue="ARM64"
```bash
mkdir C:\sauce-connect
-Invoke-WebRequest -Uri https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect-5.1.0_windows.aarch64.zip -OutFile sauce-connect.zip
+Invoke-WebRequest -Uri https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect-5.1.1_windows.aarch64.zip -OutFile sauce-connect.zip
Expand-Archive -Path sauce-connect.zip -DestinationPath C:\sauce-connect
```
@@ -29,7 +29,7 @@ Expand-Archive -Path sauce-connect.zip -DestinationPath C:\sauce-connect
```bash
mkdir C:\sauce-connect
-Invoke-WebRequest -Uri https://saucelabs.com/downloads/sauce-connect/5.1.0/sauce-connect-5.1.0_windows.x86_64.zip -OutFile sauce-connect.zip
+Invoke-WebRequest -Uri https://saucelabs.com/downloads/sauce-connect/5.1.1/sauce-connect-5.1.1_windows.x86_64.zip -OutFile sauce-connect.zip
Expand-Archive -Path sauce-connect.zip -DestinationPath C:\sauce-connect
```
From b1653edff6dea3779a7e7731ac1eb94f7ead8659 Mon Sep 17 00:00:00 2001
From: Yu Yi Yang
Date: Tue, 18 Jun 2024 19:30:43 +0200
Subject: [PATCH 016/148] add Parameters and Response status
---
.../acct-team-mgmt/private-device-mgmt.md | 4 +
docs/dev/api/rdc.md | 281 +++++++++++++++++-
2 files changed, 280 insertions(+), 5 deletions(-)
diff --git a/docs/basics/acct-team-mgmt/private-device-mgmt.md b/docs/basics/acct-team-mgmt/private-device-mgmt.md
index ec1b3b209c..0f82a97b28 100644
--- a/docs/basics/acct-team-mgmt/private-device-mgmt.md
+++ b/docs/basics/acct-team-mgmt/private-device-mgmt.md
@@ -133,3 +133,7 @@ Please send us a support ticket to set up Confirm with AssistiveTouch on your de
This feature **requires** setting the Account Allow List.
Please see [Testing Apple Pay](/mobile-apps/live-testing/testing-apple-pay) for more information.
:::
+
+## Private Device Management API
+Easily manage your private real devices with our [Device Management API endpoints](/dev/api/rdc/#private-real-device-management)
+to obtain device information, assign devices to a specific team, and update device settings efficiently.
diff --git a/docs/dev/api/rdc.md b/docs/dev/api/rdc.md
index fb0a7c072d..598b90cc7d 100644
--- a/docs/dev/api/rdc.md
+++ b/docs/dev/api/rdc.md
@@ -1338,49 +1338,320 @@ Learn more about how to [manage your private devices](/basics/acct-team-mgmt/pri
### Get Private Devices
-GET /v1/rdc/deviceManagement/devices
+GET /v1/rdc/device-management/devices
Get a list of private devices with their device information and settings.
#### Parameters
+
+This method takes no parameters.
+
+
+
+
+
+```jsx title="Sample Request"
+curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+--request GET 'https://api.us-west-1.saucelabs.com/v1/rdc/device-management/devices' | json_pp
+```
+
+
+
+
+
+```jsx title="Sample Request"
+curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+--request GET 'https://api.eu-central-1.saucelabs.com/v1/rdc/device-management/devices' | json_pp
+```
+
+
+
+
#### Responses
+
+
+
+ 200 |
+ Success. List of private devices is returned. |
+
+
+
+
+---
+
### Assign Device to a Team
-PUT /v1/rdc/deviceManagement/{device_descriptor_id}/team
+PUT /v1/rdc/device-management/devices/{device_id}/team
Assign a private device to a specific team.
#### Parameters
+
+
+
+
+ device_id |
+ | PATH | REQUIRED | STRING | The unique identifier of a device in the Sauce Labs data center. You can look up device IDs using the Get Devices endpoint. |
+
+
+
+
+ id |
+ | BODY | REQUIRED | STRING | The unique identifier of a team in the Sauce Labs organization. |
+
+
+
+
+
+
+
+
+```jsx title="Sample Request"
+curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+--request PUT 'https://api.us-west-1.saucelabs.com/v1/rdc/device-management/devices/iPad_Pro_11_14_2018_real/team' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+"id": "8f0444d7762548bd81ae46722a14e1c6"
+}'
+```
+
+
+
+
+
+```jsx title="Sample Request"
+curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+--request PUT 'https://api.eu-central-1.saucelabs.com/v1/rdc/device-management/devices/iPad_Pro_11_14_2018_real/team' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+"id": "8f0444d7762548bd81ae46722a14e1c6"
+}'
+```
+
+
+
+
#### Responses
+
+
+
+ 200 |
+ Device successfully assigned. |
+
+
+
+
+ 404 |
+ Device not found. |
+
+
+
+
+ 422 |
+ Team not found. |
+
+
+
+
+---
+
### Remove Device Assignment from Team
-DELETE /v1/rdc/deviceManagement/{device_descriptor_id}/team
+DELETE /v1/rdc/device-management/devices/{device_id}/team
Remove the private device assignment from a team.
#### Parameters
+
+
+
+
+ device_id |
+ | PATH | REQUIRED | STRING | The unique identifier of a device in the Sauce Labs data center. You can look up device IDs using the Get Devices endpoint. |
+
+
+
+
+
+
+
+
+```jsx title="Sample Request"
+curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+--request DELETE 'https://api.us-west-1.saucelabs.com/v1/rdc/device-management/devices/iPad_Pro_11_14_2018_real/team' | json_pp
+```
+
+
+
+
+
+```jsx title="Sample Request"
+curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+--request DELETE 'https://api.eu-central-1.saucelabs.com/v1/rdc/device-management/devices/iPad_Pro_11_14_2018_real/team' | json_pp
+```
+
+
+
+
#### Responses
+
+
+
+ 200 |
+ Device successfully removed from team. |
+
+
+
+
+ 404 |
+ Device not found. |
+
+
+
+
+---
+
### Update Device Settings
-PUT /v1/rdc/deviceManagement/{device_descriptor_id}/settings
+PUT /v1/rdc/device-management/devices/{device_id}/settings
Update device settings to allow apps, system apps, and accounts to persist between sessions. Check out the
[available device settings](/basics/acct-team-management/#app-allow-list) for more information on each setting.
#### Parameters
+
+
+
+
+ device_id |
+ | PATH | REQUIRED | STRING | The unique identifier of a device in the Sauce Labs data center. You can look up device IDs using the Get Devices endpoint. |
+
+
+
+
+ appWhitelist |
+ | BODY | REQUIRED | ARRAY | Persist installed apps and app data between sessions. |
+
+
+
+
+ accountWhitelist |
+ | BODY | REQUIRED | ARRAY | Preserve store and payment account sign-ins between sessions for each account email. |
+
+
+
+
+ systemAppAllowlist |
+ | BODY | REQUIRED | ARRAY | Access iOS preinstalled applications. |
+
+
+
+
+ applePaySupportEnabled |
+ | BODY | REQUIRED | BOOLEAN | Enable to test Apple Pay. |
+
+
+
+
+ skipCleaningFolders |
+ | BODY | REQUIRED | ARRAY | Retain specific file paths or folders on your private Android devices between sessions. |
+
+
+
+
+
+
+
+
+```jsx title="Sample Request"
+curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+--request PUT 'https://api.us-west-1.saucelabs.com/v1/rdc/device-management/devices/iPad_Pro_11_14_2018_real/settings' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+"id": "string",
+ "appWhitelist": ["SauceLabs-Demo-App.ipa"],
+ "accountWhitelist": ["account@saucelabs.com"],
+ "systemAppAllowlist": ["com.android.chrome"],
+ "applePaySupportEnabled": false,
+ "skipCleaningFolders": []
+}'
+```
+
+
+
+
+
+```jsx title="Sample Request"
+curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+--request PUT 'https://api.eu-central-1.saucelabs.com/v1/rdc/device-management/devices/iPad_Pro_11_14_2018_real/settings' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+"id": "string",
+ "appWhitelist": ["SauceLabs-Demo-App.ipa"],
+ "accountWhitelist": ["account@saucelabs.com"],
+ "systemAppAllowlist": ["com.apple.calculator"],
+ "applePaySupportEnabled": false,
+ "skipCleaningFolders": []
+}'
+```
+
+
+
+
#### Responses
-
\ No newline at end of file
+
+
+
+ 200 |
+ Device settings successfully updated. |
+
+
+
+
+ 404 |
+ Device not found. |
+
+
+
+
+
+
+---
\ No newline at end of file
From b833994b71a560b5863d2985087d07909f698f0b Mon Sep 17 00:00:00 2001
From: Yu Yi Yang
Date: Tue, 18 Jun 2024 19:34:57 +0200
Subject: [PATCH 017/148] add no payload returned
---
docs/dev/api/rdc.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/docs/dev/api/rdc.md b/docs/dev/api/rdc.md
index 598b90cc7d..3aed6a5661 100644
--- a/docs/dev/api/rdc.md
+++ b/docs/dev/api/rdc.md
@@ -1471,6 +1471,8 @@ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+No payload is returned with the successful assignment.
+
---
@@ -1537,6 +1539,8 @@ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
+No payload is returned with the successful removal.
+
---
From e74498512c9dbe6367775089688765f24341a864 Mon Sep 17 00:00:00 2001
From: Gil Megidish <136448141+gmegidish-saucelabs@users.noreply.github.com>
Date: Thu, 20 Jun 2024 14:13:01 +0200
Subject: [PATCH 018/148] Added documentation for fastlane ci (#2816)
---
docs/testfairy/ci-tools/fastlane.md | 79 +++++++++++++++++++++++++++++
sidebars.js | 1 +
2 files changed, 80 insertions(+)
create mode 100644 docs/testfairy/ci-tools/fastlane.md
diff --git a/docs/testfairy/ci-tools/fastlane.md b/docs/testfairy/ci-tools/fastlane.md
new file mode 100644
index 0000000000..f7cb9fce34
--- /dev/null
+++ b/docs/testfairy/ci-tools/fastlane.md
@@ -0,0 +1,79 @@
+---
+id: fastlane
+title: Fastlane
+sidebar_label: Fastlane
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+Upload a new build to TestFairy using Fastlane. You can find your API Key in the [TestFairy Settings](https://free.testfairy.com/settings/) page.
+
+```
+testfairy(
+ api_key: "...",
+ ipa: "./ipa_file.ipa",
+ comment: "Build #{lane_context[SharedValues::BUILD_NUMBER]}",
+)
+```
+
+```
+testfairy(
+ api_key: "...",
+ apk: "../build/app/outputs/apk/qa/release/app-qa-release.apk",
+ comment: "Build #{lane_context[SharedValues::BUILD_NUMBER]}",
+)
+```
+
+### Parameters
+
+| Key | Description | Default |
+|----------------|---------------------------------------------------------------------------|------------------------------|
+| api_key | API Key for TestFairy | |
+| ipa | Path to your IPA file for iOS | |
+| apk | Path to your APK file for Android | |
+| symbols_file | Symbols mapping file | |
+| upload_url | Upload API URL for TestFairy | https://upload.testfairy.com |
+| testers_groups | Array of tester groups to be notified | [] |
+| comment | Additional release notes for this upload. Will be added to sent emails | No comment |
+| notify | Send email to testers | off |
+| timeout | Request timeout in seconds | |
+
+### Lane Variables
+
+Actions can communicate with each other using a shared hash lane_context, that can be accessed in other actions, plugins or your lanes: lane_context[SharedValues:XYZ]. The testfairy action generates the following Lane Variables:
+
+| SharedValue | Description |
+|--------------------------------------|--------------------------------------------------|
+| SharedValues::TESTFAIRY_BUILD_URL | URL for the sessions of the newly uploaded build |
+| SharedValues::TESTFAIRY_DOWNLOAD_URL | URL directly to the newly uploaded build |
+| SharedValues::TESTFAIRY_LANDING_PAGE | URL of the build's landing page |
+
+### Documentation
+
+To show the documentation in your terminal, run
+
+```bash
+fastlane action testfairy
+```
+
+### CLI
+
+It is recommended to add the above action into your Fastfile, however sometimes you might want to run one-offs. To do so, you can run the following command from your terminal
+
+```bash
+fastlane run testfairy
+```
+
+To pass parameters, make use of the : symbol, for example
+
+```bash
+fastlane run testfairy parameter1:"value1" parameter2:"value2"
+```
+
+It's important to note that the CLI supports primitive types like integers, floats, booleans, and strings. Arrays can be passed as a comma delimited string (e.g. param:"1,2,3"). Hashes are not currently supported.
+
+It is recommended to add all fastlane actions you use to your Fastfile.
+
+You can review this action documentation and code on [docs.fastlane.tools](https://docs.fastlane.tools/actions/testfairy/).
diff --git a/sidebars.js b/sidebars.js
index 1561098b70..7170f1ab96 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -1225,6 +1225,7 @@ module.exports = {
'testfairy/ci-tools/bamboo',
'testfairy/ci-tools/bitbucket',
'testfairy/ci-tools/circle-ci',
+ 'testfairy/ci-tools/fastlane',
'testfairy/ci-tools/gitlab',
'testfairy/ci-tools/ms-app-ctr',
'testfairy/ci-tools/team-city',
From 28df62dc58bd013965c98f1c36477b609f4017c1 Mon Sep 17 00:00:00 2001
From: Simon Schaefer
Date: Fri, 21 Jun 2024 10:13:37 +0200
Subject: [PATCH 019/148] Fix documentation on device-team visibility (#2804)
* Fix documentation on device-team visibility
* Update private-device-mgmt.md
---
docs/basics/acct-team-mgmt/private-device-mgmt.md | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/docs/basics/acct-team-mgmt/private-device-mgmt.md b/docs/basics/acct-team-mgmt/private-device-mgmt.md
index ec1b3b209c..8f50688270 100644
--- a/docs/basics/acct-team-mgmt/private-device-mgmt.md
+++ b/docs/basics/acct-team-mgmt/private-device-mgmt.md
@@ -17,13 +17,7 @@ Private device management allows an organization admin to view and manage the pr
:::important
-- Everyone in an organization can access a device in the the default unassigned state.
-- **Only** organization admins can manage private devices.
- - An organization admin can always re-assign a device to another team or set a device to the default unassigned state.
-- **Only** team members can access a device assigned to a team.
- - This rule is enforced for all roles!
- - i.e., to access a device, an organization admin **must** be a member of the team a device is assigned to.
- - Devices automcatically return to the default unassigned state if their assigned team is deleted.
+By assigning a private device to a team, you restrict access to that device to that team. **Note:** organization admins are not affected by this. Organization admins have access to all devices of their organization.
:::
From 14022429167d6a2ba46f1364b9b279ae0cfe0500 Mon Sep 17 00:00:00 2001
From: Steve Rossen
Date: Fri, 21 Jun 2024 03:41:46 -0500
Subject: [PATCH 020/148] NOJIRA: add Aug/Sep MW (#2809)
* NOJIRA: add Aug/Sep MW
* NOJIRA: add Aug/Sep MW
* NOJIRA: add Aug/Sep MW
---
docs/dev/data-center-maint.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/docs/dev/data-center-maint.md b/docs/dev/data-center-maint.md
index dcbb499f4b..52e306214b 100644
--- a/docs/dev/data-center-maint.md
+++ b/docs/dev/data-center-maint.md
@@ -26,6 +26,11 @@ Saucelabs.com and the Sauce Labs testing service in the US and EU will be down f
| US | June 8, 2024 | 10am - 12pm PDT |
| EU | June 22, 2024 | 7pm-9pm CEST |
| US | July 9, 2024 | 9pm-1am PDT |
+| EU | July 18, 2024 | 9pm-11pm CEST |
+| US | August 8, 2024 | 9pm-11pm PDT |
+| EU | August 22, 2024 | 9pm-11pm CEST |
+| US | September 12, 2024 | 9pm-11pm PDT |
+| EU | September 19, 2024 | 9pm-11pm CEST |
### Backtrace - error reporting service updates are pushed Wednesdays 11am - 1pm ET across all data centers. Individual application servers may experience a short period of downtime within this window
From 5bd56096ec8b6514d61f8ef5fd83fc047b61bb0f Mon Sep 17 00:00:00 2001
From: Gil Megidish <136448141+gmegidish-saucelabs@users.noreply.github.com>
Date: Mon, 24 Jun 2024 14:39:07 +0200
Subject: [PATCH 021/148] Added Private Cloud Architecture (#2818)
---
docs/testfairy/security/private-cloud.md | 65 ++++++++++++++++++
sidebars.js | 1 +
.../security/private-cloud-architecture.png | Bin 0 -> 111347 bytes
3 files changed, 66 insertions(+)
create mode 100644 docs/testfairy/security/private-cloud.md
create mode 100644 static/img/testfairy/security/private-cloud-architecture.png
diff --git a/docs/testfairy/security/private-cloud.md b/docs/testfairy/security/private-cloud.md
new file mode 100644
index 0000000000..8c76a53b87
--- /dev/null
+++ b/docs/testfairy/security/private-cloud.md
@@ -0,0 +1,65 @@
+---
+id: private-cloud
+title: Private Cloud
+sidebar_label: Private Cloud
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+The "Private Cloud" deployment provides a completely isolated environment for a single tenant of TestFairy. This ensures
+dedicated resources and enhanced security, making it ideal for organizations with stringent data privacy and compliance
+requirements.
+
+Each Private Cloud instance operates independently, ensuring no shared resources with other tenants.
+
+
+
+#### Key Components
+
+- Dedicated Instance
+
+ A dedicated instance is provisioned for each Private Cloud. This guarantees that compute resources are
+ not shared with other tenants, providing consistent performance, isolation and security.
+
+- Dedicated Database
+
+ Each Private Cloud instance comes with its own dedicated database. This ensures that all data is completely
+ isolated, providing enhanced data security and performance benefits.
+
+- Dedicated Data Storage (S3, GCS)
+
+ For object storage, each tenant has a dedicated S3 bucket. This ensures that files and data stored in the cloud
+ are securely isolated and managed separately.
+
+- Dedicated IP Address
+
+ Each Private Cloud instance is assigned a dedicated IP address. This allows for better control over network traffic,
+ improved security through IP whitelisting.
+
+#### Customizable Configuration
+
+A Private Cloud instance can suit your needs better by its available customizations:
+
+- Select Hosted Region
+
+ You may decide where the data is hosted, select from one of AWS available regions.
+
+- Firewall Rules
+
+ A dedicate IP address and instance also allows you to select custom firewall rules. For example, admin panel is
+ only available through company VPN.
+
+- Custom Data Retention
+
+ Apply specific rules as to how long your files are stored and when they are removed
+
+- Provide S3-compliant Bucket
+
+ Host the apps on your own S3 bucket (may that be AWS S3, GCP GCS or others). Your bucket, your rules.
+
+
+
+
+
diff --git a/sidebars.js b/sidebars.js
index 000b25462d..4561dc705e 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -1182,6 +1182,7 @@ module.exports = {
label: 'Security',
collapsed: true,
items: [
+ 'testfairy/security/private-cloud',
{
type: 'category',
label: 'Single Sign On',
diff --git a/static/img/testfairy/security/private-cloud-architecture.png b/static/img/testfairy/security/private-cloud-architecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..10cc54cd648a5f737dab624f5feccf05d9987ee9
GIT binary patch
literal 111347
zcmeFZby!sG+CDrq(%s#i(k
zj#@$`6FkT=dJD
z$C1)-MTG#!brbIY)F0)EV(Vl6so##*p(40+aw*s#A~a7b{**lI0|n4N*E_YB_@MiP
zdD=td>VhuvnmEK!0d*vf{hpa5-)IlD1DkPRR
zS~{EnBqG_f)Y4)QKu~_q1vglUK=YW=Np8~)t}X0plHNT)@%gZ&UuyuI%09R-63x`|^hop>t#xavFOSlw!|DnC^gdQCR)q120XhI@RN;K_92(Ff_qcP!
zwksEjHkLM!=2|ZnmjRDtT`7w5?7fcy1GP=_y)Qo^g8XQDJ`(V+Z=m&X1&Jn<_i)%0
z;r_58Gw3S#9&7JeT1Tf=|NRBl<;;tq#(VSzyu*o_Q8~zUf#D2{$TkmRX%Fjd6-i~k
zV+orQD$3fZC*BS9jiiS!XoD{sT
zu|$k1E{`JwqMzl?DI$!kr(=}<9C2@-T`4G4OnOvzdI$q8^;&XxFy(~7V%m&>It};L
zy_eYc6!6-z`c>}4l(2@erxL=MB{4+#hQ%;MovtApF|&I(#6s3sDncY_??hMCaTtCR
zN5+LKQJd4BewH~92>2B}a>o(+Q}O8Rr*448CW|zaIlB*`n=TniTjgP{myfW{2
zNHv<<9T5u;xo_B&iuUFhGZ-h$!in8I!B%$U{q-b)npO9%)i2zI&sN+x;Qh&V8PX9u
znvGY1uPfhH4%NoLpO%|eedRpw(Qeu;BiHA6sTWKq9dor4$NL%2%CRneHgJby8gtVG
zdphcaZQtvF0AHE3x9^G`3DyVI7bQdK51#$3e*Zi$`9pGhGI%xk9R6e6|E`rb;Rpe?
zkkHW&tutll#N54i-5ej&OVWiw<9iA4<72jmCyVkv^AKZy@$tszdzq=w6I{e
z{R268euG1&Zj2CU1J9ckhAa`IiH~}gr5CB2ODBNr&`CAgcc&Ry7mAH6j~R>V$#6$2
zV$SiCFCY3uCyxLiytA<;TFOm3C
zX_Ps?-*uI7JfTfRwuquK;&IWl3RX!f`$Da|BuR?w#gvQ=+;z4IeIFyI^s&=
zxCNzdpQM=5Diq%{ee7}+jLT7escx?EO}?7_6@woUJu!wF%X7Mce_*}I`=y|6I$$!O&Z);~s$OCE+OX`s=8xua(o#o_f`KhN?0O7|=flin4E*fw
z%wp;MX{`eVoKz&-@#L(@&y`>3a+Xit*D?5ce~E*eJCCcCTa_C-V}moBd+&j4Ib83&
zB)%;EEtV#$vT|{~mVM0Noy-L;_X@*G)~W1Vt&wuRl4(8N`}BHp72}4qhI5tDQ!SO5
zmAIA0hTzJyDW1uk$LW(;Q-hOu6&Cv22JBU4l?{^;Ti%o0Q}|WOhV)+wof5ysPWDfk
zRMu&JZ&OKOQ=iZmmQOEl(etia=N##~o9Lio`?dK!+I!dc6Yt%4i?cGx%(ykH44qSq
zVvHb-WsMDf5hp&o8oRdh7Lqy1rFdrSs*WwAA^Fsj1u7KDR>{y56QN?ao=n0$U)8PO
zTZg`yKHI)E+acp6+i08i+ixeGCtGV$wimWkw{<6$D?%Sa++R)gwC!I}Rap_kh9LF}1$_8IGYxNnbrnENye^n(8_Ok~|X*yg!QO
ztB)0BPb_R+vZ1qeu@R;7veB{?Xus9^uAQK@t-Y6bf0)AIhlBI*!;#-3Nh94OjxT0%
zm+KhJ1bBpar%hje2yl0@fAOfLzy51|pTw`xRoPEb~AMe`AOnsdHos0YRnRU8r
zL)Use@8fNoJSQ`!rvrE&ygv}ny4G&fC{wJ-YKT`pnbdwt`m`)KJoxRUA_i@YKnzoi
zN=$aih$?%ErNr-@P4{HJWQpVjn!V(&G{iz>kF<_*W^@{L%*!>(oo(OPqV$c@F5ErI
zY{(a04lFt1CC}At9%9Ni%C33m_ReNTa>i23yUDPLt0@nMSB1ou^ZQGwuEnw7cNh0h
zQ|R8&ozq>&TphkY9X|QCHYYs#m?rdFqi0IHR=c>RS=-09A4_kR^4eR2w1UKCr({!t
zMuGx67J>@|U2{x_7l*S$l0$4DiXnTZbk%d!#8)|?siAS9s$mZDLGsF-k@6FriJkME
zR}9&OFBI4#?sOG(aYwq>)tXEs({N~w>}rSfITrJyCXpuD{6pfy~b(@^(*cA&1+X1Vvgmp7%A+MSj^
z&RttiQ%$`>J)mH-pqZ=A8NPYY&RVNHKd{Je=BUkfv**6*HwyrzcdU{ahB
zak;LvoO-DK=xf{bDK>95dNtP9Y-K++EvTB~P}
z!|Re~bJzZNhE7_3g~_DIlZrDD**;9-j^&QxcB}qn+Txx0x$@J46yum0
zHxos$LH+vf{DAXVwnVn;Lse6D)0qc!MoaIPf-d8a!CXSz?~H#xm^P*~Gu1*Y3=!RRv|C$RMwQeS)3VmqwHcrc-+CWFOJVt%^Ibc*Zw
ze}P#|G0qn~M}KXtq8MuHU~6okZ?LhF+WmIq)ksXTIL(~rp9lKhrkm}(q6*!5Xy#+q_v6dN#whA53E!;1#uFQY+7}(XHusI>UJ7Ks`usMJ
zQ>@kP!0q_kXv^i6PFMbz|HdNoH}0025Xeq=SLBwQ%T>jm*RJHrmuu^bl37)MdT)A2
z!1L2p&C^filjZhfi3L-?#E)rqad+C`L7$F(k{6Q~T*O~bo;7Th9uGx^o?lHZ$#p<3
zGS8-<+okTmmUaTR;f=lwkD*3W(&3M5L^4-6d
z`G|kD_zl%+Pqg_m;`d`tkkWmmSZ|EY*}87mM>T8<#u`bOr$~9skg~P1@KD=BnGO8F
z>mYRf2afwk=U@iYAR|z2cOOtu#M_&wJ7{ZzxPaG~AXFqO5E}3b33$jNQUC3=3K9nh
z1#ui11d4G2q5kn19pL%qFBN#)jJbVAdHxK90Z2r^BcKrZ&rhS$6r%k38l@h152RqA
zsICq?8`yf;+q-!`a`$5-3*ha^A0zrR19zc8P>mm|NRgoFgY
zfDpfs5HIivUhhCRAL{^KH*ecV8bFCZ?Mc{q67e
zI_(3T{(dGm??09WERg@^9ezPR0sg7Boy@h>Ay{ytJrKt$-TL;v#De;oS2+ulpj-4!^ekL=&=^~d19zWK*MY5tp~|3wwI
zdPW=t6fKJ-&Hp!}$zn-nt5^Ycq;XQxH3XgkFT43engjlE+&@*s63
z1;YTOop$V(w8}3;Erp4n53{^rv_@A$?!P2s31hI!w9qRlX6TRTsi(&KeQ|2)7&$hL0SguBew6Y7vKqr+zK42qv{t{}v*A^tYR6(b5Y;
zU*C3jxs6lJGF@NasS8=%_QeNdZ{9toq@bAP^!lBcm>A1z))>oaP!{__*m2zuJDwK{
zY2S?G@aJ~>_0>f$8o4
zw(xt=e0j34C>2SBiyCy~Oc54kP6&dqweb?rXz8Us$3sFjlzhpt8Ud9LXKfN?3R#3v
zK6HYL-BtNEk8&$?oJT{UO=xH9Gd2DdxbR$8P()8biun7&ezE!BA3yjd0@y=k?6j2BN8Sa8=IPX90-|NAlA5Gn>S@$1)0Af!wp
z4&*roaRP>cy0}`3hFpN-llzw0&$=YgId`{WMp76
z6zU@@Gf<;qAhSq_5*}<*eCdowfrJynW@+{j!qEsnDh33%Qw$Q)uILJ#aY5nTo_@RF
z#MY`l*Wz7HK}}7}%gbB*;lq@65eF*;YNxw^p$YY2CklS7Zs_j`SVO^OwfI&=N%3K4
zjYzcuIVdEutZ!a?-x=5X3tHH6;g32|z=YgJ)da>CzM0J@^UiNwRgsbi_eb1q6H>cb
zk)bn6#Q$?=fM#Ods>t9OVxg9A{tq^VWn%rqN&)xPN_|cQxUWVbrd=ddK8&T0jVXi{
zh04SeDkgA`CJ*ISxOHEof8)MsF6FPDR0b?xEU_UGmw=zjjHb8<)J7!7L28WEjqSihXJh!Q^4&TjACv3I2^sssS#k6zgTj2Ad&F
z4JShhL1F!zW(q|J-)~(q;@`OB0N|3C_mhVKmqZr&V$JW|)5^r4+^WV563*eGWN)kfE2iuta@(DQ#$d+jW&1ZAsEkg-f#tgew4oQ~1)
zZGQ@L>>{-Jp1I$gJ?vz`J*7SZoRmWk5AMT0LxZFfQd~c~;7tlph3mMrckC5>JZXdV
zib1OOAmE@=gKM6pYxe?j>=X&~%Z)n`E&EjqRaZm2mhZuV2bmv&W)7;hjYFM1vxkXc
zg4kWwbMwc={#Bfk@Trie#;oY)eR;*avXX^-!A=RYccpFKyDuF2hC_#N!AbispDgJ1
za&bx;V&Oq&@UJ?)qa9Q+Bg5I!Ixn+Sp31}7%-$0G{c?g+WSCyH{z|a9Lc8X0pnoDR
zC4IEc?R?&GK6UZ~@(reZk!dXLz`HC0`FN$gXkp`Y>T;Pm36uwSJ`#j|w|b3hGJ}K$
zZ&<0xb9>l9wH5=_J5oHrz7!S#ML
z)VN7r?rdYk-ToX(4u_p{piXUI!^jV|g+jQ|Vg@&&Rq`IUML7W1EG%@DZT8fAq(%ih
zB2uLo<__!{@iO6e6=h*%-?biSqw@@Cx-O)fme{V+$FT6qmXws(=wab4
z&$TJL(9xm2>RHGmqv5+6WVPw~ij8)b|Lt|lB7Gnix2M&q?}D9CSLbm
z2GYbhEI5`zJ8^XvALjO|f@`klVUcH3YRT6hdJVEar!CV-B+CSRe&64VM!WkU8|%we
z3_N>>o0Nbio?OeL`z6i%qE76cPeQWc`md%^SCgutsX?VM{76MuoPsx~BS6P-
ziV~0e;&<;n<7!i{D#j$QS9a?0Ix2=Wpy-NQMZdh*F?fK6vA>OR-FE(#hyI{yPXH(w*&kQlm9!*53|3B7j;+SGh#yeOokeVy;DU9IPVcOh41bM#++
z6hRdi>9XOkzP7gpObz?t-kF2gp~bMkP)clV0$d!0?)1?Sd_gL;eDPy*b6=0SvY$8{
z7Qn4o%2JtY?aMRh1jl#jkYR^pZ0D=5ZA=y2I
zyWrZo_){O(GW<{>`58MO&=5$CIFcq$(lSb+#8bZur)|aI2sJ7xdx&Z1C*JAK`#Rut
zB$!Tm`VbjDeeap7hS!6}q!ptxBh8VKuHik`7_Tjz<`{d>`GI;tV&Ls2n{UT<-BV;e5U6@O*EQ
zlEmR=-Q6IT)%Y-800@M}(>HKp?44&4EG5=n9~wBjPY(v2xut};%FmgF5t%dT&8>hS
zd|z>Ec=oC3*!g&o0RiVv;SgcsQhtshC7=ONhNd<^jARD1671|SA{13RW9^%8Ic$E`
zi#64EBZUMS-~mzLjvDYZ2Eb@O!iu1)Rvv2m7nlqo+FIhJvxnGSjJD2U&{RSJn>kmM
z_?*_Ak+(N%TFQt7?+;NUEiEyIbk%60aurGF!^@KRF}c
z`R*fU(%rY;7i{!D$L{cvR>i>3n46N4{tx$xWzbY9@=Hv;~spDZkT@=~lr;ido8
zISgo-^LO&w7MD8z!({prA`=`mFV;+cN~S
z8K(kXtu$at0O$yfcRr91^8Vb}PUg%tieUE$nk^cdRDBARzA-9^%`$s=;HK%4_bRu}
z&HR2X5EGA6p6O+;y*%Nw@XQ|sG$vn7XDEBzEdu%rP$8?F)!U%6x7hgS>9-~Dz-1bXBC;Y=G+h~Aa%
zZKI%J&EFmjG5O%s3G%w{pKUTPv!GU0Se@oMD+&J+1nVrOK)hlY|ODVN5t~#5#*Jt
zxMPYuA$;B}iD;Y&`W#?OoO)y4&lKx_BXNr3r0i<3t<0hz^Pvnzwp1{oArAnEtc^sm
z!UN3~2;|hlfZPNL8k~rYKl+FAeqPX3xd5Rl4*^F67~9*^Nd?vX2Bpx>fS?Fd5>FTk
zW5PkdjlzYegOL;0=_S&@Ok(|-&GL8>?JzC?ncvs4qsLxEm2gv}5Ya@D4&jmUn*
zG727QNJJ|WW
zz|}xL0<~1MYVz#9a(!)}#?Y$Sdzch#GXg!q{9YGF%QczZ>n(}qSGhm&%LQdHC9{GR
z8;F7WLS-p_7y_a&AV~zp!F2HP^_sL}<^7w;;{G{G-c=*DeP5p$5d&W^SK^NXM?Fj$
z{n|Gdsoay^R9OnuU_?ZsGjBi|kunZ>LJL@7?wN%Tzn4#`&+Xf}r@
z=Lp};dN~I?Q{Q5S(B>pD=`&dk0l1hUzYS~@+$EB}o<}FqHGK3Gtt(tK)U;X^?x2uh
zX}PbN(!fI&i3l?@)EkogA)V>$c!TzFJt8PXQU4(*_)uf?ztBj;ovn?C0Qszq5V~tY
zcmQEp
zL+B}=JzJVYjVb;%aLS7JB1e#h@
zLo*J?CxKca+6WYG$!*EV+w=v^mX7wN1wnjQ7(?qZZ&HJ^sPg{ynAGGd0u1JfQDaCL
z2uEQ;g_zx)gFcve)tlAZIIt!@=~dkb@FB^xF9<#z9RnY@xq4{L97$J=+@4a>2D$|k6Dwtno@k5-BX8M2MT;!KnQvZzv=uG}G$D98zHpi$@xH2u80KXneo&i??Y{zv%M
zvf5Pg_QCt6##D^V|48X-6{8`dKZFY5rb)S5jG(R}I?1+C#*n}R(;v8JZMTHPZ78MFAcmqHxilpYKM@POvem#^`J0a8<
z7AknM1v-hG&!Z=(UEyr*BPK~_uIM6?Ghtv!a}it4Tj3_AF+z7sFhec_V{#GcOZh3_
z#mFq5OwG|rtSL-h;B|$Q=KJO=AlzPkU-Q+ck9c9rANNz`Oc5|Bl6Q+tUN>MsvU>+8
zmQpbtJt_5~tgY-NQ8A2srhU;5%*g2u*}M1yv9={ah!kXZbM^Z(F7eQr0{@DE|0pyjXz%D1b@05J;H))>E+})P
z)(fdt;{89dWd0lHOfvEG@4yUMG);L<#fZocDwxJE0i5fu|FEsRHyz-tWpVsGPzJ~t
z6cX1Ta4TMpC?04t6r#l>K)m9_gSzh9czEb(y%19N@$tEPpNj7eB~p)j|IX|JddRLI
zP7CTjwUE?FBk7I)pDvAO>7hcLToq-X-m<(jlz&XW^ziP-o?rX;NC;@oCX#@hBKUtf
zrvR+(e~`fHG?oAR!?NLi??1$!Op_fJJ_pe4Sg*}$wehQ0=i4zt_5jZ>5aVbeLb@SN6-rHmrvT+<
zsiIDe=-!_lwIfQFVSox1O6MeS=`(JM+%G2_lHsb5P1+xt!`C$Z*1E%GkOPmL-5E7%6%f{*Cv@l1=K7Mm^vtJ+QkVqbMpc%%3P25$3
z7J$l!20>M;7x;<+c|7t=h5mRDZQA`&l>W()?AeGL={t|;+m?n<+8-^ArMCyuIrHyX
zkDf4yKN9e|a;Dak$cusH$paLKxR9_N^#D*Ia
z6-~e;=;5O7wC~<4cV+<&L`nJA?nJ4;zsO*ts_-(?KBR52)rrxd{k)Vl4iQ{LwWt>9
z#e|O;PW~B
zAxB3b))_@$6HzRu4-HpuYYE#-G5%zLJq_)GYs
zL#$$%j^KD2lrCKQ+}E8~Lo1;Z{L;Hoe7o(ahjOEhx#>*X8T)W81_Tq6b5Z1=gg@)N
z7a|(A46ns4vIE24!B?<67vo7ESQufehQeU>55^e3;vs?I^QLiCdCEY9?7ro-d7{~n
z73FP#{h({5h_-IF*43q);zg=9gXo#FIZ&k)OjQ7!hJc2OvFE!qEE^-`LmLS4A$27U
zz=?g6A#5;wnwaLwbI!5XT9vQDo@tzyV86E}I<9#V89PK!~!{3W(@ee43(6o~CviVI}m
zo92&(PvMnQI8;9W6KuzyQm;2KJeQlWf>pdCc_5;M+{mHNzZmFiAv|h7kBFmqu9N>h
zOh0!wefcrMC>cs3FGkoQ+PSeqJOl`qO`>G=?C*({!S&;O%mwY9MCkKWJx=io&g_XY
z?F6{=>EcHE3Hj$fU~*d?ak_ADa`k7~@MQ|@WL4Sow~aDvs4+oinYtlI$Ec;oiU<^{
zWHe7h?(W^Y~s*BZ~~>+57~2HTS1M12q4OM{NHqPlbYrd9I_GC;#Sz1iu0j|Kc-E3
zm<0_Uec1m+OBFu8%KLT-D#ojS_b42k+gAEvo*gnZ?b&%G%WE*Qb~NDbO$Otl2D0Iw
ztXS)>tk|O4`fsc_=Ua$DDB0K#l9(pl8SsIaDyj<#m+FL`j|S>E7G93!3nIOHa|Dp6
z{>PsT_ZLtfMe!ls3d?Y#QNOmcAz%YRgik#IxTk7jK03$^04gAIRp<_bN^KCEJKLh&
z#R!m~s8~(6qSiY%iPmpmO5J%h`H?I_k=Jgsj5*|oSN3PG{XBHmkAa>17C*;LeK&
zrr-xGm0S1orMQReR`*Vs-qK{19-ssIXXAy>%zNrn8vZ*=iy67LF;jB7=RgOB#Yxlk
z?wK|&=|Cbho5l4_63{Ex_W)EQqOI-tYs7ux8SGQpAD21%kCUYXO4cbx(Z{Cz_#+nl
z@mpyf4ZKVt&W&zgGrRR}7EnjO+Kt@^rh2w>2vjclz0H!?2>j`fXdDJe_}{uZbGc@&
zT@@ORbzz3AOurz&0=-SfQ1;F6X@75Y@(1H>2Lgme!=rPXJr@n)EzVsr=<4AGAPL5{x^h2p`-H)>yDDDPJ}NXasQYkDHm
zj&nS{Z{{;e)*okpK3`65H2S(U|GaFz@aU!(`X{=uWPVE*L{PWdjSdDvFJ6lOj50QE
z#c_%vl)vrNK*etA!7%Wr)lz|W%#a6i(Ebwgc(g-$*>fgf8Rt);#?x=9IMEzcAJAD)
zGm>CHi&?1)a2{TjpxKBC8wwj7)5v&<4v=vtJy<5j0fNtWy0bF1bwq+KgN&XSkU+Lb
zH8JrrU7D{gNgzLE6ym0CBlj_;@oNQ-3J}Xi&GqjdVTqYASPRpa(^+O%izdWms=cJ+
zYO(T%8Y;3AL8no#lb%;WpM6YUyD!IAGNh5c?@}r~xR;TQy(>=`K&WA12B?GZote{(
zo7*pwlkvFCfqjWE{2R_q;}8yo5)2cO9d|BwEbl)VEQ*Qi=09U+roAK2z>94E)8}n8^!Va
zM;?UPtXeoc77`rlX5`VyM@qTC>;O3au#glgh9*ceBv7Qw`j4&6fPu8|3sKCBmI>>~
zyxk9tv~&xc@>AjsiJioWL@qEV0vjzA
zdf*#KuwQ(G9Dx#@ioNi8aE1%Wl(RwiYu^p$Co`Sb?e3E}No~0$hTSw;ZL3pJFhNMy
zn824AYWBtmXkdP-Mt|urS#Wuy#6Szpkgh}%I+?RW6cVLR9{ETB1cOZ3JX@)7_;i&8
zuOr1(O1fiLId~4C-2P|OUVw6;7~w*47sr>B5sKfY8N_=`QspXH#b1u6kNwK4s}roV
z?ehcDD_5CLz6zb3I75$xF_`sd+V!O49&<8DdFa*zG~21$gBIfN8e-}~ODFh+%e%ZA
z)NLE#8q-(urlRr=pz;r>F(->9zP5kmq_
z@^BTG3mCli|TvQRoYS}K)maK`mHxF(O*xt^mm8o0Inlo7TY1G2uu_XC9qYv0-7{|Sdku3xiJaudXxx7
z0-sd}RMePng}B953wXK&I-Rk(2zyRO#s0dZgQ7pKv}z~K4j4EmNolztkCdiXGdj*`
zF+&>29aMO1ziw}kp$&KD|DCWXE6J6>WGOa
zC<<(b&Z04*zlI7(HwwQn9JB>U@$1Ewi81v$h2Zr;WoE(dE{V1-63i|}3NA0f9{U(}
za+LcOq=*YQ5%0vfMyk(_%LegP4l
zSkHFu$pd>2*5oYJc;dKfri9=7DG{cjj{axUcy%6!-R0P@O7s}vm!!28;mW3cRVy7S
zf`xQ*Kjf?3@QJVtc11r+PZ;@FNCWTY4H!^R11lt31*V>#wP%gH`%!DS)o+w;R#QYoNw+M4s}?8#o5t3G!{*!@aS;$=
z@<)3N%knSnvHX?VAlm{H;bxgn0WLN%SjYAUFLmxu=W{WL>tRYrihiU^9Y1KJ$@+*m
z(|nR^3_Fjzl{PCv`PBPNe{0u?!5vK2_=xLO0v^Q{^3;Db9OHn(B7ZRL10KC
zE?^hzLsbHregldOfaXUOcee<>J6A66mQXfAoA(Q-=IZNhK?H58)MT{b%_Nv%;l_h;
zVCjpI&t*60X5(@TL_mk`)u%!l4;cpBK?#aTO1$BPFxQwE3F+0v2_VK9bnPEt0G?GP
zX>zD^>sbvQa$?-#R@qp@6CXJPf9i*e&}eM}L7c--8hF!lPoa(Gwm3@AQ8lSv@C*2K
zh(2w|gustDoRmEPKcp!ufB%
zU1vWQULE#59JMa%o0}EhWb_fxXsADR(`ltkU3cKXa>GKJffrAFCBbd6Sgr3)&r9QI
zc0x>;`%GXH8}P$O^p6bR#Sao3A#<_6Zb1A$7~mboYXu1m+uCO+N21XB?rs{c=RchQ
zSWA6fQ}h*BFm67tHTtdYYX3!40=1@|kGR<9n>C4-_gBgTiIiK>!;|ke`60WnM0-)C
zlHoaoq2Ib__>X@dnO6U`i}(ivrd3loizk)DQ$+@-LZtwac|Rq9xvVv
z5#56wA$5-@!tU=E|KzKC|FkhphcO&L+kf6ujj#V{h}0E+um5Y^*W<8^
z0lse?h~msec*9F7l%DnZ1NNj#Y(9=aq%PM#QdcS|P1air{wGbJ&1@fMXAN(MLkqid
z&Yo)M%0AB7M$(L)J9{XA3~jPP_Iig{#HyCbXBd#mD616x#t=#kKwmQO1uXN5f%yS0
z!WHvg{exwMZ$s;^mbF?~vBtv>JiW;T{RXB}NIEFvm3UdwX~e*R;m_6oBB+2=LP9&5
zIha6(j!
zLlX40ux%tKz0od;;r|jmw3v1wwHoH+OluE#XJb{bSlz=%e6eJN8E8ra-}N{Dkqh>b
z{A9D(*iD=zR$E4dxD*Y$fS`@L3~ODnX8gB~F8b>dn2OQV=626Woh?n8O{&}auiRVN
z)W1USEq(;b00qwUqZyQOD_Y(+);BQ3T>T7)B;qW`S{25d$nR{B@t{gQwCf+`zJ+tN
z+jS}$dBj=}*vMnyb=yj%tCvbYgX(F_dwb6Vc}h(2zJ~#3^9^X1J?h_O0&>;2M5Qim
z1gd?x8>Im5cao>N`vr}%4}oebum6Ps{zNqqnw%yiAgtE)(tLD*3=_^0jGMH6m%(+@
z<&H2AQ~~Mq{`^zIN?DadSV2*
zuYX+WVndP-)*S$35%&t=xTOft<;@n|3pSN5H^}fU$HK%TxyM(URIgoyF+N)1+7xTl
z!m6X`>^zvTXs0R6u*m6Zcs{8*H#5)F^z;7p{vEpTyKo0j24SODCfS+SaA8)X6yZ%6)LQu+JzSnDq=6z{N0sdT;h6Kn%E0oyNvp`4G9VH+e#J7+US3kD
zO%ca^flozMrC4?}#wOg`|`JLzFv+=a9%gIkotT
zqIF%LaDEs&lC2;owS@USl2=`Q?2d*XlZ42
zXvYQd7Hj*l`K3crD|C7%Pw)gwoc#rZRr+3!s=*>GVw})li-jIh!~Dg}`Cm^mCI>H4
z_Y`#4#?9JZ!7c2e4Cbig`+2=jd?f1&Gea!_o_f~}?pIBGmOMx47fhNBO+kP{L#-|2H
z_z8NS&Agh<
z>9t;EU1q1HS)WG^n0s!jCsbk)&u7(Ny7u!k%J1)p4UGSlL@9XWXcguDgzW4H_ik>+
zzRa3s)4AxxSnIq@9C(3zIh_bCeAjY`u}qGC{Zow8@&oX#ML*(QVaNEN!KZ{6e9|g3
zTvB(QcECuBT?aGb+YV;#qUZyZ*K#uXMlbCDRxck>^f^UwT)uJ8wSD*V+)EORKX#@g
zu7sq+IT%+M&R9
zqDM|*ToSZ!$^ToOZ`CZ<)H$I>%for53*aiE4vG8AF=s|{K=bC@x6{i
zzQ0eVEH3fR5?s^EE?H_d%#YkvG+W~bd9i(}eo^dxnE;y}g7DI{o}PZ?CanqCHtXG9
zdT^Z?zlwt)QewN@ji2Hmw3B)Qfsbq6%LiZon(#`BAry2zorA6Vzhu{u{I2Dy^2^^Y
zKxtl(LVM~PWAOb3#mT!vqY_WmmPewisP5olrSC>6+T`&VXm@9TOS~i{rFsoprWMy(
z3%U>Ub)zqGD*e}a>hj=d_9k<8n_25M+ui5+Cd%I!-&?&Xc_3G*WBOTiU@_U%tR%<)
zI6|A>YP{wi(C1;;F}Tb`zVVW+Jg#x*N9mM9sLPM-blJoKa7dYIbH#5`oh|Z$`x3tI
z9hWaFb4hHNP-6&8Jss15u0lR52PZxP1Pp60GNp?~m0i
zmCwXG(ub(w{Bnz(j*vWDl_RcsdJT?miJ__AK8}A4C6H-dYcP`et{XDb+BdfY-ui4#jzvU3BCpG+(Wr1K`#H0od5kNL
zSAoA)Hj5x;7r!38jWa#WAH?|Crg(Mnz#u}=Y{3oIBdkO2el-M1-ZFqZfv+TAlQsqK
zVbukGN0&$~V6%MsQvx>W-ytPggTA4#r$nKCYQJb;U;dcC4zgo4k{-bImFfIGWL*0C
z>^rQbkDfSB>{oo()kv}SVzr}h{Hx281k@Zp)3Pm|H_6W*9@#7^;>Tvc3gyc!o@ctu
zmvBrDTC}^aNM2<1SHHh%bY3;ypX^#+Z5(S0+-C{%m5wtSX{uNDq{qo$SkDhcQK8>_wXdJy+DvK75kjs9H0sWy$%|!^
ziHLNhx5t!YUfwB^RqrZNm1Uk1HfM43eVQ>|+)W?q8*{enI}?{}8Q^AY0sIC_Y&*WBz!P@wT}6CJLK+e>{OgmZ
z6}A5DKYt4VMh@Iv^rXOoUD9!nQAc)9+7o8hH}hUEVn9Z0nIq)#JAFb|_y}=hMfg#3
z>WplI0ZrYbH1Qw5gnO4Tb|Bm2DNiE0OHRM>{%qdD@Y1_#e)&Le_=X?5!o3mcVCJh|-&pIr8)x3laTZAJnRE8I5XxNau#cX7
zi762ges%SozQoyKS5`F$9?$J>U9ydP43t%RFFb9thwxIU6ZGOW5fElxOr>M`0ONIi
z&B0`FRZo-bp|#WIs9JUCM9eiG5gL{0lA4F!%&B^jLd{X3UxS{r1kcqrzJ}oU{))5L
z&|0+)uY)$YAapK%zBM_MFmd&BuVkb2;cMy$#bA}nL$mAWR%1Xz^v&1*NKLGb
zx)k2}?oZMiB{+8+mOe6y%w-kWgGR1ajw~ML_h*-YN2VTPT6j%u$eGnE(XjWTvXNFY2qK
zs^ZfY$5ku;c%CM+tNIS`uZN#Cy|SXX4BoaD`n~DD(&!~QcfLA+HTSxcY>C9ZHAC+q
zK3!y|Yu%vZjK%caufy&g@DgZWPWw)KCwhv0&Fb2+spkuH-qg&a|*83?cL
zbmIqK93CiypomRi;#I2Cn*EVbE~sT9CyvL3AwES!DvG5pS1(QAI)@B7&7_;kS
zMvlCbIVA)7hV5I^WybqGCrj5L&nri{rft$YtVS*&2WaP#pS-;oKcf^I3rzmT
za1ObC>e)SWrHMt6r#wR^1IsAYEHTA111~WReKdu`>-SV3$yLT8Wcj{XK%c!2XqHud
zbAtK9einRVXmq7@(eTh~;GUc|68768DmnCxV{GZqpsLVKt6|yUzI<|QHcEg&@Bi)f
z3?=$%VNiO|2dm1L4+I?dT8baMV?Th+m-p0^rWT_gZDn77U;gFLGP^3pjHFOxq3fYn
zLs2oqI605L<(on2^|0(=!3t2Su!mev6lfq>8~l3QyC4fEth?q;N$%GKh@o|8%g2*A
z_u#zQi%t|JNRTot)R-q*n3yguih`Bs+{RX0XB>|HForzUNZMlArtglQ)l3E0>UVIdPTH9gE#3LmyNB3{
zyaJCe6w15F6q;s$4A=Ytr?f@>rd`m5mb;R9A8;nr@NEbj&2#K{MtQ7c&U+&c+t^(A
z#|Oy6SFZ_aCO=e#h9oraN-YyTHXHIg?;fDkS2Afn)4pG)-nEi(dKqnw0=vr@X3j>}
zcGZi6e}B4JgoJc=iL`V{cS#ANAQBSN(kLxTC`cpH0wN$K
z-6bL&(jiE9EZ{%a!W}+)Kfh<6=bZC@b>8gjVtcK5-}j6$#+>szK7*jQ$MK7x-nm|2
zGgKBYY?wy)NUy#7HL^2p%2Dp;M*kLRF7GO}I;#wlQt$60?lf2C=){^SD)n-p_L1c27PbvV*vMq;o`$x^f;;a-4O$pU!MZ__XPH=h#&iIen05
znRBro(kdgO_bAb%Ovh)CgYIzBMTZ~R@*`2;EALgaH?FjT?@U>W&YSAPaCck@_C<6)
zGm5PCsS^*d4|{~FcU=_4mQuvwiZ1xq+&{0I(>*S-DLbqb%el>S+&OY#J5s>pcl@+i
z5pg~=S0|o`a*5jUg~ur>sq*#%zw4#sWf!Z!DZ!{2aVAAY!{7g&7`6Vhp?FADNhSe-5FQOY#vLdA@+UmwJUR#LiJ4S
zJV5WUE@<{>O1rWH-G#l6v%
zRzKk$iG4oMgId+g(WDkIWA2;@51~i1np(;pDyP=yGIF$$L*}ie92Gxe9S3I;VZKW7
zvEo;|U7O}NjxNEfF6QIi8`vq*zFQQJH(Kns$I#Cv&|!9x*B5$55?Sw@PI$W56cT^Y
zE!n+~ni?z01IEke7UKnPA{*;1h2_-i
zC9@km+IU${J-OFg9KoVL&10sQz!U|}Em|q2FAQpWw2LVxorav9rtK>P1)A@Sa1*m6
zUp;G*9GvDE42-nN!7699I)ongpP*nb8WF9Qzpyt(TP%R!$rs1vR=@m`Zp9GUF-8!y
zGoBG}ZXMiAz;dR<|3kKyQZvmcFlhB^EiGyy%SOG1oyW-v#ub4V21ri`1qOf6H#bi#
z8e#I$&n~^ca+~TU7~MGGozH&9k-~DHTQsT2_Nxx>OA@<7XVCkb;%%s~%9)!#1>q4q
z?|jWD)M<#Bw7_{q0C};v&P8djE68_|sakk@+A2XZCk`zAG+zz*W@AM4;^^CdIq}~{4Dd3z4b$XsuB(G|SQn0~7fE`K
znxYWz`6jrwqEFuk=2~4f6p$C?@28N3q1#CLwujS%qWgM=
zjMCp1R!zBKS|@W&(rZ0k9&$6YFni$#vQncom(5XZv7g?C9d8}$0;Yp!1m&mH;)0lB
z1UvltYOAN-`!m_uC?N~n#H+5)?VXJ~U7h_4Z{PP&-U#n!M_+7D%U<;^PM{y!SMWVF
z7P&HSR5dy`pq)D#`w5?Xp%K{zu@c7inbmL4iT+jr4-~y$6S#o^9Y27zx+kUQo
z{a23`$kA;OZ!(Foz8l)0*+)TtI^uZ&RXR@WJo-U`m3-=O`n2-w)Zpe1en!*~^vzE?
zlk_x?Yu+Z)2f-cT4-lPb)AsRVt^vv4-bUwPNLBO?MX39zmlkKO?%m+kCvtCttJ2BE=v>g9-eggcwn8wzv5
z#oi*)xDDxU9MnIFl(uj8h=A%ztuLe(86KUCL{yyjhPa7r#h75v9nhGN*<0qJO&NmhUo1$qrof}w
zc%Z2md2?hK=W-Ml(LyoBfQo*6e$G>T9#FYST5%J3%V+U3Uc2JsgICx$%T-^~yRRMP
znW*mE@3-?W3v4d-gUW6v*%m(|NzyHqRu^99cX~1T%%W|hbdiJDFK(`Fzu)3D82)mB
z?^S6>IZDNalNZ=*!kj{=AuNC?@Gh<%YG-ueUG}l*vE->p6?Y4V?fK5`S>JiV;+E{w)%+wC8z
zQs>0|QTO2@liU!(Z;xQxo3x#{WPu~DF^&EjUC#5F>2P^xr}>*{V9@z?6vE6pp2m+%
zo{5f;jZeFPLb5#WB!)##JI1W??x1n~?Zjel-hA)F)Y_I6niIz|=72=Q_xhii
zZ*4#A>oz+^XU2rA?njC)%$W6>Yu0xZm~BrpqrWdb9Ov^QUU=a7?b*edYsu{E@?k#8
zxI3!?;Vg^X#P#Rf0?~f#YK84v!MoEO!6#->EzblFzfsgiy;m&a%NTx;Fy7C7|50uV
zb5TsGknii0m*FD2OG*>^XRGKW1AxN_1r1YL!;OE-NL
zicp<0TPziG*Ey$8{Umw34!*VH;|=O3*|gf9*`NWaLiRCf3gk*Gy$-kml^>6)rntQ1
zy2=qQVuPzVbVJL)#6z0@(Fb|%qnZk$o@qwEcfxW-$V}7XktTXRX&C_l)+Il{d3MB;
z!^FTKZ{`96sgX{J_FAEHxp!5|Mb-vIW8j!xXZnJ4&iZ)1^Wha+x*So3q2!YN2vu5Dh>!!Ce>25@t
zHJG`DcpQ=gH>~8aMIhZF3*tg&a?mx==`ggBlt%|I_=s=Q*pF4p*AZq6lWG=Y<(8vD
zZfx9gI#7^gHd9DoPOUsVv^ZW~a0}hxlc1R8+8Ke)FBD+(b$(;^z0zy(WqFSrBKpzc
z%BlcDIal_$UdCOk_+&MwK#x`}>^JK)X(m2?WfZb5MPX!+)t6ya=u||Yv
zzrLTP))&71VdKHTMCLxrZH~jQzDf@fJ!`yKbk{#;INsPBVhNp}_DKAS){=QR#U)Bx
zPkQDYps=qb&@7Dwv3aaqUYTi>BhA(2@yXlrUh&yMJW|&Ur;9?#cs_~L7(V8kDVUJ(
znl$LLUnu(G4RS2w^4#Uj+>ESb;hTDHo`Y|{$gYI9h|=k^rLj$=Glj+dE6
zl)XI*g_Vm2zA*LWxe5*1Uhk9Ku3UKZN_abx@0mR>F-gK~x@M^4cbAr1PaN+}%wjg8
zk7`oDcckN2wIpP?izUGGpt(GyHu*y>!>M_Kf>-dVJ~DjoIrVmr-1DJ
zvdB@h#sZp0M6uM>N)xg`lH%TFKDK+2KV+&{T+`d&FVQ<+{Yp2YqFEpOiPODEvngbJUADeD#)SXF5(lxK
zl`w1lu*8;sE+t%m{a)EraX6;p#X_soNXWU5clQ=(QYiC)@F%(8Vo
z987}1XM~G~R=1vmR6fal=;BL*(3;{?r!v;e)%Z0*SDUh|@>S8u4zg#;9)7JHq~V9Y
zi_@6~lN|tfepP2b_MrI`5}S8#h2zcdB>~t`_)Yh&e*x4#Z}Bkn%Y@;
zjpwPwqZ$tjj)xV?Drapk$i#d0anN5X)Mjr(=bv{zr7R}3_4U)>-<1kOv>|D8iXc@G
zm4`xiINp?_ekhtv?;4>Iu)QP1X4UgTM)6Q$H&c3#u04eom?nbpdpWYl@2nn9mhX6N
zcbGcgSR8J&&Tdw%LTkO_EFO+bO3hKx27T!<^VuwmgmSQ~Pfzlqs`4;Ls2la#hyvfu
zL0k6I&Jm75nTWnZPtL@ZYn&BNotcDL#nL>F8ovv?%sJmuV0()r*A&zwjY)Az!)0cC
zyfv+W6sxSGqyAFSX|wO)tBL0l?4+IJgkyQ1*?PS0-B;=D@fb>)`Ve6Yt}aqmX(LbgNPm7p=3oVqdP6
z7Y7yH0{B)PhNL!DfnGE^_5nlX%c;%?lGOKY$d|gEPqMvuq`6}9KIhpIF9q!+_G;T{
zB1P?(7UrZ|srSU3=N0k}-5{|M3@{SSFm>}9RH*Gre}7f$R7ZvPUZ2n5v-cxz`Rn{b
z-7ATi&TYY~y8DV+3Vjlqo^1?hpE32p4Ptk#_ZzRwdq?$
z{bcU3HGO@edj9P!%{unSq6=oV!Ohhn)US|wtzD|d!|pAueOu)1MVB6&jV^tld#Y{m
zVjVpNVvO?b_9i&j9KIg6gaor0=%m)c1~(HC^Ad5Z3?+hwhGYBrj6Rd=N^+O=twyF!
z^DXzh>U+OoZIzwqlYYDOYFu&1#z_Ym?y5+>TYh*^k_ZPO?I0e(ki_bkXnN|zjzFvW
z@jHXQ$F4p*nZ6AkcY5b7+P~<(7MnWM?)xe}L_hdJ!n=(?v6+YX9k`%={qsEPr)+kR
z=zGaYP}e=*A|TA0G;Dzw0VpVUg`icB@1$
z@|PoP#~qNW(X128O!@H-&2CcpTd|9I8c9tpcSG(bW3NOI8Gjut+$k_Lv?1u@KTc{D
zj{89?{G>@v!mV;`YvC@PayeYZ(}>pUSloMq_F1a?&T&@iH~SC8+9INKCK}xj4E23w
zZ(@Smpr~K8VQ`uAZ>r5mlYzTEw>6b#Le&+JA`u`!mW$+w&a4Z+E7wHCi7f^)GgVfn
zRkTZ)8Bjd_t77`Mrf^Wum+TuXf%a0D@lt!KWG0&l^oJBTjGJ(hLE^Kyp!qM-kxPLX
z0!m2wcgKg3w!Zxaw$Paood2f_NbtfvZrF;mYWLFUS*3*8<&|)2Rqj{tUJ*^#7Q95@y2!6^x!9ebWEEDA
zKWFy^H~-Fm;H|orat=$x?W)#6MM3|DwKal@1Vnb+b~0oe_;6YBMx~Qh47h=Qip$C%
zdHJ~J%8nS=<63wJt1lnd^>-W22Y>+vlFuW<>T~uMGJ~tA-|HqkD@J8N@Wp1PU0#Jt
zQa?Yj4&k!@p!+l8dhHLSRxz(@4_(SDSALOKUTX#t`9DNl5jU?pAcO3L
zrL7n4a3z`8OFgO?e%iuS^Uf@_!wwqZLTPB=ScH$!-G5PW&}!V#gj7<$KwG4YY{Y?0
zl#f7YO1*O_G|l;tj|}FS9u=o2{iUGZ@ZSpRzly<-Gwo4LFE3?e!~aZ17Q=Lzv-|2E
zVdvcse3ZZNBjQ{`u!c^6Mm)07{Fxh&5)b#skT1cNhBk^|I^OX_vn7I`S&2;`=OD6a
z1h0LXgMa7WXy{2Cp1l?`$ObBUOAApyGgCap-HNLM_oU&o@t(Bg#V63>v2g_X2e_>G
z1+fVEF_<0?Xg5ZbFXe?)f3r${lTp5#ZTN%>EWovp@VAd)SI>+qw$}VWfG>MrB_RN=
z|^3@`#ugUHemlaE?Ur|r!DZW;iUWO{NCZ^A!&37~NJ
z`{P;433|W_Cuw|N><*XmZ`*@SLN~=NoiKPR3)6M6x<^28Y2H#udigRGaKHWjC!dAr
z)1UY(K-KwsBHizJi8t>=^`sor@ts}lT*PU!<~>C?UExnErvMVMTT=~*%J8+x9zDCA
z0@4Q186MVN8kdPbk|JQxu*(eFte+XS%;%|JW1o{Rc{OO?5v(JLL^$F~@J}v)e}u@D
zS0x^x@wU|$-}vC2ni_DZO9gT|SUME-n&BeP?3_PuLz{4Z5y-+vb`&HfG|NuGlM;3S
zJIx>HGxLL(G!|Nb+biXTCpi5}P6MqlihRhUyCy)g9`Y#s9ah=;)-AoLh(`)=k*9ku
zb{?z|d<5j;IJge^ncA;ApI__)T;w?c!F%MUm(;u%CC2BSfQlnd#B;UE-bFQ1bxl`mn2KHZ
z2OwHsM+*{w32SdDsMsXHd<8}UUDX;$yC8d~1s6qc+2Mg1EJpTWH~dm>E&aPh(}MKL
z)t~wF+HB7O2`J`ZG8wG%-d;_jNg^beA<1MTcdqFGsVzbbT8;zo2KfP@ofJsd(QsX)
z+b)wz2!64xzb2KKALtYHrMKxbfL?U{f`doU-HtVMSxI<^+qzqJj{_K>)g{z2XR5Z
zvq`e(rOlN!RYZl^T!gD0S(j$c?myYw|7adSE(5Y#-ZkFBq?l!H;#TL
zn#S&^R^`{rw210|lolcTq2*`tsw%zbAKN6r&Aexk12Q2rGmOl*8t-gItyBqo?vIYn
zUHizU<6MA@N*V%8BjhoSK+QshpNE{?%L{f%%iA3lgxG1*AjI?@e^&h!Nb3thKDqXe
z_d!l6VU-=eqo?1;66BGkAOuo)c1_4%L`)?qoo}_NM+hmEG0~FIkfdlafTWyAHmDn-
z!AqS!>;;zX4@}5@QM(8%(^M+;k6cI+v_EnZnh%N@}{h!o5NM
ze2^~qVYvKd(kHm3sF406eGDIhfanIx@YG^_4LrE~NkDbMZ;6F(kq~J$IsZsO#g+LZ
zKhY5Zu#yp&v-|^?PC%cI3=C;!OgzM#KP2Vj
z8<+kzFu$-+EjPU>1RZI_bX(kMwCU;G3si+bGwL|~{U!q_^$j1R2b-OG0f%wc6SLd*
znDZYH1~ArFJfwN}fyjh}9jR`kPw8U6^dj`B0!yq@GBOgJ=HnW{xmzmf>9_Iydv1hI
zc`QCu%;SNf22+jHa;0QE3TdN1D@JFs6
zpOh0fI$+-6?y-au%HBf$jO=SO`L^Oe(~#s02v%?k9De=Ghyc>b7)Ue`_+aJv@0gnp
zAM^~RKrkSm*c5)koGxL1>1k*9lqL+euR@LlcxU4*U?8^0Ld5^(ksl_rEWTB{itf^T
z=9u(2+1aUJ4k`vU_0jJ*s2
zV2AQ^ZUQ{v)Hr>1#gj!dzTq-WVoK_9f(YD+Hn;F-%rO)TS-#%%DqBFYeMB;oFNXgG
z)(M{J6zZ=-ryVOhnhCd((DP^GFnyb6>G4#;VGjT)&yC*~u1Czce?UEY#R7;DmJGr;
zI5-P}&2)VR>@m2O<}Ru@D*cEw^%$e-WIMK8HYySRsrq3C>|g0`^3lx2GdnyeM5})g
z{pK~^C1(NT*QcF%WYKe}^e%G*0!~QlOG5x}gCXHG-yrX6V56X~5|P}m@AhZ^j6G-)
z=D*=012uVxUr!ov*oy1@}$WNRD;r~dTuqS}epO1>cKH_si
zcD{Cn$n~&jL;MIgiN^TH&*?MzVdMyq-|X#(ohxN7$uzHjA=B_0z+P@En-cIg|G?4t
z`yR+TIzD@6Nc|iC7KT?t`!k4&{E;hcL>;;aeiA}u!D1f4_zva+`bbCOBHh13^=AFk
zNB#x5`wxGq;tSJ)Keom8^yt{oF8N&x{(3YINmTd9HuiT|O!WXFU`lG2^)bK^d0tx+
z79osQ#NrgNZ@2C#Q?8VKFXLOJXjtn=M*`gC#3zD4v?jG
zN(q_n%fkozo_v(PZwn7s-3KFV-%|RU9Fj*_tp@tGKd0zDOOD6q^ngUfRAl|L(MF^{
z!v;UQz$bdtxDtfUm!+|B1N+EQVTCcIVUtmK)CZ6b&(=a_Uidv?2k^LB8C-Jsi+#x*
zJ_b3{5MdnkDjZfc$M;Usu(5rgQI^jTI-URiy%I{jUGBS8jH5y4;i&-my?7c#~<4
z!E`vn5&fA>3P@vI^>3bu11lE+oq`m;aw(JxZUn-AD7V!e+?5~Y4{s6hLN8y1@Ap?R
z_AOC)dh_}s*inP3S&6-X8d}{uWq0W-Z2p6%4jr!0hqni+XpmXkoOh%pvVKE(UAYjyl|d5E1s?Ul{%6xMiV)bookrjSjI5
z1XVbffBYOzekG&eZeVnRJUeW{F3D1aAY}cWprUfO2xdiR)I{d~M42W>gmv8vxnZeT
zOK})x4$&nA6!%wJ)2cc;3i?zW!=HfIMFd}9CZi}?pj#H2nBb^f0;i4+|5uNMaohfz
zU;cq^+xlA;%Wvp51{B!*k!5&mod!rhFp}#`1%XUiUy#{2RNw=^>cK5PgWFmk0MgVB
zvC?tD$%QYF_Tlt4nxDJPKhxXj(?zKON)+iPKgArJ;)+%en`yXELMHC4v7h!^JLXoC`B*6D
z|Lp33vDp5%7b={7%DeeLM^&3YGqe#q|D2)CP5d{=
zl+nB`ewpIkElC;5Yy%fIx0d!+!nlHGr|IAN6D|KgWUe}H=N{wGkcfDGK}
z@XLfBc>WEX>^CE2(SGjzPjS~wNHE_>$7C*7O7~Ybndzl(q+?Pd83XXmCKHoHf=l0s
zDDnT?7$`IF|J>MrGvEK88~eZD#>AJOIp8m+_|*vmAYf@TAAbl4RQPd(C+6XhYa^^*
z7cB6Itc9!ibMWdVjXV^9Jabvrq~wy2E%EOO*`EO+`yc)IUN;X&L>dkLbJ2kZu%ZKy
zd{A=0^G_uQU`%eE%O~FJ{@rmc{4Y8#DaVfRtGysHgs}z5q1p1`RuWq(u@z{Yjk}`O`1zLy
z{RJccAAj^uA@Tw;;JB3GiAS=+B_(pEg5EKlu
z$~D#B!Wh_E&wjgV_$BxQQ7)5a3(PHD8Exi;i4zATYpkMZl_7pNPR
zP7VmW_kSbo(!+=)^@4hrultAJk>dVe+dcv1z`M}?9uU}d8XFZfIvBmRUP7+t_f)ZU
zh2fPIyQ6&S=#R=P$eG?=@@*ePr*_2u2X?L;7mn>T1LMv*Pm>4wmvdQ=PLS7*4&f3c%bMHE8fzZaCQvn
zRu@MLa)Chv08m3sn`EvG?Y=gHH?ieaVqKg#Mb@=9uS@OsC(gi;Sn
zDtQDS>%QmqpTSs{la1skz^Sm>GhkGHucGim&=eEGQB-LWkB3ddO@ya>N7^T*{X`Tc
z1cRL9g3j0Q%dG*-E#oWXBrFX)*yOf1E?4>2S*RRXmF`HW!*cLeZJH?4{Aac*HBYbw2_H47tX;L9vE0uzfoOt
zULF2WUy~qnry!z3KF%Kni4g_k$rF?q)$6gU*AG?BHw*ZDvin|3EbFG^7u6+Kq_K#A
zvgdkcwGOTtBNJvm0^#!Hhjvq%4_a6-?dRBtM{avQjmax`SS|7cHNyq*dMi2NWPM3?
z`zWX{jdSN6HUj*QN>-ToMm5P9QERKfj`BJ=gLy1C=fDD+drbtkMnljbW-#4$_O42B
z7h0nSVIR|Eh5K3fqxI--tmiSkqC
zRltx(RJr9gK*4^eSFNz>cz`{Syla5tS_(bJ>xJyub2V;v_E$k>#Bni6=uqZ(QQ~e`
zTR~WSZaZ>~#Z=u|;aEu7(4uu=+TjZKs5~3PN13&9ktCO#AkNoxwQ@+f!f&v@x=F#Wtp0c2>)=pk9h^cS)hyu?EF@TA%<+
zqpT!!n)L{`UN5&%wjmCDI(1BV{T(micT*o#%Jw648;`5_llf8S@um>4Tjdxa-$@tFQyoPf$4TjHx-~J`oTaS|Ul(4>-bIc}sohaKm%o
z2-R1d@#`_R??7k4NItBQnGBk92O?Z&ZW9t+u7IxxPqRplf|VhXG0SXX2~@
zzkk1!Jw9pSL@D8SX3&y%Kl%0Qfq})m<3)CoE3oVX&!no2Nn6iAcble#2b#GT%Bl$-
z+g~-{S}iCb#Ivz5$Q%74PJZo!yY(%csCT*n#Ozy(Co~8MQV2?N(z=uTN=ZU-qJWxD
zhjL`eU>!7r|3rCb!101Pt=WPLp}zHt(zytzR|JVDr^NzrI-B+?fQ>4;c$BKMLSu1QZKXaQylu?}aE*$ji22!KH(2=^
zP985+psY=I+ps_rwnZbg}J1eTE`;_=lxZlu%{964b6>s%E|{$7uiobka`j7QT>&a
zu7j#S(ID|Q(QI=Q+*lwzxux#bTWqF$qo
zrQD_vf3|vCQAp_idP*H3Url!+MQhhmHt&j(qT(7mvF(9dD3_@Z;rwhgG5eAEaTyyD
zhhF81SGG_b1&3Ay1ZcWkz9_rho~-X&Dvkq(ZA3Dipae{8uNm79Qy5c|h{3I|W@)4d
zR3{^XuQS%Cj#I~Axb+<-n8v+s#<%U|-|inrYHUPiSTF;I=-#fTHyMTp50&={sRJ}o
zc&T!Jc2*NDN~sd%(1Gw4`}EB%V+l8r2z`)u*Y)$AMU{9TVFYUb@TpU(Z#O)#cHqLXho{h=vt>Fx?R}=v*
z6`%KEE6Co@xwm*?I73heO!a?Rgy0SEDcOT;ChJ$0$e@AKE(|X=hO6rQ=!7fRHHwa1
zCvFT{b@AxueOUvQnf@@#g;yUPw+0E_&O)MwtYlFgI(Strz5>2F=^@J3Z#PB`!Dv>T
zbqdr!G!7ZJ+nKmlWHe}Cz(hURQlwpy@tEKI-sYG0S1Aqi-ozN>n#=br3JMD|o}8R?
zEczzr78bf13anz01+XZ&B-EP|9O05JvqrePUg+=ei75Np*KNs-K?bRSUJAF3i7T%N
z2#aPuE>|v%*#FQ>QUjmJx|j3I%GHfN9T7jYkpD>W40g?5hhe^$Ze3Y&+;l|^Tho>o
zs5^LFV*EY}fKHw~ARB>J+f&(;g6b{kPtQ>rr4bn;48heE$`yG;L|SuLbs>H8LGG3%
z?B{Nam9#G4*Wd9Ki~?-IgDbNpe*0t?L`6~>c*IT%kUvDyD5nK3-fu}G1O^dbEyo7W
z&NLO_#-KvnqPWo#t$(?YR={e64HL}%XnqGJv5BNUBmh4me@%-B+|28PN`~gBH`itC
z>b9&6qOfHY5TL;jr?fFQdpYBL^*Dis*xNwGmahR=dDe>KQ%s;u#64(FeI(2Py_hbTP
z&yEtmoXpM6-Z6C3b9J?LO`rLWk5J!#XY-9!67&EE2Q3k(K=EIFxuRy~AtQuOe3cHt
z_t{LuS?lHKsr(#0_&h(=OrVAoRIC%)BXa?{wSKHO_u|505R815At
z7V87Zz2~AxGeR3UugC5uO}n1rh12$D#H4jv;k-7rKWVzFFIohl039sY)c+~s~tYAyKba<%d}bgx|n#p+CvL`m@91DUirVfcG+;|qH47Gt}NmY|sj
zXF?D?C(s;oA(NNRnZURY_UMkkOmYx69TjXcHr_EmdM}wre@G{+%ebB)Fb)QTA3!e+
zFZ6~Fq3TcV3L&L!D7OmYmY%T?I*Taq(ZOiT}|^FJNL~I
zCCDhh(6Hx7icJqOpalmbrD5Nmn|N+_;MRJxYnt~O>+{3?1IvNg*%wcntlRgVw&yyV
zP~HHG(Iu3j5J;1OA^p03IWB($;)u?0YeKo^DZ%`xhmf#Fxiztt%0k6piOJRD-czi$
zk1@*^!F0ksuLto*Ei0&2A*u@JIGhbELC7bvi+dsQUMI>}5MR7EGSnaqABm=LJPa(*
zapF0o91Kv(*HN?>tS0be?X};Y4C3cC*IgW*FsDF%=@j_D9b=FcP2lBnH*L%)^rJPN7d*MK
zV!uD%=2;UM^b*DXTN%;HY;&_ksBb|*!FRKzM2q8~F6na|_Q?BRNSGvM42ae*oaR+V
zs3)K#gp^TsxmO0-M-+FBm?QfVG4Vn;i89s_>b9O(5Mh-EBOH~ZS#n~-%|*pG(6KOo
zstTLwzZrN_14mXOjFK+~Gv2$90o_*_jnZ0rdQ5FY_t1!rJsp!xz=t?j>6AJS*{R~}W(0#^=ZKaej`{p=-2LjDYM*^&o4+d=i5j;jG
zd=)9Q`w?uN_p(uCiwf!HrvC-JU7Xhr>wa3~cRez&+=0v)g}d-v7g!?h9UD}D^J
zcVG+Rzz*W|I-k=!1+1r7^Q7azQ5>Uws=hHQFdc7ddzf?z2|I|!SU$&|9v9Y1zLs&l
z{-a;!x<5_$+WA=QYAINX=y>}_c%`SMHVWTTOT$pz67Eiob|V^}057vLKR8XF1l`D9
z-k#YSm1JQV)W9F`87PD9KR(5_wUx_UtS7iV_VR>cX?j|@m0x`wt=`F^xsI#o*vD(&
zrqev>g`r99iHgNk;L`(&Cxnkc>V<>)qA+mINzmbevi)izoRa()c452KKF*xB+U)q-
z&gcqLk2v(~%qeMwuVIba(Kq0!P0_NB$q7hUj=_p9dV5%^fCbo6VEG;mnq7}qc^OdY
z{0yjKrw1`0DJdy;C6x?UIqsg
z(QdauG^=TPD(lLRmO-bNE3cQ@8<*naziZ
zqx85*=fm}Tj=%i_EM#tEt1WAqc=3I8l~91lu{I;4(S9+P%LTq~kPZOBC*157ffA5j
z1rCO)eqJR$6UeVDTxXLXgV%f9V>)aNn=ssC9H#NW&V4PX3$X?NVB7L-csX%8?QDU>
z=?7OuXxharcLi?YmvP`>Gp;EN+reX@bOP9}grpQiFc{3?F^?K}v*>H7fGQ3ab&h$@
zDhX+K+EE>;F+1ez1N=OI;(()os-=;rAy#=}aH^nFrHq=bo9mW#vY3sA6R>@&fv&TY$ZybE5E_elx&rBQQ3|IHA%
z+qWZ@)YU%1dGY7Hi5*Uez+=&tS49$G+gpl^J`%Si?3G*V-ht!8Ca!o&3VS@o*nyp{
z_k)69jm!->sG51q4Uyl9eU5O{tH5a5ei;p2{7W>X!+yCf@oK-N+iBKLD;&83QM@Jv
z0+zuBA`@~Xq>sQN;3Fxa$tTurUDbW2LIwO2l|SVjVt9M6?0$Rczq4Mc=Z$L;=&V{}
zc6hgRSLLYPfiZBurJxlHkAfO4W^aIy4J$s9&q)da+7|G1%MN5Fp@eKz;;@ei)JqG}
za*3h9Em9{gY~zPh`U4AcSmuf{EPOv^oKXBDI%hx|E$?+;hVFe4%^QV%c=DHQldu)+
z=g#sSS22OrARJB6TZIK^pL1UlgJFZk@t2Vxd@qSpD(iR+1wVe7*8H(lqK+_xUZDZj
z41ErNJHh~IYI2h!z9?vajkUxEY(+uzkyU&Tptrdm;9tKb4^C)6Jgfu+B(RtJyOyd0
zgJ}FOSC+sz;~E7$h}Q1j66eMv1Ht3<1_IK{;1SdPx4>nG|L|lrza=PfRF7TIZoa+@ni0PI@S+$CXM_~#80
ze7Ep)Wp<{xE*2#uV7B@EZTMu!jAnFM$guSU^4Bjo@{N{saFc7*c_q?r-2!D!ukaL4fF)_d(F9x+so#;^`xqobua
z-&(-ki;V3@!V#zyM_bgDpT^@lI6R~^>;ao?`UKXl6G}fRavpHA)DnR=F+A!$TVhYq
z#Rs-JiFdCq6JExU4nJc^_<7-P{`f$dloEo67nX63$jg6?HoyJZm7)3e2&X+fV+16k
zd#)bVis4w^AFHd4bP24^d%@x{6FkU-O{HpTh*(y^eRD?~d=4XHIVSWADrCjim>{^Y
z)Q{+<1mPGJB9)fFd=d=%`jsh5o`cEH~s$PQEDi^9iMQ+sn~+=cgH(-X$YSarL#^);f?idx$0@x!qE
ze4Bp$`;aqH=A4IMJ|s6e;fq`@dyy;=G!QQ=5CsQ~f;YXZ5T+Ld?q4kxJ8GgeDukLSWTn8ztstMU
z{Mj>$;k=xPf$0l6UP~+61Kq66wJ~U%$AW?+z9`LYmRc#2;!mo{Zeyp;<|VMOVAB1|
z@mENHxqDh}%5`~F5$EjOyn@}7)`zz)qxf5@FAa)-UG*%VV>bY1#z0X)=Q(`eya-Im
z--R~TnJeg1A9MT$%U>hM<=O#b!tT1XEb{(Q$kCaALBwY&o-Unv7Ih-mXF8~l#rND@
z!vZ$Ad80p3PM!2_zNl!9gm!Zr2y+KEn*&VjmgI$+*hP+H_}KkaF7?{IT8mXJ1p`hV
zZieH4
z$EXJKWmOvt)jo|faq~_dv&ExmnhQ-aWwTY!q-&lZ5)PLt!n5y25eL1@9T{UapSL?Ex
zy-I}qP5jN~7ir$nX^m8LfqUJIS}GSi^Bh}JwVUQSW%rSWT5luXKK2&ZV0%3}nam~X
zmy
zny_1VLr%@K&^qA;7oTbHwS9-PC(Q`6y7DWWGI}F}iUi7YDl1~G!BzLD6P~9(JH>c3
zJna+eu@UbiEi9=q(D||1{f^}9fPygY-d-rV&F+yGNdviM+LmQRYtcF|RI;4bz2tYm
zrke{xv;>T0TMUWq%_>-AAg~&T1x~|av^wtLg2(`zhiM}=N?*Cwyhh9-{KbF2h{ufM
zcI6?ph`HF@0@GZfke{u~mg4ebyfsqUAla%Q2jxxXjG4uDq0n06RFZFx54)u8#9KYh
z(sP>>!PdfNnQ!V=GLa3MPSG+}B=UYQ)2v0vsu(UoK%SmB_Y>YEi
zPaK9PjvMjLzkO=4QB~Y^XK$t`zGdmcJ%_Tg^u?FzJzd@(aXOaN)VUj;R;8o6gUsy9
zmW@G{B)H6d$!tdIVoE&;LS}>gGoup+Vzq{1r}g#mfvxX!)UT*1^bynuO0XT+O|h=e
zl*LZ%=<}Q=Oj`uXE~|*P9=PIZt45N_?}qKlV-J0+x{Lm@R*7=FRs|>a+V#9e44Zi*
z-ra@PH+2t;K0-6#B-U|O^cr1H
zD!9YZKm6!yw|rbZexRssqi8oXO559>#v0|bSWr438H{#(86yR!qo~
z5plDN{L!7$3l{m{B~O+x15?lP1i|G5t$sQh9TEyw&ABTT7m;Xde)zRzeP$Ky{pPXt
zYrFX*T-X{U5mUzxoq9x;y9$mAPEOLGns(J^%Wr&7TuSz0y5*L;MO&B5F2eO&zmwwf
z>)q`~B@H`Rt_bDwJ4)fq+>hjI{UPDE{@p)rr*>-uy~Ri9Hc#>E8~2NZPv_HK1bw?r
zZs%~e>tnI&;Ky|!ep>b}wwBQ&y{G2s1@MKR&o&D$D5!)!ayQa`Afp+2ssCFO4Z
zZb!l0A`hE&sySLU-dUbQmfCqFz#@`JojzG};ssPp7V7wIDmU?uxA|ioufIf6-e978
z5~OM+)MST+iNa#$5+=OyY2=0fi*2m21lL7@JcEZiZ1UA>D8N*1qv3
z?WF9ab~7EOE;k}iACs0ml_NV)H*}fB>X(-3cu0r>-RGTFh`r{r6e2;-+$Vh9mS?vn
zY<0q!bf17Qr;_?&*kg}(&YQ4ewR0fA)9claJw5a=+PbCPg!_At8#f
z?3V0ye40fH{FvwW)9EW37t9PTs#$qlYbDpBT7o2YT)um+Fzu|~Vkh~uPvxB0w0n4_
z^vUt!Y>pOp!*f*zxph22(7h=6rncIE5=rf@%nqZlwBYRV=>~DqrU^%m!WKemPW_h4
ztN39_dIP3An@HP}XBc8)O9esv9P|(0TpzU1`foyr0yon!~aCEf+;6
zf#1h#lb#f8TP!_TaFPks9;vIHvm`Y4`X1jczWK-u|5094r5)J2HOUFPf#4LgT_(;Z
z5aCEbn&*7v@<3AJ*8|C>J;yDBX{EsChOIk(+VUF)Z)O^Fm_5vokw8tiFI~n|xRu5a
z@|(2or>b%2CNsyk#IaaA`o5U_wh3JW2EL*hY>#uWK&Fap0zIOZ1
zOD7*p;e|itw?2F<>?k58WzWbHe)oH~aItseqdiaao^9NXs#&j+_{k&N2Pe%))dyuN
z(<}u`(rjrH8ahbiMn)}j5&B>KPfWj_otGGog!VE9I#%&@PL*DqUvai+mj-)DMogk4
zzn27TOEII48A9$ttw8$#5samiM68fefQcHyloPRe9C
z9YU)Csl*&6yOVt?3l24dtBie!BxZnAuFzVtVA+^T?ss;$8M@q2;9rq>+bL@AMuPeP
zi5H$rxZBQ)nM%TErB*7>1AME`Gd3?mM!gPcEGZ+$?$^t3R$0q0iG_*ugjK|`wHJ(@
zPLhlXIxu0U8f`bY*C}z>i!sWl-t8EeQ~h9xg(>yv7#01XEJ4Fw*y)%eteA~|XpU?f
zAGKiZ&3VHFw4z=I3!`UIB7eDP$cza6feq$k!5+~Id+m+{VV@hV_rKGZScuL(E^CPw
z=h~=ULEEPE6n?MSuiDhYQGE1nuk8C+y_wj-K$>E7SS@wbE$48LA8Hpd`)^(lD;&`P
zAxNXUW_d3uHTu#UEH!Y30K3EAfbY^oL;v$GtzXJ#3n8Z_)W*$v?ecQO)YKZ^+eClw@%5n{pFsI_{`oA
zF`Yj?-Mn%*(BP6_XPxl?OKd-Ap8Gw%(}j>jOwo~D-x}ZNm>^^B*ma-du=bWVGpH)W
z%9w4qp(^bJCycW6iJ9ZfBIEO%fW4Rq9x`GBu}m!JDh6b?gCQWk$BtG5YpQZX!4Jx?
z(=n=Uc1F?qn&zxB;V@XJlZ^<^CruprIyEFx=SLo8&YX)=i_Ffr@SI{;#Pr*G=)?s<
z-{i4z*ctDWng#mr97&=HirpFBp
zl%-Ph@i>crnC@|PcY&X{?clRtb$GU~7;{OAY%2P)_s+nFXBz#3uj-@mzbbe;oA(F}
z3}QwxHO|SLyCon!J>T1TNj4kU5+=gx>!%f(Upj*7S$xyJQI3AnUnTvd#uVT9Na@Rt12!qoHjRbZ6-2NtPSj(lK?bt|
z`31wfCioF^%+KTUU#~IX=V`VYRsx8AMtQIUHSK+3(LN5$we&npQC4PznlblicLWD9
zriNXd8Di$t^KU70Jk!;Nsq<`Cq5E}-zMk{NU)E0g%xbeL5HZmlPFB^b0+BJv2H4DJ
zj;D`?6ZBZ$N^LD%ncLtoQ_z8ow-SZdIzn*$DU6NT&|02bo1amTiERsqw>o}qmt;fF
zqU4!@))&gx5&fGVSBehqd@)s^?I(HjkN?Odj|?O9~g#$$Lw?mMJ{v>vu|K
zb1t~X1tsWE5$k;ETPtVS*eN@9SP6BZ-Ld%?5Lte`pu4hblUuoaH@^RPJH(=BewDc~
zV_7QXJIe;y
z6XGtkHVm){M&HML?8qP8-jP&yvj1*$&h*Eb+xj;S-|dXUt`+{|wp3WF4`?Ic}y;K!F
zxMd``VTC-;EnYm{s4v+cg
z#O;NHXLPFURdXpij^S>ris(hZX++#wRw1zhYT+7Y_qdsp+3o3$a~kG^p{k?VUV@(A
zs`BC2)Q|Sv*-D;^ISJcT3#63P=MxT**0%ikr=ANrA02X9JD_yIwMaw-M{)7~As_Gy
zSEOyz`KsMw@KzwZv8D})Maebi?;rm5U=(71oxxyW6Zz93os`d+{xjv$oWStGdm_Ei
zx>$P1&5<8ZP$+r?Uj8~T=42eiK2B1=TMUhK+(v(I>NmJ5!A2(((qWnVv}3tWGgHw6
z&P#!(SK0n1YAZaU(2n?!a4{l$m&N=ABOl4OD|
z3WixQi_4X3WN=h}AfUW#YV2$QBU4OZ{n>?%Jh9CxtD{j=1I!sLmZG8u(Z4&7h(OV+
zI|(7BQ2mN9(QQz%o2Mbj(SxW*is#{4U1G#fMoXQH+gOJ+&hkxSNr>pc()gLl!<3Wd
zWy0BG5=?Qgtovr0{U82hHmtuOljKduTTmYhLekjSBzr&^+!i%XqQ!n*!K_R~Krf2F
znAgvl@^THLA79E{2#?7<3T5OUK!lX$@>bHBANDT>F)tswyvt6!2tuMca{osX;fo|i
zqP{qy`JrK}Zv6qVF<5PS5p}o+>@jJhU|av1(=i1d;UJO)sAZYvglDAWpl4xsQoZk#ljuJTh_OJ0!vEcY;fk
z7(ADDiRyHTCe9u#xO$A%n6-qopW#dLz!e$IJ#((^#ESsG^&zC^NbmY15qm;P|MCU_
zGh|CT>RTnRq45=#;R+@(m)K!tjXw@bp6Hpj-iwrv$Gl(d#Jm0HCkdKYJcUA7gerTW
z)HuvQ1Vular&^HfjE)hXBAc@}+A>DkGYGwIzFxDC`1}UCvF3NliaC3Z+HgzjmHzr>
zprVj_%=_}=BD(>v%cWDd&j1OUd#j?wK&-{t`}qEv&}G}Ib7N8!gn;i6KCSL8lNUcl
zdi5Sb1CidSKgFZW%FRjHYQ3ToZV9^@^SV7AB1$+Sp7Nynf#M^en(3RgO%Gwf4R=3m
zoqr_!*mk;yq7|mQSjzbub#}oecsZ0OOH_XGE2FL>O9%}X{&(33WkOoueq%1g9D9Ov
z#S&CT|5-?H1v95-ZMEW-SHi{Fg(ywMrT0D>$(}cClOB%=aydSa`THMCiNt@BwQM3=
zVV}n)s$ei%kuO5fK-8LBmkqf*zfHbNfgzrw5Tmc
zL)%OdhqqUoZ}4JFcQIsQL&%Dl
zX_M4;(K&W=RWYJZjAJuaod3ZL&8=jA;BNBTYYZH;$SaAr3rEgns8}f5x;$sP6(6+e
zQsb|Gn&I*zl5`IbHgZB65qx-yN)YMRXseW8R87QF4KFO!IlAz1k$K_3FgG
z_{Cva`Wx!U*U}r(FIb}_Ct)O?DVb#y?%1lv3vZljMR@_
znV=5;%v*2h(b*J5Aez7EJjLc-3X<1N`ykTjd#(nZjIWDg&inqJo)I5p-x|!QXj9_+
z+$4Exj5JVctrb)(y02$L!hYT;_~#t^g4j^cah~g%Yxv&9E|;-_dx8p4vZ1yf*XqdE
z*tMG_>laf~?g_D1wjbrFJzeg}P|qJGMTTt*j5Gy_aiBKhMs6Mub}H2X*U7__fh#tD
z-Z28vP5iuNPdT@^wki?%eI&u$?BI1?U5oJ{@79m%PO`n*$_xT1w%5Ue+v38WzebIN
zm;7Q&GQ{uJ}cWM<1G&-ANYoj@iH(vC3kJjnp->CB1XWs9!
zahAuM0~>X#NFZ{Gk6ZkzgC_sF)LWZX{{H$~FJ^4%Tiq_|`GQ`e<^333UmeP;vLkut
zn48LypBINJizr`LgrgMNkZefQnq!OkDH~pt>hITLt(V_!@CwHTA^C)hN@Y=LXt&9o
z>hC|ZG7GlDP`KHY$bMEWWC3m8PD08esrvW~$1Casq1gF|x)*k|*a-uo5;XAHw|QG;
z4cOwds%tLXo>YvlqL@9xXU!8)OM^a{la5>D2fUv(c{9&BYm`xZ#MYcq(p|sHksq9U-}pjv<60{xhI5ks
zTn4WW9O-Spx!fFtVqf%oktS>F8Z#o{k0;j2_>SuElzN55JZ_`LLOa_gF!p(bi$TDC
zPxXn_8?9P>Ss~d8*E(xis<@V)ig`$;6g5?1+kXBLGkX`&UPCuXBQBQh1(9E=*i-rV
z)KW|+K~}+Z60#)sd@LlA@FlnGjqV>*o8Io=8W^+2#=L;qE8E^KK{NceC*8wZOxl!D
zk6I_exTwS-7x7cPkJ8%D$yvlvmd5_H#yd{470WtKiI%LCqWnOsV1?TEbWK0t`G9tY
z*861fXO@_AX@6sBtn0uFvLEj&UcScJ`6HvP;*PbN-lAVGT3eoLn`U^b>phzE
z(x<6IQPMw3h^XBO^ILY0XqlJxDw^Iu`?MW8ohw~_y3@=}TyK9xJZ)XCq#3C6}P2ewAvjxNr*@Y6F^haV@X80@q!FErN;
zg)itAD|B4?SL-C9AOm`1(fpF<+E#1FXHjM(6b&fyl6{4iS0GKtpYblO9|claq)Y23
z