From 39e5415e0a7992b1090baa58486118b26fc00d17 Mon Sep 17 00:00:00 2001 From: green <41323182+greeeen-dev@users.noreply.github.com> Date: Thu, 14 Mar 2024 11:08:52 +0100 Subject: [PATCH 01/30] Update index.md --- docs/docs/auth/migration-guides/authy/index.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/docs/auth/migration-guides/authy/index.md b/docs/docs/auth/migration-guides/authy/index.md index 7a938bfa1..64501d3f6 100644 --- a/docs/docs/auth/migration-guides/authy/index.md +++ b/docs/docs/auth/migration-guides/authy/index.md @@ -91,10 +91,11 @@ to ente Authenticator! ### Method 2.1: If the export worked, but the import didn't -> [!NOTE] This is intended only for users who successfully exported their codes -> using the guide in method 2, but could not import it to ente Authenticator for -> whatever reason. If the import was successful, or you haven't tried to import -> the codes yet, ignore this section. +> [!NOTE] +> This is intended only for users who successfully exported their codes using the +> guide in method 2, but could not import it to ente Authenticator for whatever +> reason. If the import was successful, or you haven't tried to import the codes +> yet, ignore this section. > > If the export itself failed, try using > [**method 1**](#method-1-use-neerajs-export-tool) instead. From 56b750c1ac71cb6db44bdda4faef15e8c44d3a7c Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 15:35:31 +0530 Subject: [PATCH 02/30] [web] Exit fullscreen if needed when pressing the info button Fixes: Info button is not working when videos are playing in full screen mode. **Tested by** Wasn't working before, but it works now. Still doesn't work with the keybinding, have left a note about that in the code. --- .../src/components/PhotoViewer/index.tsx | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/web/apps/photos/src/components/PhotoViewer/index.tsx b/web/apps/photos/src/components/PhotoViewer/index.tsx index 702542172..425290023 100644 --- a/web/apps/photos/src/components/PhotoViewer/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/index.tsx @@ -178,6 +178,14 @@ function PhotoViewer(props: Iprops) { switch (event.key) { case "i": case "I": + // Enhancement: This should be calling handleOpenInfo, but + // that handling the case where a keybinding triggers an + // exit from fullscreen and opening the info drawer is not + // currently working (the info drawer opens, but the exit + // from fullscreen doesn't happen). + // + // So for now, let the keybinding only work when not in + // fullscreen instead of doing a mish-mash. setShowInfo(true); break; case "Backspace": @@ -616,7 +624,18 @@ function PhotoViewer(props: Iprops) { const handleCloseInfo = () => { setShowInfo(false); }; - const handleOpenInfo = () => { + + const handleOpenInfo = (photoSwipe: any) => { + // Get out of full screen mode if needed first to be able to show info + if (isInFullScreenMode) { + const fullScreenApi: PhotoswipeFullscreenAPI = + photoSwipe?.ui?.getFullscreenAPI(); + if (fullScreenApi && fullScreenApi.isFullscreen()) { + fullScreenApi.exit(); + setIsInFullScreenMode(false); + } + } + setShowInfo(true); }; @@ -851,7 +870,7 @@ function PhotoViewer(props: Iprops) { From 91c5e54cdcfca63ac6679f1bb8f6eb28a42e6984 Mon Sep 17 00:00:00 2001 From: green <41323182+greeeen-dev@users.noreply.github.com> Date: Thu, 14 Mar 2024 11:11:44 +0100 Subject: [PATCH 03/30] Update index.md --- docs/docs/auth/migration-guides/authy/index.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/docs/auth/migration-guides/authy/index.md b/docs/docs/auth/migration-guides/authy/index.md index 64501d3f6..d215a610b 100644 --- a/docs/docs/auth/migration-guides/authy/index.md +++ b/docs/docs/auth/migration-guides/authy/index.md @@ -51,7 +51,9 @@ following in your terminal: Assuming the filename of the binary remains unmodified and the working directory of the terminal is the location of the binary, you should type this for MacOS: -> [!NOTE] On Apple Silicon devices, Rosetta 2 may be required to run the binary. +> [!NOTE] +> +> On Apple Silicon devices, Rosetta 2 may be required to run the binary. ``` ./authy-export-darwin-amd64 authy_codes.txt @@ -92,6 +94,7 @@ to ente Authenticator! ### Method 2.1: If the export worked, but the import didn't > [!NOTE] +> > This is intended only for users who successfully exported their codes using the > guide in method 2, but could not import it to ente Authenticator for whatever > reason. If the import was successful, or you haven't tried to import the codes From 324eeed1c5301efdf112932e05def6e29411b700 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Thu, 14 Mar 2024 15:53:26 +0530 Subject: [PATCH 04/30] [cli] Add admin list-user cmd --- cli/cmd/admin.go | 21 +++++++++++++++++++-- cli/internal/api/admin.go | 22 ++++++++++++++++++++++ cli/internal/api/models/user_details.go | 11 ++++++++--- cli/pkg/admin_actions.go | 20 ++++++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/cli/cmd/admin.go b/cli/cmd/admin.go index 0e41bbfe2..d46fcfbf7 100644 --- a/cli/cmd/admin.go +++ b/cli/cmd/admin.go @@ -52,9 +52,25 @@ var _disable2faCmd = &cobra.Command{ }, } +var _listUsers = &cobra.Command{ + Use: "list-users", + Short: "List all users", + RunE: func(cmd *cobra.Command, args []string) error { + recoverWithLog() + var flags = &model.AdminActionForUser{} + cmd.Flags().VisitAll(func(f *pflag.Flag) { + if f.Name == "admin-user" { + flags.AdminEmail = f.Value.String() + } + }) + return ctrl.ListUsers(context.Background(), *flags) + }, +} + var _updateFreeUserStorage = &cobra.Command{ Use: "update-subscription", - Short: "Update subscription for the free user", + Short: "Update subscription for user", + Long: "Update subscription for the free user. If you want to apply specific limits, use the `--no-limit False` flag", RunE: func(cmd *cobra.Command, args []string) error { recoverWithLog() var flags = &model.AdminActionForUser{} @@ -80,11 +96,12 @@ func init() { _ = _userDetailsCmd.MarkFlagRequired("user") _userDetailsCmd.Flags().StringP("admin-user", "a", "", "The email of the admin user. (required)") _userDetailsCmd.Flags().StringP("user", "u", "", "The email of the user to fetch details for. (required)") + _listUsers.Flags().StringP("admin-user", "a", "", "The email of the admin user. (required)") _disable2faCmd.Flags().StringP("admin-user", "a", "", "The email of the admin user. (required)") _disable2faCmd.Flags().StringP("user", "u", "", "The email of the user to disable 2FA for. (required)") _updateFreeUserStorage.Flags().StringP("admin-user", "a", "", "The email of the admin user. (required)") _updateFreeUserStorage.Flags().StringP("user", "u", "", "The email of the user to update subscription for. (required)") // add a flag with no value --no-limit _updateFreeUserStorage.Flags().String("no-limit", "True", "When true, sets 100TB as storage limit, and expiry to current date + 100 years") - _adminCmd.AddCommand(_userDetailsCmd, _disable2faCmd, _updateFreeUserStorage) + _adminCmd.AddCommand(_userDetailsCmd, _disable2faCmd, _updateFreeUserStorage, _listUsers) } diff --git a/cli/internal/api/admin.go b/cli/internal/api/admin.go index 1c0b2c50a..0f21e2d82 100644 --- a/cli/internal/api/admin.go +++ b/cli/internal/api/admin.go @@ -25,6 +25,28 @@ func (c *Client) GetUserIdFromEmail(ctx context.Context, email string) (*models. } return &res, nil } + +func (c *Client) ListUsers(ctx context.Context) ([]models.User, error) { + var res struct { + Users []models.User `json:"users"` + } + r, err := c.restClient.R(). + SetContext(ctx). + SetQueryParam("sinceTime", "0"). + SetResult(&res). + Get("/admin/users/") + if err != nil { + return nil, err + } + if r.IsError() { + return nil, &ApiError{ + StatusCode: r.StatusCode(), + Message: r.String(), + } + } + return res.Users, nil +} + func (c *Client) UpdateFreePlanSub(ctx context.Context, userDetails *models.UserDetails, storageInBytes int64, expiryTimeInMicro int64) error { var res interface{} if userDetails.Subscription.ProductID != "free" { diff --git a/cli/internal/api/models/user_details.go b/cli/internal/api/models/user_details.go index 259ff972b..6a5310d7d 100644 --- a/cli/internal/api/models/user_details.go +++ b/cli/internal/api/models/user_details.go @@ -1,9 +1,7 @@ package models type UserDetails struct { - User struct { - ID int64 `json:"id"` - } `json:"user"` + User User `json:"user"` Usage int64 `json:"usage"` Email string `json:"email"` @@ -14,3 +12,10 @@ type UserDetails struct { PaymentProvider string `json:"paymentProvider"` } `json:"subscription"` } + +type User struct { + ID int64 + Email string `json:"email"` + Hash string `json:"hash"` + CreationTime int64 `json:"creationTime"` +} diff --git a/cli/pkg/admin_actions.go b/cli/pkg/admin_actions.go index c9ec00667..a5d182973 100644 --- a/cli/pkg/admin_actions.go +++ b/cli/pkg/admin_actions.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/ente-io/cli/internal" + "github.com/ente-io/cli/internal/api" "github.com/ente-io/cli/pkg/model" "github.com/ente-io/cli/utils" "log" @@ -24,6 +25,25 @@ func (c *ClICtrl) GetUserId(ctx context.Context, params model.AdminActionForUser return nil } +func (c *ClICtrl) ListUsers(ctx context.Context, params model.AdminActionForUser) error { + accountCtx, err := c.buildAdminContext(ctx, params.AdminEmail) + if err != nil { + return err + } + users, err := c.Client.ListUsers(accountCtx) + if err != nil { + if apiErr, ok := err.(*api.ApiError); ok && apiErr.StatusCode == 400 && strings.Contains(apiErr.Message, "Token is too old") { + fmt.Printf("Old admin token, please re-authenticate using `ente account add` \n") + return nil + } + return err + } + for _, user := range users { + fmt.Printf("Email: %s, ID: %d, Created: %s\n", user.Email, user.ID, time.UnixMicro(user.CreationTime).Format("2006-01-02")) + } + return nil +} + func (c *ClICtrl) UpdateFreeStorage(ctx context.Context, params model.AdminActionForUser, noLimit bool) error { accountCtx, err := c.buildAdminContext(ctx, params.AdminEmail) if err != nil { From da3c6a78d46cb9cb373b313522ca2dee2e6d638d Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:01:40 +0530 Subject: [PATCH 05/30] [cli] Make it optional to pass adminUser when only one account is configured --- cli/cmd/admin.go | 8 ++++---- cli/pkg/admin_actions.go | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cli/cmd/admin.go b/cli/cmd/admin.go index d46fcfbf7..fd22bc739 100644 --- a/cli/cmd/admin.go +++ b/cli/cmd/admin.go @@ -94,12 +94,12 @@ func init() { rootCmd.AddCommand(_adminCmd) _ = _userDetailsCmd.MarkFlagRequired("admin-user") _ = _userDetailsCmd.MarkFlagRequired("user") - _userDetailsCmd.Flags().StringP("admin-user", "a", "", "The email of the admin user. (required)") + _userDetailsCmd.Flags().StringP("admin-user", "a", "", "The email of the admin user. ") _userDetailsCmd.Flags().StringP("user", "u", "", "The email of the user to fetch details for. (required)") - _listUsers.Flags().StringP("admin-user", "a", "", "The email of the admin user. (required)") - _disable2faCmd.Flags().StringP("admin-user", "a", "", "The email of the admin user. (required)") + _listUsers.Flags().StringP("admin-user", "a", "", "The email of the admin user. ") + _disable2faCmd.Flags().StringP("admin-user", "a", "", "The email of the admin user. ") _disable2faCmd.Flags().StringP("user", "u", "", "The email of the user to disable 2FA for. (required)") - _updateFreeUserStorage.Flags().StringP("admin-user", "a", "", "The email of the admin user. (required)") + _updateFreeUserStorage.Flags().StringP("admin-user", "a", "", "The email of the admin user.") _updateFreeUserStorage.Flags().StringP("user", "u", "", "The email of the user to update subscription for. (required)") // add a flag with no value --no-limit _updateFreeUserStorage.Flags().String("no-limit", "True", "When true, sets 100TB as storage limit, and expiry to current date + 100 years") diff --git a/cli/pkg/admin_actions.go b/cli/pkg/admin_actions.go index a5d182973..7b9927c6a 100644 --- a/cli/pkg/admin_actions.go +++ b/cli/pkg/admin_actions.go @@ -102,6 +102,9 @@ func (c *ClICtrl) buildAdminContext(ctx context.Context, adminEmail string) (con if err != nil { return nil, err } + if len(accounts) == 0 { + return nil, fmt.Errorf("no accounts found, use `account add` to add an account") + } var acc *model.Account for _, a := range accounts { if a.Email == adminEmail { @@ -109,6 +112,14 @@ func (c *ClICtrl) buildAdminContext(ctx context.Context, adminEmail string) (con break } } + if (len(accounts) > 1) && (acc == nil) { + return nil, fmt.Errorf("multiple accounts found, specify the admin email using --admin-user") + } + if acc == nil && len(accounts) == 1 { + acc = &accounts[0] + fmt.Printf("Assuming %s as the Admin \n------------\n", acc.Email) + } + if acc == nil { return nil, fmt.Errorf("account not found for %s, use `account list` to list accounts", adminEmail) } From 6af62d87278666dc7ca6f12837b25658a4be7ce3 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:13:11 +0530 Subject: [PATCH 06/30] [cli] Add admin disable-2fa cmd --- cli/cmd/admin.go | 13 +++++++++++-- cli/internal/api/admin.go | 23 +++++++++++++++++++++++ cli/pkg/admin_actions.go | 23 ++++++++++++++++++++++- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/cli/cmd/admin.go b/cli/cmd/admin.go index fd22bc739..3a54b13ac 100644 --- a/cli/cmd/admin.go +++ b/cli/cmd/admin.go @@ -29,6 +29,9 @@ var _userDetailsCmd = &cobra.Command{ flags.UserEmail = f.Value.String() } }) + if flags.UserEmail == "" { + return fmt.Errorf("user email is required") + } return ctrl.GetUserId(context.Background(), *flags) }, } @@ -47,8 +50,11 @@ var _disable2faCmd = &cobra.Command{ flags.UserEmail = f.Value.String() } }) - fmt.Println("Not supported yet") - return nil + if flags.UserEmail == "" { + return fmt.Errorf("user email is required") + } + return ctrl.Disable2FA(context.Background(), *flags) + }, } @@ -86,6 +92,9 @@ var _updateFreeUserStorage = &cobra.Command{ noLimit = strings.ToLower(f.Value.String()) == "true" } }) + if flags.UserEmail == "" { + return fmt.Errorf("user email is required") + } return ctrl.UpdateFreeStorage(context.Background(), *flags, noLimit) }, } diff --git a/cli/internal/api/admin.go b/cli/internal/api/admin.go index 0f21e2d82..c2b948111 100644 --- a/cli/internal/api/admin.go +++ b/cli/internal/api/admin.go @@ -47,6 +47,29 @@ func (c *Client) ListUsers(ctx context.Context) ([]models.User, error) { return res.Users, nil } +func (c *Client) Disable2Fa(ctx context.Context, userID int64) error { + var res interface{} + + payload := map[string]interface{}{ + "userID": userID, + } + r, err := c.restClient.R(). + SetContext(ctx). + SetResult(&res). + SetBody(payload). + Post("/admin/user/disable-2fa") + if err != nil { + return err + } + if r.IsError() { + return &ApiError{ + StatusCode: r.StatusCode(), + Message: r.String(), + } + } + return nil +} + func (c *Client) UpdateFreePlanSub(ctx context.Context, userDetails *models.UserDetails, storageInBytes int64, expiryTimeInMicro int64) error { var res interface{} if userDetails.Subscription.ProductID != "free" { diff --git a/cli/pkg/admin_actions.go b/cli/pkg/admin_actions.go index 7b9927c6a..a7a060f66 100644 --- a/cli/pkg/admin_actions.go +++ b/cli/pkg/admin_actions.go @@ -33,7 +33,7 @@ func (c *ClICtrl) ListUsers(ctx context.Context, params model.AdminActionForUser users, err := c.Client.ListUsers(accountCtx) if err != nil { if apiErr, ok := err.(*api.ApiError); ok && apiErr.StatusCode == 400 && strings.Contains(apiErr.Message, "Token is too old") { - fmt.Printf("Old admin token, please re-authenticate using `ente account add` \n") + fmt.Printf("Error: old admin token, please re-authenticate using `ente account add` \n") return nil } return err @@ -44,6 +44,27 @@ func (c *ClICtrl) ListUsers(ctx context.Context, params model.AdminActionForUser return nil } +func (c *ClICtrl) Disable2FA(ctx context.Context, params model.AdminActionForUser) error { + accountCtx, err := c.buildAdminContext(ctx, params.AdminEmail) + if err != nil { + return err + } + userDetails, err := c.Client.GetUserIdFromEmail(accountCtx, params.UserEmail) + if err != nil { + return err + } + err = c.Client.Disable2Fa(accountCtx, userDetails.User.ID) + if err != nil { + if apiErr, ok := err.(*api.ApiError); ok && apiErr.StatusCode == 400 && strings.Contains(apiErr.Message, "Token is too old") { + fmt.Printf("Error: Old admin token, please re-authenticate using `ente account add` \n") + return nil + } + return err + } + fmt.Println("Successfully disabled 2FA for user") + return nil +} + func (c *ClICtrl) UpdateFreeStorage(ctx context.Context, params model.AdminActionForUser, noLimit bool) error { accountCtx, err := c.buildAdminContext(ctx, params.AdminEmail) if err != nil { From bc47368a01b5253c69b4bfc55aa0490e9bb32c90 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:18:08 +0530 Subject: [PATCH 07/30] [cli] Add API to delete-user --- cli/cmd/admin.go | 26 +++++++++++++++++++++++++- cli/internal/api/admin.go | 18 ++++++++++++++++++ cli/pkg/admin_actions.go | 17 +++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/cli/cmd/admin.go b/cli/cmd/admin.go index 3a54b13ac..8a2d7f006 100644 --- a/cli/cmd/admin.go +++ b/cli/cmd/admin.go @@ -58,6 +58,28 @@ var _disable2faCmd = &cobra.Command{ }, } +var _deleteUser = &cobra.Command{ + Use: "delete-user", + Short: "Delete a user", + RunE: func(cmd *cobra.Command, args []string) error { + recoverWithLog() + var flags = &model.AdminActionForUser{} + cmd.Flags().VisitAll(func(f *pflag.Flag) { + if f.Name == "admin-user" { + flags.AdminEmail = f.Value.String() + } + if f.Name == "user" { + flags.UserEmail = f.Value.String() + } + }) + if flags.UserEmail == "" { + return fmt.Errorf("user email is required") + } + return ctrl.DeleteUser(context.Background(), *flags) + + }, +} + var _listUsers = &cobra.Command{ Use: "list-users", Short: "List all users", @@ -108,9 +130,11 @@ func init() { _listUsers.Flags().StringP("admin-user", "a", "", "The email of the admin user. ") _disable2faCmd.Flags().StringP("admin-user", "a", "", "The email of the admin user. ") _disable2faCmd.Flags().StringP("user", "u", "", "The email of the user to disable 2FA for. (required)") + _deleteUser.Flags().StringP("admin-user", "a", "", "The email of the admin user. ") + _deleteUser.Flags().StringP("user", "u", "", "The email of the user to delete. (required)") _updateFreeUserStorage.Flags().StringP("admin-user", "a", "", "The email of the admin user.") _updateFreeUserStorage.Flags().StringP("user", "u", "", "The email of the user to update subscription for. (required)") // add a flag with no value --no-limit _updateFreeUserStorage.Flags().String("no-limit", "True", "When true, sets 100TB as storage limit, and expiry to current date + 100 years") - _adminCmd.AddCommand(_userDetailsCmd, _disable2faCmd, _updateFreeUserStorage, _listUsers) + _adminCmd.AddCommand(_userDetailsCmd, _disable2faCmd, _updateFreeUserStorage, _listUsers, _deleteUser) } diff --git a/cli/internal/api/admin.go b/cli/internal/api/admin.go index c2b948111..9e0bcb90a 100644 --- a/cli/internal/api/admin.go +++ b/cli/internal/api/admin.go @@ -47,6 +47,24 @@ func (c *Client) ListUsers(ctx context.Context) ([]models.User, error) { return res.Users, nil } +func (c *Client) DeleteUser(ctx context.Context, email string) error { + + r, err := c.restClient.R(). + SetContext(ctx). + SetQueryParam("email", email). + Delete("/admin/user/delete") + if err != nil { + return err + } + if r.IsError() { + return &ApiError{ + StatusCode: r.StatusCode(), + Message: r.String(), + } + } + return nil +} + func (c *Client) Disable2Fa(ctx context.Context, userID int64) error { var res interface{} diff --git a/cli/pkg/admin_actions.go b/cli/pkg/admin_actions.go index a7a060f66..0105cdc19 100644 --- a/cli/pkg/admin_actions.go +++ b/cli/pkg/admin_actions.go @@ -44,6 +44,23 @@ func (c *ClICtrl) ListUsers(ctx context.Context, params model.AdminActionForUser return nil } +func (c *ClICtrl) DeleteUser(ctx context.Context, params model.AdminActionForUser) error { + accountCtx, err := c.buildAdminContext(ctx, params.AdminEmail) + if err != nil { + return err + } + err = c.Client.DeleteUser(accountCtx, params.UserEmail) + if err != nil { + if apiErr, ok := err.(*api.ApiError); ok && apiErr.StatusCode == 400 && strings.Contains(apiErr.Message, "Token is too old") { + fmt.Printf("Error: old admin token, please re-authenticate using `ente account add` \n") + return nil + } + return err + } + fmt.Println("Successfully deleted user") + return nil +} + func (c *ClICtrl) Disable2FA(ctx context.Context, params model.AdminActionForUser) error { accountCtx, err := c.buildAdminContext(ctx, params.AdminEmail) if err != nil { From 9c04c8fbe654e2b2dd6d03af81bd9bd6e7a8798c Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:18:37 +0530 Subject: [PATCH 08/30] [cli] Generate docs --- cli/docs/generated/ente.md | 2 +- cli/docs/generated/ente_account.md | 2 +- cli/docs/generated/ente_account_add.md | 2 +- cli/docs/generated/ente_account_get-token.md | 2 +- cli/docs/generated/ente_account_list.md | 2 +- cli/docs/generated/ente_account_update.md | 2 +- cli/docs/generated/ente_admin.md | 6 ++++-- cli/docs/generated/ente_admin_delete-user.md | 21 +++++++++++++++++++ cli/docs/generated/ente_admin_disable-2fa.md | 4 ++-- cli/docs/generated/ente_admin_get-user-id.md | 4 ++-- cli/docs/generated/ente_admin_list-users.md | 20 ++++++++++++++++++ .../ente_admin_update-subscription.md | 10 ++++++--- cli/docs/generated/ente_auth.md | 2 +- cli/docs/generated/ente_auth_decrypt.md | 2 +- cli/docs/generated/ente_export.md | 2 +- cli/docs/generated/ente_version.md | 2 +- 16 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 cli/docs/generated/ente_admin_delete-user.md create mode 100644 cli/docs/generated/ente_admin_list-users.md diff --git a/cli/docs/generated/ente.md b/cli/docs/generated/ente.md index 6d0263ce4..b9d3cde17 100644 --- a/cli/docs/generated/ente.md +++ b/cli/docs/generated/ente.md @@ -25,4 +25,4 @@ ente [flags] * [ente export](ente_export.md) - Starts the export process * [ente version](ente_version.md) - Prints the current version -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_account.md b/cli/docs/generated/ente_account.md index ec26f9557..c48a65336 100644 --- a/cli/docs/generated/ente_account.md +++ b/cli/docs/generated/ente_account.md @@ -16,4 +16,4 @@ Manage account settings * [ente account list](ente_account_list.md) - list configured accounts * [ente account update](ente_account_update.md) - Update an existing account's export directory -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_account_add.md b/cli/docs/generated/ente_account_add.md index 74b2c23f9..1904ca370 100644 --- a/cli/docs/generated/ente_account_add.md +++ b/cli/docs/generated/ente_account_add.md @@ -16,4 +16,4 @@ ente account add [flags] * [ente account](ente_account.md) - Manage account settings -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_account_get-token.md b/cli/docs/generated/ente_account_get-token.md index 58ef3e7cd..d7ee77255 100644 --- a/cli/docs/generated/ente_account_get-token.md +++ b/cli/docs/generated/ente_account_get-token.md @@ -18,4 +18,4 @@ ente account get-token [flags] * [ente account](ente_account.md) - Manage account settings -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_account_list.md b/cli/docs/generated/ente_account_list.md index 3fc6fbc2e..cfc59bb8d 100644 --- a/cli/docs/generated/ente_account_list.md +++ b/cli/docs/generated/ente_account_list.md @@ -16,4 +16,4 @@ ente account list [flags] * [ente account](ente_account.md) - Manage account settings -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_account_update.md b/cli/docs/generated/ente_account_update.md index 04c4418e7..acb65412a 100644 --- a/cli/docs/generated/ente_account_update.md +++ b/cli/docs/generated/ente_account_update.md @@ -19,4 +19,4 @@ ente account update [flags] * [ente account](ente_account.md) - Manage account settings -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_admin.md b/cli/docs/generated/ente_admin.md index 91e70324d..aafe51b39 100644 --- a/cli/docs/generated/ente_admin.md +++ b/cli/docs/generated/ente_admin.md @@ -15,8 +15,10 @@ Commands for admin actions like disable or enabling 2fa, bumping up the storage ### SEE ALSO * [ente](ente.md) - CLI tool for exporting your photos from ente.io +* [ente admin delete-user](ente_admin_delete-user.md) - Delete a user * [ente admin disable-2fa](ente_admin_disable-2fa.md) - Disable 2fa for a user * [ente admin get-user-id](ente_admin_get-user-id.md) - Get user id -* [ente admin update-subscription](ente_admin_update-subscription.md) - Update subscription for the free user +* [ente admin list-users](ente_admin_list-users.md) - List all users +* [ente admin update-subscription](ente_admin_update-subscription.md) - Update subscription for user -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_admin_delete-user.md b/cli/docs/generated/ente_admin_delete-user.md new file mode 100644 index 000000000..56c96841e --- /dev/null +++ b/cli/docs/generated/ente_admin_delete-user.md @@ -0,0 +1,21 @@ +## ente admin delete-user + +Delete a user + +``` +ente admin delete-user [flags] +``` + +### Options + +``` + -a, --admin-user string The email of the admin user. + -h, --help help for delete-user + -u, --user string The email of the user to delete. (required) +``` + +### SEE ALSO + +* [ente admin](ente_admin.md) - Commands for admin actions + +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_admin_disable-2fa.md b/cli/docs/generated/ente_admin_disable-2fa.md index 19183fdfe..333f0912e 100644 --- a/cli/docs/generated/ente_admin_disable-2fa.md +++ b/cli/docs/generated/ente_admin_disable-2fa.md @@ -9,7 +9,7 @@ ente admin disable-2fa [flags] ### Options ``` - -a, --admin-user string The email of the admin user. (required) + -a, --admin-user string The email of the admin user. -h, --help help for disable-2fa -u, --user string The email of the user to disable 2FA for. (required) ``` @@ -18,4 +18,4 @@ ente admin disable-2fa [flags] * [ente admin](ente_admin.md) - Commands for admin actions -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_admin_get-user-id.md b/cli/docs/generated/ente_admin_get-user-id.md index 0151a3ec8..3d26f624a 100644 --- a/cli/docs/generated/ente_admin_get-user-id.md +++ b/cli/docs/generated/ente_admin_get-user-id.md @@ -9,7 +9,7 @@ ente admin get-user-id [flags] ### Options ``` - -a, --admin-user string The email of the admin user. (required) + -a, --admin-user string The email of the admin user. -h, --help help for get-user-id -u, --user string The email of the user to fetch details for. (required) ``` @@ -18,4 +18,4 @@ ente admin get-user-id [flags] * [ente admin](ente_admin.md) - Commands for admin actions -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_admin_list-users.md b/cli/docs/generated/ente_admin_list-users.md new file mode 100644 index 000000000..8841df57b --- /dev/null +++ b/cli/docs/generated/ente_admin_list-users.md @@ -0,0 +1,20 @@ +## ente admin list-users + +List all users + +``` +ente admin list-users [flags] +``` + +### Options + +``` + -a, --admin-user string The email of the admin user. + -h, --help help for list-users +``` + +### SEE ALSO + +* [ente admin](ente_admin.md) - Commands for admin actions + +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_admin_update-subscription.md b/cli/docs/generated/ente_admin_update-subscription.md index 30339acf2..cc1fa9623 100644 --- a/cli/docs/generated/ente_admin_update-subscription.md +++ b/cli/docs/generated/ente_admin_update-subscription.md @@ -1,6 +1,10 @@ ## ente admin update-subscription -Update subscription for the free user +Update subscription for user + +### Synopsis + +Update subscription for the free user. If you want to apply specific limits, use the `--no-limit False` flag ``` ente admin update-subscription [flags] @@ -9,7 +13,7 @@ ente admin update-subscription [flags] ### Options ``` - -a, --admin-user string The email of the admin user. (required) + -a, --admin-user string The email of the admin user. -h, --help help for update-subscription --no-limit string When true, sets 100TB as storage limit, and expiry to current date + 100 years (default "True") -u, --user string The email of the user to update subscription for. (required) @@ -19,4 +23,4 @@ ente admin update-subscription [flags] * [ente admin](ente_admin.md) - Commands for admin actions -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_auth.md b/cli/docs/generated/ente_auth.md index 4a64a944d..5770f36f3 100644 --- a/cli/docs/generated/ente_auth.md +++ b/cli/docs/generated/ente_auth.md @@ -13,4 +13,4 @@ Authenticator commands * [ente](ente.md) - CLI tool for exporting your photos from ente.io * [ente auth decrypt](ente_auth_decrypt.md) - Decrypt authenticator export -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_auth_decrypt.md b/cli/docs/generated/ente_auth_decrypt.md index 1203319e9..e573db2a3 100644 --- a/cli/docs/generated/ente_auth_decrypt.md +++ b/cli/docs/generated/ente_auth_decrypt.md @@ -16,4 +16,4 @@ ente auth decrypt [input] [output] [flags] * [ente auth](ente_auth.md) - Authenticator commands -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_export.md b/cli/docs/generated/ente_export.md index fb4cc6541..c5783236c 100644 --- a/cli/docs/generated/ente_export.md +++ b/cli/docs/generated/ente_export.md @@ -16,4 +16,4 @@ ente export [flags] * [ente](ente.md) - CLI tool for exporting your photos from ente.io -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 diff --git a/cli/docs/generated/ente_version.md b/cli/docs/generated/ente_version.md index 0254e2ebd..b51055697 100644 --- a/cli/docs/generated/ente_version.md +++ b/cli/docs/generated/ente_version.md @@ -16,4 +16,4 @@ ente version [flags] * [ente](ente.md) - CLI tool for exporting your photos from ente.io -###### Auto generated by spf13/cobra on 13-Mar-2024 +###### Auto generated by spf13/cobra on 14-Mar-2024 From 80498340b6fd163c1137c9762d5e77fd0c3e5b31 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:20:47 +0530 Subject: [PATCH 09/30] [cli] Mark docs/generated as generated for Github --- cli/.gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 cli/.gitattributes diff --git a/cli/.gitattributes b/cli/.gitattributes new file mode 100644 index 000000000..71965b858 --- /dev/null +++ b/cli/.gitattributes @@ -0,0 +1 @@ +docs/generated/*.md linguist-generated=true From b9a7d0926539f533c506c570ff22fdd0b356735e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:23:51 +0530 Subject: [PATCH 10/30] [auth] New translations (#1093) New translations from [Crowdin](https://crowdin.com/project/ente-authenticator-app) Co-authored-by: Crowdin Bot --- auth/lib/l10n/arb/app_de.arb | 1 - auth/lib/l10n/arb/app_ja.arb | 3 ++- auth/lib/l10n/arb/app_pt.arb | 1 - auth/lib/l10n/arb/app_zh.arb | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/auth/lib/l10n/arb/app_de.arb b/auth/lib/l10n/arb/app_de.arb index a05c7ca0d..32507899c 100644 --- a/auth/lib/l10n/arb/app_de.arb +++ b/auth/lib/l10n/arb/app_de.arb @@ -407,7 +407,6 @@ "hearUsWhereTitle": "Wie hast du von Ente erfahren? (optional)", "hearUsExplanation": "Wir tracken keine App-Installationen. Es würde uns jedoch helfen, wenn du uns mitteilst, wie du von uns erfahren hast!", "waitingForBrowserRequest": "Warten auf Browseranfrage...", - "launchPasskeyUrlAgain": "Passwort-URL erneut starten", "passkey": "Passkey", "developerSettingsWarning": "Sind Sie sicher, dass Sie die Entwicklereinstellungen ändern möchten?", "developerSettings": "Entwicklereinstellungen", diff --git a/auth/lib/l10n/arb/app_ja.arb b/auth/lib/l10n/arb/app_ja.arb index ed1786f71..5b281747f 100644 --- a/auth/lib/l10n/arb/app_ja.arb +++ b/auth/lib/l10n/arb/app_ja.arb @@ -145,6 +145,7 @@ "lostDeviceTitle": "デバイスを紛失しましたか?", "twoFactorAuthTitle": "2 要素認証", "passkeyAuthTitle": "パスキー認証", + "verifyPasskey": "パスキーの認証", "recoverAccount": "アカウントを回復", "enterRecoveryKeyHint": "回復キーを入力", "recover": "回復", @@ -407,7 +408,7 @@ "hearUsWhereTitle": "Ente についてどのようにお聞きになりましたか?(任意)", "hearUsExplanation": "私たちはアプリのインストールを追跡していません。私たちをお知りになった場所を教えてください!", "waitingForBrowserRequest": "ブラウザのリクエストを待っています...", - "launchPasskeyUrlAgain": "パスキーのURLを再度起動する", + "waitingForVerification": "認証を待っています...", "passkey": "パスキー", "developerSettingsWarning": "開発者向け設定を変更してもよろしいですか?", "developerSettings": "開発者向け設定", diff --git a/auth/lib/l10n/arb/app_pt.arb b/auth/lib/l10n/arb/app_pt.arb index 10c34ab29..aa6a2a837 100644 --- a/auth/lib/l10n/arb/app_pt.arb +++ b/auth/lib/l10n/arb/app_pt.arb @@ -407,7 +407,6 @@ "hearUsWhereTitle": "Como você ouviu sobre o Ente? (opcional)", "hearUsExplanation": "Não rastreamos instalações do aplicativo. Seria útil se você nos contasse onde nos encontrou!", "waitingForBrowserRequest": "Aguardando solicitação do navegador...", - "launchPasskeyUrlAgain": "Iniciar a URL de chave de acesso novamente", "passkey": "Chave de acesso", "developerSettingsWarning": "Tem certeza de que deseja modificar as configurações de Desenvolvedor?", "developerSettings": "Configurações de desenvolvedor", diff --git a/auth/lib/l10n/arb/app_zh.arb b/auth/lib/l10n/arb/app_zh.arb index b6d4ed244..e07e7dcfa 100644 --- a/auth/lib/l10n/arb/app_zh.arb +++ b/auth/lib/l10n/arb/app_zh.arb @@ -407,7 +407,6 @@ "hearUsWhereTitle": "您是如何知道Ente的? (可选的)", "hearUsExplanation": "我们不跟踪应用程序安装情况。如果您告诉我们您是在哪里找到我们的,将会有所帮助!", "waitingForBrowserRequest": "正在等待浏览器请求...", - "launchPasskeyUrlAgain": "再次启动 通行密钥 URL", "passkey": "通行密钥", "developerSettingsWarning": "您确定要修改开发者设置吗?", "developerSettings": "开发者设置", From 2905315e0077e1a467b360e03eee97235e4a0542 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 16:23:53 +0530 Subject: [PATCH 11/30] [server] Improve the architecture diagram Add a dotted arrow between museum and the hot object storage to indicate that clients talk directly to the primary S3 storage. This has confused some users who were trying to setup self-hosting, them not realizing that the minio buckets need to be accessible outside the container. The actual flow is - for both GET and PUT, museum conjures up pre-signed URLs by talking to the S3 bucket, and vends these pre-signed URLs back to the client. Thereafter though (unless routed via a Cloudflare worker, which is not the case when self-hosting), the clients directly connect to this presigned URL. Maybe too much information to convey with a single dotted arrow, but at least it'll give a hint that there is a direct connection there somewhere. --- server/scripts/images/museum.png | Bin 104994 -> 166243 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/scripts/images/museum.png b/server/scripts/images/museum.png index a93370da8a8e620bbd2ad6d21b1caa9e4a016388..bd837dc369507f1a083ffd4926ff5aae1ca9d35c 100644 GIT binary patch literal 166243 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

p9?9Eg(^ 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 literal 104994 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

)dQy;6CZn3NSbEW;w z8|NFA)~4r%>ef7k+V$)RODg{QYm0pdbpAMzP}{mF&`9uUGwj=i9MbNP{2l*W;A(F2 zh?o?4t@v5k$``FQA*z>u=AFNU{PGrYEnYS??`ku8G95-6BWICT5g8gK+TPU#NzQkE zr(Lq)lA#oT0#dc#;~no>SAl)q>Z1c05-S728<3e|t+u?Qws)aBwSx|SKs5IKPEEl@ z*j{%0Xw#gj6qNl`H&4c&WhaR|-DaNi02)(@519Lo&D#7`5{G!csrNUE57Wx_oji_S zT}V!!$iuHvB~}JGjLz%Os0)jp$j*%~w-c2dRuNgZLr`W~BZB|F8QhgkMMcGAg&0h- zBuV7O)W9wb4;Sryi`^XX^T8@$QL1A{!%X#Dt*E>w?7*1%Z%E;D2KV%M@@@&3|MXW_ z=0>vS!e);b(RhkkO-u4BF&$yfKg(F(>6!($Dqgwv}1K5bWz6s}qn zP14HBkx9;bkw?N;oARv6UeV++<*Ghnzk!P1=@DG$bGoQ|=`Pc(#yoQjZS7FgEAqM9 z#12DLTKPA7rSR3}XG<4?M1Qx@=xw-MpoH>x*4GtS?uivkUp;MKecJ}ynuMZtdGzHf znWedy zsY@w6dtJH4gzTGXt@j&QcN10vYRHeA^?1~k&wl&?)P2i2^6v!~3z?V*yF(klM!Coa zfQ^rjFLEE;{aZlUF&0SFfZO;3)PQK&Z^=!xhU*i^Mj>;*Vc42hwj0D#DSlGFIe)Yw zyC{dMC;kRCob5vVtzD13e=GlS zXW{xVskk<--}sbpYe3}x1&{%j{(r$BjsT(SufoM%k;VA0qrYQ_nn@s~Jq=bmzhQ1R z7obI43(9`$QhZU6Oik|pBJ>+=1INVx^(7o1{u?b4^1lEwQ&0b|W3U;4DJp*_^8bte zva_#UNIbJHCO?JMXq^`|f}NYcw7lD&SnBIKt#X99wQ&jqtj=rNss||P1D8CyjGmh! z`OM#*=z>tRvNa=9i68sp`>+A-QcU;oF|F|;TjykZ0?UGv#N^RvK@`5V^a$b?vL6Sr zrNO*0o%k4UX~YM^N1ef!nHe|v-ehW9nzI2s7mRY~R;nfreq&~hc=OY@mF~>GOSE@u zeYwh&@*erukJDj@C>W7p60|0I%fA7*hR6@M&WC-H+^+z`|gY| z!*-1U+h#G1^TAwpyJ!XmKVN`#qmebQAQZX18BJRjnY{)V1^$Iw_ERYEHF5kH2M%Ij zcPK^f64Q&l20jy^_}-WzKrgp|g(*Dww&K4Y5D&P(?PW|gNTPrPOgV^8bp93F#Q@uV zCi`i70Je8Q(%6Vk{+&81^!3Kl$UoMz6Q3Oa*Zo_;h11OS*MK=Oz5~x>MgA0McjO9Y zsynX$Zu!*Fq6!vl-EABMPkzEiy6~2%6TiM@)vEApz)zoFBv1FSbSub}~H z1L!y3K=~r7gS_8zf~i+wkrwj$@?*-h;W~oK#hV>}R^L~~b}^-ZMO@9r{+OFY-(f2d z1!5vOiSnh>eF2*DN=G&^p>p$fKx9V)XGw62IBQ%U#@Dt^n=133sc!;r1J`(Qyoi24 z3@1@LW16~TIj_`V$m{@haKMOx3mhDvW&ww5AN=ky>-b?iQ?V=r`(M>A0%*Z}XJ>2E zJoVl_{kA!?EHgXcbOOly{S-4gPrMFc2`ZoWc-r{s!aw)@^#qQ@L{MVOAJVt$m7Hx_^V6n% z@JGtH_Fg=0EYTMWEmEJ7Ze(u4PRj$w@agBfU^l1a8W{4DHgal)omgmg#u%0rx4=|S zJG1XmZ8K2Ef^+2s`J0=}51t}4jf}W3p$XjX6$sZ}g{RQZDGCXxelpKB9`D)C4ZvpT zYaZOn-^wSi1ptT3u(1&vV$K>9veP>mt_5rU5``vi;cr%akq}DxQ0nrS36_Za8HBg=m&$tQXf=BVeH1KyM zc{oQ4k39+2K|b+qk!5xQ2>7dC-y7uvC+y|q9F@Us4bV5XwL9x`m*M`vgaBtnF z@z9~-H*cdubpk*YVWQf27q^OEMX%T*R9`x81%F_WR%-SJp~+C}*7jeil^y*2&8i{Y zul6P_4+K%(;pfnJdD-}BX7W(WmdX}!)`cDl7XsutE{wPK$e{OS%$R6LF!Q><>;~HJ zczqdw$4MU!C-7ehj~8e!DGez96;k{Y%%A-HtxcE_6TqbH0{qQgXD5Ch38lDqc4Yi> z?fR1%6tFHdpGvy*x&;J}H_Q*Gu7l*b=fuev3vj!Qth;ENEY1Mz)@T9A4kVT%b8yvt zq$3(kMC0HA$yAAs*#vNP9=i79EY@w{9@jj7T9=vdQ2~>Z-^>XEPJ2p6^RsTO3LA-* zQFxXydf|9r^k}*G7D35;JHR!e7|rfVTy@y-BYT*^1W+sSW;PnYWXR1q8s9!?ZW&5J zb@VwgwkbGUh$wAGZVNcyP92h$U^Mn^MAc-{jcuIs7%*hXw9c!E_0~X?0muwcz4d_I zUgWczE%Lw&%7StRV#;8mY&$8<^cb4KYC8ATtN_9+^A^!%-4&qOb!*b$J(3v+P7`HD z2dw*az_HkMvzZs1p$N`E^PUpJ;Huj{kBTq`3ivl50a)=w7J!g{3J%AIzo+v6i8st8 zlF2=?^+B3+cR-0W9H$9@nr?qZjN%+WmG@wk9vA-eB{-I?b3D>i-`2d*7l54sR4;U6 zz3?5}YROu|GoQuQS2L3+Cie+}3j!4E-CCp*0#^jAStS=N5C#P?bkI_u4pQJlGZ#Zt z^GhB~0ml5q!F1pVOVSVI$P(sn&nt&aGmB)#fnz*TR(6jCBMwx3u+_@jTM8L}sAh(! zdjZ7E2=ikr0N@I+J~8=<$Kl4d2GYc^f1+Uh$!QrN$-n%h{P$H&@B&CE3jxeE%({N3_)8)@!>dY`xOx5t|DRWTEpU~mWWLr=PpnFC}&x!nZ#+e^|+C?^?^ z1uQ}e^S6@AD79xoYA}G38}23;$A#dk^Fv2BGrTe<|27bAU@-w;Ka89t4g`{Jg5ZRl z%al`0PS^rY$n32(2&riYCuC+OSY&_`n%|Dn<(dK86K#Mdr(!|#5L+#{!q9G;5>vP_ zq4V>YD&rS?E`S$?$9I78k}@Ei<6du_Zve4xc~XNJ?GHQ`O&}sO2JSU%oRiX$IKrvg zxnds9@je?J8e_)oY0HW=8b7vvF8-iiB=>vZxpeA7>0$``Vq_D3?$c! zeAJ;8@>!kK<5OH)on~ey%XjA&7n=niy*|ZL5$d>;jgx4J<6))Q2;Dbcsm7)fhnviH z(Pmx{KL`dVURa$A#-Q zvqI{DqxZ|r1TkV3D{{7W3t6#JBjA|+8eFKmuAuv}S=EDJyB0F6V#OafQ*?w$rDdOG z4Wc#HTB1q{ZU?xTM@9;V&0l@e#0#O+L6chB(*55K1nx zqxAGwzt5O|3nkd zSSARvBH88(j>Dl8%P~(aSg}#Y>K*7$`@m#EJ(Y7VISaD7O?TjX`Dovmp1&ehB8%ro z@fj3KEw@x9QZLxEGThR3?Tk-BOf8ez)f7;EB`IfuPKLlYK#-fIq?Q`Lk*iD}B$e!Z zs23upTsu@UX>{E!A3YZF=7Q3@>slU7g^fc`sjDN=(8WBH@?rd`vAc-Pxp(cTbArnX zkH{@oZ!CMd-&jehpRW^Y@gqu$3k;0NPe)-#s(+F%OAOU3PuX8Zi=TTf;8t5qc(wK| zI`1yB`scF>lY2eO)?XIOpkSp6qhG(HM zSZrOv0b--&7YnQ%m8S#MD!dDwq$4q-w=Zc%d2HnZ_QQR0_nE57;L`%tBc73pR6Mff z2JHLF>|Hk>q0l!`?zFKPgOYLQ!;H0~@r#-hPx@Qw5zb*LNuQk>wUcvmQ}5lvqzcd@ z_?>9~r66L-_>j|=S6ISzY>hUm1X|45Yx`2XsY;9UV+r4xC8?vd$`7sc>MTulKYR4h z^Tp<~63>DY{6{{PEkCVVRIDv~v?cH$PF3e7q+5weKaSNyC&pwLVE>TAgzMmv*g-bvoLFi^kATVZkVH$DJg6c)3H671D>lv^u*Ws)?$v zY?4z7)^56mwbMojG}g^=_S^fd$XVW4D0q#$ru0rLCKNrJt79yYCv}~W)ljN%l(uBO zM1?(UeUyA=EE8eM+fX*FxapX3a6?d&EcXv-YI@mlqPb&q-IulMYw8)QDb) z`1&8W+Fo~`{fP0uF_dm2eq(X2Vy2)!xX%u@I?_hi{-p+MyqcDUCyCQQ(|h5tqUfZr zdo`M^h6)X^v4J$PdY!6{eFjTDMoFn*^CvQkfr=SR> z_?4EI{Q*B_VR(_QAA}(EaN>2J5onVg!F^Y_;4*5? z=9&!pV7FekIIYQ&IQ3)Zhk0<*SM+nrTlln|)k3@D?XLT|M-OWCPC0_Wr>kp}fujL# zVz&&5sj#gs)7&DNFNxXNOm;pwe==GrOiO&o@{1LkLTpS?n$U^_$JD>WFD3IHT{yVY zS^=6=_i(A;!x38=io_m*<%`KekLF&Ql{nQs@?=`ceibKwb+Ar^WA|ySF)hpV4vJtq zU44KeNRH@PY>92dZk~QZUHX*AOXb(0ASJ|!ij-|MQ3<2_fj-VFEt<6=TfC?(=~_u@ zc)^3YZEic&}LQs!)tvDyxd1TTi$rx7@q5!6*z6w`#oUg#C4m`+DFHB zqVN{%Lu<2&9H)A)Hq<56jZ?>|p6+rS64+9e+`CjmQ71aYM65hyzNKd-EF}ykLCZ>X z`w6Z6vNG30OreR286{BPtCEZFXnp{;O&y0-(l(CBY_i-uE{`OP7-0$+XPkli?%Jj@ zUn`2JEG#PWT>y<@FRI=L0^MVA54ck5KRK(t2gQ^}7Fvna{#~J@omcfrkuQSeyhNvl z4wLKgz7qDIvRLnv6;Z;2z^+Huifp>vi4yNROx}jbtIwNJd-!lW$vQW`fU&PpqXU6a zdzxBXQuNlsI=G}6;3QPy$K*W8W*6YSX4R)Juu)`Z6|1YN z#oEc{H6P=*-jOC60ncXk19r^82wxOaJ@3DI?sAZlBjae91rxopx5|i>6_O)(XL}{c zLTtNc{f&EimM1T5D_`Fv1U=VJBBmL+HKLx;V?&04oe>awZTZSef=-1s{sUI7-egiD zJe}?GFedIS`g>=N>rlCeH0t4Z<9k&(wvaA!e29mWo2<1hP2{JcXveCt7RABtHA6e3 z24YO~g9l_T{(Wa8Av(ahALe{7;&?)r5JNE{gYC1dnSUHoCJd%HmnI8mQ*--Z!3^W{KBj2TH1&sXS(vy2C%xi=+QQj)o+t z=fVYeF>nd?YGP)C&)ZjIq+FGf$R2*%m_Xum)rPLn@|UtVIlubR%qUAO4MYiAaBN9z zX>xlG=crT$wq}4~HWOI;rLHCgvyM1AN^I9sWGiBNrav|FKC1c5e)$O%wrt2s`^?kQ zy4ec7Pi$MKp8i^Y3Ex!NG1RHsx%6!2KV?GyXpjU1!gf)XA0I}W+z`u7%E`e+mY5Dk zxh!5^=`R$BGq*dOjU5^4ix=r^Eg`&Kp_PU+ESSFr9_xC-6Egrp%iuKumi#NAWWKht z+TcT+eTbO!OB4n*)J${V5ylJQzUMyFcHor0*!D+$&cKj@!nn zLvuOhna%Awv-WYYpf{Dh$;+7m9q zUc1WmI$W3Ta8o2DGi5 zl@T%&3$D_OoB!Ce<{Dtop2`G}{C@-D_l~V2t9*Pj)WO7eBT2q`Ku;%LEOyu<&`b!P zn8vO4*Sn5UXHGB8QHnR6hB35`#vp1(ZUTjk=nx#LZ210@1^=&Fl_T~N5>RrsC`d-Q zw--dDbjxO-7v5gf@E$o?Vgy+VGJ0Qu%-dcOG_*AE7m~1E6*zYswLb$ zyz8t4L<&47-zf+ZaY>fBsWVko-cP6!3EHn|eWW2)R8>Xky?>GkJgFBv_y`r)Iejdo z<{|rKGcr9-bEaXyjiSrLroi!BGu5C`?KPo}AEMyMeEX1#;Sj)Qvqz$foO7@NDD z>D`@x)w2@BRvx#s)rzw1Q3Yujgn@~sA=kPHk4D66KCSSOPLo)Bi~c+fpJP-2!kBR` z#Wt8lpOoR^&ybbO$dmP-_3er&#~+SUm(W386DX~-&yzp8XoPZ`UFyd7stc}WHck4P z8eq}LfPN%eebW+94H|tvbtQcg?9D+dUT z)cF=KgY4FVsLQ1SKwhkSY*s8xqr`jrN()(=k@^mS-v#2aCF{8nh|3f}3OL5cCzHzA zY_DnAkb#}mDqgatTqqu~5l;~FEgy;*%l*>zzDFj~$UmZR5tIXG+=ddp*doOSswQc4 z)zcRX5^AYQ3{;pTNcI3r#0nn(-iam<#Gfw9gVyhgcPHT2q{8ZCM>y(+d;^Rsj*A9r zsto%guvW_TRrAQn+d!b6-EUDfbL z#kJ!DJ+-X|zKRXZbVZUGX=BO!1DJ1k_uQ8p(;z#Ek>>eLw6JuOpy98LDoIN|2H1XOi&bcXUhFHZ z@=*8EVzYIaR7>ZWYAqr0dP7Qw_Wa_*2hek;t3;ZO42R!C*e|QlTE@v^O_3|Y$Q1?J zCIasPkMre>)F<4Q?X>#%skDekEEsDDJ*-5DG*ol!4go$rNyNr*>~xU?GGXP-AZb!JwRx3c$A&hC7{;;VUWtDHz&KSyb(n_V?cZZ6xTr+9 zqID$kg5Op|s)433l9~lB>5G7F&ezt1A8XC-Z6_79BL@a5OU-CDRmq1wi8JhMk~?GP z?OnKdW2sj}!Cmbls8rT?v3nUKPSD;=`+q$YS0-NAmAu^eW5GU&KEVN!bv zvw!f{Ieb6DYFnfyQFZ*bo;Jfa3E>(F>w==phe!kY=N*vMmD5k z(`IN2NYyp% zf5({8g4?K$4f7fqdcaq(C#cQ7k*U_jdj8B5}Jn1O@*z*)B7of#WQsRrXCi? zngo68a8*o4nT$Nm6rGv93!!Wl>1y`l+PUNBLf?#a&koJ}32qL?%H|?#W}6GGKam9^ z%(>EoaC@P*h9Nz&G(KRRy? z(=1qZkOgUDzIC9qrhtFLB#5sEP|3^2fx32n5b%J;U2z<`fU?bRl^GHeI7*;Cj1+yD ziUl1GGN7X%cTd&igOKW22URD=Z#b2K&WU06b|i>_!3(yDRhsF0aOC~}^s#?EnF3cR zDRd74-r_D`q>gg86uN_|oteiw#sz=O8Q=|Snw|;U1-BCdFPLVK$w?5(YUjX5hR!1# zw-ZAmk&4Qz1paJ81}!5bsclILr$LeQ;6+}>sABoc(2S2YC|r@a^Zc%Z))z{JCL`hj zVR145u6}f?AK)tBvW_D+3Gb4`+1_}m!WgiS8W%u~EKh%P2%84z)|m0|G(UKlmB!uN zzusZRfH~!iLBSSoWhf}wYzyd(b|w7y$WAnLaiKRQ{+DaN{v>)A=t@c190ZE49H15~ zCO5w2_8#0HEg1~?RvM%eV&tF4^@#@b|t{kzLkCfp%sWS29YqcUzYy58*JbVf3?uN$PBsx>ND0(W}m^QtK>_a4v_5*P>WV|HsP6108DQC$gx5(0{P z2r*^zH*x&4iGh4hGIW{Vx*xRqBgz^ZlkE zR+>ph{|y$*2DZybuuD}z%HwZ+K0{E}!^W-6vFCY_pjuYr#kQNj4{?_o5fL#(xC`|eZT8amp#Vl9Y$UB#Rn1Ovn$RM2iDEe32StJ5k_FbH|Dy@-YMT*~}H$|%gCP0{Y&$)4piXbL8gXR0q z4wAZTle=>`M~2AH5EWC!dvMA6KO|Wp-k_yt4WzA8yKI8pF3Zm04fP@|rrmZ&hW+i7 zXEhY=nW;{;dqNpt(BKV-?em7`76KQ6_Pc|F-X;}VjeH#jy+yGTQ||Qhjt@@u6!ziQ zv<8wnN6{p6v~O^kGidvZ1X-ZNyZBG_qJKz9ob>Pa?Rx*SF&PG%LnrS|ngsCt<=rPR=)c#G6pLPtEkO$geUIM^LNS~UW~dIEZc9nC zecFBbdeq0i=f)g>nXG?#dm!6leGp>3H9vkUf4gdCkCi2a@>8ye-k7e!T}d7Yt|$kI zd#S^PbaA=>QA$Czs*Isi_9l*O`#ZQs!1`#p`X8{ueFC!;ru266Ut6l9!IpotHx=`| zM;yf>R0jfvmUhv_INunv}hE*F<2pMzUm4E9m!~mp@(UE$STW&Y5NtfPaPTdP^ zm7z-~;uPGL(D)c&Z1iCb_=1BUucL`^@x&gw-`1QD8YKT7+5<;RpYCXRyn%#o8ujjC z2krdTCxM-O^t7-<8uz!6v~Z#B?rw`o-q(LurV&7wiC${gw`7kIXm$h*>@oQW6JY#P ze-Z(&rI&c^{ToL9qPg?W0pzs3%M$03Q^qxc7GJqbgjC?goooo}+tMs??FZ8qbze+F zLqqR{V9@&!>2kea*y1=m`S@R84+gLk`f4@*!Z?397f6>6Ff3yU2_3sIrW^m50{BIi zvcjB{+vkE7F|uP(6{`N#-$3-nWEZ;=z$D+dJA){JbFm_YxBiC;n|pV#5o6ns61^_f zp7M-x0P7WnD$q|v&iz3X^Eki(>ZcJ&THMG=!Y}ID*@EPG&rjuLfA+ z`?aFVD;NcE;WK|Cith+JQJ1HQ$vs&x!*qXOXi|Ykc=R$n`4fGpW?c#mAe6nZv%O4b zvR{C})kt=@@-lllpr_9-dg7XNszRzi89k(T1T!jKv0yF$FS^i4y+jQIWg~94{src! zy|E$=F)x@Z&kUh%JCmyz1D$!^qe`c;s98!pj_*6 zkjTuh4D&5Pc`k=IiN1Ihpo(Cv zsK<;vm_q<`ht9N;sx8f`=0Q40@0g1_xTCiLOx-5U-T$8}{@0H`>|IcsE-P{&O}JeZ z@$y5o0XM)CG>RFZ@ID|dZdn$3R9T#@)g^XPc;S?Hy)+v@5flxHU^bNU+8l(o1HHa4 zMj(_Au_ng&fFbC>rN?yH#3rlR|IMQRNe}>SKVTjIl*k;hn<1#cG{JVorg9^HFe{{p zn`x8zV!=dX!N~x|{w!zL6ChMYWwMd#RcGFb#cl`apw8Ysbb<*To4G+pf7Mocl;3X! zlGtTSKg%tQVIs-lWPXbibP{YJTw?Mr9A^p$X!bZuG*PHIuR0Qxt-5gG+7?&npnjLB zjblPOI1EsZmQDS9LLO(kot7)gGwvUy)*Mo^o305q+-za{3pV~n6XW|JsEsr6!An6X z^Dc53ig|mjN6$W@W0WVE6Aaq?MT7r!j}zd)lpRTm>&c7WGEw37Cc_L27sQZGLazMH zOyxL71SDFjZw&K+6g(<|jWpbq5uu$RlOfVvQt+K&wQQZ;PJ=Re@`+FCML?>G#$r&< zaHz2#Ri&3Uk4yO^`w2D!jjhELsSyCFDrPy-Na5y^RAZ_Bt?gL5fZn(oKjXEU;lqZ; zXu|E{R#gC0nR@M&km(X+n@;9pel`0qvXz7A-MS!3{blA$-UOfX_#k4V$PEX8Lz}Fy#Oao&R z{xkL4G5(4x3~Jp=QtxUl?I(Oix@hQDk%hqJWvl8Gl;(j;avUffqK(dopHx zmwB1axPl1m*F+9d%M=c#2D?NHan(ujS|iR&#XT0}D1MD(Fyjqv;Es}C&jxlwKq!ZI zqMvZHh}p~u{e)kc^4B;h_oxV4R*yD_VgFs2aL2(%rzTu|E5O&=WV_}k*og9qcHtF@ z83@lgA7+*qT;9$dNbT1fQ?8(wqWYeEkkcrT|7|e>)DMpdI6VMNq>v??P!PHppcYCI7a=q=R~up=B=*lJ1yw7dHsfNz zNl<13e01=vfv4@C`W#?>YwJNjP|p+KMeu@>TQ_b+-?%dm{K z?s<$R(@Q!>fTK_uQVuHulH+nf=3mtCRyj~~C{^R|HH4!<=U)ZA4Ee`rJQjGaE#>tr z3(yDQ{_54NGgi%)_3sv~`Mz4bsZ4HV|7BU*Ey6*)M*cudE;!PT3v#=&*zfD`+s8#> zc~uN$7w!yD-Fo2AaWsenB-PW}KmzwnY}X(-UwNe8Z9-a>lAN>9!munR0XE0M7O8NDz0GuL3k8ftv7@_*gUZkxH zf{_gL?#pkfJwwiHf>4G{sXs=}m6HPu@)AysVa}0eg4gs+G=kL9&MD6HpQ!Fy+V0sP zNZ1J*CmjYgYV;zeek@X|&Fb4uy44xIR};mTN~8q8Ye^7l;HNbr}TyjCa8BS#fZKO|7(YJVxSr44vf3;0QH2xA{ zHEIXwlKrRrTk~&Qb-gNbqV1Uy=cvDk^40V@IZ~x|fH}&n5lV?G;k-}oUH#Fw|M;C` ziQvSMrAcsULKAw?%zFKkS<*aKXeaVaD?aeeL$Y+&X#xYzAYK41C6Fu-gH-GzBLmbd zp;vQai?wNqE@dkR642j@Tz;;7s0t>3&)Q$5Ht&~&gn4~zQ)dI64P#Vwerp53KQUZi zQSZz^!_2lXc+@5BetLJ#l7UP8fy|13UWu(-aWGk)C#xU?wHA6zU&2z(7yZ4M7B>6l zN&T8K${d9cK`m>KkBE7L-U%dZ0?|&d_YE$QI(CqyEWzg=b(pxaXp}ltrcR}<0pz5?|t`I6c;0pQ86P5IRt@bhIW@c|UTQkmj=Sk}`SJKz4nw zLRRR=W4hrQQ7>a&mItX4jGj%j{0^Kna(DGVV;o$ zwIma{lWQLi5G4rD8%|byl&A+NM8>Wu38662poF; ztIO?<9B+blMr@yzsW!7-h~2ME%6Stg@DfHVd$TYHld{4-S>Q|BVMSi*x?SI;rw3=HL=-u?M1ehNM@UiX=L5)S|SfFO+-W(A)Z`6BPC6KMR;KL-9vt>cJen`)9 z4kafl(PYoH(jxzMO>fmDVC6Ikl@Pmua(lYBY?9^#1K2B^((B8kYJm?{5%jWFhvg|E zwmX;R9XagpK`UonP+d^a+XW^iF1)8xvw!Q-TKi zprH{?W&4t9d#QnqSolpZKzvv5KvJ+etgj5_**8l{^*#~%5nF@29!?05;G5QS{8-mY zt{<2e;r?Fze+awIfTpshy&_0c5gRICR8&Noh>FyJ4FxG8iqe9x0!oR}TM}Z!260u2 zAS8+)g0!W#gcSh=B=inZkQPd4A*6rj>grnGZ-22dH}{m8Idf*7dBzOm!ss2)7@f_( z%^M7kCW4S-63saCAyfrTAeMWyBR%;0xUS-AaXil82V^UbIQ(ml*o$HmsXS zl4JKGbmzN{kbB1->%qV<*3(hE)$0J>z)tGs*;&=Hy^l>`1Kd8cL=pmy*7R7oeX+e3 z-n`H+E;D@-e{A8kaON{PX&ZGr+MmBLbH0Kc_4BfMnwgRf?ZS5l$DHE)G#Mgoaea=O z-1Er9e}d~~D75UGYO2AdcZi7P)ORU}+}wHKqhxKsE_kqTeTCkE>@)K`!(q;I+Qpp~ zLv|EmZoX`TA+3K_5;30Df8bHxr*gCJ&L;hKXji-r3(d`9tMAUQLKu%uTqL#cE4D;& z(A<%+!l5&C_C(;F`Q*+mTgmDp^6%>L$>D+Z>nB{4{NcqMp3cNP69f(8PW)S((r_Ld zW5OS*q)$xk#m&+gOVpFOdZ@Ld473w!_$9Npm7%pIg~T|mPGxi7?h5*GA}t@ zPUmThjAWjuqi>B$qagDa#50%0f$Fahvz+n9;F+9#|=<<&)M|pNEoK;Mj3I%MM2NmX)IH`%1ZTd#(fuMOY%N zh};|TiYh>`@3I1Y?S8&PWZ^+1fjzosAt97#P`5bt_M=(Ji`BGN_-UaT$=Ab=hA)rb zkzcax<7`#jowKuKjvu{*MoC4Jh%6KKnLZvUW+iXnuGE()n;rTPoLJjr*a2tRhZJo> zCRWd8cU038X@hQ#+fhn%7z(HMm=n_a9HTvgu$8KQO3r>&ewFXGX2dGE+vhXhOiR@T zl6w<@Y3%`$*Q_(^pU!xSaX3M5pE|YM@?GT|eZWw7GwS8v_X?n0!5^;aBC)7xqvD8# zR~e?g-elcTGya^JzYIT`Kf`ySO*)O2PHJc4*GDM4-Fo<}7Uqu9PEMLxc&`@PKWk*-@-{@?gVo#8EHr@Vh#75 z6zuZ%yD}C4+vc2vnL0Y`OCx2|c>X>cB|i>(_ZJE$be4wjoT4+DZOm*nHlBEz(0%7T z%lno-H)G2gnsOL&A|Vgs-&nO!Zt$>h-cDm}jzH#^%&O`mWrIlzCrefJWPr~pFU^7( za2qU_Lxg7&f}T5^jqs|I8VOgKJy?#tIsR}LTPY=z(qU*$v8hi`MoUgANH$0WyOUq^ z{p5@%@61v=|7U9S1>_(|%-%&^YnOagJwCfb(snpYH!6*P9o{RG?;kNnPc3&0A8z3cIW(!9`DE|E<%+Bzo7r%oamnf_5k01RBXgQqQq|3 z#+b_*%0#o- z9%E&vNlr^VYPUB&muWz@5)J4b#IpdY8wEhyP7qTPRps76md;f@#xNUhfBbp9Y6gX* z7gcT5rRZ=3#jV!6!t^g2vm29D5T2*g9&P;2Vu6Fl1Omnz$?YWISB|f1JyN*w99n0I z&;&R2-LS`+afUYXboW!c#^f^HZXtbsa}yr%X8p8~h-%H7K2 z*t`_VS-UF{-PZr0tZ$W>&gG(4Gh?;VKVM!f4}sXyb?k};vqh&O1)X;QB*^A`W1x%< zRRCH};!=5I-PKBLkukHA3a=$C7?DE zzsu`dFllBmX*EN_3NUwM0#qiR^IWQ#*Gr!Wi-I6<<<8iG(#v~g3my0B`UfdgDzUt7 zF)+c-mrPI58i4@1($S6(&R=qd7Ijpd#EOUAzEki2nTzl*b>jAv z9>P$Jg7#JI=HYZ^-UOkF%o<54$h7=JdoNGIxF;B8uRv!2vzPd8??-eNoX;ftd#J$J zjW~3!8%2t=P)SGgCTYCMV&7Z^8Tia!I9sA8QOF>77HTX|JenL=Or5&%{Urp#|HD5t z@-)aQ+iU+cTX)J=aA@laO05LiNexAf=epR|zc{P%DWbG$#Z5Mu68OG9XdR4^L{lEj zLh~nE=c07oF3_5+Y3KSh&H#ib?w|1Y+6N|O{xDpZ;L>6!;fP?OkeU6Q5YIlT&0eG? zT8F`+;Fk3tFq$!{?T@;dNvfy|x-ZdF{|FZ>O_#gJA9sP5yhuOc;%Q~8eqh1Cw`{J- zIIbSnLbP=$dN=44{I37%;z4tGM0oz|y@|NNm9#{-u%e%$e7aZq+grU=hPOYsjotdJB56@Os%<8<|5K}LgXcUJ{z~}@dTa` z&EA_r+&|A_(9U`cv5^cLt4Yx%wB1GTlLG@Sw(?Zqowzc0QGbb5NIE_HK3iB1PdVg( z$q*SaD*-nn{i<~UBnu3hbpo^ygBA;Gvb;?WG(Ihr9pm6#Ay34;mV?4%AB zJKEIsW9AwSz3J+K5%Y8T+f-y~yC?wz;c*9;m)7O3{O9zBl&)6RwMt`KORh9{| zBW}$y=k(>9hlr2wMAN$SN)~ABQ*IY7mkaNG^54}zCLbW1uDmidGt1h2N^+C=dhD>7 zf7o2LeQ%^`!m0)<=g>XZfY5rc-ftD+p!g~{2?b7QzG0=&(wY#VErJn-nkf-$5C5Sv z#!jeKV)gmy%rzXeo4Dy$$?bB=M==iyO=}6vi@f)~wVql=uk_-Ocw;2uXyJ_e{QluL zf60w8O3A(^vzn7un1!hibaqprcr|e5M<&7h(qktrB}aKFyvaXr(ANGph%r9!M})YrQ*(m zu^(yF2z?HAVT;589IHl%Z@ia*-LYXs&S-G0PE;|%US$&7cCzM4aG;eSU9uw@HprdU zx-#!|OG0*T$y_!cwAFi)e0KC|RIF;d#*22flX^xk*P5#g5*d?I-EJlpO+>V~ZN^8Wt*4t~!0?Oea&d0+tv zh7RN=>&tjnHfD0ZWk~t+q|B|bXO>`S()opk2kf*@SNIujf*HSwHeNm%?D8}k_h@cR z=5+K}`1(o7H;j5JZXc3va3$s}rF&jvp!Oesrj}X-QAeF}oc?!2dkG^WsonGv5N2)c z8Q*?)9edm3R(2(^86hX@vM7bzUcce)|C~dIGav+;WpPl(f28YSF<)uV>to9SZ_SJV z$-Eeb+A|MZ&A@XFE}QjR3DF~A+RK2~P@W|qb%#_I5v2G)#5L1aY4R9?bENEJj!lI{ z`(&X3LRyXIZyT&;cY!`qgu9?53CqcqD~)JBv1J8qS*1&3gR7x!flNkqm~g+O`j8Vw zr&_K1of1vzZ-)4!Hz^1wamTe$tUs>!YWrw zZ)`knaGcMY8{(g@S;XyoSF$0+oU3wpUHn0s&I29tQ@rokz*PYWy#)tWN3~uXXv3oY z)MNUMIxq2^WCv!U0yZiAY*<3(A$wQtw(;6_dhvPz<4QhhJorv4JXS3>NKF(QvzPy% zU$V9ra5S9LEu~q}t`Aq~a`t(Ltjt4G6 zfzBHqwTrlJQY9rIi87zkR5H^vJ=mV(>2!@I*-||-YZDnWxbX>Fm(laU@mRKVliyB4=1=2 zcpDSUbdzJyxxiOz(g3^4Bk|WtEVDB2DL#Q*YM}CoxMuN7PyrsdKuqUS!m1ExM-! zowgFDx6a3mg&q#~awpAtK(w22g5c&9FkW`fSNA5IkyyF9b|Big6hjZbGb*2%l*>qN z%`N0Q9v^J}hMe#c$Om8^Iqp^kwN-dd6G&f@{gc#nNpH-C#4dvBfVBdW4RF>!2`{{J z3bWiG7q7fUh{zwPoJ+T2tM1tL7_WsH1k`GooE6L59R!;mhz!><9>4;!H~Swt1H&!+ zVel|TJ8WLEC)!w$e%W?;+dygG%FVn&R8L94f{+ztO0XV6erqt@cL;h>1-Q=H%=ivY zu#-C}tMp7Aku+jY@4l_|HTFq>qUiXVCpqA3fA4oC@2nZ zi6!Ya!wF#0{u>K-5MXO^&sB?$Nbe&Y^pk%z-Z#a1D~}%!_M_D?(83U+TQ`8bh$Dy7 zX`*G(J-E)Vqv4xYOi*=)9=Rlpip>Wr;`UYPP7W0Ic@2bX%zGLkSWVIUJnk$Tl#rOy zEr$>vxkop>VsSMxlTnp3^WwU--G=5EmQ6`hWxJI1)~9LzT9-uv4^{xzedX=N)KARq!n2p9wn3)Io($cw*x_!7^C5Wls?w4mWh%%R|1GDQwlujae zyYyS=OfrTzHn&i&AJ~Q(=e#l0yRXM;#QDie(W}E2IU)pUflJUt8cIfH0=J$q$a=~X z;ns3*w&S_uE+^L=dW+Ka8}DER^FK-IjdE$s#l3df7+=(U$hFy`m+3xNSZ);0BdC4T zUn`rl%76nAoG2^1IfWugX)!~;2Vr}@!|-l@*s){gaNn64djR(6eA2iJEa3PVfVIZ4 z8yHa{!^%iXS`(2Wz?u&aMB&8vBd2n%5bWADf|NTSV2vgUs(i8E>snKr94b;?n%Zyz5GgH(IA%=WIK7k z8D#aOL18hfCyZC;@1KN!=u93a@X8GsDae8L>ku{hC-tb3?BKN5T)ud@J_>j^1#{e} z#F& zotjVq*MtzqlQ;WTsfT1;>AuFjKcws(v0t=Pk{yVf=RCa1TyH{3(g+Hj;-TfHpA7A;#1XN@F| zsrRy5qj7hJMd}hKCk`wW`n9ZA|4^{Ah&WP9xX*4vVjlAw4oajmyi4*K+7u|3n|pZE zqzQ?it~k2P%2${!*+62IB}lgy2p#^f$o|O6GwbF@9>|*!i}UmIX|Zk@>*rTj(mNT=4&4ec6l6jFj8OHYKeTMWytcKt<`os%){G(;8MJ&DLw=!zN} zoftdqnK)iMpdMj2i68zTvIDs6H_t<+~tepeOR*$Kj$XQ2UjBy z@F_*VfAp~bgo;|XUPSmxw&N{Mi6^xbhe7O*YkE$KYWj=j>3+wmh*!#;O7CT}?b6sH zv}A=%1blKvF>sYZ9D$^p6JuK1rwhoiAiY%-Jm63iW56GO8$LQSuw?E;^gX@RfU`0c zuxez!+TnVzThMWy^TNqkL4fV0dFj$NWqMt%Dvj|KMM3Bj&|WrL!uL9hywjBn!a1|B z)ENr~PL?9lL4z0icI(Y%nCip+38_oPfpe~cWLuX3ZwREYk=Iy~4b_^{Z?;iyKjPGk z10-0EhW}w8WOWt}%>Gx&p}ZQ$SGl3+s6=zFTcy{0cIts^v%%4AN|zDb&CLfs>5lm^ zY@s1{Z^8W5xx>a};s`k-Qf6297fgudp>pIM?+qdb+{f=#?dFNb=R%Zp`7L*V8wJ}Y zz+gl*oS#i)n8&i}6khTpT?6vi)QHVx9<wTGQ+RE{E?|jTT{%rb348WMGT}D`z>d&EYv|K(ZVX z1mHWO3Tgf@R?M;gL~TV(RC%BD>63M-s?me1?p*Ml-O8TXZ2!exisV{?;KeXjs)daH z!?QE4>51__3r>^?Tex!z+&^_TDD55*;pQ!yO&dyM%Vr1KFdrWj-bX7qKLbv_w{fXZ zRmrK<0q2U??cE~7PWie2!89CV1;i_9@m8cf?Z0sBmN*l*iLdXM_fi!bxK?$n`NTG5 z@M^z>Nn##5NNus+MpY&Md_b}{kM3Bx2&2+I7viXeq@mDBKBlBjMp<<*Ngcpq>p6fD zqsxo{ zKSz3o7em=*VxrH=K7*)pkjPG%^e=emOl6xNDR{S)A_~Z}U#Nh|SlT!+9gQ+=N0yH& zdm|>)n!j);>#q`Gy-UV$|76f!n2ZuP@zt_9Hyn1vOWws3n5Z*Q9< z`yqy#X+{dpUDfv))8}sW{ZU5Qy`VOxXVl^g_>z2?6f~^3Fmq2F|3!3-VX&?OSm0+{ zTcIkhAdwJ$-Xu8ztTOI$v(cADUL}-K7?d7kLXxbj9&2?x!tJjTWN-Jg!GBFxA6YTN za~l$o*YXJh$1qK5(v+4uky0d+0;f9~Ro`(a;{+^p+^FEvIs)PmheP>~w!9$?6r0}T zFMJ4Rx5F*9G+;1t*lj1Lvs@9L(-Q7*Uo&%){&;Y)>p_wOd|qJyu)0M%1~@PNIsL)NiX8#p;W89 zp^R}a<&@yyi6!ssaqoF`Ovkm{H42sY8D)$l97?jOI?)z9Xj%)x24Yv4XE(@Lrd z_+-u|mp1>qq<>&N)Y4e=#c@m4&y>*>4qh0D4Z5!452V%kxzugyca}#gC z%)JhcyTrq~Sg@|cC$6!j4LwV>f>OOrTh?y_H!0cSIh6v6<}18F;qIs$A zKCaqtuo=ai-ZFZE3#>TT&K(q4>q`sP+m1{QCTNI^lpHSo3fG9q zE01KiH>FX!3#r!GGtHG-QYdBZv{dPx_Fv=|gwwa9mR0FN^KW;^+H+Y2a;>vUc7WmU zl)E(P$Y5zWH(EKnehOqkd)#1+Ju`#0B2!Hzo4yHN9ss!22bqfvP$o-^)Lj6!6t7t% z4(=HQ3lPybbtpRc087`{S^m_;dwagbaT_eK8snq9vOQ6yAfo-{kiG^kSw|4USAa(t zm0W)a90RMIr64~vNvPhJLiH|7557JZxluj*%QSNjJG4(uCS=U@B)Ue|1hd!IbD8(K|2`I9P#@|E zb0}Q`Di|^3zt0Y|4k-!HA@+Eem$?u@dd`adq$XYI3m3B4M0}3x)lWC$&u83-d{$u^ z+rN45W)yt;*JiJIYtGo(j`IdSis(u<;X+U49TcLUl9rr!1SpizU9YGhCG_tR`T39S z+p@CUEcU*D+BSV!2m%Diip8Z6h(n80m&o;K4@l^3<`4z8=%FFKO8XG7P2PTWuWvC9m^l6B~cJ{|_B z>q`>PnMgKhxa<3V)zF_F(073FstMrbMzln9$H3%5qM%} z_z|J5Eh(AhoAx{t6=2<1`pomUD=a8-9CBk%)H_>lPeE4gug{SJ=x=JtceUo8_Y-xX6B*o!7i4E^j>w#j zJ?sWrD4F{K($W9E^8KP?L4%jkxIMAzBXdT7udH=tPNuAkIQz!)v6~*Dwttm)~ z6gHHIa>}UwALDue6^XXx_~waHyVXB}0M^~Sg#WQr$3e+DT(`TeMJWZzGY6HO@T#ES zk?@1n+a(Ql&;7A91{hQCurvCUp6u4&G2=jHt`nF!7i3?Dq8K$!BNtTFhrihP#W(uJ zX4HXG3Xb4c+1Z&>9&cXLpy8rKhmst>nJ+;LXcYDCVJB;#QG9c;kums-7!#hwd zsNp1|ND((c`Gy_UNAzYl?*854fYl#@q*^06a^f!nG3cNiA+s;W6=D?mc_g1c(a!+r%dcIHnk)k~ zc}NjJ3Yg=6{Tqg`EU1>mFu z6yl#_9KRKzU4VQSeza=-5vU1xZl+AY6SEb+Hx1t}*E-M-4u1E(Q!*&P!EXfM;h_AB z8xik8#%pd)LJOxZRh3!&+X7s0wHH-tP5-B>+ZHR+LYW;dx!>Tqdq9bRznf^iU2X-X z9bhXia~s*Z8xd*vpy7+fjQrNOw#Su!J7Mf?K;w>R#9naA@iHf2{B4A`w<8yEKPt86 zdSk0`s>zrIl1dVVnN~@Jy$U?1nS|k44#xzf|9*9)rs5L8rN2zqMg25YY!ma-N_h zTafT90oFvgjG8v~nBZJd9w=e|@aT7vWVLF+=zpWP|@1foGLOtixNP;|wsG^Y3=eHiY-S_AGL-`3xr$#q5!#kXo+ z27S;<2Tgb67opOK{b`iWvx0MHAyO2b-x@q{?Pvnm4(qCHm4=0i#Y2X?zc1>n>cV9s&UQ{?|K!*V*pzI=8@> zU;>o_yN#4R$|=`b%<7?o`c%J=af#Hy)ZY(T&>3{0!>`X1H!&tG1J9$a5xP`aLxR{M zl&3#v=Q0y%H~Im|BA@*xiS*-QTiWQSo|u?!EZ!^>3)Sj}akgCQI4+n9*nG4(Zf442 z)Y?t|MIwJxj!3X*R(`H~+%2)&mw<}o6C^PixCu6O$y^cne@a*i=-EiDNlf&R6W^l% zijr|U9MhPm`mJEbJsS3H4p^l|`t@VnB5f@Y`a} zR8TFN*`MOt93e!7ChD)l*%?F7?*)B{|DQL4PPvFY$;O0RqAhA*sAld9r}iwu7K1sC z{qH&62Xiz^e4@NcD&-`oEXOZQrCkyh@Rj(Ntme0RYrY2P?WrRNw3D}+hY^4aoA<$L zdYu5MbN$S6^ZN&dz=La!7)U3pm=8h^(m(iPB?V*GHVkJ#y_A1zVjTLwNfU?*9U~tn z+=e8{xq^1!pva!R1hO4Ol|lZsfdQ8j9dOFdw)jsx61Rl*ksPvMcS#(ZEd2j1P7Kr~ z%YG(9TLZfjs%0-)MiOU8x*Gq#`W6WIMuwkE#(GP|xIl}_o^sPaM)3H5_rD4t>)l}N z*J{$#Jpz%EF^1sb%(^MJqnjJr0KF0Me+rMY0#LN1e794k4pESzdR0)UOY(FHxXuWn0N6=g)}A0O>AF9k(6uWzl2%kPHXbV0Nf^kG7!^_BP|DHHp?^X1Dq;EV-c)ZlHg<6EFv z`&_c=Qu=4sburm(kE$VLx%G|M3>vL=YNl58IgGzhjbd~H{~mix>@_*=o}^ zg(%$pz0}8m`CMJbr~NI z2wvQN?bFX|RR6BJ>64y3^Yrs=T`=^Sr-#5y&J#uA#!>G-98?m;o1Hvw}Aw zy7r}z#%|=z36l!%Z%MHdsj~s`&_|$?oLSWg$m?>ws$Z8(nk*h`diy|L*pC5rdoiOE z1cE^P#ume+J2#qbIEDIdLLl0NK5#GfLWcgeNj@3ltES5VB>^;2(Y=TS`=c%@KCBXq zzma4;W^TTfK0LH@ehvDs;FMZcLz#Zrr<$krPfV2RkH$Qf=Bz=}B(}a}yum;NnajWO*ORlg+3sa%q zyC$mx*xi%_BA-h`Y9{IrF)pT;s`|1#1siI^O$h`x)c&MHLdB^D*2}C;?YqKvG0=Xt^;mZaj;x2 z0G-i;J_uofzP3Kxlc0Q2%0s>6;Gr`{9)AOTORA)Lp36<>6Y$txO?+ z0Bru%Eh+f)f;4dLBuoli$tlLYckkvu$cyxGq#IsPm@v{94{CN-oxJ$%HbOz9I-pzX ziGG_QLjhnS@WAGC7gx7PBz|1?`E>x|lga(aH_pu925@uve@+z7NkpTAT6W5OulXPg zZ0c~X$M~!?=q57^hT%{T0;A03fUQFFB_3&P`)?(?>y>g`dp%56k&w`w16;8m5Ndoc}zZP@;s9kcKE#asQ6kUy*%7kL?6LTV_Y7D@1=9 z1TqR`TUyboDVg&NuCm|H_lrBcA_fqmqWk3Dv%nxa4ggjrA=B&r;3YcyV}D2XF$AJa z_}M=Sb-+&o@gEU>+u~G0AZ{FZ2GQ$%{pD}|aA*TFIeVuBN=4lOZCfR!x8O#&=n zU5yOQaK6P4E`mCZ%nyVMzpf?+7K8vA3(4Pnu@g)PC@%qaIPGk;HH&z5;DyGor`TYG z&CZ$6Hgn&WV+t+I0iaK!25p5K3{c_1X3f8w=5nCW+U4Fm!Mav~d=D@|A=6reb2nf;OLI=&kT*g6ijkK!F z8LyavoL`{+PF8mSV_3TZx-d8xfq5wWvoEDfgo>F+j-!QP@bF? z&*41q1{wcvaJAn)`6b2{1X_gL1rMk%K~4{XH*5@nSbcvnYY^2^+M6t|1(Fe1O_9>9 z$4$C8)ue#aB6SA*KPjp55jc;@qziXN8uTdXMsnP2hNSw3dF5?ajK%)(ha{$Y8?TV3U_=+5VSc0 z$z~+mO5c|SZ0?Va!Z&YPcN$o#mk$TPN9F)LfLd>90*ZdXEpX$nWCeUHD-RfHH&`%G zSAbO3$2@v<=Qaq#Del`83s4%rl(2lDT}Z4G)ZqE=&`@x9%}52OC@9;q8?C#Znr~k6 z&3L|BH!OINtpz?R-v<`WBXm6DZn=}H(zD==QY}`_`g{IV5h&sKX-oM_{YsD=0v2Ja zWcq3VXzwG$8>X8x)j_r$bPj$fo zdjzBgA3bTfCkb2~xhtBbZ34qq#V47He(9~n@C`pY4v+%t&q7gIn3L{SeTSt$Z`Zk+ zz5soGh!z!3)K0E0EbOvl-luq$82pDz_-5t=F9F`&vqhU5Hwl1DJ5XYVNFnbTpbL3$ z-_k5nC`#3j{EU(VNG~F*jlbrzza9J0V@GLe&~9u4v{a%MwMRri`(L%YT59?Lnb^As zC6jM;6s}+E{Hr}q1)f-D%~4ljP@)5}u4I(R9$@0G027z$Hz|-wuX{@JvN8g-ckC?J zU+#A|Q1^mGf5-g+a)%-#X`1yCM0irQ#Phi#hGh=Q_hKXg08t^-}f8KC?vAO9}oPcM8mP%=c|MPTq#p_SQpA+pYl|CQ#tQZ|9{M&Je=s z-80II)Y)GhVKLXshe)3F{izwy1w;(2h#~Bny41ekNsb0*Xd58EpmKoTd0mNrmmGy4RG{ z*Iq0DTwH| zYon4)hPOKD3~qJ(*n-9Zeg{7-?Dh)2gAtxbDz4z}-|kGqWQowd74WNS-&YU3kean8 z4?rlyMv082wv7&tgW?Z5+y}r-=LSaoQ{4GUr=s9rZ;-DfXcVI&mlO|NKVY6SO}33B1p^Dy}~a2h`PqqY{0G1jn?tjBjJWcnBEF7AdqfDjA>5Cbhv+!th7z( z219UsGPq$$t10SY*i_NiyBVr;MN(yF=T1p0Oni6${P$>a&;})zpThE3Yv6sz!$UN8 zk(ku*6?)EfaQ|YFiA=?)XQVvucT)Dfg?^fcFbmNd`HbK-In*$P>N^rbA9s&yG6Tq0 zg=QFaiLlZD=3=R zUEc_vxd!yp`y9KBL(9zt4pcpfsnQyWbX?E2okyHdI)xdvpJG<52s|B}a2Zyepou5% zaPE>~MB!g^2Qt@tRdK5#%QhU|gpqi30)9Kz>G|eMGd+&C?-6aIZWjnM7{}98Veh|| zGk#~acPce-rO09$md(H}?s}=eT*}*3XFM=M+H}(^hSvzMC+QKLso8EZ54Tpjj;}=t z&!$ZdrypR*aH7dORG;8o7}1R2GVetcV{Hw~ih98))nuRX)_0@~A_{+g(trEdr})p0 z7I#P?imKd~dC*}32P$O+mInqYUB(+P9|*2sdtKTHdajN$*>~>o)M+&?{s~UE zIM4Z=LlevtU}Kn%ZRR~oabp{qo_bBQ&xAtEOsp+Y6=H|<`8}gaKG`mZ*@Y5i=O@EX z`TVlw{i)SiJ*YK?hvPte(O5rb|Jv>|&@RR?d`*?ZrX^!wJEO{R7WQl5eHhN$ha2HN zpj4lM0R89S?3it^+95;D5H}+UogAK5Gknl{CU1Zc7U7}Qazj-7BTdr?yQFvEH>S=P_=Uv!#OD)&BDQPaYp42@VL{0~Vo$#Er1vG^-HoCW@y$KWa&d7RZy2%go*N86m zhBzl+B7_B3)oE|7t+3*_*wM-${l^B0zFf^$4W2<3OYJV>f$~sai?1j6Mb#-#3cqWD zLgE*IFyCxu)#z~s^437hdx*2E?gY4D!8jt-Y@v@=^BMWOBWf8bv|cMTg7=5MJFatK z@GNK0sVpH}pO>(zgRXHHMH7*!JdskmPYIPg1nSd&7BK;yiRBsXv7`s_kSl%xX6e;QDL+1^` z#&6$4AKeiKYNeGIZ9bP*bnej`giT?o?tC@dO93X`JrHAS#w_Hp#&1o|&dy&>@TVOcy2z+uxxmf6wk+5UZ^i6)dq&nS^#fHXnltVb)3_FVG z9D`Vt_z?cby{o){KD&@jn=s~^uAnz#T1iiHGyjXPWu=!lHV^Q9 zy8@4pm5ich7x=4FF1rhtt#?2uK zFZAB7A61rzrLjBt?iX6IriZ)v9(n>ix;ekeozEf4j2oul7xS|>jBFKH29`_1VTJE! zM4aW}O|L-J?x`b*K@&G0&9qC^cESq1lq<`Ie++OC)(dc7F-j-q{BNKCD80L+Y<=S1 zUi*)sn1P*FuX06Zy>H^LveDi9s57_qy@7lAZ}l)xCU42YAV$@BC%-w~mJnUOWAeKFx&!ddGk|aY&4Jlqi52NF!vs6c2bba=(bVM7-aEQ2g}AY~ z`Y#_}qIO5~A_DeYr13Q>MP{5vxgt{%rRnM?NgSO~zZWT`7sJ$TZ*5YI0__SXM4G z`nw^S`(s6n<=kn6ozA36brSU%-+8ZF2a!v+Gq9ezRU0`3~r{kR(Kx0hRwSaWh8 z*u|lpQ;q$>Cw_LdQlj*c>tO01<=)&~KP!gaC;GabV{CY*lYtW8h)}&95a{0RFjPD! z|3#zc0mz|zx!{&(n2&LHMz0UbTK0oLr{C5~P&quY|H(J|_V3lJ&X7=g994H0#}2MO zxDJk=zSJ5d>O(|W?1X%ZzUYJO0FO>iP`HPzHK38L*l_`%(Lpu!J}&UtVkQGaK>F@j z^%4PaTArW8u!jMqezf0DeFMvH=wG|7rnp~#86yj$fyr){zvt4INhYeEiaW@bmPk)m zjf9cKu<_u=>i=}u7FvxJjDG;m$yda-Gzp|`su}hnXO8^5I583W*REHS+C)EUtE1oD z!$;&=i@K{eAlp!a49T`?In_84$|Pb_12BthBai}U1J^HW34B#M2t*(%44Qu=G9#=N zxC~>;)bI&~7{8u_P+4-Z0JB1!%s=})JUG*AwA>5{ez{)}igJHS@`UPpfPlcPY^vMs z&K7p&NbZM)PG){(>vMn+$7f`AePl3bZS)50uaO|RMn>+~xWIfk3GXQ4^%`0P zQ7f5wm66ZE1reW+9{bblL=K6-)RA)KcfuacOsw-SbI&YiDJ!a=NMQ%+a!I2N)F4;b z2h_C%qcWkj;J@k#>^=0SM2k7p!#L!|$1)91TgIf#wK?ex?*g|Gko9M%-(|ZXchv?f zG8%y@icvra`hq;0GTa7ZC1<`38*>3O{@QU`{Yi7G2o=dr%JXTKO&eq6W?I)s-#zEv2C50`r!WPAWl&ZZFlvq&3m_OZ@#sYVXU*Qt#P7`G6NIos7L6q#v?Xl)W)SA;ZKu$qo`D znU^z)ELuG@%x^UF4zwA;K3 zi4_?mvDn#S)s8jB{V+}_skJ`Xb~_5SnfvT;t6`}Ac`(9e+1sBgH)*zt2j)N!X(v9= z$_06CTcx`R(@cD7Jo!TpA3GSH>TTY>jPVuO_hAZb`8FSi+t7}Ie?2RDUZKB{yUwoTQ8Z+jWHAoG}l$;!#3 zkg^Y<^yKHOz35D?Y$bPy-OJ~U_8x+i-<@4h z#8Pm}QZ|+5`zkxeK=m=QZ{3(AR!j6_7B8DTZlu<1|Kd4_ktGZyw}N8?B!^&;f7P6HHML%~T6L|HZ}&B~0Fo6TszhPT^?Ljfi7 zyR$#O+*@eNUGfJ`cIM5KvD!^RM+gbP`Wl)eok0qWj5$Ts^t3h!Enf%Bs9M94$6kzd zX>I#6rlV2)2{Y4g{t2ver)kKc2VPEET}Ci%Ge9Z!xteLmPLA!7qSJcSvo}Eers9?2 zkKs;zk=J*bXHHx1r;TC%z^00Sd_*VfxhLULai@w<#)BGA5P&cWNXp<$zz7q(krEk^ zkiWF9aKO&Ko|j$0bpz$`mG|ci*|eNIEwItlyVs+BJnCkpZYE9OIl9J2$(XIVz!0AR zmAW{IwcG(r-u>mJ9v&^tvT!GG`FB}5=>_gAh)vFRfZik0XT+NS*9Mn8HO9S2UtVv4 zdtN~>BCv>MWt2lL!BNpt>I`qqpq-={9VqO#TDkg19W;@;**S}0QB;eny_-8#lvMB0a@GvHAEOfhSCQdyX4Ru*H?BTa-VGLN9LKcbLK zP^4cu5HY63$Oe&|lf{9E;S@Q_gl_RH&;0T@jEEU{OfGvqYY^HY{RB;NAbBTa*dPzg ze$nw`$~YI)_fXpYYDWsZTYIzBfXE7d`aU({??-c|WY7=3zlV z*{AgIX7-P#;XctrH_tCY#T~Ilh~^q^nmj=&Stuc{r?*P`!|*Ae@!jfcKeb%$uAqeY z8ktGu3=f=0P($dcgHD28rQUUEs7Y1+_2E0ac#p!*&&avr7^JD^@s~)pR%ltqWB$S_ zY4xFj$F2t-H<$FFfyg_9J#k)T^R3Ga-KOWolt_;S=O$#)y7CQx0CiWBv7wZ8Go{$4 z5Pe#XJq*LPfW+6lk^gI-DmdFt(bhshF6W?>tJsLCzW&v|R#r?H50#v!d z-qkk#XjFm)qs(%jX9ht$)3cdpXNX1!A*h(=Mn2Ta7KHG(-7t{bz6p3Re>~m!<4RSD zjrTQoWQ;=10{4l6`=v+oKItL(_X+<3;CCtkj#NepzHU>zCfB~P_1woOeD+=koX`>xhb?0TuodD8t*~-Fs4+W-!Mcxw2 zqlonBh7ABiu@wN;dmIkE;WcD8j%m;IHj*zNF#;fSD(mXc@R4!{Y`0$4>1%UW8QoCD zbh1bf8YgOZO4=AEnbvjFRRXGid1JtR;-kMSRwF_B z@p1V-5-*bjcC*cgAy-&k_NEzS2(@ znzzSWa2}sbl?NH7&qBWjcwknS%=f%72ES7I;cG$r=O7EX{<>lr+}bsOKhzrVhZ0nP zm&~e=u=P=8-CiDZkN9+PA~;Db%|ObsOs(;0L}+NA)lZG}973?YfbFB2AGEDE5Z{?R zpr{3U(C-xOVNJHuL(#Ojw3eM7Ad~$ipDzu;{82gEvhtt&9ee}``+9?trQeAdcZbh(Eau|fc}!nc zw?aHB@LZRPIbQ@&BZ}{N^>#T_@*F3`doKlu(>!k%vnW8&A+c4KS!Xf3`C{8aISWu8 z3hqd$+g2E$9)|HfXH{ogFTQBoa}4a=v&I&wAC6Z*0wLL?O6obgQ7h_}N_0#l3&B^F zIw@#N*0YfDe_GlO5hB!CZ9+SP&}+aPk5i+}X2DdGhxy0Rf9a;qDLu<_KB zLMdyEC{mV0_AyNq5<1zFD51!fHQUINvW@Kf6vw^{#u#SI%ySPZ#P|I5yq@Rv`~5e@ zXFm6K-PeA-ugJFB{{kJmey2A(M;SKW9eS`rr(j%PKS~CN*XEn$!8QV?ijL{Nj0fw` zn;4N;ac|DC2loq$Jz^|YvMf`k$@gRrOhzu>BjT_w)AiwNt<=a?B1eN6o$eJ}MXt$R@V^lN-}yd-Zed ziCj+Qkhjh0PYaEDVlx58032LAkG~Tx?%X(aVvq2Jl~MRTg4?fAbxuO+w%Y@7;)9@x4vX-l8~X$d)qD?8sD8RvcDUC+gBBM3L6 zry)pCUQo;7&94BNjj)D_h6SWg%J)anB@-PQsKe*ZAxInyM24e6fEY$<8(xFtWqr0l zrIkvR$WHI@#0l?kLN>KdKbI((X~$bW1&? zz_SY`8Ds{01raA+x+vbCw?jGi1#Ol-4@dm?^zHbHyLulU0524qN)wCEAdwGv%Vp#$ zl(^>=xg*1eRV%xdgFzZ{jhgE#WI$>*(~#g(#n}xo!>SN~P=X`%{V=ao)*vw7FPsg2 zXg}@Aj&Ha1tr$7_Z-_0PYwF0D9+xrdnp0UF4moz+MjygM=vlv8|lkhnc6pHSBA`*_Yqq_-uol=?b5= zRoXU;x|88#-a(0??qCobR4|_*xlBkiJyDhbq`Hm8&<>!ghWV0tR zMnH?$3C{4srdyw@ch&w(5nRqaB)PnIf0#IDF){gJhNGkW!%WE|H>5^Lf#M=2B>7R;X}%sL1^6sS_u9!H zWTc`#Aj`1B%S1t{{m&H3W$Fvanl4BmA>3`{XbITSrYuR2={=~-qq}XCFgz&%teRR5 zUG^SS?#>GQ^{?a)<}yJ6_;Qv$PDlZ8jTmv@!Ip_{0QrNsT(S8wwB1*$1rv^fjN_p% zHyK$x%g1tnaCDdT%)*ARN@CjzeoUKi;oD`?os=yu^uMUtLFpy9lu-8lrGG2${lE8i zZZz36$LZ?p`WbrkC21EGYmTb#sK#Iha$j-QLZTy_Ls|Y(V38oJu(( ztyS$JKcww2NJ2TFlXGi5@*%S_BV4(BtL=7uc|}bVbKJwR-^4i!na_7fci*nA{#1qJ z2t@e^CH;^rzW>~hI;KZJ(Voi;H7mm-37?-4DP8$e_VVq#VHo9ZiXddxX(qbT;np+> zWVw;F(iolZBtd}{mL=CD6x3E)!jJz^Uaol!&9cspCoJM4i9F_dLwOza)xReNi>uv1 zpwLj}=?F=<6sp`V)3Z59ai-JNcU>Xq)4?IxO`zBg^Vu8Gx_ncJTDT)-mC#W)ryI2s zSvz^of~2g+A*PIT*a&XVE={4U04HM=d9e=toTU^w8tVIfe5P4?>>lraGxIFBL#fyl zQ%a5?^NcM`1mAUPugvMHeNFx0Gig(f87cWT9m8@dybziD0qoC9nKez$lTYnbcp1-G zY~DGS=|XOg6ddlk-NrWizQx0zh&p7bQ%*0FPOt zmM3b%Y>SldGfYjzwYfoj7%yy#YjX=o?ZsJ|FksL74gfWH3#CdFAeVzGus;K7K};sv zmLMo&5hHA-TMqYj&KB+}M zRLGUw(mpHe)6DT6q)v=YDB$q&USmKD^KDKS?Pd7!BX0}|1Yv~~s&eI%n=KhoS!K4a zhu=VTY8WUBVGlrw{!n(hss8GdCc zAqjgKf2CzVs?~0g&QtytQ z!19~ad$#PPs}<{A+<7a%0)+m1LHQ|!WPSSQlgi^SVMYJowsa?+P}fiYm7`~gKAO3R z1;8(E2WYA4YrM#3KWuPkp7&X~FQM)ckLQFVP!Wg(sWy2|bHv9H|S-pV&%7>6Rtl?$8wxw+icB;eDg4-Wv=!%^4N`-LAAW3H{-xAhRY?cPtx4cWf2 zrM~=`2ydu?-BT!*1Fn3ZFGb*{KWReN%&Om5zUG~(o{j4_V5K&DZOoF(`9!G{+E>cV zJ(;j6bi*t@$LennFGMp?x(1nxT0pHG+8HDP^~*!#@(S;}o4eQing8@Q8@_F_+12(q zt@D%sj3j;yOYf?DfhCc+l7w4WQ9M2C#L)TZn`g4Iv+yk4Z#BQ@~BNFy=3?S07!@^M(&cGd9 zPTTiy3e?V`$<_J%?BuYUWpeg;tjy&Ag|pFoO&2RvC;Ck%?Yc00#RyrWmcp7oC}bxC z)Z@vevtW=ge?XD4$@K|DT%qHMPS^IKj0Bxk(O*KDWcN>=mN3YJex2Tr!lVN{@FB5K z;y7joBtT!=FGC1fCOYr0m2&H+lK(ah zcr`zJ#1DcjQ5~RK`lW$_ta)91^&d0m~~8Ys3P3O;cHq|dC8I)5V*N1DuT7PiXYBXs9YhtC) zp8qC#6cXb(rD|1PhXSi?I17Fe{?CrupM?o4#QefLiXIgm-cS9kH%~n9UJzxG+k0RU zjBoW>O@U6qB*!#HO_d)YjR5Hpx~BiFNy^^7L8*O69Xp1x_T5z|zF`?!g${b;lRqua>pXU}5Kq^+Y< zzRmEn0*3-)6%DFIPspEo1f!vrroer(`u>UQfgIVNWoRmZze%$P+;>m+5n26daCN5u zMb@WZVU*V%J;MJM$HTRr`sks~n$KG@qUE*@jF|sr6_8W=?0(@T#IrqX<$LRc-pV%B zn!^mZwA_Wx=y@2fRWqIE_rVPKgQ6lcg@9ZKna>;z^iQrjLe0q*Qs>~X3x>a78h>r_ z;)ixdoyS6f{#NcBeAYChzV;DHVwh3ev-r@`4{ySqHn?3;LUz`-kjtW3G7=2hylQKjDpNHn!dFWj`U~vVUQ}GoyZrv6yIXaM8t7 zY8c#bBU1&Vv|DI=V-o|f^cTr4`5>-@)=!eU)1)x|&~zlqfT1%Lg)vnyny;5n_1f-T z<7e>bLtq#UHFZ#21HZ>qu?sw(NGNF3TH|?f5r&4i`^YG`5=A^4E9OhpXCB)A5o=i_ z_-J$Re(Ys+@H{+|DNcq_|2mwPkiGgU;Kt7xw0c~>jp4(U*rH|%s*9n7(9+RW7Y*(e zx)A&TX)D9Pd}!Pm7RRWAEx^a~{h_ZeyZ~*%kexpf(z4*jdmfO79pmhAI0KdJtC<_& z)@u~OfawlgG)^ujyqJ$OaB_P`D^$=YQ5szYLuWV?!?-I;PGiZ1FZyeXno-@culjA^ zmjG%}t@{b+sa}Q&%Kd{3e{#M!HJ~@$*bw&-yt3sM$if2E%?4DfI}B#I>KM@ou*Vpa z8U~+1A7=%H++EyjRR4gBpai(basTI1V26w$Oj*akiD(pY!*{O!ZlKw0yrs80gL0bu zckk8tlBMe1MEaOjr3E%?;u?T?G#^!8V_x@*#(_jHS%4NiDmYF;w4Ngsn4e-)nqNYQ zM6UE7EzTeo^hpoBt9y^p9j}Ko=f<@uM(KXO>5%oB1Kk8v5VIhljvf-PU{Jxwl)!Ck zQ9&J0+*Icah}NMewme}}We1@4b*{N-Jdq&n#Xjp6&>!J~8z1dvT*g_>I*T<{a{6@Cm!2p7c+8`KKwl>^DW8K*Stc&E{Vm z_U9F?07Z0S_?DsFYaGy`4)a9G`1^b0_btlx?3t_R%!`lBPXav&h_X^H%VlLGbJ-NZ zYIZWvQBv1`W8}Q9{NK`V4yOR|mv5SAzVyq*A=RG3k0~^bQsq{1g)wg00x7C_fpKI%pBGwC79@UTs$+dG0!P2 z`LR{2!HV8&&cMDwaeQdi^m~IN+wrj})md5J%K~Y7SyxIIQ6Z!CA++16`aMajssm5-jLQpMDtW~s z6JvW-Me-~c=f`px0D>W2eQLV0+70+DcBdDY03g5J9UK=GceVH6kWIXlN>(GL!ya&9 zN1Q?gt=LZTh*`t$q~AuME9lHuzW%xGKsgD!05iLjy@GHpXk$EY9@T8W|soiXajZ?hXdSz5VJnZ+caeD3*&G z&Z73Ps7Q}e#I3&3_m8l}0o3vTE5|>42g(537<0ezrkAgt1Jx!)Axg5y56Bx@60ZAB&Au@6*cit zU)Hq))~sH^V*#oQ7bX=1p(WY`JGpd%JLV<_Ao6?tCF3=aT5E?@ax z_fh{bbRo|x$gl`C5sdUC{*hV^s2A<7<}awpwO z!p8>$ik^}VRELIhUP|UjkEw#Fa*JZ417I8CX_$|F6+7}JWjp+0*4mnRMXc10OYOFfj$pC&gQS^&kEoyY%em|-S#`KxIo7C5c56#$~qtC6FiN(nGU=~oXmL9ZAcvL zolBocwodnHH?-7YKnJi46{HmE_arl}?%_lrX;#}rUr;wXG*RyahG9D(?s!(9V5Cvi zLV?n0^f=w82iXZ~z&7u~=^(CbpfU&oJqS3DUHu>Ukb=9MURfVRvU*(!WvDu@7}+65 zBQBzP8;Sn?TqWeNi~I1&fKD#*cj-VShvhRam3?bwfI_KZiaMqo|7Kr)?cuXbFK@pP zLc~vbGsxYAtK}o+r3vd?I=1SKuX$5V=Hpa_;;&n*s*?zvgUo`s}r1r_(Y8R?CFl1bDv^qp0 z(H;NEMbaBJ@vqur_y?^co2G5^r6QiI_LbwqXTrJL9Pg&vd;o=2TMLht);$a+HI{pb zq-{Ps*Lrb&8Ni?bN{X|61|wGSn`)1W-1$IrlRcS-soNwwZ(6*QiBTvn4-O|}X3TVx zubG+3#H#i`?%xI5DX3|Lo{_vec(p14p{^Zt7=Ln@p~+P6r#eKwIX0!TqGlG(%B0?a zy86IqU_RM`O%)XJCAz!Fh+N0N2f+Q|BBz9Ph(W3hnw`-5ruX1*Hi#mZk5t; zpy+<-LET zas}P5hH&etK&>r$!&v(tz|coU#;;S)$R2mKirs2I-#|Tg%NZU$w!cC}8=m8n14ypT z=|%36_}MXc9c30a#P{y-YS{H-s2c*K9SECQNr}0TgazH-(g=PI@Q{)cs+ zp=`KySgVZ`^^4~fhG+RMYpF2hqtI&&vmK$guUFzC`Z3b&S2;|czO1oUwP-#;%s^@& zpH>`iavs#@-`N z1$GL_k9W;l@SV2;R1A-0+GLbzbPn+j?^Cmkofl=W3di+Y_RURa1W`ppY{Yo2tTzw& z9##0M2-Y9nj(^ErqcJ>SAIY?>-&9 z2dblfvkPzrse*tgM6Nlm@b%Q@fip!V+e(R4jp*B5WFjhuMCqmD7)>S?SH<{Xd<^K? zfq(esIk`^)7IgNzTaSr;RhKFTWoA=JYdQJB{uEMZ%djs#31Rn)cln#{7oA~oIz&Cg z=D}!@x`bJvwb6=p&2IvU{aT&`XPNqwxH+D`sXpWYLT5Ej!@RN!rUQ#Gf{_v|KU2p- zOr@60FH9J1s1rXmOrO3R;SYOOhlCd7kAk9`UXWZJ>gq;hWF`KdMcie^QMUKls38nb zDs0hIXI5xlxZIDpVHJIJJ9~#yfx~FARTUeWtESxg%EXtsgT( zYhvw(z6Kq*ui*NDAj6Q;(T~9nAN9{&Jidhyi!QT_ytTsfG$`{xVYYLZ^!3xLkf2); z^cwXtTlz0$E>8dZmF)Ok>BZ7VIU1nu#=Yh-cDxMgX$2d913bK_dCqSdut|XISB`(I z`onSPy2N{owb`d*Gm%e6em%wGTXZ5t^$6X00QbgzqAaZ=tM_2`++CFvS6r`QKu2I* z41HoUO9RZ2hk;>uwQg*M!*|mzU9q?L*osr{16-1yw+0_b#Tn)ut8O-P{n#P%dox|Q zW@w6`8)m|;fhJ689W(wx)19f4G@>mtu|35yk_c^Qu#~LR(NRwe3puyiYb-ek#tHJD z2+g8Dv`SG`4)Ko{sKm0Jsk?d*HEUvbWbUo8qm?qDfGC8?ju*-=ap%|JzK~qR+3IoR zV)uH^pJf0%0Yx6D4l-?)Wk?_l)q_IK(zc|i58BX`R3u_RrOkaf=SDK?VB$aw2v;m6 zIOEq$+o}x%3vRpbN8Xzle^l9N(=aaSM>yiH{swAepU}e;X9Ogl({@2V6}`8kDtYF~ zmI`l<5qawuXi5AB#9Sk8iU>1c9i!*5Bdjfj<)G% zTQ7JC5)R&(K?j*^LQX`EOXSfC0~|uVdk5GHBx7&e=;_6|x7P%x!XD6BNHH};m8$On z;d9Ow2p3qEujCwo(Cyg3OB&Rk%qpv+P6TF;)_n}}SIDm`BqrmvZFmZ%M}@S%O~37# zB3*L%_a(8t-Uu-@`aQy6*e6S#Fi=s#LCq2wszh9QN;)yNyJwvG9uxmTYFbM+Q><+l zyR~Q3>F5za{vQHTX}^pX#&*LkHg2mLt2ArGtHuwT*QW`m0%oIajA;ATly;HjxK5z1 zLX^K~l%=Q->gM!wdty~(otu@zu57J^h7)h|0hFECqbUw+<(AID&Z%s=_3%d-Bfi{z z)dA(m&SLV(L&e{%1^w^I@%^yN=BI=pj95wSIE$$4(JR?09TII^u!0aL<7nzD^jpa` z9@0o`;Yn$2;VKP=5XSC?5bJq!e zqLSVGcih}usz$L9;jJzv_f+es>xgsn&uaO#!WC z5~hg#;#QCeBtosV5}y~$G8`bxtD(`XP8oAl{0XycdHQ=pVA3`F zsyMMtX&nD5wY&&rc?wFgg;b-JbM~&c=5z1wFLkJjvtf@gMWl^Q^PlqP4Cp78;nn}P zJEi%Qxp(&Cw=DAyE;Y2nx7#bzv& z!j4!OMS4Ap45`GLb4P(h|Dwq@1$>`9#6ajN3fFTj@bIjof`ZM|bMLu4aQ~fht!SBM zjm*y%RF6meptrQIU~!j;Pi>AaEkz>zq3$`uI zcU83!6ZtJr>d{RdqxZ^WW))e>K%d(z^-UKM5}E-HXHYt-T&c>am>LANITY(R+#O$l znSIPWOZ-+i-87E`5IWq#DrW@&t%sCwc&{UDB`~M+PkuJr z4r~5_?2t%583NH^2|CNK9qEmyidniEx|DQ$%Fr}$zH!Ete&9VlQ5B~S)DH{T^`8=# z=K)+o*MI21jNdwGx=-u($O-|yXaivhA-4uWv+VxS$GFb6CO#KZT~^qYF1~zalnF}p z;7c-Np=sQhlXI*?}&rF zTGgX0$2lQ4c6c|-lxh?vl-3i2@h)ir6VWPFg(zyrR8sj`hxkbI2Dv_s_Q$+IwI*H?pPH;-3oP>ze^6MG1%1XK6FPEeV!3%Tqwg>vd!DW_|YsvF&UTuh2qLY^W+aBBqqP$ zI5q@7-(?@iW|ZsT&C2({xdN?uK$ga0v^8OF4)gVv@UI)&%&%l)-vq#?p>u>x{F$g- zAuM5p*p}=M7e?{OfUGkop|Fyp5)lfgXWpi3MG3fJp}O8h3L*Icw*e%x6wrKaEdOO& zdgj1Lw*X-v?!A?R6TR`;yj=Bnxvna-vK`TJB*UXUK|ViD3S}zgO1q<~2}Nx>@Rpv} zZatl2;Vi@NmW-}-ccV?qOy3W zLOsnayo7^r=Y7U?NmVzlX6}%tdSXrJo*kd%B-Y$?Dz|7N4 zasl2phm3$5X;zU6+3gOXMhjBUh<#*n)Eg~dM(RcgbAPgWe|@aI{cPz_XAiYw!k_Gx zMIBlXWeHN_@47;F%tP7lU)hfIeBT@Uw;+85 z&91WBaow{$=suxP;O5Vt%cG?Hxrr4|H>)3Ed(6_(WQPSY%8S_boEK~1+<(+^4X2M`LYlzL5GVFW1swS9jtw#pE9 z$(1QcA_915HlnTnMph+@6>fXInQOrv#zf}y-rZEz`hB))#6-T`kt_Ss&{P+3?#Xnm zEDqC!pBC(v-pQ5HoMjS*F>-xeUL1#Hot<;aNY^!Q;nd;xCbXqk;cA9&p<4KHh&f)c zzzISWUCQ9Id%+HNtzD{l7bp|W1u2=ZvfBh~bvT)qZ`+pu$_3*#U>VgbJZM{C4SznI z3d~Ubx18LGYJ<9l=U|`r-$@kV@{XqY5nz!8UWNCr_{69lss}2Xh;?N9g17bS4)5rb zkUkbyxdO2Q)GBQVDrst<1wbwj%jDw+d@;Z0oh(1qv_)Um+|&i zUAX+0MyUQzPOd0Zxh|rS@Tg>ck8WNkj^@|RDHIix?1*}wZZR?96!yv~z)g?REmMY_ zNG6-e5U<k|o%a1w65;SNHC}+pyQ_aVriah&wx@CP%F?J>+~$H7UoO zYLy~3?S*jlAr)~$J-u6pzJ<st{EyOJZNU zd5v-;3aPAuA*YB17>1Q@*dWp8ytkwP>DI%^YO79B+~F)oJt&^UaBlI+j4rycej0TK zf2E42C+O!WROK4N|uh?K+Z2@vGe_LXC&Zz7P9GH!xgsS<~$oC$GNe~D2eMeSU=6Yf`6O2 z@Qq1UwpOl`N#^x!!+xXPB^ySOA}{H5T3#jlu3aS9UF_qFOax~i_j^MI6GpbyQ<(); z076U?!A8q#48@6k{+FiFXOM)6p-~ia9S+i6?)5dZ3>b)51uGiI?dz=FvYg$)jjuw| zI!N~4Th*D?3k~bR<4+hLwIG_3sT$P7`_1x$`JKB>?GsGvBEFHI@DY8b4KHQ_dM$ zsZ^O&t~Nt#<3v(VH;u9M$OYfD$vG?EsnSK8wo5LEC2&fZeG8rL9hQrXB*{f_;s#%w z%(}R@CwJhsJD&JnuCoMi?gN^`nXls2BW0U!9#8H7IQc1|Cs&4W2L9$Z!_gXJM-YU~ zz1-QDcc~|wp&AXS7lnm0osEyq-l1n%rDRu;61>^3aCkFcZVN4diRXzG>^InkV8m3> zU%6(g#Pltlcmy(x#QClbf83dL%>_nsyOI?&m)UALuDeNI#j`9e$c3+?PqjW}pP`;q z0Z&IiMUGmdNHyW*urHVIHZMq(8LBkD-=982xP9Qg{|*YlG>zA)rk%I_TYUF>QulD{jCMhV*Tnai(5WKGjm2WOWg*M6C|3#8D?JdnC@azs6rIHrpRTMC`*=H)LN* zq#J5{-wi zKT!uCueMh|nhME-jyb(u9yDONe45{^2HR+6Kz50Q?|Git1)ZMG<;fee zKpx1wYgq|eYGYX5eZ zIG7tgCBnbdGdiyBf?GP|f`Je0vmGssTyjJB`FHgOu%^``U@p$$$taK!_Wu4C z=syko{i74je|D`x@84pnYA13+R4PP2%WBCyG_Al+WR@csrA*5=g6Wa4cxZLpQY@9j z1q+e$ke8PiIQ~+~0D(&W?W$eB11ex*0|#q0&LQyHKGY?%{9~X6W8yP}3LtEn`&Q`L zD<;KwHkuJM74lo{yqE2laSjk~KU@-4+}uCMw+GEj9Aj;lIM7!+XRts<|GujlnajL# z%lBaZ<>+KEaPskOe~z^L8}tugQF;x(lUgC9{+LKD=y8M#{=E9Emb^1nJK89Poe`k^ z(Pjp~ZdRGwvUj`(@fn0hxx{~sFMb9%x3)`MS*x1h*S0qS(=8>whXDof>$}xH@Vo{D z?j4q}7Bc;>Uk?N3*<5eSz)AS^-D)4$E`p;uqju##kA?^s%<$mJ|4J2OdIY*dK@Y?w ztTy|lH>Jo0BJVYosc+?6@Oa-!^W@JTH*pWhyg^|0DF1oimOl(X!Svz$*aq{_4G7(> z`UR_Ixh&n360q~^*h?2y+ngm70yj1UN11zS+p_4{(ii=F0s05nc`x&K^C^o<7rgS> z)MRj!hJ33rgr(zxlvc3wCFz$zEa`vGQ5W1YjA($z|9%R@(VQ69TQA{%^wwRt0PjK0 zAtJQ=@BbK=U;GrfBXyym=J}@PWC@nbD0r% zQW&_fkj(r)$A8nHaSr<{d2dZV)WVQ+JDo(A1=m-b2Ne{iQNG;;2y6dy*zNznf8k{# z;Ln&(A-dMvxc+~iAkfMcfL)G!AoH_@&f3?I4fM5yUaqme{p@wb3o*Fk`& zre4)eIi6PYUu1^9uz6}{oz0}S=zm_rM&Ntaah)U1r)I5kjF&GNw+9E0WU24u*Sv@x z)sZ^dM)*3C_0;`X`Psx(o}WJuG{@$BE_vB={!eupL8jl+A|Y#wzt|66sJ(yv0te`> z?R0ZZ$`ap%ZqBcMUne1+2QrLy@_)zYvGRCk9b_47hg+_BX?nSJb6)*pO+Ar5SP82G zVTm?K+AZ&3#e;Y`;FQjn_;z3|f-+_Uu5_qNM6^3wgZ1C{i?~>>-cwY`Mt;HB8o)6> zL>^A<-66APQ~JY+MFwceX_)TLV)Y$rTdn|xNT7yE-X)I?n zF@&L@!U^s^DgTWf7eI2yJNWzUciU~6H%AKo`np{2m@%bX8Lvgqcc}p^jCUaid0!rp|X+(EgbqFhxdJ<5DbRcJUj@a+oTVA z1vJIQPw1;KYKFV7@WSXCA)xN0Vv1#IUtRO9OqZBzcjC=&W(KXbLY~VY?uDUaL+bw# ztA1nSX8n1`jK}F*e~|RYa^@szn0a`xwq3*uw&Od8PMh61ShvI5wa6GO$QHtJzf8ju z;OX40t|I&F-M{sKrU*Jrg8n@FgeO5uVdOOV2ozqu=8aJjOWn~FZ$GB|Rc=@rJGu>2 zDYG(WkxotDOAzofq32Rfj#kMu-NgPfnlyvI{c)+@;Jy+Y2YP%BJ+T3OOviUr{L8iWB0MxV%4=cdVu4&I$7BsoUdwq?wY6~oG= z5q(loAtVVi^eA{Yp(M}aIm?^B-jGE8RM!^2QF{fC|E_>I3PXs(a8kqWo0)Y3m5)Bf z`rAAj*8^bIy*=r>Ck1Zk%&J08yCD9+i~hwD;OChhtM=mNx+)_pLd&t{xN^K3t~cH7 z0LWp!<~I8|gH3)%UFfx4#5H*|f2u#cDmP#UzCkpkTaCgpilw~`sfkpB%pG`!-6^KY z)@^#wZSJ^vnR$9oPuOYWI-oHGN*!ohTUX%;gewpftVtE^`Wxn2La|vkbmW-wkw|$x zU#(pb0q!q~Gm&E0kQnR((lqYD%s=ety=;0wQM#_#xVAD`aiG>}lY1A&tq*Cd!33+4X`vvYqbzjje?v=9FNwl9c}bmXOU=Y%Y%fVTN74YJ9_D zg40u7a-!!P({$n|WL6NZj9cgQ+^O#Yc1+|~nlGO*Qb5jF6sQyLlboy;DiiPegs0|6r z*pc4oE683)Kytk77i4cTm8clZ`Hxa#wulPiV+r ztARH%X`8*O#3o3MkyVY;A(9bEMa0$b;}Urbw*gz!^@7ntcF&mCXosL=a? zg!j7tcJmr6_}2;5`T}1xw_yM3GUWH0|KE6F74f2SL4aN4V$I?rbIU2OAlAvm!dtuz}>S$ZaL8x-Ps7ThvgbJ_usY~ ztnE0Vn51=MY+1U z7wlywVu!If!?~OS&?3N(VY9!`V3{!pfE>2f7#6&{F%(hRhuvn=I(KVuSY$b;2x9}A zbp45k_OcfOZKSW>k{teVn0ah)xPRL=x1=pAT*&CJz&h9XqhIpnGsg6)t_;ogMn@a= zs*&~v;kiPa0mur%HvS8&^qK*t1zy+877oEh-$N+j2?q^;PeV$oGZ3+nCTJgva zR$$_=ZQh|wz}R7IB=hQG!Q<`XN-Mzs$NN(N_?8RsK?9sdep6GDByWn|gH7<+me zs41K!Z{~3eek~fLt2AS?YvKa#(5~p6OIf~FhAs^XH*D01^A&r)Habp?|MaY4dUJ9X zxpst%Pe90jn=k!YGNkbkQ(s(i*`CGHq@Vv%Ieh2l*z*imGv((R=|@6}mIeqJkD%`Y z*I}hhvdeNAsKrPn!tct`4_ryM?o6PFI3UDs#rMl^1$cAOLBIqeitLX3@tJRHim;kx ze7GgQNHPB9Imdk;rRD9(KGiyLk9;^mMwdLr<^oh{C9AGxz#ed|h1OG%6o%Y`EC zI+p43jU3*0Xj)$Qcj{h39re2VeM&Jj^qRQ&R=(A{sZXss=D+WP>Ehj=@)o=B|+#;|2O8UxRkN+VVPyr z6{HBfu#Noy#$WQFdN8;T;UkZZT%-%ELRv7hBH)CedTzg(Vc zjU%=BQy6eRzt04n1TLdZWP#k0scHVbK7BywP#KbP0< z@Fs$EHOj#}D*J;QtyH=WHrqu1mc|O3i-nEmV36kT$0pLsVWF=PQTekT)rFZ+roSqz z=Er>mAf}-HG5SmAUK?1{*>x5dsKu%N_&e#9md0O_k%v$j_zGG_7jooN@>XimJy@uM z+d#o!E-xkbrQ{&o z%LTV1qivp(UniAtKB&MZkIQMvO!s})b=OitB%WA8D30D_-h_P14@;S$#D!`zIbmrA5s4di1G@vm+m=P>fop@K`v}ux$VBaDWotLw8Br1ULfa#tQpx9@BFO~NP59OuSRFM@optb> zvWdhTsctkQ7;2FyHeJ(V`fYRX1W0e>w&5ZUqy`A~(;WE?kqfd=oUURC^-RYj3k=31%;)*KDaB@rYy^WxpqM{n~I(qj{ zovGNV#(dE(PE`Hau$QbB4AXo|072eP>XOfnK{{4CxH0+) z5&D;4H3ryMx*FfCcWo6XV^W2PFw+Ch1fioIl&ziGBuN6Va#-6Wh=Ro7+=^T*Bp%N>#4VAF*( zfaJZbjf^=XX$6Jxhns?G0;`7>S(|XTui<>Jt=XkAB;3B zBx<5Za?(Lo?Fra%ZCZ|2Ssw9eiorq$1*8jYh`Do$loK3nsF4Zm33laz;c8Iy(K0|{ zM-6J|XbcKY`70oY#^tMTzeXa+vl{Oe!k%V})f|~VV%FX-Ibb?X!MK&c^b5>$&cdPn zrBvT-7ZD0tbX6N_X@cR^eeA6Nj!hI5iwkS-?FBH7ziI9>z;=Xg_+YTeU;wAlv_i{$ zxbcb;GR#`~Y(RqI6hpe7qEmj@|7@yzNfpih`fT_G9Y*2XaYO_S^~hUOMr^`=mL)dk z%uU|Plzu_Tz??2qJ%Ai5H`SX7JMWH~9#=mVeUUAmFl>6B(tSdx5{F8kg~J;PIB}tK z*F0~UPQA;y3(vrhnX<=$ix|v@b$<+~&3lJZ*4ye3WqthKv4Hma8NdW{%jC``loXJh=q__^(D0Iz?Ohnq=85^3i zr(TxD<(wS9ATR2-Y6cCQ83#sQIw~Zc)RV zu*@5BY64U2QM#w;@_IPji-%;68f9^4`7%T{wL~~T8LQ8Y{6WNU^& z<0ew%Hng>5LUt~ZU?Ei|JOe88cyo?qSL05OX9hZ4Qvl%fJv`}$nUi&IvJRNyw)loB z4)}FN(u!ldv@f=3IrSq8ce!=kzA6|s+Jzq>&d7;Bn0BX$KGB<&FrfRFkfc&5fg_m^ zP%@%@UDBYtEi_d(cs+ACpAqm+@>EYpIL z#B!rAg#re8+eUQH4cec&UyG2N1Q6~j_xIu=9#?kIBgN?T$%cso_6=rsWBbY1o9H?@%sFdJq=RiH}m5P^%7N1nKB820R1ex z=U6wms44fL&-0`hx#%hJ(pX=|TJUFF%I&zpf7v_7{rjROoQhsk?`?FB<}J_NI76K# z$~|-}z~z(3?qay9S=T;ozJuNh_w--GiU}vV*bkOkk`9y1D;d`lW(%syZVcOu=J7h~ zLb;U;p{{dw)h<2w=JUwZSiE}fBC7#93~-=ST~5fBRbBd>#AYDcUP^RTCspuoe`V?! z6{yQd9u4EfX~>+UOkS#fZG)%er5DMVc>&nysj@VoLP@Gt>$B0wiZ)UMLScAtOKTAE zw4U=o{~bGx4m*-6+WAM&KPWenkSO!Wgy!kAGbiZ=2)ex;NcP7ehpTh3B@`3++5WwF zdQ`m-t==XMH`f+VFs#O))eh+M0*4Yp9MzNEyfVAIZkXc| zce!YYeL$4ccz4YqOv{V)H1u#+9a}TB(ySEqqf|Pg+~n&VmebG}ap%96z+dRoP4 zzFXz;px7j}{0TANt^c9vZ28o?l29nu@sChmVKX~hMg?q-}AKolINY){-(N*Rbj zOi&CdD5=q}W&>WI$}xnGjat5{{V8Kp%T)HAqTA`1iyFNR@3aC=?D3139_wtcpJf19 z{vuL%@WunizTegN*QUUQIo)SE=?S>X&knSIVtWR^OiJ$U!f&->*2=FeWa}kih~a${ zY>XH~CpD~(#Smgq&rOsZpL8~N(ZsaPKPumWN`A^Km_7h@X!-&sJNLL7Q|+u=TaRwM zUN?}UVFg}Pl$C{I3JT};y$BnNnoXzQB({aUE4*ldL1awm@R4Kut$cG8UR2+ufAPcL zemAYvns9(4BRh1UXG?1Z#}9j;{nUrL({?7tTVCfr&;DLtbTI_0K(TB~H^*+!F>>zhjSr%Xg9g*=!tqO86wx|p?5SCJO1x|U+!yW{ z7=<-sXP+D!3wf-Rv4mN-5VuvwPN?pvRX${z<&g9(GjA}kHLnQ|%7fIV%iZTL=OS^p zBMvFwq=#nHuRY!_Z{`V$+}I&@Jsq2pXR^OQMy@|QeRsdDdi*5KvI$vr8Y7oCt(!GP zefd$SF7HEcAMEbi6YBzQN2GVA?5$VqD3@hYfk@PC?DigmmKk;t~AC)SefeQ!l;de(h?2zo`zLh5{g)gd7SdUcRy-eQ*E`i7QpLR(vBW}fA-r=c^ zysme=Pb4HHKpbJzV4pEExYsEbIRCb3d*Hh`K^a|P88V52K#G{b%+kz1^o1>@Y&Rbk zi8FOy3y@Up_qy14Zm7ku{hw_$V>a(7-$xqFzAevlXI!7#8~d8ZJ}lETnKp6e^n5As zFdCADh|HVrc`p|%M$1;%`MnaiY1gT<_Jy`-yK9usrLc*nn!78LE8FR*dY|s;jO@)n zptF=F0pxRPw8ai@y{WX0g44#j5K`1k-x;qdAdNdg4PtI>PLM-$GLLq) zkO6i~_zed6BQtmu^9vx4VZ%iqg@oj#RGb@L018;x90BeeO3QVOqT9dgti|ooPUAhV zv;wJ{A3Cv9fv@T~LXzEh0I`m9+1%hq7|B+9{geuVAhJvSKfwK6%0_nb$~kS^0wy^3 zIW_U}A65Sk8JV;OElSzTl=sptrBBQs79D2l{=ql~<%^lJON}muXc7UAPn-3*2219m zseqRA?=UD-AN+QP<%Qm;U-Xam$Vsu zk+p-Ep>yO(g?7PjiNe@3;|}03we`(gx{BDHIRGuJCU$QF>u_z47*H8ydxJOcloEcv z!ZEXH2e4IB*zK9Qf8Psm45bhW4;tZ6p`p4(BQKd5gymOQtr@!XmbVU*k%x zt}b=_1GgJP7T6!{N*4 z>+cV*>s+$)ocp<-yX(11J8V0GrC8XH6(Zu51582zi};ZD$_|`K>=#XY?`-Q;>gjpH zNqZe{sWdsaxo*OM>AQyiVKoyjnlG>gR1Vg1a%ffv@we&@RaYaD)e*$AMW0kLuym+^ zaxTuDVkP5B4gLttrvrtM!0jv3KZgAL+Ik!?Bn!uw0JXZ}Q5+4_x{=pW&>PPib|S~E ztR+a@V_d0YSGkH0u+osv50pg##g|c{{+sk-3&k)?n{Z3eu#Bby#u8Rn&o?^)gMz9S z7C+5AD&352@C{&vh~vJL;WJd#YAH#_n4nS~(_p4;d4+C;G~_JfLE>gbWRiOv31^4? ztikJ}2N=qsAl75H?>lXQ)kR%+SulkE2aRSi7h`u>uoJU@OMxb)Cu*P;vNXb*^5q*W zK-IapY3Y5HsMRX+4+Ikd=${pY{ zFL3Ury52#0PT1GCxSp7_(&L4Q${zaljw6k!p#I|L&0oZyWrf_Pm8rlY^(O&i-MNH# z2D%+bqX2+u)N@LNYGkw58Gz@M2m_4m;dc7L>4fa1_2Pf)h}m*~bW^}N>4B0EzcH*OIKXXoWp^IHwos6f0&EzX!_%TV}K=Y9Mgr+Bq%JCDJ0^Ryp$0S zM$w6jt@A}lK-UdHQ&k32^bqZQzrYGC{j2Jmb z0sKNyp)ZOq%EEOS9IG7(09{=!NBk!dLjdBLD-&am zG(ZWRWYQiKrWe?ZKTz)4nlX0Dc9YxzC+(v|%s4~DKRubI_5UGzDIqgtj>|T<%bxP$ z)o|R{NXWCr$R@vp+wsSV%7YY7j|}qj;<7RF;oQCMUUbbkNVHCkUiG;#`@QNtY^<)A zGr{QSUTLnfg4_zOp@QS&&|Hn#ed}!EGm$3>3|KT~!5ZcNdO9%GaW%_ryQH`?RUq>2 zp6oLk^D{epzw&)e1&C3yWPtwS#ms8G|8S$LNU=k8U6NE zf1JrRvC~pgSLM6SORO5yU!J91$NgpH{SkeSf3Ke7xszV0k6trbn89E{OOIt>i+zou zGAl_wv_A*#U$meTCOF8c(JCN#*PiR74-H|fvM0yvB%S%f3z`$1R8AHquuWV%^CjT+ zIBwo{HjA%0jY~6gd-V1Z+LHk$rxk#+3^V+%`%7vP>JxAU$PY9+thJl2I|r4QQyaxK zFmEG-k9&(4M=d0RPr>hZfb^k0qt7mPmu}8P?Z(}|J3B}GDt2tscOp$HdxsnRxBCKC z2>dJ!fBlf8^$b0M+4139)g`)M4!{s!~9s*Usyf4M*9-ouRm* zuqEs1o!38pr%`*{t>plAk%0WIplN%q?`38{5gH(41JP;gO|!SjP8Y3|pwhX-cetI_T? z-*oU8Ex42wlUV3-V>b&JcryTySB;7IW~s5EOE(_4Lz7pSXoTu-b-VEsz)U>A0IatA zn(W_JON!wm?GyVG2fww%FUXTh!2k<Wy>B~I9U^+~6T4uT9`7>%bxiyL|B^;-! zsw!DGQX5Xx|NCr?+L|D zUh0WfmIFvyY+v1EW>DcYWKfcubHo{%$n@*!Jdc)>=yjCt-jEybH34?0keupwXOa5T z9;9$BVu#fZ5{1!~sKBr1_%sj%fI3Lu~*!re{B_zjA6K0m(ESnkV>6z zE3@zWh4;*vn?SdP^GA|7pHSCl0^Um8P9;ey+9)6I6Zk%~dd11X^ivZ`4!$YV>9^8bfs8)b<2G6=QmSKVb?Z#8 zo3};O1%B$42bGopw=s5+WUg)T=JA6)p@|o``Uiyv1@Ei`hPYc?$`<~zBBmFbz zs7ez>rDCu36ns~$msh$lN$S+QiOIe6SJjDMs9(NYsR?ff z7(6EC*ne(;{c*q|eDAE+-cpRZQi~r<4tvf+r2^c`%BLzE;U_kje&fSZr@ni2sK;iu zl{6Ub+b@_A))ChE$vR>Bs(!?d^;N+TqwEYTyB*6My-_pr<>I}0x2^3IyV!pbh-D>k z?z`5uo%W~VmP$F`-Q_ZiD`t!?eT_HsT&hdz>Z{1fomsNe_}9C_CIk++J9rP@;(j-6 z=f^+AUc5>b`xnnyrdCPs7e7@o2>H~9q=LTzEnq>OfEPJjsl(`0gmEOsOkNBrwKp6> z8gV)lKAnyNE*e;!vl*@$J){1TI(6WGlNh*VFGsY>3mw4-)-2rGYMIABE(aid{t;;A z=;&A-ihM1)cZ6CFmsGnWRAbB7m2QKx{lFU!lLK3)>yljiw|8}C*4WM+~8rx2fe37E;dU6=2SmQM^=>iXU zTW3RT2w7S^`GETFAMWwEVyfYk+L&Cz zt%*HKH4`?0YY#U*i&`9FjLS|tx3bp}hR>a2y!?O)Ehk{3W531;Zq;Dgzz;}0MscHV zf>VAaBu5E7&M8GjESn=h2_KMTHR^xRd^;%&Q1zhftNJN(tQ1OK=0JCo;7_UP$kx{s z^xFBlKl?}<+1yYP59t)!^Cu~q8@6K(Iv=`zJU)~vHzG|a+VjlgbSigI-}=E2rDp*Y z4GuCrV(U9e6}){t_fx4PcVC!W6I8r{{!IN38j6wSP((W#@r|w{cLj)-b@wce2wA}rr{jx{$|1!x=-vu0(HSd4a zm7`SwqmIJ!w@&YJ{z5$+nLR($sWnIJmY8bT;rR>{QRTT(KeT&BVfE98qnV*pGFRZE zINqu!rXKwUcVh$a+lN+15K8Eve*@kI{qUVAXGB9zY)X{lEt^o=TvYS}t|WW-LY}TvGZSzN?^dF^ZI3cVxeCL!Fwsl>9>G7ChgxxZ8Ut&un(|0 zY_M^Vh-7EO#;qDScAn=p)Dxy(pernIaqy<%|Bb*!1x>`9r-hFIxS;jRR_24H{10v& zn=!|jon*?GTH%oKdA-*;==o2q!a11%9~}Eqf`M|8=AR@1=cgDtvH`Pmhv_bC3zvP$ zvoY#Cmc_VjU@Utp2C!tJ@5;Frwbn06Zs6Y6$woa-AT)cGf+ufpZvoNc`}MZGxJo3X zGF6&AGR?Yz$}&KytlPH!!4>>|8KwU~xEbb2PJln=N?3Vlo%yZyrNVj=FeMO*Y+K$f ziQPTJ1{1<(d;*Q1y$cT69k1xAmIrk-%Nu(ZwA9VXU>f}cQI?hzqYnssZ=c$=EFp2{ zKfuAyGWWRISS$=>l5c%wB0a8I$dWw&(xME}pt zoqkS-A`gG6GlJm+x66Cp|B3Pn9&SyHu$NZ+)-M6$J;59%E*O1IVV4x`UuVs~`zkuX zJPgY4E&VrgH<3F<0+Cp`Gy(edw7zNelc2VXw>HM$3gF#zRJ(@q4qWVTF)6G?FvBQ2 zHfYW(5x+P(`6aivW#gKu-TNXb0jq@p_FWYB{y)wV`KO%aoE=;n zYFhXl)M~?sj7l*B%Z){L#HG{LL0RktIb;AIS-= z8cewTfvaxjMdHoF5WY#?Q;895&Yqw=tOEX608Xt%W8nVlE4A$tyuq4s;=Rw~ zPPz>C#)SuH3x>xfqLG$wTpZ7Oa*ceHyLL7VdiD&62K5xeiroD}y=sOW+r-9jskgqi zt|R#F#?a!G6!mb$6^LMr2FubVs~b4yv~EZ3aJ)$X{X+0|ebG`ag)-#v9E9(}%D1{f zjeX<`u}Lk%PU;r-(YDZ!U}L3s6canX%3FvA6+((**1cvDh)^UvPv$@Gn_>h#dtr`*78D3l}C1n5#gG=kGa$l`Tgo#;Jsr8>QBvX9iY# z+RI})JMnz;@ky>+>5ieC{qHTjmT%;{T*w0zMmP%;iaZE6Mdsu<6OjrDRZL@m6V|?b zAh~~@t6t1u^%{r8`v`G~Q?I;rm;EAK>^vIE&C6{+#Wz^pSUWd{j`HFMsC}we+lqb7 zKgOA(S9-c*@OW2Myn@C!;tLQit-suAS?(xzb_mkyGB^`$ zk*Soo)Fq!QQ@VadADw$MOe%x5e~sKWF5VQ(PgL=95-5DbqB$kU%&lE+J8P38Q4>9S z+9D5{J70Zd0q-=L?>VxRr;aKdf;3q4KV5OrXBATK2sq$k^YL2*R^Z8EH@1SnxX7jN z18W&~O7my6s8SBdZ8qY`c4GB+MH89o2t6Jr=03H(wO*8#Btlf0z2`=}A9~-ujl#L@ zM@+o&9#^%9&O*TQdlrv$i!DDJ?GGGXQ;u_XT$MejchF%SZ{8?2T;?;97S7(>AB(kJ z26w!SsoRgj-*@gZ`o;>wj<-}3*`fU%PO}qn zcbKdLcv%!oc}p<>MP_!e z)97m(;rV>uBF8nIJi!F+=T0375KM5lh6dWLcOatgV83^%flqmj;WWN(@4^1Ik?^Ht z_t)M?54@3{W^1k7>#URbT-&;irjYf;D~7J1I6dfR!Jt5wD*5jRtzR>n<`(5w2`x;5 z+yagt;(5zn*M~)}yLXtW`{9`t70$<*)DdrBsvXdRWRic~VrD|PqDpz$7}S$XWxmQO zZQ!wg8Ggki!8;*G>Z!Puu-@(fO-6|m0_$j=spBmg(6!LJ7zasGtu zOS#2)JI`K>{aRrwMpegE&Uejt%35pz;)7D6b9jU%^*`M$aBG&-5;%4=#r(Gc$Mi;s zThqcoZxhX2J@i>{=j#9~I^?B%lLdLA6H>G(A2UMG7#}Zs4~qF-?jbY9-i`KevkM!X zIx@Hzfzc?+6ORN{tYs`M76)R)ad=bv1pk1;4MnLLNNZtS=6RkosDd?7dq=>F@X%_P zGChvy49tZ}n4LoCpJS~(Hs0S%9zCVmEWZBO*|zD6h4u9Oq^z)4gwhf2GGu3t1=N=q z-`OjX{qEU=#R~CREx?VEb!M($({`**6c7F0qHp_TA|-}_{oe?Et=b3oo_M_^GIh(A zGUAIDup`JDFmV^eNJ*W5?)iI)VY3o#$;Lc|{&Y&g+fL4%VagpvjNubQZz>kPYl%{` z4oaYd$|`f7h`Sn!LariFj*6II_q<)@UDR$*PWi zr8jSZgw7Mx5WH^_vAoRjxdq-TCyp-7=@z+$6z7NW>*lxgI;aG2ViI)3T6Dk29Gebe zy&f*zCYclZ9eGL@eMH-FkxTuE5@d;s4^#FnnBX}Zm|$YzXnhJ{&F?+WvE*I2z(BYO znp5SQTjZZp&Cf;0=tUL}VKBz}?`z#I!wi>|uOi|PVgtv93)si~mnz}d7CZ+RPho!| zK3^VV;WB=~O{MlRn*;QWs(<&*%-piGE}1S)xl#nbCnIdfNXk|D3F6((#b?NEM6n~r z%1U1RkO#i+Ju?G&kI-h_5)J_-6Cx(Yg&QJ>eTMvLNc}Ws-qFJWHtF8)pl-DQC%Lgi zcBcy8?Kc?~!TRF?D`*_hk1%XQ*|;9hNj_ccz-6nCD7m9298TAiE*5wl=b1v}#F=%^ z=13qLI7xjoxjU-8^B<5_vP&xxGsV}@!7Zj;PVpU%Rcz=WEdU91#A3$oM2N|2ZFVRt z1EH+_fxjew;TO>2OYz3_z=U1LB8Jm(8lPFUCAzT4W!yb$(JpbQnBMKxgmXM9Fi7#Z zVD)vc=Gq02AEuh_b)Ci;Lt|YS5Zz-{7oiQ@Dx9(`BkJ9nrY3)WnA~RE7j=w}7#%M< zQ>F1)%}QA~^v?C0+Dog-hKJNEPU1`FONt{_o2C9Oy%=E7#h7e5Zg&HD-gVip2&py@ z>K%M|u)kfCF}J`sw~GFOu^DVuKCa{N;7Wq44tSoB;xDE*V?3i$g~fMH3Sy_j10ON9 zeDV)JeI)C8F}EQ$hto`Y;^?gxFT}5EBR-U5ELb}bQeKp+J`*<_YB3sK=|RJq6k)2> z#^V_i#5pE82XCi^dR&X`efcxt0#mb|py{u_2Q|S}n4;e*?9?QryMChvk0?i)q`u>6 zz&B}OJ?DOnE>=SU^#usF6IN^q!*|Y^<05d7Un#x-;%Ux1m{GS zMU22q4#;`>6a&$h4%GA&CNX%f!t6#yK*lK4z1IVdv0jjOPcz zE3ZQm!W_lT6)_V_X)R`ET$+pNDROgXV2sr$_)Y6m0tVJbIX-a411Rzfz6!UgIIpX} zhYN#2dnic)M#eNnv{B-|))3Dc+R`Do7M+WLAM*T1kKD^TUvxQO4!J@pFmZwF+D0NS z|4PigxvXyX5FwnIjW0xM{C+UCUuzKa9*DjH+H8^!yy#ot7LN@2|t zDgJW4F8O;N9kGN8ln-ZI&7Q=u)-)J;~Q2pfVpylDTZoj83!wnb@$3x^Y21vVu= zd{?-7$Rv|{#y84m*YumAV#olehDH9u)8g5mo5-A4RxLHya(PHgiN8KOOR7ZIFyGxc zaRM%WogEU5-F+80yXofjo_p4$L2Z>NrShe&URV&}+GLr=s+jsIfq{{u0RcPrMw}KF z@DJ1^`jdwD%rDuK@@`B_`%PTG=ASyg77Z<)iw|kSrzf;rcj;V@58lglgrHa_=46|B zqfdBU`9;iK2@FQ{$m{O8Bdgy(o4C;_omsSXy+fFALoU+fl;Meo-jshf3quNGi;`$| zKIs9s8Wv~v2x9&i8eQQtGLXESAntG1_7#)wWBO^-!*P3}{wSwLQ9l~ujd?XII(Dzj zJQ}#FB51-QLFC07)bdPI9YuS5l@2WrcB{^3X6WsA>;DK$8*+H>HYguwhk9zT8mN2w zq(H%IXiU|#qoAn&V&%Hv#QWu}22^BYRAvxc;DNv_L-A}TalM@}9X?-G-zPYO65sZV zC;093H%wV=tcIMNd-B|@|7o|k+QJQFg3w2ib-g3P63zZ`dxHwR8IKhV&R|s6?7(Zv zF9HfK!H}jOIa!b}0E zS#f0rzenDDal8jvGe%c96iN=SO55LCEtP7E7hg&Bcp5OehV3N=cFfkkuJE(yGq9-R zWT?})#>$e5KTI+iG(^=H^L~xT5+j2UZ=Jt#VeIOLHB!yvg5~@BK-rq@WPxi+fy&M1 zA=7z>J7gVut|5l*7%BLi2>UM4B|0spb-R4%o4hJRV0C?SHzwg9rf#)!GFUdvh0dvp zzW1K0zKG>cY`2w@A&E39CmxqjesBar_y&5jQlbb^`zTs-EVrs~6<^2NW*7enc`+b> z2X8R&b-f~E?hSTq66t8x_QHsk3BWHUT7)l=+uBj1o zpRS{$xSYNiG@t^D#r4AL@Pl+bKBhWDM5tu8Ci{k!fHlQUbKeJKDH zzD6HbEFjQ&NU%*Ry??UIv;*}xdL|T6%)Gp}+L-Jo3YgkIY1U1>i+`l!aX4>*tlfQ| zv8t9Z#sgWp&1~k%n}aj^9)YK3=N>P9@c7OK+8BSCEt$umivmtqCXIuEu=E=eL*7_ zCZTJoKJ5C^)pcwhk&t%`_EJH@hljZ}FalqgXpw0yiK<=A(K>E54324^@g9*kX*^9x zaL)YqFpIz|%tNhw7tt?{5 za8CztCqaVsVb{VwC1eOa!K-7joA=)e<94}h(+XDuNb*RnUN$&HAveeq*<@^X+^*E? z)(%LhN?7R%*D4gU!!=VUc+@%5Jb1oF22<7{I@<6|wvTlC+k&G)qA>%faF~9gvWiT9 zS9ABW0GTjmrmKJciLuqfd5D4c%fVv7HaiZ@JFxo(>(%px!){e9!a3F=y~fsiSC-zI zy?8S9_7f~_&EVDw>sw7p7IB`bGJIQ3lVaD+6}^B`G|p4#by&_kOx`&xFRa3z`}%^RVOl>*~mCzlgugr5-I_sPC?J?$H6 z(Djn9j%r<4b#$-j81|)2l$fa+T=Een%Kzr*{W{@}U3RaZIAO^c7P17sMGXVlX$Qm6 zgqYyS!)!u|d7mCLk`V>hW?|RLJe_)lHVvl+x9mATJlnm#FrFBMN`QmPm)PA3H9`(! zbA5rk5hv*+&VKbX8dPaug0ar8vaAlV8^lJrdf9U&5|Gm z4-w*I1Q@fY>Hu@D7PKF4B+Fs#2)9_9g_E$i2Qlx$#CKh`bew!YYGf2&y1g<`&^%7| z639d`ajo+Ua}h4&RWmf6ofvMc+cV6L<^Uk=gEZk?W@is@a_7k-80kL zjQ6jVg5&kcZHKwEpzgyF@HYnx<5HbeBS<=r+}$03qv4y>OhYd8>EzovyQ)uR_izpG(5*m;-$$jS}2b z)*g8=FNMBC{rhPkYj$yGOR8NP#-2_)v5L5pF4QvQ@ItlI9Ak5Ns6Xr*esrNNsII5A z-nWURfW_@vbY_K_{&&=w#e5sLQXx>;?dA)cPO5;CJn94PkfAl#L=fP3RK>+!$m+vU zK$exZ@1((!Myo(0pO|zy#X*;QJ6PNyl}~#W3&I>U*iS_3+X2PQH4b6Z+560tjU1Hm6yO1eN$TNa^wQ5?;IH z{vq;0yv(N4Ql=|-f7Pi3C{57m)Z1Kp2}d)_o%T72A7(`Mnw|}e1n;8fVc=ph9tN(p zHK60-Fpu;1cfYc5|1DRV@GvH^!_gl)UxjJHXSY2L@0QO&h6Z7Ovxa*dP#a!08~kKb zpSR+0P`~kN4m* zdtR7RLcKO+L>csMUD}xWuiW--I7QbQWtG3@pJ=G{Spr4(MOD$(iUR2gz~l8&FW!{> z_?1*W%|^$XEti&<86r6ybvaM;J3?+<=Zu78$&1u4G*0Nyarm_?L!VH;DLztTqfU?< zZ8nOE#{`xq`QJctYwMBjY;^>bmQg3|EiEEBfH_23c=Xn53+&KG3Y}JXZ}nF94K*_k zWNIpzcdWt2wCS&IF_#`JzB^t5hqURKd}O}c;Mwm(AYA*Ip_Ut*M=lf+AVD|p{Qe^q zQu`ebzN@uLxWxJuL#2k1c{DTNTnM3o)7YlV7(n@>{E>Eluuzuu)|MPJ&Uq{EniW(|%HzwHDw zYze9UX9Eknab=VD!Q$+DGzpg>GDfAoj|KW#OoLI<`X_hqdtlzkNi`VU$#7(&5bKED&B-@@YD3uTgwQ)7Pgo z*YdzG05vSE+ZH4@-rIP9j~!yuRSUB)^ZDTVD9QQvankRhla!P!_-K>@IuM0CqbcOo zexB>^H%UN*DP=;=2lxH;N*VWaKouTK{Z`2M5jxz!_S;`)weRou=uFaS*CC>SFqc9e zZGw99dcPKir%;HerLpl#WM2$n<7@xp!SeZ!Xw=cV9va7ci*p2sQZH%2WgZ}oPoF+T zDAw)xMyBfz6mw2n#=a=D&p)8|U=%p_K>trLSFkk;Zk&{{bj<@zd|Z>$Cv*l`=ZI`v4}6N!}dnVVdHgc8M#QQ`raoX53+-W5S$f{yD;ZPLa)KCNbS z5g~z5$=Gc6Q^#niWP_)K_FT`sZJjp@By+X9;*FfYR*t?Lg_HCPrSOo33kZ8QGrnG7 z{;3XcO1Fb27xZO{i_E_EsEu8iod8n%ASI>vId2P}Ghm~AhD;lOqj|ukf%#ejGX{9^ zkm}OFu+`Zs`s?P*n#7byBBMX7Fkrv6T~|MX^r{wP+=&^Hy}0`GU2qFU7w7}Gd_Q{h z$k*1Ajz-2)F$T6gO%J3Fj6;zmAW8rFN_ZVmiXb2xUsQm+ObU^Ky-j>$k^VUffpjhm zi2mnJbyuJ*XoV2Rp7jm8WP0*fKUz{gT|xR_gkHPREO=9{X`_bny*9UDzWN!JdN*~( zM$Ibqk5C@nF6XkLZ-l2SJqKVbUm>%5E|mS=vKAm$qpVyHZX6!X!{Etx{JQ0}h0B+2 z17phLnTJtOA0uT=E)b;!V*1EC{k z?q*(rm_W-t2kJQ6t_(X>vqmLDt|RoWf37*?R1*!5$I1&)vNh{Hx7y}6US$f$VK1IY zcyfM@!uX80T#2*B=X}Fj->Zt0loj~O#?RjEufDfxZhJSv>jtUsrlb~{-xFLs8{;ep zRH96yZjc29jISf+o<3h<=@#`w}FQi`c_JLM22Js9UNRUXBZD*s9uWHKYZ6RNS=5_$Mp$jfnPw_-}6)LqD5!;7oR}3jv_Jg zt=LvrH%REb>DOyBf({}AS8bfIJ>;vdKtA2=`fzEP`Kn$RD%?f4(DYoFUU?1V={$5e zpkJ>(4G0d#c#8<_22xNCQnY ze%&**^2?$A>s@0OG5HWEvdI<=r0#Nekb|W(IqOE8rq16LF&WVDTQp;rz?9E-EFoSa zfZ$qetWH<>kZfAr%zpcON;Tz+1r_;*x##?Ad+N?FVN*5No(Kl--yPx~6YVQZ&PBGX zXt%1r@@sj?YFm4VG~m`-XtUPy@`|U}XW4}``!Em(PmNq8w-(=gtzbx_`H{MLk+U#o zg+%44;$Z?|WeW0i+PbkwnK;|4AORl=b{8?ZrxGYWH(M}O^#tF@`xU`I8Mtz)<`9cQ zqP`b+b#7X}WqIsZ{^oQmouq*}Mkfq?hLB#rDSty{{#HY{NS$e6xW+a00D4kdV!5@a z-;%~;(EXCN|RpIY^8KJz>XFFG;;(K+&jeyPCD zLZeA#2cx17&#K(T|k z5C>WvpW%1Gd=v}b))P6$3=|@3kNn#1#Y>jOR?3|lltBB?8crAbq&ciH_lzQsK}U)B~!ZP`b1J ztOtU$pgPsWL$fyO^dd5;YEDFIo7=@hH*NVLV`GGBJqT?k`Ilt`*u$<2RZk}~XY`8f z#UmZZJo#Yx20)cpJv7*U`j<27GbMuKf|YW_!;6%>_mHR zlxS}k$ptd=&mFgyR$aFK6|K>GI{kkcbOh5R*Y$G1Dub~cqpeTbklMM~y8k6x@T#RYit=jd(SlqPF@uP~Tb#!FZXY&j=K#j5wbtUKa;J=+fQXp_aKj zWD(tOVzma8dzoW-!kTi=t@XLdbhEU4WnsW(Bo;f#w3+coHu6ad6^80tO=JajN8mYD z#D-O#2TwQXJ0tSVNXk)=Q@wZ4wG&RZFSC{>vR?3=n3JRUBl4@DYtRd&!{x@W^dfI2 zV)rdtCE!&iil8X(CIVi}p>Cx+#jYCW`KhZnV(1{TLL3yEolUMFpeFfhJap%D@IuG! zplychlXo+-M5jjYW{%b(Al;1)h3Sx$uc(CZB#SpegOAq>*WGk3o{W3bQd?r{ZUD(s z*YUoI6ZbT^NQF`R;LnoC^zyXz%XC+xHprFsVUgiHkAk6zdVpllqTOTld&|q(AX!t7 ziD~_AOs&?W2%gjQgGKJ`ks0a5&X|g%I$0Mze?y>}YOh;Z4PbeAc(Sj|#HN(j_~2mg zeM}dCbc;e7;-)0(6If>3%O0abUnOR&PwlV=KH#7ardUis>v~l7Ku8#uA1RQ34Pm7; zkAEsj?sz0RK2nB%rQcFA9*HZ*tMOYk8Ggp(<7=+eaFHO`bj4$OS~tHWZUhGQQrfsl z=Vn)Fd+{o)#!JJeUHks<%bW;!Ro;=tBloKW7%w`F`)Q>Hn_O6R1 z^OdZmnB^~7-BXoGWmAn-ipX})5p2eoT;O66{OJFdpYT*=d|J=}Bw%C{zHiuEB}!$x zMDI||Vve2_kD3HB(|q}um{-a?IuTvlV@{sRAX_fSd=8mTbZ4#-Oe~hp7^l{mU(}>{ z+P1c-3yFjXo+~s{HfV6fPtOxdtmg8U#1Be+C_SP3PAyDYSTH z3f1nZd^^u0Yr*ruzZ>~@!J-p00Tc+anNHdDPfeggR=nnjdZZ%9G5;>Ls^bjvYNj=; z{U;YoCZ8jun3i~5)~mVJzQ)(>!FztX*$~4%%`pE&B2Y3r0J~U6GDVO)mA`TccaD_G zUFH^UYoX{gG&FCzzP!ff=?v!>F+jx=x$N$0t$;tF#lioM_#N3R0F#7p9_#e8B!_Db zJXYfm-uYx=Y}~y7^4gBa(`wbuUWsaJ0D+Nu#WuzWekJ$G*6t1m7;Lt$;6_F8#L5Mg8#XtYt5FV`q^ z)@tDiVb1tW=F!a*^L*ru)VuBnD_z3-d(>w`Lmv3#o*xv&I%c5+bx+nx_m)iM?oon? z`R3lvM+90wEo86$@@7!Y!`kbfnn0*r$aFr#p5EeP1?-sWrQ9>h_5My>Fp)Kczm5qP zzVLt!=PkKY+!?I7kI!blgH553MQDOQi^Onkrg?ctX|4hYW&`%e>>Z;g zk2i-)J9MpCq#>XLP!_W{kb8zDdfqAGgB-T?pvnk9A52OEmHp;r*2DZ@%eO!qtoGrV z9708WGB!u?Unzqfc>(`~mbXN)%Q)&OoT@KL97aS=tGwZB6$RFmkZ*WCAGCWCH0mv#uVoU>=AKe9suxSgo6Xu5k8 zwL)zKX?+G36>YkXKotV4;p*%dUMT^Eri5w+tCjkql;~c#~MWp%3A2>mvYVZ{GDUanGyvi~6%n}mgcoeIbCx!P{qvOGpQprz zv=zSWrd@&d+tiIr-k@AjULQCR2UNG<&V>Cnj#24K>Akj?GhU(zP15SN-|$45S$caH zFYv4YVT^0nA|c6i|2O`CRg^_2mHeNq4{e@Zz6Iiex{kEw6Nf4x7nRd%(AbcQ?};k=9Vjsi=0%vCy~FzP$elGeIK>r$tDad5cjufAqKG+b(u7 zqtiB>86c4V83Lf)R(G1E@}p^rWIL=;P|PHmC7Qe6O`X7UugLmd;o z79K>t;M$cgt$eu1k_J%j)&{z!%;cQ%G^qIY0Ge<*{KJuAC@G?jycmMjDvX~G{qX3t zFC9HW57!Y|R41ZU_1AxcKfQnM}#7P_^h!CU!TcF#PPCA`FJ3 zAx1DO!}&awbq@!hGMNY^x8bzGV~NGIpZ&qwB)*ICFmvBB;y9^kiGjJ4Lw-NRIlzvqJ#4f@RgPZ)l} z57z%NE8;DjfhGyH)h>a14^=6`j?_O0L=#OlF~MbNx_^=X0FhEeFMiS1u-#}bIZbNE z#{2}TbpBKJ^!@0z)je_Zui)TI?|n{h|8^>^=pd>`xb{FbvqHck?F zxS0YT8ySx4okO|`W^ueN{9lNsq6nO`2bgX2ErI243QHug@^Ww>pbAkU_d7P#Y;E<4 zNr4}7KwDdO|1}X>`2NHf<>jPqN?sSRn;g81%K!3Xpo~<{$qV@Hf@#{>za8IM_|LOj zNeX;UD_piZJYaH2YFb)9f+Bol?45e9{gnwS1cAC~beSE`ma&iDM+x6{h|>BgD!P5r z`tx752TnRkkqSVI?Xq!6xYhfO=GU!|Ou;44cpe=S^EMttF;X&AhW`S~Habz3I|7h~ zlhU*`#8hJV4KwgRM-ESZ)&eG(i5x@j{a;_Fz6i$dzS@k4LeC*1Bhm9reddQ z#M?esK!f(d`5*>2mj3dIBm_O6)cB`}Qxd0-{O#NyfQjKaph%$#@@10}qWQ+npvrG; zxm{Apzoxnm9fF639_$}Pyc*t1yZpZBN_$nHcD}vwk^T0aHpM_ActmASt35Uc5P*7J12X@cXwLGiKcY9Zbeo9#zFo zU$@)d)3JX#hokZm`x*E;^AmbfwS!LaR8H9~DGIf;>e6*|bj<3vr}YmSnP+2kjjd>n zX)tJSymWcjEdmtzp+@a4*o@orfDic{A4HMsaSsnsn`>RXzxQDw1Jlj?%5KmCyVKm+ zpBHXh4(;dzsNLJ@A6lB6+y>XU4)Lzu#sAH3$ebbcANVc0d4wC+QF&Q;r<)fFc772O z{Vpy;3aKN%TYuW#UH1GR_}sx&!b4Q(b!YWwb0sH!bV9?ChuAndv&%nM#E@mK0KMWC z>Fk@bpruzWXIrQ0QV+8OMIW%paudG{?bnAW7u&_MdShDCM^$;bUL-juX1fNFM_vOl z0y$;GIufCj_zdMy?5Zfl%-wnvE^6n`hbO43L^#S@TiYpo+53YY*&G43cLSytK<_-G zx;Ye1Q91l1B9+}JKCav>PAgbY@LLW<;p!(Iu;oAW!=MgB{xp8!M~`+{z8{pW5{ImY zPj#&zfQc2oQIz(1^$r-I`Um;n2`Im^x}xyX7HA8e+oSX2fWS#83MTbil5_U&-@hdL zx^0u?(L&FY>v8Q&Y}L0bKWB}JT&S!cNSS=Qp-WnwDJL8ej!Q}7$}!G;*#M=jk2I>7z+IWgS)Dq9;Sd&RHko7cXckgq5Q$$&`ux8)4D!8*D=XA z73CU8TOzat;{Sm|58i}@p|uE5AH!$AdvLa(UH~3oWxy9T%D!&mBT#vHXPOu-ur#`c zmSzBhq}{F^MOyARld=7}ncx2VI#4qPIAi*c$8-qj(xO*e<-Tcl0bkw?kPT%fo!i8F z+8NmYT^N|h3Pi$M(lXQ>`5^}Kf78B}7k3C@&jXSM|f6Df_Px4jckp8ixGA zvg@p<)eGdhqkrYuo0lz51r7k7vcBT%`+CW3u^b@{f1&2P;O;%;06J$eb1G)pfajSV z!NRuHhG~iX=4Ea(P0*lCL~nz3PIA#8DKmz)5Pqv;Io(4S!CC^8sPxZ4-yu%F-f9LP z?OB+>>ualj{`^QkJFQ8v#p-O9a48siosZPhV+`cew);Epqw#sS+zmlLiKI!et_{{~ zU%}kBK2N*74TAgq(3)I1I%+evRx&#mSLI3D54F{c`wA=54Kn&rVdxm#ebV!z%3Ff) zo5bS}O@596#5m{wzBc?93q9up1`7Up$tDfnetrm;trpBTg(0F>D3LnV1EqhJ-%hL= zixbVs&SiNAeuK3IrU8spYHri?)!!Jzvo&u6=GlWvcIWa-K7xd=dD~L`z5x!PBiE+F z>@D9M6gwRrnJ%H#ZWOV_fZEMF-FbOvJJ%{Oh!2eRx&Jp=ImQG?CKaH7X;0B@Lf6iV04?-clt$^aQ zOYkrR^b_P0p(Fe3KmY6z);xdqsw4MbJ_P30q(rBjy%0i1i3~#rXlf1?@12qOR6f$>*4xf|XKi)f22jn!s53+D!c!gm#DcG1zmCopVa&B)-~M9k z`~!5yJ>etOM+n2pUkm}V|8@9E`Gj)L+Au5X-5BX|)!%W%@`N5TqXYul6uPw;kZ<`& zet_tJUCZbUD?3yJH8Q+%}BD? zAOZULJVf~ReVP9ViOnk~nbKPY5)tIJiMoDg)bWW{7z7{~%xwclRc-q>h8g=S@Z)h7 z@Z_^Ky-U30PvM<#n!D>VkzgpIns%ytuU5dO}-Un{S@V{&JNDZu3o- z#?i>zjjy~Lpqt{s@f8+?bQ>#k1rVg<$)2SZq^S1mD~L4w?38C!&qAgT-*g8UCO?RP zK@_6%J4|-kr69Uf$jutN=Ha*{(v&n-ACm)}Sb|J>&FlY_VUHhvVm90XBdaKTt-~w| zZgs*m+zF2Fc#F3MUAUc zQVtq}$r*l4$QeG)Yz^~wgcV9cW~LpwbG;?c#emS4B;H<`o{&ese zbjB{qLZ++AR)^Cm$gz9L2F979+*lH*uY8hZB3OIN?}_k|LV|?W!hEkit4B62_~3JV zWS6|Qn{t?>+oV4lNtexjNSO1Q*&hNb+wD?)x z%CA>*MYD|9aP*U$K4k-(I+ul>OK_ZxdIukN`1VtU-`rLX6@&2Y_=2zjh z6?^~q*BP(W-kqu+U9@YH`t0Y|EX?=C9#AblzxM0gN9Q9?-@382@Mp!^uHNfAS3hb~ zKd|w}&5ac^4R7DKTj;muYsSBoUyuLTxB9A?`18K^>fOnQS-c;6|K0lT(vP738^1oE zQ(T$-+sOX;`S}meU48lde zk9l?cx8>s6QwwD0uSr+?KIdcEy%|}%u3LSd<9p}w%AH^5{H)ya_4vlJzHv3+LS`pWx*d)GcM)6czsr}VA$irZ^eA2Bh__Om>G_U0_>cT10%WzTh!?@$KP_?LRH2{XJ}xd`H0e+R8#nY4^70 zH|*Z^Pn+>)?WY|6_^-QIj@e$Vy%Vil`?czXer@6VQu*&m-fzBs{c2}#XLmk7KY#b^ z*|R_X`Soj8fAx;vfA-&h|Lz@MR_fd5&z~Ee2hP90sW_H$(c;)=V6K1n@#DsR`Q!gv y{`a0QtLb0y`0xf{0!?OYWdXcU7}kvYz7NdfGX-)5j+CEZ00K`}KbLh*2~7YvKDT86 From a010a90ed6b66cf1d0f67250ce4b04a0943d12f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:24:13 +0530 Subject: [PATCH 12/30] [mobile] New translations (#1092) New translations from [Crowdin](https://crowdin.com/project/ente-photos-app) Co-authored-by: Crowdin Bot --- mobile/fastlane/metadata/android/zh/full_description.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/fastlane/metadata/android/zh/full_description.txt b/mobile/fastlane/metadata/android/zh/full_description.txt index 301c5bd35..2410d9da0 100644 --- a/mobile/fastlane/metadata/android/zh/full_description.txt +++ b/mobile/fastlane/metadata/android/zh/full_description.txt @@ -4,7 +4,7 @@ ente 是一个简单的应用程序来备份和分享您的照片和视频。 我们在Android、iOS、web 和桌面上有开源应用, 和您的照片将以端到端加密方式 (e2ee) 无缝同步。 -ente也使分享相册给自己的爱人、亲人变得轻而易举,即使他们可能并不使用ente。 您可以分享可公开查看的链接,使他们可以查看您的相册,并通过添加照片来协作而不需要注册账户或下载app。 权限 +ente也使分享相册给自己的爱人、亲人变得轻而易举,即使他们可能并不使用ente。 您可以分享可公开查看的链接,使他们可以查看您的相册,并通过添加照片来协作而不需要注册账户或下载app。 ente也使分享相册给自己的爱人、亲人变得轻而易举,即使他们可能并不使用ente。 您可以分享可公开查看的链接,使他们可以查看您的相册,并通过添加照片来协作而不需要注册账户或下载app。 权限 您的加密数据已复制到三个不同的地点,包括巴黎的一个安全屋。 我们认真对待子孙后代,并确保您的回忆比您长寿。 我们认真对待子孙后代,并确保您的回忆比您长寿。 @@ -30,7 +30,7 @@ ente也使分享相册给自己的爱人、亲人变得轻而易举,即使他 ente需要特定权限以执行作为图像存储提供商的职责,相关内容可以在此链接查阅:https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md 价格 -我们不会提供永久免费计划,因为我们必须保持可持续性,经受住时间的考验。 相反,我们向您提供了价格实惠、可自由分享的订阅计划。 您可以在 ente.io 找到更多信息。 相反,我们向您提供了价格实惠、可自由分享的订阅计划。 您可以在 ente.io 找到更多信息。 +我们不会提供永久免费计划,因为我们必须保持可持续性,经受住时间的考验。 相反,我们向您提供了价格实惠、可自由分享的订阅计划。 您可以在 ente.io 找到更多信息。 相反,我们向您提供了价格实惠、可自由分享的订阅计划。 您可以在 ente.io 找到更多信息。 相反,我们向您提供了价格实惠、可自由分享的订阅计划。 您可以在 ente.io 找到更多信息。 支持 我们对提供真人支持感到自豪。 我们对提供真人支持感到自豪。 如果您是我们的付费客户,您可以联系 team@ente.io 并在24小时内收到来自我们团队的回复。 From 966cc697e71dbe002aa46acc7aef2d59fe24b773 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 16:35:36 +0530 Subject: [PATCH 13/30] [server] Move the server related gitattributes within that folder I mistakenly assumed that the gitattributes file can only be at the top level. However, this doesn't seem to be the case - I noticed this in a recent PR - https://github.com/ente-io/ente/pull/1104/files. And it is indeed documented: > When deciding what attributes are assigned to a path, Git .... .gitattributes > file in the same directory as the path in question. .. > > - https://git-scm.com/docs/gitattributes Ref: https://stackoverflow.com/questions/71784062/can-we-have-multiple-gitattributes-files-in-different-repo-subfolders --- .gitattributes => server/.gitattributes | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .gitattributes => server/.gitattributes (100%) diff --git a/.gitattributes b/server/.gitattributes similarity index 100% rename from .gitattributes rename to server/.gitattributes From 6e9893e5c516bebb91504d08b3ae2ca91731bce0 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 17:14:34 +0530 Subject: [PATCH 14/30] Create infra directory --- infra/.gitignore | 2 ++ infra/README.md | 8 ++++++++ 2 files changed, 10 insertions(+) create mode 100644 infra/.gitignore create mode 100644 infra/README.md diff --git a/infra/.gitignore b/infra/.gitignore new file mode 100644 index 000000000..a0090b46d --- /dev/null +++ b/infra/.gitignore @@ -0,0 +1,2 @@ +# macOS +.DS_Store diff --git a/infra/README.md b/infra/README.md new file mode 100644 index 000000000..e1ad6de6e --- /dev/null +++ b/infra/README.md @@ -0,0 +1,8 @@ +# Infra + +Various knick-knacks that we use when hosting our servers. + +These are not needed for running Ente's server or for self-hosting, these are +just additional services we run to make our infrastructure more robust. As such, +it's unlikely that you'll find the pieces here directly useful for your needs, +but feel free to have a look around if you're curious! From 3e38d56579af95eeb94d074677a820bda5cd6720 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 17:15:37 +0530 Subject: [PATCH 15/30] Import the code for copycat-db --- infra/copycat-db/.github/workflows/ci.yaml | 29 +++++ infra/copycat-db/.gitignore | 2 + infra/copycat-db/Dockerfile | 34 +++++ infra/copycat-db/README.md | 144 +++++++++++++++++++++ infra/copycat-db/Runbook.md | 13 ++ infra/copycat-db/copycat-db.sample.env | 8 ++ infra/copycat-db/copycat-db.service | 20 +++ infra/copycat-db/copycat-db.timer | 8 ++ infra/copycat-db/src/backup.sh | 50 +++++++ infra/copycat-db/src/restore.sh | 42 ++++++ infra/copycat-db/test.sh | 20 +++ 11 files changed, 370 insertions(+) create mode 100644 infra/copycat-db/.github/workflows/ci.yaml create mode 100644 infra/copycat-db/.gitignore create mode 100644 infra/copycat-db/Dockerfile create mode 100644 infra/copycat-db/README.md create mode 100644 infra/copycat-db/Runbook.md create mode 100644 infra/copycat-db/copycat-db.sample.env create mode 100644 infra/copycat-db/copycat-db.service create mode 100644 infra/copycat-db/copycat-db.timer create mode 100755 infra/copycat-db/src/backup.sh create mode 100755 infra/copycat-db/src/restore.sh create mode 100755 infra/copycat-db/test.sh diff --git a/infra/copycat-db/.github/workflows/ci.yaml b/infra/copycat-db/.github/workflows/ci.yaml new file mode 100644 index 000000000..aa57e206c --- /dev/null +++ b/infra/copycat-db/.github/workflows/ci.yaml @@ -0,0 +1,29 @@ +name: Build and push Docker image + +on: + # Enable manual run + workflow_dispatch: + push: + branches: + - release + # Sequence of patterns matched against refs/tags + tags: + - "v*" # Push events to matching v*, i.e. v4.2.0 + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + name: Check out code + + - uses: mr-smithers-excellent/docker-build-push@v6 + name: Build & Push + with: + image: ente/copycat-db + registry: rg.fr-par.scw.cloud + tags: ${GITHUB_SHA}, latest + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + env: + GIT_COMMIT: ${GITHUB_SHA} diff --git a/infra/copycat-db/.gitignore b/infra/copycat-db/.gitignore new file mode 100644 index 000000000..75236ad1c --- /dev/null +++ b/infra/copycat-db/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +copycat-db.env diff --git a/infra/copycat-db/Dockerfile b/infra/copycat-db/Dockerfile new file mode 100644 index 000000000..4328ef17f --- /dev/null +++ b/infra/copycat-db/Dockerfile @@ -0,0 +1,34 @@ +FROM ubuntu:latest + +RUN apt-get update && apt-get install -y curl gnupg +RUN apt-get install -y tini + +# Install pg_dump (via Postgres client) +# https://www.postgresql.org/download/linux/ubuntu/ +# +# We don't need it for production backups, but this is useful for local testing. +RUN \ + apt-get install -y lsb-release && \ + sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' && \ + curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \ + apt-get update && \ + apt-get -y install postgresql-client-12 + +# Install SCW CLI +# Latest release: https://github.com/scaleway/scaleway-cli/releases/latest +RUN \ + export VERSION="2.26.0" && \ + curl -o /usr/local/bin/scw -L "https://github.com/scaleway/scaleway-cli/releases/download/v${VERSION}/scaleway-cli_${VERSION}_linux_amd64" && \ + chmod +x /usr/local/bin/scw + +RUN apt-get install -y jq + +# Install rclone +RUN apt-get install -y unzip +RUN curl https://rclone.org/install.sh | bash + +COPY src / + +ENTRYPOINT ["tini", "--"] + +CMD [ "/backup.sh" ] diff --git a/infra/copycat-db/README.md b/infra/copycat-db/README.md new file mode 100644 index 000000000..95ca44ea4 --- /dev/null +++ b/infra/copycat-db/README.md @@ -0,0 +1,144 @@ +## Introduction + +Copycat DB is a [service](https://github.com/ente-io/infra) to take a backup of +our database. It uses the Scaleway CLI to take backups of the database, and +uploads them to an offsite bucket. + +This bucket has an object lock configured, so backups cannot be deleted before +expiry. Conversely, the service also deletes backups older than some threshold +when it creates a new one to avoid indefinite retention. + +In production the service runs as a cron job, scheduled using a systemd timer. + +## Required environment variables + +##### SCW_CONFIG_PATH + +Path to the `config.yaml` used by Scaleway CLI. + +This contains the credentials and the default region to use when trying to +create and download the database dump. + +If needed, this config file can be generated by running the following commands +on a shell prompt in the container (using `./test.sh sh`) + + scw init + scw config dump + +##### SCW_RDB_INSTANCE_ID + +The UUID of the Scalway RDB instance that we wish to backup. If this is missing, +then the Docker image falls back to using `pg_dump` (as outlined next). + +##### PGUSER, PGPASSWORD, PGHOST + +Not needed in production when taking a backup (since we use the Scaleway CLI to +take backups in production). + +These are used when testing a backup using `pg_dump`, and when restoring backups. + +##### RCLONE_CONFIG + +Location of the config file, that contains the destination bucket where you want +to use to save the backups, and the credentials to to access it. + +Specifically, the config file contains two remotes: + +* The bucket itself, where data will be stored. + +* A "crypt" remote that wraps the bucket by applying client side encryption. + +The configuration file will contain (lightly) obfuscated versions of the +password, and as long as we have the configuration file we can continue using +rclone to download and decrypt the plaintext. Still, it is helpful to retain the +original password too separately so that the file can be recreated if needed. + +A config file can be generated using `./test.sh sh` + + rclone config + rclone config show + +When generating the config, we keep file (and directory) name encryption off. + +Note that rclone creates a backup of the config file, so Docker needs to have +write access to the directory where it is mounted. + +##### RCLONE_DESTINATION + +Name of the (crypt) remote to which the dump should be saved. Example: +`db-backup-crypt:`. + +Note that this will not include the bucket - the bucket name will be part of the +remote that the crypt remote wraps. + +##### Logging + +The service logs to its standard out/error. The systemd unit is configured to +route these to `/var/logs/copycat-db.log`. + +## Local testing + +The provided `test.sh` script can be used to do a smoke test for building and +running the image. For example, + + ./test.sh bin/bash + +gives us a shell prompt inside the built and running container. + +For more thorough testing, run this service as part of a local test-cluster. + +## Restoring + +The service also knows how to restore the latest backup into a Postgres +instance. This functionality is used to periodically verify that the backups are +restorable. + +To invoke this, use "./restore.sh" as the command when running the container +(e.g. `./test.sh ./restore.sh`). This will restore the latest backup into the +Postgres instance whose credentials are provided via the various `PG*` +environment variables. + +## Preparing the bucket + +The database dumps are stored in a bucket that has object lock enabled +(Compliance mode), and has a default bucket level retention time of 30 days. + +## Deploying + +Ensure that promtail is running, and is configured to scrape +`/root/var/logs/copycat-db.log`. + +Create that the config and log destination directories + + sudo mkdir -p /root/var/config/scw + sudo mkdir -p /root/var/config/rclone + sudo mkdir -p /root/var/logs + +Create the env, scw and rclone configuration files + + sudo tee /root/copycat-db.env + sudo tee /root/var/config/scw/copycat-db-config.yaml + sudo tee /root/var/config/rclone/copycat-db-rclone.conf + +Add the service definition, and start the service + + scp copycat-db.{service,timer} instance: + + sudo mv copycat-db.{service,timer} /etc/systemd/system + sudo systemctl daemon-reload + +To enable the cron job + + sudo systemctl enable --now copycat-db.timer + +The timer will trigger the service on the specified schedule. In addition, if +you wish to force the job to service immediately + + sudo systemctl start copycat-db.service + +## Updating + +To update, run the [Github action](.github/workflows/ci.yaml) to push the latest +image to our Docker Registry, then restart the systemd service on the instance + + sudo systemctl restart copycat-db diff --git a/infra/copycat-db/Runbook.md b/infra/copycat-db/Runbook.md new file mode 100644 index 000000000..fe8160c1d --- /dev/null +++ b/infra/copycat-db/Runbook.md @@ -0,0 +1,13 @@ + +### Service logs + +```bash +tail -f -n 100 /root/var/logs/copycat-db.log +``` + +### Backup timeout +If you are seeing time-out from scw while waiting for backup, usually just stopping the [service](.copycat-db.service) and letting the [daily timer](./copycat-db.timer) restart it later works + +```bash + sudo systemctl stop copycat-db.service +``` diff --git a/infra/copycat-db/copycat-db.sample.env b/infra/copycat-db/copycat-db.sample.env new file mode 100644 index 000000000..243e8aa5f --- /dev/null +++ b/infra/copycat-db/copycat-db.sample.env @@ -0,0 +1,8 @@ +SCW_CONFIG_PATH=/var/config/scw/copycat-db-config.yaml +SCW_RDB_INSTANCE_ID= +PGUSER= +PGPASSWORD= +PGHOST=host.docker.internal +PGPORT= +RCLONE_CONFIG=/var/config/rclone/copycat-db-rclone.conf +RCLONE_DESTINATION=db-backup-crypt: diff --git a/infra/copycat-db/copycat-db.service b/infra/copycat-db/copycat-db.service new file mode 100644 index 000000000..819baa73c --- /dev/null +++ b/infra/copycat-db/copycat-db.service @@ -0,0 +1,20 @@ +[Unit] +Documentation=https://github.com/ente-io/copycat-db +Requires=docker.service +After=docker.service + +[Service] +Restart=always +RestartSec=3600s +# Don't automatically restart if it fails more than 6 times in 24 hours. +StartLimitInterval=86400 +StartLimitBurst=6 +ExecStartPre=docker pull rg.fr-par.scw.cloud/ente/copycat-db +ExecStartPre=-docker stop copycat-db +ExecStartPre=-docker rm copycat-db +ExecStart=docker run --name copycat-db \ + --env-file /root/copycat-db.env \ + -v /root/var:/var \ + rg.fr-par.scw.cloud/ente/copycat-db +StandardOutput=append:/root/var/logs/copycat-db.log +StandardError=inherit diff --git a/infra/copycat-db/copycat-db.timer b/infra/copycat-db/copycat-db.timer new file mode 100644 index 000000000..c3f6e2e86 --- /dev/null +++ b/infra/copycat-db/copycat-db.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Schedule copycat-db + +[Timer] +OnCalendar=Daily + +[Install] +WantedBy=timers.target diff --git a/infra/copycat-db/src/backup.sh b/infra/copycat-db/src/backup.sh new file mode 100755 index 000000000..f197f4b0f --- /dev/null +++ b/infra/copycat-db/src/backup.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +set -o errexit +set -o xtrace + +NOWS="$(date +%s)" +BACKUP_FILE="db-$NOWS.custom" + +# Scaleway backup names cannot contain dots +BACKUP_NAME="db-$NOWS-custom" + +# Calculate an expiry time 1 month from now +EXPIRYS="$(( 30 * 24 * 60 * 60 + $NOWS ))" + +# Convert it to the ISO 8601 format that SCW CLI understands +# Note that GNU date uses "-d" and an "@" to pass an epoch (macOS uses "-r"). +EXPIRY="$(date -Iseconds --utc --date "@$EXPIRYS")" + +if test -z "$SCW_RDB_INSTANCE_ID" +then + # A required SCW related environment variable hasn't been specified. This is + # expected when running the script locally for testing. Fallback to using + # pg_dump for creating the backup. + pg_dump -Fc ente_db > $BACKUP_FILE +else + # We need to export a backup first after creating it, before it can be + # downloaded. + # + # Further, our backups currently take longer than the default 20 minute + # timeout for the export set by Scaleway, and end up failing: + # + # {"error":"scaleway-sdk-go: waiting for database backup failed: timeout after 20m0s"} + # + # To avoid this we need to add a custom wait here ourselves instead of using + # the convenience `--wait` flag for the export command provided by Scaleway. + BACKUP_ID=$(scw rdb backup create instance-id=$SCW_RDB_INSTANCE_ID \ + name=$BACKUP_NAME expires-at=$EXPIRY \ + database-name=ente_db -o json | jq -r '.id') + scw rdb backup wait $BACKUP_ID timeout=5h + scw rdb backup download output=$BACKUP_FILE \ + $(scw rdb backup export $BACKUP_ID --wait -o json | jq -r '.id') +fi + +rclone copy --log-level INFO $BACKUP_FILE $RCLONE_DESTINATION + +# Delete older backups +rclone delete --log-level INFO --min-age 30d $RCLONE_DESTINATION + +set +o xtrace +echo "copycat-db: backup complete: $BACKUP_FILE" diff --git a/infra/copycat-db/src/restore.sh b/infra/copycat-db/src/restore.sh new file mode 100755 index 000000000..8df19c62b --- /dev/null +++ b/infra/copycat-db/src/restore.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -o errexit +set -o xtrace + +# Find the name of the latest backup +# The backup file name contains the epoch, so we can just sort. +BACKUP_FILE=$(rclone lsf --include 'db-*.custom' --files-only $RCLONE_DESTINATION | sort | tail -1) + +# Download it +rclone copy --log-level INFO "${RCLONE_DESTINATION}${BACKUP_FILE}" . + +# Restore from it +# +# This create a database named rdb on Postgres - this is only used for the +# initial connection, the actual ente_db database will be created once the +# restore starts. +# +# Flags: +# +# * no-owner: recreates the schema using the current user, not the one that was +# used for the export. +# +# * no-privileges: skip the assignment of roles (this way we do not have to +# recreate all the users from the original database before proceeding with the +# restore) + +createdb rdb || true +pg_restore -d rdb --create --no-privileges --no-owner --exit-on-error "$BACKUP_FILE" + +# Delete any tokens that were in the backup +psql -d ente_db -c 'delete from tokens' + +# Delete any push tokens that were in the backup +psql -d ente_db -c 'delete from push_tokens' + +# Delete some more temporary data that might've come up in the backup +psql -d ente_db -c 'delete from queue' +psql -d ente_db -c 'delete from temp_objects' + +set +o xtrace +echo "copycat-db: restore complete: $BACKUP_FILE" diff --git a/infra/copycat-db/test.sh b/infra/copycat-db/test.sh new file mode 100755 index 000000000..d4ac1b35f --- /dev/null +++ b/infra/copycat-db/test.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -o xtrace +set -o errexit + +PROJECT=copycat-db + +docker rmi "ente/$PROJECT" || true +docker build --tag "ente/$PROJECT" . + +# Interactively run the container. +# +# By passing "$@", we allow any arguments passed to test.sh to be forwarded to +# the image (useful for testing out things, e.g. `./test.sh sh`). +docker run \ + --interactive --tty --rm \ + --env-file copycat-db.env \ + --name "$PROJECT" \ + "ente/$PROJECT" \ + "$@" From aaffc740bc59a1c8829c759c1c8ee0fedcd96957 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 17:26:11 +0530 Subject: [PATCH 16/30] Update paths --- infra/copycat-db/README.md | 50 ++++++++++++++++++++------ infra/copycat-db/Runbook.md | 13 ------- infra/copycat-db/copycat-db.sample.env | 4 +-- infra/copycat-db/copycat-db.service | 2 +- 4 files changed, 42 insertions(+), 27 deletions(-) delete mode 100644 infra/copycat-db/Runbook.md diff --git a/infra/copycat-db/README.md b/infra/copycat-db/README.md index 95ca44ea4..5bb556a36 100644 --- a/infra/copycat-db/README.md +++ b/infra/copycat-db/README.md @@ -1,8 +1,8 @@ -## Introduction +# Copycat DB -Copycat DB is a [service](https://github.com/ente-io/infra) to take a backup of -our database. It uses the Scaleway CLI to take backups of the database, and -uploads them to an offsite bucket. +Copycat DB is a [service](../service.md) to take a backup of our database. It +uses the Scaleway CLI to take backups of the database, and uploads them to an +offsite bucket. This bucket has an object lock configured, so backups cannot be deleted before expiry. Conversely, the service also deletes backups older than some threshold @@ -10,6 +10,32 @@ when it creates a new one to avoid indefinite retention. In production the service runs as a cron job, scheduled using a systemd timer. +> These backups are in addition to the regular snapshots that we take, and are +> meant as a second layer of replication. For more details, see our [Reliability +> and Replication Specification](https://ente.io/reliability). + + +## Quick help + +View service status (it gets invoked as a timer automatically, doesn't need to +be started/stopped manually): + +```sh +sudo systemctl status copycat-db +``` + +View logs locally (they'll also be available on Grafana): + +```sh +sudo tail /root/var/logs/copycat-db.log +``` + +## Name + +The name copycat-db is a riff on "copycat", which is what we call our museum +instance that does the object replication. This one replicates the DB, so, +copycat-db. + ## Required environment variables ##### SCW_CONFIG_PATH @@ -90,8 +116,8 @@ For more thorough testing, run this service as part of a local test-cluster. ## Restoring The service also knows how to restore the latest backup into a Postgres -instance. This functionality is used to periodically verify that the backups are -restorable. +instance. This functionality by a separate service (Phoenix) to periodically +verify that the backups are restorable. To invoke this, use "./restore.sh" as the command when running the container (e.g. `./test.sh ./restore.sh`). This will restore the latest backup into the @@ -101,7 +127,7 @@ environment variables. ## Preparing the bucket The database dumps are stored in a bucket that has object lock enabled -(Compliance mode), and has a default bucket level retention time of 30 days. +(compliance mode), and has a default bucket level retention time of 30 days. ## Deploying @@ -127,9 +153,9 @@ Add the service definition, and start the service sudo mv copycat-db.{service,timer} /etc/systemd/system sudo systemctl daemon-reload -To enable the cron job +To start the cron job - sudo systemctl enable --now copycat-db.timer + sudo systemctl start copycat-db.timer The timer will trigger the service on the specified schedule. In addition, if you wish to force the job to service immediately @@ -138,7 +164,9 @@ you wish to force the job to service immediately ## Updating -To update, run the [Github action](.github/workflows/ci.yaml) to push the latest -image to our Docker Registry, then restart the systemd service on the instance +To update, run the [GitHub +workflow](../../.github/workflows/copycat-db-release.yaml) to build and push the +latest image to our Docker Registry, then restart the systemd service on the +instance sudo systemctl restart copycat-db diff --git a/infra/copycat-db/Runbook.md b/infra/copycat-db/Runbook.md deleted file mode 100644 index fe8160c1d..000000000 --- a/infra/copycat-db/Runbook.md +++ /dev/null @@ -1,13 +0,0 @@ - -### Service logs - -```bash -tail -f -n 100 /root/var/logs/copycat-db.log -``` - -### Backup timeout -If you are seeing time-out from scw while waiting for backup, usually just stopping the [service](.copycat-db.service) and letting the [daily timer](./copycat-db.timer) restart it later works - -```bash - sudo systemctl stop copycat-db.service -``` diff --git a/infra/copycat-db/copycat-db.sample.env b/infra/copycat-db/copycat-db.sample.env index 243e8aa5f..ba557714e 100644 --- a/infra/copycat-db/copycat-db.sample.env +++ b/infra/copycat-db/copycat-db.sample.env @@ -1,8 +1,8 @@ SCW_CONFIG_PATH=/var/config/scw/copycat-db-config.yaml SCW_RDB_INSTANCE_ID= +RCLONE_CONFIG=/var/config/rclone/copycat-db-rclone.conf +RCLONE_DESTINATION=db-backup-crypt: PGUSER= PGPASSWORD= PGHOST=host.docker.internal PGPORT= -RCLONE_CONFIG=/var/config/rclone/copycat-db-rclone.conf -RCLONE_DESTINATION=db-backup-crypt: diff --git a/infra/copycat-db/copycat-db.service b/infra/copycat-db/copycat-db.service index 819baa73c..d3ec6c485 100644 --- a/infra/copycat-db/copycat-db.service +++ b/infra/copycat-db/copycat-db.service @@ -1,5 +1,5 @@ [Unit] -Documentation=https://github.com/ente-io/copycat-db +Documentation=https://github.com/ente-io/ente/blob/main/infra/copycat-db Requires=docker.service After=docker.service From 7ddfeb93ddd4346b76cca3a4eab3b177a78cd639 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 17:32:54 +0530 Subject: [PATCH 17/30] Fix up the workflow --- .../workflows/copycat-db-release.yaml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) rename infra/copycat-db/.github/workflows/ci.yaml => .github/workflows/copycat-db-release.yaml (61%) diff --git a/infra/copycat-db/.github/workflows/ci.yaml b/.github/workflows/copycat-db-release.yaml similarity index 61% rename from infra/copycat-db/.github/workflows/ci.yaml rename to .github/workflows/copycat-db-release.yaml index aa57e206c..5ec942879 100644 --- a/infra/copycat-db/.github/workflows/ci.yaml +++ b/.github/workflows/copycat-db-release.yaml @@ -1,14 +1,7 @@ -name: Build and push Docker image +name: "Release (copycat-db)" on: - # Enable manual run - workflow_dispatch: - push: - branches: - - release - # Sequence of patterns matched against refs/tags - tags: - - "v*" # Push events to matching v*, i.e. v4.2.0 + workflow_dispatch: # Run manually jobs: build: @@ -20,10 +13,12 @@ jobs: - uses: mr-smithers-excellent/docker-build-push@v6 name: Build & Push with: + dockerfile: infra/copycat-db/Dockerfile + directory: infra/copycat-db image: ente/copycat-db registry: rg.fr-par.scw.cloud + enableBuildKit: true + buildArgs: GIT_COMMIT=${GITHUB_SHA} tags: ${GITHUB_SHA}, latest username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - env: - GIT_COMMIT: ${GITHUB_SHA} From ddeafe074984a55aa77d1e1d5a31cbed832724f1 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 18:16:01 +0530 Subject: [PATCH 18/30] [mobile] Update the link to GitHub APK for photos --- mobile/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mobile/README.md b/mobile/README.md index 114a3ab38..005d303b6 100644 --- a/mobile/README.md +++ b/mobile/README.md @@ -23,7 +23,8 @@ If you're looking for Ente Auth instead, see [../auth](../auth/README.md). ### Android -The [GitHub releases](https://github.com/ente-io/photos-app/releases) contain +The [GitHub +releases](https://github.com/ente-io/ente/releases?q=tag%3Aphotos-v0) contain APKs, built straight from source. The latest build is available at [ente.io/apk](https://ente.io/apk). These builds keep themselves updated, without relying on third party stores. From 7aed64118999e90c2e4e0d2e8168aa0fb9cdb4e1 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 18:22:51 +0530 Subject: [PATCH 19/30] Also update the links in the fastlane descriptions --- mobile/fastlane/metadata/android/de/full_description.txt | 2 +- mobile/fastlane/metadata/android/en-US/full_description.txt | 2 +- mobile/fastlane/metadata/android/es/full_description.txt | 2 +- mobile/fastlane/metadata/android/fr/full_description.txt | 2 +- mobile/fastlane/metadata/android/he/full_description.txt | 2 +- mobile/fastlane/metadata/android/it/full_description.txt | 2 +- mobile/fastlane/metadata/android/nl/full_description.txt | 2 +- mobile/fastlane/metadata/android/pt/full_description.txt | 2 +- mobile/fastlane/metadata/android/ru/full_description.txt | 2 +- mobile/fastlane/metadata/android/zh/full_description.txt | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mobile/fastlane/metadata/android/de/full_description.txt b/mobile/fastlane/metadata/android/de/full_description.txt index 2d953ade9..4d963c1d7 100644 --- a/mobile/fastlane/metadata/android/de/full_description.txt +++ b/mobile/fastlane/metadata/android/de/full_description.txt @@ -27,7 +27,7 @@ FEATURES - und noch VIELES mehr! BERECHTIGUNGEN -Diese können unter folgendem Link überprüft werden: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +Diese können unter folgendem Link überprüft werden: https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md PREIS Wir bieten keine lebenslang kostenlosen Abonnements an, da es für uns wichtig ist, einen nachhaltigen Service anzubieten. Wir bieten jedoch bezahlbare Abonemments an, welche auch mit der Familie geteilt werden können. Mehr Informationen sind auf ente.io zu finden. diff --git a/mobile/fastlane/metadata/android/en-US/full_description.txt b/mobile/fastlane/metadata/android/en-US/full_description.txt index 53cab6c96..9ba4fe314 100644 --- a/mobile/fastlane/metadata/android/en-US/full_description.txt +++ b/mobile/fastlane/metadata/android/en-US/full_description.txt @@ -27,7 +27,7 @@ FEATURES - and a LOT more! PERMISSIONS -ente requests for certain permissions to serve the purpose of a photo storage provider, which can be reviewed here: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente requests for certain permissions to serve the purpose of a photo storage provider, which can be reviewed here: https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md PRICING We don't offer forever free plans, because it is important to us that we remain sustainable and withstand the test of time. Instead we offer affordable plans that you can freely share with your family. You can find more information at ente.io. diff --git a/mobile/fastlane/metadata/android/es/full_description.txt b/mobile/fastlane/metadata/android/es/full_description.txt index dfba04a96..8c0667934 100644 --- a/mobile/fastlane/metadata/android/es/full_description.txt +++ b/mobile/fastlane/metadata/android/es/full_description.txt @@ -27,7 +27,7 @@ CARACTERÍSTICAS - ¡Y mucho más! PERMISOS -ente solicita ciertos permisos para servir al propósito de un proveedor de almacenamiento de fotos, que puede ser revisado aquí: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente solicita ciertos permisos para servir al propósito de un proveedor de almacenamiento de fotos, que puede ser revisado aquí: https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md PRECIOS No ofrecemos planes gratis para siempre, porque es importante para nosotros seguir siendo sostenibles y resistir a la prueba del tiempo. En su lugar, ofrecemos planes asequibles que puedes compartir libremente con tu familia. Puedes encontrar más información en ente.io. diff --git a/mobile/fastlane/metadata/android/fr/full_description.txt b/mobile/fastlane/metadata/android/fr/full_description.txt index ee93cf62b..f94e467af 100644 --- a/mobile/fastlane/metadata/android/fr/full_description.txt +++ b/mobile/fastlane/metadata/android/fr/full_description.txt @@ -27,7 +27,7 @@ CARACTÉRISTIQUES - et beaucoup de choses encore ! PERMISSIONS -ente sollicite diverses autorisations dans le but de fonctionner en tant que service de stockage de photos, et ces autorisations sont détaillées ici : https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente sollicite diverses autorisations dans le but de fonctionner en tant que service de stockage de photos, et ces autorisations sont détaillées ici : https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md PRIX Nous ne proposons pas d'abonnement gratuits pour toujours, car il est important pour nous de rester durables et de résister à l'épreuve du temps. Au lieu de cela, nous vous proposons des abonnements abordables que vous pouvez partager librement avec votre famille. Vous pouvez trouver plus d'informations sur ente.io. diff --git a/mobile/fastlane/metadata/android/he/full_description.txt b/mobile/fastlane/metadata/android/he/full_description.txt index 094285850..21719b771 100644 --- a/mobile/fastlane/metadata/android/he/full_description.txt +++ b/mobile/fastlane/metadata/android/he/full_description.txt @@ -27,7 +27,7 @@ ente גם מקל על שיתוף האלבומים שלך עם קרובך, גם - ועוד הרבה יותר! הרשאות -ente מבקש הרשאות מסוימות כדי לספק שירותי אחסון תמונות, וניתן לסקור אותן כאן: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente מבקש הרשאות מסוימות כדי לספק שירותי אחסון תמונות, וניתן לסקור אותן כאן: https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md מחיר אנחנו לא מציעים תוכניות בחינם לתמיד, משום שזה חשוב לנו להיות עמידים ולעמוד במבחן הזמן. במקום זאת אנחנו מציעים תוכניות במחיר סביר כדי שתוכל לשתף באופן חופשי עם המשפחה שלך. ניתן למצוא עוד מידע ב-ente.io. diff --git a/mobile/fastlane/metadata/android/it/full_description.txt b/mobile/fastlane/metadata/android/it/full_description.txt index 2437688c5..9da92c97a 100644 --- a/mobile/fastlane/metadata/android/it/full_description.txt +++ b/mobile/fastlane/metadata/android/it/full_description.txt @@ -27,7 +27,7 @@ CARATTERISTICHE - e molto altro ancora! PERMESSI -ente richiede alcune autorizzazioni per servire lo scopo di un provider di storage fotografico, che può essere esaminato qui: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente richiede alcune autorizzazioni per servire lo scopo di un provider di storage fotografico, che può essere esaminato qui: https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md PREZZO Non offriamo piani gratuiti per sempre, perché per noi è importante rimanere sostenibili e resistere alla prova del tempo. Offriamo invece piani accessibili che si possono condividere liberamente con la propria famiglia. Puoi trovare maggiori informazioni su ente.io. diff --git a/mobile/fastlane/metadata/android/nl/full_description.txt b/mobile/fastlane/metadata/android/nl/full_description.txt index da0877f72..80c925263 100644 --- a/mobile/fastlane/metadata/android/nl/full_description.txt +++ b/mobile/fastlane/metadata/android/nl/full_description.txt @@ -27,7 +27,7 @@ FUNCTIES - en nog veel meer! TOESTEMMINGEN -ente heeft bepaalde machtigingen nodig om uw foto's op te slaan, die hier bekeken kunnen worden: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente heeft bepaalde machtigingen nodig om uw foto's op te slaan, die hier bekeken kunnen worden: https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md PRIJZEN We bieden geen oneindig gratis plannen aan, omdat het voor ons belangrijk is dat we duurzaam blijven en de tand des tijds weerstaan. In plaats daarvan bieden we betaalbare plannen aan die je vrij kunt delen met je familie. Je kunt meer informatie vinden op ente.io. diff --git a/mobile/fastlane/metadata/android/pt/full_description.txt b/mobile/fastlane/metadata/android/pt/full_description.txt index 2bd26df1e..8e6bc4833 100644 --- a/mobile/fastlane/metadata/android/pt/full_description.txt +++ b/mobile/fastlane/metadata/android/pt/full_description.txt @@ -27,7 +27,7 @@ RECURSOS - e MUITO MAIS! PERMISSÕES -ente solicita certas permissões para servir o propósito de um provedor de armazenamento de fotos, que pode ser revisado aqui: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente solicita certas permissões para servir o propósito de um provedor de armazenamento de fotos, que pode ser revisado aqui: https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md PREÇO Não oferecemos planos gratuitos para sempre, porque é importante para nós que permaneçamos sustentáveis e resistamos à prova do tempo. Em vez disso, oferecemos planos acessíveis que você pode compartilhar livremente com sua família. Você pode encontrar mais informações em ente.io. diff --git a/mobile/fastlane/metadata/android/ru/full_description.txt b/mobile/fastlane/metadata/android/ru/full_description.txt index f374837e0..567f5a947 100644 --- a/mobile/fastlane/metadata/android/ru/full_description.txt +++ b/mobile/fastlane/metadata/android/ru/full_description.txt @@ -27,7 +27,7 @@ ente также делает так, что делится альбомами с - и ещё МНОГОЕ другое! РАЗРЕШЕНИЯ -ente просит разрешения на использование хранилища фотографий, которые можно рассмотреть здесь: https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente просит разрешения на использование хранилища фотографий, которые можно рассмотреть здесь: https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md ЦЕНА Мы не предлагаем бесконечные бесплатные планы, потому что для нас важно оставаться устойчивыми и выдерживать испытание временем. Вместо этого мы предлагаем доступные по цене планы, которыми вы можете свободно делиться с вашей семьей. Дополнительную информацию можно найти на сайте ente.io. diff --git a/mobile/fastlane/metadata/android/zh/full_description.txt b/mobile/fastlane/metadata/android/zh/full_description.txt index 2410d9da0..3660c6259 100644 --- a/mobile/fastlane/metadata/android/zh/full_description.txt +++ b/mobile/fastlane/metadata/android/zh/full_description.txt @@ -27,7 +27,7 @@ ente也使分享相册给自己的爱人、亲人变得轻而易举,即使他 - 还有更多特色待你发现! 权限 -ente需要特定权限以执行作为图像存储提供商的职责,相关内容可以在此链接查阅:https://github.com/ente-io/photos-app/blob/f-droid/android/permissions.md +ente需要特定权限以执行作为图像存储提供商的职责,相关内容可以在此链接查阅:https://github.com/ente-io/ente/blob/f-droid/mobile/android/permissions.md 价格 我们不会提供永久免费计划,因为我们必须保持可持续性,经受住时间的考验。 相反,我们向您提供了价格实惠、可自由分享的订阅计划。 您可以在 ente.io 找到更多信息。 相反,我们向您提供了价格实惠、可自由分享的订阅计划。 您可以在 ente.io 找到更多信息。 相反,我们向您提供了价格实惠、可自由分享的订阅计划。 您可以在 ente.io 找到更多信息。 From b79f8347b6cf3e31674b4699052a714a28dd7f43 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 20:31:47 +0530 Subject: [PATCH 20/30] Import the existing DesktopDistribute notes --- desktop/docs/release.md | 92 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 desktop/docs/release.md diff --git a/desktop/docs/release.md b/desktop/docs/release.md new file mode 100644 index 000000000..bdda428e1 --- /dev/null +++ b/desktop/docs/release.md @@ -0,0 +1,92 @@ +## Releases + +> [!NOTE] +> +> TODO(MR): This document needs to be audited and changed as we do the first +> release from this new monorepo. + +The Github Action that builds the desktop binaries is triggered by pushing a tag +matching the pattern `photos-desktop-v1.2.3`. This value should match the +version in `package.json`. + +So the process for doing a release would be. + +1. Create a new branch (can be named anything). On this branch, include your + changes. + +2. Mention the changes in `CHANGELOG.md`. + +3. Changing the `version` in `package.json` to `1.x.x`. + +4. Commit and push to remote + + ```sh + git add package.json && git commit -m 'Release v1.x.x' + git tag v1.x.x + git push && git push --tags + ``` + +This by itself will already trigger a new release. The GitHub action will create +a new draft release that can then be used as descibed below. + +To wrap up, we also need to merge back these changes into main. So for that, + +5. Open a PR for the branch that we're working on (where the above tag was + pushed from) to get it merged into main. + +6. In this PR, also increase the version number for the next release train. That + is, supposed we just released `v4.0.1`. Then we'll change the version number + in main to `v4.0.2-next.0`. Each pre-release will modify the `next.0` part. + Finally, at the time of the next release, this'll become `v4.0.2`. + +The GitHub Action runs on Windows, Linux and macOS. It produces the artifacts +defined in the `build` value in `package.json`. + +* Windows - An NSIS installer. +* Linux - An AppImage, and 3 other packages (`.rpm`, `.deb`, `.pacman`) +* macOS - A universal DMG + +Additionally, the GitHub action notarizes the macOS DMG. For this it needs +credentials provided via GitHub secrets. + +During the build the Sentry webpack plugin checks to see if SENTRY_AUTH_TOKEN is +defined. If so, it uploads the sourcemaps for the renderer process to Sentry +(For our GitHub action, the SENTRY_AUTH_TOKEN is defined as a GitHub secret). + +The sourcemaps for the main (node) process are currently not sent to Sentry +(this works fine in practice since the node process files are not minified, we +only run `tsc`). + +Once the build is done, a draft release with all these artifacts attached is +created. The build is idempotent, so if something goes wrong and we need to +re-run the GitHub action, just delete the draft release (if it got created) and +start a new run by pushing a new tag (if some code changes are required). + +If no code changes are required, say the build failed for some transient network +or sentry issue, we can even be re-run by the build by going to Github Action +age and rerun from there. This will re-trigger for the same tag. + +If everything goes well, we'll have a release on GitHub, and the corresponding +source maps for the renderer process uploaded to Sentry. There isn't anything +else to do: + +* The website automatically redirects to the latest release on GitHub when + people try to download. + +* The file formats with support auto update (Windows `exe`, the Linux AppImage + and the macOS DMG) also check the latest GitHub release automatically to + download and apply the update (the rest of the formats don't support auto + updates). + +* We're not putting the desktop app in other stores currently. It is available + as a `brew cask`, but we only had to open a PR to add the initial formula, now + their maintainers automatically bump the SHA, version number and the (derived + from the version) URL in the formula when their tools notice a new release on + our GitHub. + +We can also publish the draft releases by checking the "pre-release" option. +Such releases don't cause any of the channels (our website, or the desktop app +auto updater, or brew) to be notified, instead these are useful for giving links +to pre-release builds to customers. Generally, in the version number for these +we'll add a label to the version, e.g. the "beta.x" in `1.x.x-beta.x`. This +should be done both in `package.json`, and what we tag the commit with. From 477e3fee80b33ad671b4f338f59756888f19241d Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 21:18:38 +0530 Subject: [PATCH 21/30] Define services --- infra/copycat-db/README.md | 7 ++- infra/services/README.md | 103 +++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 infra/services/README.md diff --git a/infra/copycat-db/README.md b/infra/copycat-db/README.md index 5bb556a36..4310c73d8 100644 --- a/infra/copycat-db/README.md +++ b/infra/copycat-db/README.md @@ -1,8 +1,8 @@ # Copycat DB -Copycat DB is a [service](../service.md) to take a backup of our database. It -uses the Scaleway CLI to take backups of the database, and uploads them to an -offsite bucket. +Copycat DB is a [service](../services/README.md) to take a backup of our +database. It uses the Scaleway CLI to take backups of the database, and uploads +them to an offsite bucket. This bucket has an object lock configured, so backups cannot be deleted before expiry. Conversely, the service also deletes backups older than some threshold @@ -14,7 +14,6 @@ In production the service runs as a cron job, scheduled using a systemd timer. > meant as a second layer of replication. For more details, see our [Reliability > and Replication Specification](https://ente.io/reliability). - ## Quick help View service status (it gets invoked as a timer automatically, doesn't need to diff --git a/infra/services/README.md b/infra/services/README.md new file mode 100644 index 000000000..81a82c7b7 --- /dev/null +++ b/infra/services/README.md @@ -0,0 +1,103 @@ +# Services + +"Services" are various Docker images that we run on our instances and manage +using systemd. + +All our services (including museum itself) follow the same +pattern: + +* They're meant to run on vanilla Ubuntu instances. The only expectation they + have is for Docker to be installed. + +* They log to fixed, known, locations - `/root/var/log/foo.log` - so that these + logs can get ingested by Promtail. + +* Each service should consist of a Docker image (or a Docker compose file), and a + systemd unit file. + +* To start / stop / cron the service, we use the corresponding systemd command. + +* Each time the service runs it should pull the latest Docker image, so there is no +separate installation/upgrade step needed. We can just restart the service, and it'll +use the latest code. + +* Any credentials and/or configuration should be read by mounting the + appropriate file from `/root/service-name` into the running Docker container. + +## Systemd cheatsheet + +```sh +sudo systemctl status my-service +sudo systemctl start my-service +sudo systemctl stop my-service +sudo systemctl restart my-service +``` + +## Adding a service + +Create a systemd unit file (For examples, see the various `*.service` files in +this repository). + +If we want the service to start on boot, add an `[Install]` section to its +service file (_note_: there is one more step later): + +``` +[Install] +WantedBy=multi-user.target +``` + +Copy the service file to the instance where we want to run the service. +Services might also have some additional configuration or env files, also copy +those to the instance. + +```sh +scp services/example.service example.env : +``` + +SSH into the instance. + +```sh +ssh +``` + +Move the service `/etc/systemd/service`, and any config files to their expected +place. env and other config files that contain credentials are kept in `/root`. + +```sh +sudo mv example.service /etc/systemd/system +sudo mv example.env /root +``` + +If you want to start the service on boot (as spoken of in the `[Install]` +section above), then enable it (this only needs to be done once): + +```sh +sudo systemctl enable service +``` + +Restarts systemd so that it gets to know of the service. + +```sh +sudo systemctl daemon-reload +``` + +Now you can manage the service using standard systemd commands. + +```sh +sudo systemctl start example +``` + +To view stdout/err, use: + +```sh +sudo journalctl --follow --unit example +``` + +## Logging + +Services should log to files in `/var/logs` within the container. This should be +mounted to `/root/var/logs` on the instance (using the `-v` flag in the service +file which launches the Docker container or the Docker compose cluster). +Finally, ensure there is an entry for this log file in the +`promtail/promtail.yaml` on that instance. The logs will then get scraped by +Promtail and sent over to Grafana. From dc2474801c319062f5beab55b42a4149e8710681 Mon Sep 17 00:00:00 2001 From: Ashil <77285023+ashilkn@users.noreply.github.com> Date: Thu, 14 Mar 2024 21:23:53 +0530 Subject: [PATCH 22/30] [photos][mobile]Update home_widget git dependency URL (#1098) --- mobile/pubspec.lock | 2 +- mobile/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 5c3f8e2f2..7e4534520 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -936,7 +936,7 @@ packages: path: "." ref: main resolved-ref: "49158ce4a517e87817dc84c6b96c00639281229a" - url: "https://github.com/prateekmedia/FlutterHomeWidget" + url: "https://github.com/ente-io/FlutterHomeWidget" source: git version: "0.4.1" html: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 3adcf3ca3..ca8efa9c1 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -93,7 +93,7 @@ dependencies: google_nav_bar: ^5.0.5 home_widget: git: - url: https://github.com/prateekmedia/FlutterHomeWidget + url: https://github.com/ente-io/FlutterHomeWidget ref: main html_unescape: ^2.0.0 http: ^1.1.0 From dc29ab496ff526f06bf5f5fb7647ea9cb473f3ff Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 21:56:36 +0530 Subject: [PATCH 23/30] Add prometheus and promtail definitions --- infra/services/README.md | 31 ++++++------- infra/services/prometheus/README.md | 32 +++++++++++++ .../services/prometheus/node-exporter.service | 12 +++++ infra/services/prometheus/prometheus.service | 16 +++++++ infra/services/prometheus/prometheus.yml | 39 ++++++++++++++++ infra/services/promtail/README.md | 26 +++++++++++ infra/services/promtail/promtail.service | 19 ++++++++ infra/services/promtail/promtail.yaml | 45 +++++++++++++++++++ 8 files changed, 205 insertions(+), 15 deletions(-) create mode 100644 infra/services/prometheus/README.md create mode 100644 infra/services/prometheus/node-exporter.service create mode 100644 infra/services/prometheus/prometheus.service create mode 100644 infra/services/prometheus/prometheus.yml create mode 100644 infra/services/promtail/README.md create mode 100644 infra/services/promtail/promtail.service create mode 100644 infra/services/promtail/promtail.yaml diff --git a/infra/services/README.md b/infra/services/README.md index 81a82c7b7..17fb6ce87 100644 --- a/infra/services/README.md +++ b/infra/services/README.md @@ -1,25 +1,24 @@ # Services -"Services" are various Docker images that we run on our instances and manage -using systemd. +"Services" are Docker images we run on our instances and manage using systemd. All our services (including museum itself) follow the same pattern: -* They're meant to run on vanilla Ubuntu instances. The only expectation they - have is for Docker to be installed. +* They're run on vanilla Ubuntu instances. The only expectation they have is for + Docker to be installed. * They log to fixed, known, locations - `/root/var/log/foo.log` - so that these - logs can get ingested by Promtail. + logs can get ingested by Promtail if needed. * Each service should consist of a Docker image (or a Docker compose file), and a systemd unit file. -* To start / stop / cron the service, we use the corresponding systemd command. +* To start / stop / schedule the service, we use systemd. -* Each time the service runs it should pull the latest Docker image, so there is no -separate installation/upgrade step needed. We can just restart the service, and it'll -use the latest code. +* Each time the service runs it should pull the latest Docker image, so there is + no separate installation/upgrade step needed. We can just restart the service, + and it'll use the latest code. * Any credentials and/or configuration should be read by mounting the appropriate file from `/root/service-name` into the running Docker container. @@ -31,15 +30,16 @@ sudo systemctl status my-service sudo systemctl start my-service sudo systemctl stop my-service sudo systemctl restart my-service +sudo journalctl --unit my-service ``` ## Adding a service -Create a systemd unit file (For examples, see the various `*.service` files in -this repository). +Create a systemd unit file (See the various `*.service` files in this repository +for examples). If we want the service to start on boot, add an `[Install]` section to its -service file (_note_: there is one more step later): +service file (_note_: starting on boot requires one more step later): ``` [Install] @@ -98,6 +98,7 @@ sudo journalctl --follow --unit example Services should log to files in `/var/logs` within the container. This should be mounted to `/root/var/logs` on the instance (using the `-v` flag in the service file which launches the Docker container or the Docker compose cluster). -Finally, ensure there is an entry for this log file in the -`promtail/promtail.yaml` on that instance. The logs will then get scraped by -Promtail and sent over to Grafana. + +If these logs need to be sent to Grafana, then ensure that there is an entry for +this log file in the `promtail/promtail.yaml` on that instance. The logs will +then get scraped by Promtail and sent over to Grafana. diff --git a/infra/services/prometheus/README.md b/infra/services/prometheus/README.md new file mode 100644 index 000000000..90dc0cca3 --- /dev/null +++ b/infra/services/prometheus/README.md @@ -0,0 +1,32 @@ +# Prometheus + +Install `prometheus.service` on an instance if it is running something that +exports custom Prometheus metrics. In particular, museum does. + +Also install `node-exporter.service` (after installing +[node-exporter](https://prometheus.io/docs/guides/node-exporter/) itself) if it +is a production instance whose metrics (CPU, disk, RAM etc) we want to monitor. + +## Installing + +Prometheus doesn't currently support environment variables in config file, so +remember to change the hardcoded `XX-HOSTNAME` too in addition to adding the +`remote_write` configuration. + +```sh +scp -P 7426 services/prometheus/* : + +nano prometheus.yml +sudo mv prometheus.yml /root/prometheus.yml +sudo mv prometheus.service /etc/systemd/system/prometheus.service +sudo mv node-exporter.service /etc/systemd/system/node-exporter.service +``` + +Tell systemd to pick up new service definitions, enable the units (so that they +automatically start on boot going forward), and start them. + +```sh +sudo systemctl daemon-reload +sudo systemctl enable node-exporter prometheus +sudo systemctl start node-exporter prometheus +``` diff --git a/infra/services/prometheus/node-exporter.service b/infra/services/prometheus/node-exporter.service new file mode 100644 index 000000000..b28e348ae --- /dev/null +++ b/infra/services/prometheus/node-exporter.service @@ -0,0 +1,12 @@ +[Unit] +Documentation=https://prometheus.io/docs/guides/node-exporter/ +Wants=network-online.target +After=network-online.target + +[Install] +WantedBy=multi-user.target + +[Service] +User=node_exporter +Group=node_exporter +ExecStart=/usr/local/bin/node_exporter diff --git a/infra/services/prometheus/prometheus.service b/infra/services/prometheus/prometheus.service new file mode 100644 index 000000000..a8f6c48f0 --- /dev/null +++ b/infra/services/prometheus/prometheus.service @@ -0,0 +1,16 @@ +[Unit] +Documentation=https://prometheus.io/docs/prometheus/ +Requires=docker.service +After=docker.service + +[Install] +WantedBy=multi-user.target + +[Service] +ExecStartPre=docker pull prom/prometheus +ExecStartPre=-docker stop prometheus +ExecStartPre=-docker rm prometheus +ExecStart=docker run --name prometheus \ + --add-host=host.docker.internal:host-gateway \ + -v /root/prometheus.yml:/etc/prometheus/prometheus.yml:ro \ + prom/prometheus diff --git a/infra/services/prometheus/prometheus.yml b/infra/services/prometheus/prometheus.yml new file mode 100644 index 000000000..81d1e3d84 --- /dev/null +++ b/infra/services/prometheus/prometheus.yml @@ -0,0 +1,39 @@ +# https://prometheus.io/docs/prometheus/latest/configuration/ + +global: + scrape_interval: 30s # Default is 1m + +scrape_configs: + - job_name: museum + static_configs: + - targets: ["host.docker.internal:2112"] + relabel_configs: + - source_labels: [__address__] + regex: ".*" + target_label: instance + replacement: XX-HOSTNAME + + - job_name: "prometheus" + static_configs: + - targets: ["localhost:9090"] + relabel_configs: + - source_labels: [__address__] + regex: ".*" + target_label: instance + replacement: XX-HOSTNAME + + - job_name: "node" + static_configs: + - targets: ["host.docker.internal:9100"] + relabel_configs: + - source_labels: [__address__] + regex: ".*" + target_label: instance + replacement: XX-HOSTNAME + +# Grafana Cloud +remote_write: + - url: https://g/api/prom/push + basic_auth: + username: foo + password: bar diff --git a/infra/services/promtail/README.md b/infra/services/promtail/README.md new file mode 100644 index 000000000..1bcf44833 --- /dev/null +++ b/infra/services/promtail/README.md @@ -0,0 +1,26 @@ +# Promtail + +Install `promtail.service` on an instance if it is running something whose logs +we want in Grafana. + +## Installing + +Replace `client.url` in the config file with the Loki URL that Promtail should +connect to, and move the files to their expected place. + +```sh +scp -P 7426 services/promtail/* : + +nano promtail.yaml +sudo mv promtail.yaml /root/promtail.yaml +sudo mv promtail.service /etc/systemd/system/promtail.service +``` + +Tell systemd to pick up new service definitions, enable the unit (so that it +automatically starts on boot), and start it this time around. + +```sh +sudo systemctl daemon-reload +sudo systemctl enable promtail +sudo systemctl start promtail +``` diff --git a/infra/services/promtail/promtail.service b/infra/services/promtail/promtail.service new file mode 100644 index 000000000..b98ec762f --- /dev/null +++ b/infra/services/promtail/promtail.service @@ -0,0 +1,19 @@ +[Unit] +Documentation=https://grafana.com/docs/loki/latest/clients/promtail/ +Requires=docker.service +After=docker.service + +[Install] +WantedBy=multi-user.target + +[Service] +ExecStartPre=docker pull grafana/promtail +ExecStartPre=-docker stop promtail +ExecStartPre=-docker rm promtail +ExecStart=docker run --name promtail \ + --hostname "%H" \ + -v /root/promtail.yaml:/config.yaml:ro \ + -v /var/log:/var/log \ + -v /root/var/logs:/var/logs:ro \ + -v /var/lib/docker/containers:/var/lib/docker/containers:ro \ + grafana/promtail -config.file=/config.yaml -config.expand-env=true diff --git a/infra/services/promtail/promtail.yaml b/infra/services/promtail/promtail.yaml new file mode 100644 index 000000000..99a2578ff --- /dev/null +++ b/infra/services/promtail/promtail.yaml @@ -0,0 +1,45 @@ +# https://grafana.com/docs/loki/latest/clients/promtail/configuration/ + +# We don't want Promtail's HTTP / GRPC server. +server: + disable: true + +# Loki URL +# For Grafana Cloud, it can be found in the integrations section. +clients: + - url: http://loki:3100/loki/api/v1/push + +# Manually add entries for all our services. This is a bit cumbersome, but +# - Retains flexibility in file names. +# - Makes adding job labels easy. +# - Does not get in the way of logrotation. +# +# In addition, also scrape logs from all docker containers. +scrape_configs: + - job_name: museum + static_configs: + - labels: + job: museum + host: ${HOSTNAME} + __path__: /var/logs/museum.log + + - job_name: copycat-db + static_configs: + - labels: + job: copycat-db + host: ${HOSTNAME} + __path__: /var/logs/copycat-db.log + + - job_name: phoenix + static_configs: + - labels: + job: phoenix + host: ${HOSTNAME} + __path__: /var/logs/phoenix.log + + - job_name: docker + static_configs: + - labels: + job: docker + host: ${HOSTNAME} + __path__: /var/lib/docker/containers/*/*-json.log From 12bdbcfbdc8845aadf49c54f7e78b4db7d3eff90 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 14 Mar 2024 22:33:00 +0530 Subject: [PATCH 24/30] npx prettier --config ../docs/.prettierrc.json --write '**/*.md' --- infra/copycat-db/README.md | 19 ++++++++++--------- infra/services/README.md | 34 +++++++++++++++++----------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/infra/copycat-db/README.md b/infra/copycat-db/README.md index 4310c73d8..266bd4e6e 100644 --- a/infra/copycat-db/README.md +++ b/infra/copycat-db/README.md @@ -11,8 +11,8 @@ when it creates a new one to avoid indefinite retention. In production the service runs as a cron job, scheduled using a systemd timer. > These backups are in addition to the regular snapshots that we take, and are -> meant as a second layer of replication. For more details, see our [Reliability -> and Replication Specification](https://ente.io/reliability). +> meant as a second layer of replication. For more details, see our +> [Reliability and Replication Specification](https://ente.io/reliability). ## Quick help @@ -60,7 +60,8 @@ then the Docker image falls back to using `pg_dump` (as outlined next). Not needed in production when taking a backup (since we use the Scaleway CLI to take backups in production). -These are used when testing a backup using `pg_dump`, and when restoring backups. +These are used when testing a backup using `pg_dump`, and when restoring +backups. ##### RCLONE_CONFIG @@ -69,9 +70,9 @@ to use to save the backups, and the credentials to to access it. Specifically, the config file contains two remotes: -* The bucket itself, where data will be stored. +- The bucket itself, where data will be stored. -* A "crypt" remote that wraps the bucket by applying client side encryption. +- A "crypt" remote that wraps the bucket by applying client side encryption. The configuration file will contain (lightly) obfuscated versions of the password, and as long as we have the configuration file we can continue using @@ -163,9 +164,9 @@ you wish to force the job to service immediately ## Updating -To update, run the [GitHub -workflow](../../.github/workflows/copycat-db-release.yaml) to build and push the -latest image to our Docker Registry, then restart the systemd service on the -instance +To update, run the +[GitHub workflow](../../.github/workflows/copycat-db-release.yaml) to build and +push the latest image to our Docker Registry, then restart the systemd service +on the instance sudo systemctl restart copycat-db diff --git a/infra/services/README.md b/infra/services/README.md index 17fb6ce87..8c3a3d569 100644 --- a/infra/services/README.md +++ b/infra/services/README.md @@ -2,26 +2,26 @@ "Services" are Docker images we run on our instances and manage using systemd. -All our services (including museum itself) follow the same -pattern: +All our services (including museum itself) follow the same pattern: -* They're run on vanilla Ubuntu instances. The only expectation they have is for - Docker to be installed. +- They're run on vanilla Ubuntu instances. The only expectation they have is + for Docker to be installed. -* They log to fixed, known, locations - `/root/var/log/foo.log` - so that these - logs can get ingested by Promtail if needed. +- They log to fixed, known, locations - `/root/var/log/foo.log` - so that + these logs can get ingested by Promtail if needed. -* Each service should consist of a Docker image (or a Docker compose file), and a - systemd unit file. +- Each service should consist of a Docker image (or a Docker compose file), + and a systemd unit file. -* To start / stop / schedule the service, we use systemd. +- To start / stop / schedule the service, we use systemd. -* Each time the service runs it should pull the latest Docker image, so there is - no separate installation/upgrade step needed. We can just restart the service, - and it'll use the latest code. +- Each time the service runs it should pull the latest Docker image, so there + is no separate installation/upgrade step needed. We can just restart the + service, and it'll use the latest code. -* Any credentials and/or configuration should be read by mounting the - appropriate file from `/root/service-name` into the running Docker container. +- Any credentials and/or configuration should be read by mounting the + appropriate file from `/root/service-name` into the running Docker + container. ## Systemd cheatsheet @@ -46,9 +46,9 @@ service file (_note_: starting on boot requires one more step later): WantedBy=multi-user.target ``` -Copy the service file to the instance where we want to run the service. -Services might also have some additional configuration or env files, also copy -those to the instance. +Copy the service file to the instance where we want to run the service. Services +might also have some additional configuration or env files, also copy those to +the instance. ```sh scp services/example.service example.env : From 123fc8a8839b1bdaecfba346307bf1990607a06e Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Fri, 15 Mar 2024 01:37:14 +0000 Subject: [PATCH 25/30] New Crowdin translations by GitHub Action --- .../public/locales/de-DE/translation.json | 6 ++-- .../public/locales/pt-BR/translation.json | 30 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/web/apps/photos/public/locales/de-DE/translation.json b/web/apps/photos/public/locales/de-DE/translation.json index a515e7366..9e3823959 100644 --- a/web/apps/photos/public/locales/de-DE/translation.json +++ b/web/apps/photos/public/locales/de-DE/translation.json @@ -338,8 +338,8 @@ "SORT_BY_CREATION_TIME_ASCENDING": "Ältestem", "SORT_BY_UPDATION_TIME_DESCENDING": "Zuletzt aktualisiert", "SORT_BY_NAME": "Name", - "COMPRESS_THUMBNAILS": "", - "THUMBNAIL_REPLACED": "", + "COMPRESS_THUMBNAILS": "Vorschaubilder komprimieren", + "THUMBNAIL_REPLACED": "Vorschaubilder komprimiert", "FIX_THUMBNAIL": "Komprimiere", "FIX_THUMBNAIL_LATER": "Später komprimieren", "REPLACE_THUMBNAIL_NOT_STARTED": "", @@ -352,7 +352,7 @@ "UPDATE_CREATION_TIME_NOT_STARTED": "", "UPDATE_CREATION_TIME_COMPLETED": "", "UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR": "", - "CAPTION_CHARACTER_LIMIT": "", + "CAPTION_CHARACTER_LIMIT": "Maximal 5000 Zeichen", "DATE_TIME_ORIGINAL": "", "DATE_TIME_DIGITIZED": "", "METADATA_DATE": "", diff --git a/web/apps/photos/public/locales/pt-BR/translation.json b/web/apps/photos/public/locales/pt-BR/translation.json index 4eaa398c4..617a2618d 100644 --- a/web/apps/photos/public/locales/pt-BR/translation.json +++ b/web/apps/photos/public/locales/pt-BR/translation.json @@ -8,7 +8,7 @@ "LOGIN": "Entrar", "SIGN_UP": "Registrar", "NEW_USER": "Novo no ente", - "EXISTING_USER": "Utilizador existente", + "EXISTING_USER": "Usuário existente", "ENTER_NAME": "Insira o nome", "PUBLIC_UPLOADER_NAME_MESSAGE": "Adicione um nome para que os seus amigos saibam a quem agradecer por estas ótimas fotos!", "ENTER_EMAIL": "Insira o endereço de e-mail", @@ -227,7 +227,7 @@ "INDEXING_SCHEDULED": "Indexação está programada...", "ANALYZING_PHOTOS": "Indexando fotos ({{indexStatus.nSyncedFiles,number}} / {{indexStatus.nTotalFiles,number}})", "INDEXING_PEOPLE": "Indexando pessoas em {{indexStatus.nSyncedFiles,number}} fotos...", - "INDEXING_DONE": "", + "INDEXING_DONE": "Foram indexadas {{indexStatus.nSyncedFiles,number}} fotos", "UNIDENTIFIED_FACES": "rostos não identificados", "OBJECTS": "objetos", "TEXT": "texto", @@ -347,15 +347,15 @@ "REPLACE_THUMBNAIL_NOOP": "Você não tem nenhuma miniatura que possa ser compactadas mais", "REPLACE_THUMBNAIL_COMPLETED_WITH_ERROR": "Não foi possível compactar algumas das suas miniaturas, por favor tente novamente", "FIX_CREATION_TIME": "Corrigir hora", - "FIX_CREATION_TIME_IN_PROGRESS": "", - "CREATION_TIME_UPDATED": "", + "FIX_CREATION_TIME_IN_PROGRESS": "Corrigindo horário", + "CREATION_TIME_UPDATED": "Hora do arquivo atualizado", "UPDATE_CREATION_TIME_NOT_STARTED": "Selecione a carteira que você deseja usar", "UPDATE_CREATION_TIME_COMPLETED": "Todos os arquivos atualizados com sucesso", - "UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR": "", + "UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR": "A atualização do horário falhou para alguns arquivos, por favor, tente novamente", "CAPTION_CHARACTER_LIMIT": "5000 caracteres no máximo", - "DATE_TIME_ORIGINAL": "", - "DATE_TIME_DIGITIZED": "", - "METADATA_DATE": "", + "DATE_TIME_ORIGINAL": "Data e Hora Original", + "DATE_TIME_DIGITIZED": "Data e Hora Digitalizada", + "METADATA_DATE": "Data de Metadados", "CUSTOM_TIME": "Tempo personalizado", "REOPEN_PLAN_SELECTOR_MODAL": "Reabrir planos", "OPEN_PLAN_SELECTOR_MODAL_FAILED": "Falha ao abrir planos", @@ -408,7 +408,7 @@ "SHARED_USING": "Compartilhar usando ", "ENTE_IO": "ente.io", "SHARING_REFERRAL_CODE": "Use o código {{referralCode}} para obter 10 GB de graça", - "LIVE": "", + "LIVE": "AO VIVO", "DISABLE_PASSWORD": "Desativar bloqueio por senha", "DISABLE_PASSWORD_MESSAGE": "Tem certeza que deseja desativar o bloqueio por senha?", "PASSWORD_LOCK": "Bloqueio de senha", @@ -506,8 +506,8 @@ "DISABLE_FACE_SEARCH_DESCRIPTION": "

Ente irá parar de processar geometria facial.

Você pode reativar o reconhecimento facial novamente, se desejar, então esta operação está segura.

", "ADVANCED": "Avançado", "FACE_SEARCH_CONFIRMATION": "Eu entendo, e desejo permitir que o ente processe a geometria do rosto", - "LABS": "", - "YOURS": "", + "LABS": "Laboratórios", + "YOURS": "seu", "PASSPHRASE_STRENGTH_WEAK": "Força da senha: fraca", "PASSPHRASE_STRENGTH_MODERATE": "Força da senha: moderada", "PASSPHRASE_STRENGTH_STRONG": "Força da senha: forte", @@ -570,7 +570,7 @@ "FEEDBACK_REQUIRED": "Por favor, ajude-nos com esta informação", "FEEDBACK_REQUIRED_FOUND_ANOTHER_SERVICE": "O que o outro serviço faz melhor?", "RECOVER_TWO_FACTOR": "Recuperar dois fatores", - "at": "", + "at": "em", "AUTH_NEXT": "próximo", "AUTH_DOWNLOAD_MOBILE_APP": "Baixe nosso aplicativo móvel para gerenciar seus segredos", "HIDDEN": "Escondido", @@ -604,7 +604,7 @@ "BLUR": "Desfoque", "INVERT_COLORS": "Inverter Cores", "ASPECT_RATIO": "Proporção da imagem", - "SQUARE": "", + "SQUARE": "Quadrado", "ROTATE_LEFT": "Girar para a Esquerda", "ROTATE_RIGHT": "Girar para a Direita", "FLIP_VERTICALLY": "Inverter verticalmente", @@ -634,8 +634,8 @@ "VISIT_CAST_ENTE_IO": "Acesse cast.ente.io no dispositivo que você deseja parear.", "CAST_AUTO_PAIR_FAILED": "Chromecast Auto Pair falhou. Por favor, tente novamente.", "CACHE_DIRECTORY": "Pasta de Cache", - "PASSKEYS": "", - "FREEHAND": "", + "PASSKEYS": "Chaves de acesso", + "FREEHAND": "Mão livre", "APPLY_CROP": "Aplicar Recorte", "PHOTO_EDIT_REQUIRED_TO_SAVE": "Pelo menos uma transformação ou ajuste de cor deve ser feito antes de salvar." } From 2f86fbdd95c1bdb73ded39d8d80518eb96ce6b1b Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Fri, 15 Mar 2024 02:03:25 +0000 Subject: [PATCH 26/30] New Crowdin translations by GitHub Action --- auth/lib/l10n/arb/app_pt.arb | 2 ++ auth/lib/l10n/arb/app_zh.arb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/auth/lib/l10n/arb/app_pt.arb b/auth/lib/l10n/arb/app_pt.arb index aa6a2a837..bc43e8422 100644 --- a/auth/lib/l10n/arb/app_pt.arb +++ b/auth/lib/l10n/arb/app_pt.arb @@ -145,6 +145,7 @@ "lostDeviceTitle": "Perdeu seu dispositivo?", "twoFactorAuthTitle": "Autenticação de dois fatores", "passkeyAuthTitle": "Autenticação via Chave de acesso", + "verifyPasskey": "Verificar chave de acesso", "recoverAccount": "Recuperar conta", "enterRecoveryKeyHint": "Digite sua chave de recuperação", "recover": "Recuperar", @@ -407,6 +408,7 @@ "hearUsWhereTitle": "Como você ouviu sobre o Ente? (opcional)", "hearUsExplanation": "Não rastreamos instalações do aplicativo. Seria útil se você nos contasse onde nos encontrou!", "waitingForBrowserRequest": "Aguardando solicitação do navegador...", + "waitingForVerification": "Esperando por verificação...", "passkey": "Chave de acesso", "developerSettingsWarning": "Tem certeza de que deseja modificar as configurações de Desenvolvedor?", "developerSettings": "Configurações de desenvolvedor", diff --git a/auth/lib/l10n/arb/app_zh.arb b/auth/lib/l10n/arb/app_zh.arb index e07e7dcfa..5328a14b9 100644 --- a/auth/lib/l10n/arb/app_zh.arb +++ b/auth/lib/l10n/arb/app_zh.arb @@ -145,6 +145,7 @@ "lostDeviceTitle": "丢失了设备吗?", "twoFactorAuthTitle": "双因素认证", "passkeyAuthTitle": "通行密钥认证", + "verifyPasskey": "验证通行密钥", "recoverAccount": "恢复账户", "enterRecoveryKeyHint": "输入您的恢复密钥", "recover": "恢复", @@ -407,6 +408,7 @@ "hearUsWhereTitle": "您是如何知道Ente的? (可选的)", "hearUsExplanation": "我们不跟踪应用程序安装情况。如果您告诉我们您是在哪里找到我们的,将会有所帮助!", "waitingForBrowserRequest": "正在等待浏览器请求...", + "waitingForVerification": "等待验证...", "passkey": "通行密钥", "developerSettingsWarning": "您确定要修改开发者设置吗?", "developerSettings": "开发者设置", From bd75eba9417f535dfc89c71fb265e95bd38c49ff Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 15 Mar 2024 12:56:20 +0530 Subject: [PATCH 27/30] [docs] Mention submodules in the community external S3 guide --- docs/docs/self-hosting/guides/external-s3.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/docs/self-hosting/guides/external-s3.md b/docs/docs/self-hosting/guides/external-s3.md index 40b401724..505ae6fe9 100644 --- a/docs/docs/self-hosting/guides/external-s3.md +++ b/docs/docs/self-hosting/guides/external-s3.md @@ -17,6 +17,14 @@ have the keys and secrets for the S3 bucket. The plan is as follows: 4. Create an account and increase storage quota 5. Fix potential CORS issue with your bucket +> [!NOTE] +> +> This is a community contributed guide, and some of these steps might be out of +> sync with the upstream documentation. If something is not working correctly, +> please also see the latest +> [READMEs](https://github.com/ente-io/ente/blob/main/server/README.md) in the +> repository and/or other guides in [self-hosting](/self-hosting/). + ## 1. Create a `compose.yaml` file After cloning the main repository with @@ -25,6 +33,7 @@ After cloning the main repository with git clone https://github.com/ente-io/ente.git # Or git clone git@github.com:ente-io/ente.git cd ente +git submodule update --init --recursive ``` Create a `compose.yaml` file at the root of the project with the following From 5841aefb7540233adc8bd93e31e037fa17bdfb91 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 15 Mar 2024 13:06:07 +0530 Subject: [PATCH 28/30] [infra] Remind about needing to also enable node-exporter --- infra/services/prometheus/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infra/services/prometheus/README.md b/infra/services/prometheus/README.md index 90dc0cca3..79bee13d5 100644 --- a/infra/services/prometheus/README.md +++ b/infra/services/prometheus/README.md @@ -27,6 +27,6 @@ automatically start on boot going forward), and start them. ```sh sudo systemctl daemon-reload -sudo systemctl enable node-exporter prometheus -sudo systemctl start node-exporter prometheus +sudo systemctl enable --now node-exporter +sudo systemctl enable --now prometheus ``` From 87d39ae2dd2a3489769c3a4433e1cfc5437dddf8 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 15 Mar 2024 17:09:40 +0530 Subject: [PATCH 29/30] Disable the example.org domains in the default self-hosted configuration People won't be able to get emails, but they can still create accounts on that domain in the default setup. So just comment it out as a saner default. --- server/configurations/local.yaml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/server/configurations/local.yaml b/server/configurations/local.yaml index 47d6f0d37..2c4bd8f3c 100644 --- a/server/configurations/local.yaml +++ b/server/configurations/local.yaml @@ -174,7 +174,7 @@ stripe: webauthn: rpid: "example.com" rporigins: - - "https://example.com:3005" + - "https://example.com:3005" # Roadmap SSO (optional) # @@ -220,13 +220,17 @@ internal: # If provided, this external healthcheck url is periodically pinged. health-check-url: # Hardcoded verification codes, useful for logging in when developing. - hardcoded-ott: - emails: - - "example@example.org,123456" - # When running in a local environment, hardcode the verification code to - # 123456 for email addresses ending with @example.org - local-domain-suffix: "@example.org" - local-domain-value: 123456 + # + # Uncomment this and set these to your email ID or domain so that you don't + # need to peek into the server logs for obtaining the OTP when trying to log + # into an instance you're developing on. + # hardcoded-ott: + # emails: + # - "example@example.org,123456" + # # When running in a local environment, hardcode the verification code to + # # 123456 for email addresses ending with @example.org + # local-domain-suffix: "@example.org" + # local-domain-value: 123456 # List of user IDs that can use the admin API endpoints. admins: [] From 92ae1be40a9c9c87201b73240b630a4a7c0692a2 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 15 Mar 2024 17:15:24 +0530 Subject: [PATCH 30/30] Add a new flag to support S3 path style URLs without disabling SSL The use case for this came up in Discord - someone is running a custom self hosted instance where they're using MinIO as their "production S3", but it is not local (so they don't want the clients to connect without SSL). So we need a way to get MinIO to work, which needs path style URLs, without also disabling the SSL. --- server/configurations/local.yaml | 16 ++++++++++++---- server/pkg/utils/s3config/s3config.go | 4 ++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/server/configurations/local.yaml b/server/configurations/local.yaml index 2c4bd8f3c..4bab089b6 100644 --- a/server/configurations/local.yaml +++ b/server/configurations/local.yaml @@ -113,10 +113,7 @@ s3: # # 1. Disable SSL. # - # 2. Use "path" style S3 URLs where the bucket is part of the URL path, e.g. - # http://localhost:3200/b2-eu-cen. By default the bucket name is part of - # the (sub)domain, e.g. http://b2-eu-cen.localhost:3200/ and cannot be - # resolved when running locally. + # 2. Use "path" style S3 URLs (see `use_path_style_urls` below). # # 3. Directly download the file during replication instead of going via the # Cloudflare worker. @@ -125,6 +122,17 @@ s3: # not support them, specifically it doesn't support GLACIER). # #are_local_buckets: true + # Uncomment this to use "path" style S3 URLs. + # + # By default the bucket name is part of the (sub)domain, e.g. + # http://b2-eu-cen.localhost:3200/. If this is true, then we use "path" + # style S3 URLs where the bucket is part of the URL path, e.g. + # http://localhost:3200/b2-eu-cen. + # + # This is useful in scenarios when sub-domain based addressing cannot be + # resolved, e.g. when running a local instance, or when using MinIO as a + # production store. + #use_path_style_urls: true # Key used for encrypting customer emails before storing them in DB # diff --git a/server/pkg/utils/s3config/s3config.go b/server/pkg/utils/s3config/s3config.go index fe83ce6ea..9b273bd61 100644 --- a/server/pkg/utils/s3config/s3config.go +++ b/server/pkg/utils/s3config/s3config.go @@ -104,6 +104,7 @@ func (config *S3Config) initialize() { config.s3Configs = make(map[string]*aws.Config) config.s3Clients = make(map[string]s3.S3) + usePathStyleURLs := viper.GetBool("s3.use_path_style_urls") areLocalBuckets := viper.GetBool("s3.are_local_buckets") config.areLocalBuckets = areLocalBuckets @@ -116,6 +117,9 @@ func (config *S3Config) initialize() { Endpoint: aws.String(viper.GetString("s3." + dc + ".endpoint")), Region: aws.String(viper.GetString("s3." + dc + ".region")), } + if usePathStyleURLs { + s3Config.S3ForcePathStyle = aws.Bool(true) + } if areLocalBuckets { s3Config.DisableSSL = aws.Bool(true) s3Config.S3ForcePathStyle = aws.Bool(true)