diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 406306bbeca2e..c1a3f42508aaa 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -13,11 +13,12 @@ Checklist: * [ ] I've updated both the CLI and UI to expose my feature, or I plan to submit a second PR with them. * [ ] Does this PR require documentation updates? * [ ] I've updated documentation as required by this PR. -* [ ] Optional. My organization is added to USERS.md. * [ ] I have signed off all my commits as required by [DCO](https://github.com/argoproj/argoproj/blob/master/community/CONTRIBUTING.md#legal) * [ ] I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged. * [ ] My build is green ([troubleshooting builds](https://argo-cd.readthedocs.io/en/latest/developer-guide/ci/)). * [ ] My new feature complies with the [feature status](https://github.com/argoproj/argoproj/blob/master/community/feature-status.md) guidelines. * [ ] I have added a brief description of why this PR is necessary and/or what this PR solves. +* [ ] Optional. My organization is added to USERS.md. +* [ ] Optional. For bug fixes, I've indicated what older releases this fix should be cherry-picked into (this may or may not happen depending on risk/complexity). diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 58426890abcbf..2311d43925bb7 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -27,10 +27,15 @@ jobs: # CodeQL runs on ubuntu-latest and windows-latest runs-on: ubuntu-22.04 - steps: - name: Checkout repository uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + + # Use correct go version. https://github.com/github/codeql-action/issues/1842#issuecomment-1704398087 + - name: Setup Golang + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.0.0 + with: + go-version-file: go.mod # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index ac111ae6395a7..0838f38e4230d 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -74,9 +74,9 @@ jobs: go-version: ${{ inputs.go-version }} - name: Install cosign - uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2 + uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 # v3.2.0 with: - cosign-release: 'v2.0.2' + cosign-release: 'v2.2.1' - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 diff --git a/Procfile b/Procfile index 2bb26a086fb1d..92f69ecf8ffbc 100644 --- a/Procfile +++ b/Procfile @@ -9,4 +9,5 @@ git-server: test/fixture/testrepos/start-git.sh helm-registry: test/fixture/testrepos/start-helm-registry.sh dev-mounter: [[ "$ARGOCD_E2E_TEST" != "true" ]] && go run hack/dev-mounter/main.go --configmap argocd-ssh-known-hosts-cm=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} --configmap argocd-tls-certs-cm=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} --configmap argocd-gpg-keys-cm=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} applicationset-controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-applicationset-controller $COMMAND --loglevel debug --metrics-addr localhost:12345 --probe-addr localhost:12346 --argocd-repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}" -notification: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications $COMMAND --loglevel debug" +notification: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications $COMMAND --loglevel debug --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --self-service-notification-enabled=${ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED:-'false'}" + diff --git a/USERS.md b/USERS.md index 0f660ebb5f4d6..cc1c22e3d9d7b 100644 --- a/USERS.md +++ b/USERS.md @@ -148,6 +148,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Kinguin](https://www.kinguin.net/) 1. [KintoHub](https://www.kintohub.com/) 1. [KompiTech GmbH](https://www.kompitech.com/) +1. [Kong Inc.](https://konghq.com/) 1. [KPMG](https://kpmg.com/uk) 1. [KubeSphere](https://github.com/kubesphere) 1. [Kurly](https://www.kurly.com/) @@ -243,6 +244,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Robotinfra](https://www.robotinfra.com) 1. [Rubin Observatory](https://www.lsst.org) 1. [Saildrone](https://www.saildrone.com/) +1. [Salad Technologies](https://salad.com/) 1. [Saloodo! GmbH](https://www.saloodo.com) 1. [Sap Labs](http://sap.com) 1. [Sauce Labs](https://saucelabs.com/) diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 5f1205caf384a..4f5ac66fc016d 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -108,16 +108,14 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque // Do not attempt to further reconcile the ApplicationSet if it is being deleted. if applicationSetInfo.ObjectMeta.DeletionTimestamp != nil { - if controllerutil.ContainsFinalizer(&applicationSetInfo, argov1alpha1.ResourcesFinalizerName) { - deleteAllowed := utils.DefaultPolicy(applicationSetInfo.Spec.SyncPolicy, r.Policy, r.EnablePolicyOverride).AllowDelete() - if !deleteAllowed { - if err := r.removeOwnerReferencesOnDeleteAppSet(ctx, applicationSetInfo); err != nil { - return ctrl.Result{}, err - } - controllerutil.RemoveFinalizer(&applicationSetInfo, argov1alpha1.ResourcesFinalizerName) - if err := r.Update(ctx, &applicationSetInfo); err != nil { - return ctrl.Result{}, err - } + deleteAllowed := utils.DefaultPolicy(applicationSetInfo.Spec.SyncPolicy, r.Policy, r.EnablePolicyOverride).AllowDelete() + if !deleteAllowed { + if err := r.removeOwnerReferencesOnDeleteAppSet(ctx, applicationSetInfo); err != nil { + return ctrl.Result{}, err + } + controllerutil.RemoveFinalizer(&applicationSetInfo, argov1alpha1.ResourcesFinalizerName) + if err := r.Update(ctx, &applicationSetInfo); err != nil { + return ctrl.Result{}, err } } return ctrl.Result{}, nil @@ -524,6 +522,7 @@ func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, appli for _, p := range a.Params { app, err := r.Renderer.RenderTemplateParams(tmplApplication, applicationSetInfo.Spec.SyncPolicy, p, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) + if err != nil { logCtx.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). Error("error generating application from params") @@ -534,6 +533,24 @@ func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, appli } continue } + + if applicationSetInfo.Spec.TemplatePatch != nil { + patchedApplication, err := r.applyTemplatePatch(app, applicationSetInfo, p) + + if err != nil { + log.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). + Error("error generating application from params") + + if firstError == nil { + firstError = err + applicationSetReason = argov1alpha1.ApplicationSetReasonRenderTemplateParamsError + } + continue + } + + app = patchedApplication + } + res = append(res, *app) } } @@ -545,6 +562,16 @@ func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, appli return res, applicationSetReason, firstError } +func (r *ApplicationSetReconciler) applyTemplatePatch(app *argov1alpha1.Application, applicationSetInfo argov1alpha1.ApplicationSet, params map[string]interface{}) (*argov1alpha1.Application, error) { + replacedTemplate, err := r.Renderer.Replace(*applicationSetInfo.Spec.TemplatePatch, params, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) + + if err != nil { + return nil, fmt.Errorf("error replacing values in templatePatch: %w", err) + } + + return applyTemplatePatch(app, replacedTemplate) +} + func ignoreNotAllowedNamespaces(namespaces []string) predicate.Predicate { return predicate.Funcs{ CreateFunc: func(e event.CreateEvent) bool { @@ -619,6 +646,8 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context, var firstError error // Creates or updates the application in appList for _, generatedApp := range desiredApplications { + // The app's namespace must be the same as the AppSet's namespace to preserve the appsets-in-any-namespace + // security boundary. generatedApp.Namespace = applicationSet.Namespace appLog := logCtx.WithFields(log.Fields{"app": generatedApp.QualifiedName()}) diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index ce9dc485ba4a8..81fbad95ac50b 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -86,6 +86,12 @@ func (g *generatorMock) GenerateParams(appSetGenerator *v1alpha1.ApplicationSetG return args.Get(0).([]map[string]interface{}), args.Error(1) } +func (g *generatorMock) Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { + args := g.Called(tmpl, replaceMap, useGoTemplate, goTemplateOptions) + + return args.Get(0).(string), args.Error(1) +} + type rendererMock struct { mock.Mock } @@ -107,6 +113,12 @@ func (r *rendererMock) RenderTemplateParams(tmpl *v1alpha1.Application, syncPoli } +func (r *rendererMock) Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { + args := r.Called(tmpl, replaceMap, useGoTemplate, goTemplateOptions) + + return args.Get(0).(string), args.Error(1) +} + func TestExtractApplications(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) diff --git a/applicationset/controllers/templatePatch.go b/applicationset/controllers/templatePatch.go new file mode 100644 index 0000000000000..f8efd9f376996 --- /dev/null +++ b/applicationset/controllers/templatePatch.go @@ -0,0 +1,46 @@ +package controllers + +import ( + "encoding/json" + "fmt" + + "k8s.io/apimachinery/pkg/util/strategicpatch" + + "github.com/argoproj/argo-cd/v2/applicationset/utils" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func applyTemplatePatch(app *appv1.Application, templatePatch string) (*appv1.Application, error) { + + appString, err := json.Marshal(app) + if err != nil { + return nil, fmt.Errorf("error while marhsalling Application %w", err) + } + + convertedTemplatePatch, err := utils.ConvertYAMLToJSON(templatePatch) + + if err != nil { + return nil, fmt.Errorf("error while converting template to json %q: %w", convertedTemplatePatch, err) + } + + if err := json.Unmarshal([]byte(convertedTemplatePatch), &appv1.Application{}); err != nil { + return nil, fmt.Errorf("invalid templatePatch %q: %w", convertedTemplatePatch, err) + } + + data, err := strategicpatch.StrategicMergePatch(appString, []byte(convertedTemplatePatch), appv1.Application{}) + + if err != nil { + return nil, fmt.Errorf("error while applying templatePatch template to json %q: %w", convertedTemplatePatch, err) + } + + finalApp := appv1.Application{} + err = json.Unmarshal(data, &finalApp) + if err != nil { + return nil, fmt.Errorf("error while unmarhsalling patched application: %w", err) + } + + // Prevent changes to the `project` field. This helps prevent malicious template patches + finalApp.Spec.Project = app.Spec.Project + + return &finalApp, nil +} diff --git a/applicationset/controllers/templatePatch_test.go b/applicationset/controllers/templatePatch_test.go new file mode 100644 index 0000000000000..c1a794077c8ee --- /dev/null +++ b/applicationset/controllers/templatePatch_test.go @@ -0,0 +1,249 @@ +package controllers + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func Test_ApplyTemplatePatch(t *testing.T) { + testCases := []struct { + name string + appTemplate *appv1.Application + templatePatch string + expectedApp *appv1.Application + }{ + { + name: "patch with JSON", + appTemplate: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + templatePatch: `{ + "metadata": { + "annotations": { + "annotation-some-key": "annotation-some-value" + } + }, + "spec": { + "source": { + "helm": { + "valueFiles": [ + "values.test.yaml", + "values.big.yaml" + ] + } + }, + "syncPolicy": { + "automated": { + "prune": true + } + } + } + }`, + expectedApp: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + Annotations: map[string]string{ + "annotation-some-key": "annotation-some-value", + }, + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + Helm: &appv1.ApplicationSourceHelm{ + ValueFiles: []string{ + "values.test.yaml", + "values.big.yaml", + }, + }, + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + SyncPolicy: &appv1.SyncPolicy{ + Automated: &appv1.SyncPolicyAutomated{ + Prune: true, + }, + }, + }, + }, + }, + { + name: "patch with YAML", + appTemplate: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + templatePatch: ` +metadata: + annotations: + annotation-some-key: annotation-some-value +spec: + source: + helm: + valueFiles: + - values.test.yaml + - values.big.yaml + syncPolicy: + automated: + prune: true`, + expectedApp: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + Annotations: map[string]string{ + "annotation-some-key": "annotation-some-value", + }, + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + Helm: &appv1.ApplicationSourceHelm{ + ValueFiles: []string{ + "values.test.yaml", + "values.big.yaml", + }, + }, + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + SyncPolicy: &appv1.SyncPolicy{ + Automated: &appv1.SyncPolicyAutomated{ + Prune: true, + }, + }, + }, + }, + }, + { + name: "project field isn't overwritten", + appTemplate: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + templatePatch: ` +spec: + project: my-project`, + expectedApp: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + }, + } + + for _, tc := range testCases { + tcc := tc + t.Run(tcc.name, func(t *testing.T) { + result, err := applyTemplatePatch(tcc.appTemplate, tcc.templatePatch) + require.NoError(t, err) + assert.Equal(t, *tcc.expectedApp, *result) + }) + } +} + +func TestError(t *testing.T) { + app := &appv1.Application{} + + result, err := applyTemplatePatch(app, "hello world") + require.Error(t, err) + require.Nil(t, result) +} diff --git a/applicationset/generators/git.go b/applicationset/generators/git.go index 07c1b11849cd0..57fe2835b8df0 100644 --- a/applicationset/generators/git.go +++ b/applicationset/generators/git.go @@ -56,12 +56,14 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic return nil, EmptyAppSetGeneratorError } + noRevisionCache := appSet.RefreshRequired() + var err error var res []map[string]interface{} if len(appSetGenerator.Git.Directories) != 0 { - res, err = g.generateParamsForGitDirectories(appSetGenerator, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) + res, err = g.generateParamsForGitDirectories(appSetGenerator, noRevisionCache, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) } else if len(appSetGenerator.Git.Files) != 0 { - res, err = g.generateParamsForGitFiles(appSetGenerator, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) + res, err = g.generateParamsForGitFiles(appSetGenerator, noRevisionCache, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) } else { return nil, EmptyAppSetGeneratorError } @@ -72,10 +74,10 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic return res, nil } -func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { +func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache bool, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { // Directories, not files - allPaths, err := g.repos.GetDirectories(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision) + allPaths, err := g.repos.GetDirectories(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, noRevisionCache) if err != nil { return nil, fmt.Errorf("error getting directories from repo: %w", err) } @@ -98,12 +100,12 @@ func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoproj return res, nil } -func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { +func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache bool, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { // Get all files that match the requested path string, removing duplicates allFiles := make(map[string][]byte) for _, requestedPath := range appSetGenerator.Git.Files { - files, err := g.repos.GetFiles(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, requestedPath.Path) + files, err := g.repos.GetFiles(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, requestedPath.Path, noRevisionCache) if err != nil { return nil, err } diff --git a/applicationset/generators/git_test.go b/applicationset/generators/git_test.go index f0d1d29bca6ec..d3fd4965057f8 100644 --- a/applicationset/generators/git_test.go +++ b/applicationset/generators/git_test.go @@ -317,7 +317,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) + argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) var gitGenerator = NewGitGenerator(&argoCDServiceMock) applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ @@ -613,7 +613,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) + argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) var gitGenerator = NewGitGenerator(&argoCDServiceMock) applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ @@ -972,7 +972,7 @@ cluster: t.Parallel() argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError) var gitGenerator = NewGitGenerator(&argoCDServiceMock) @@ -1322,7 +1322,7 @@ cluster: t.Parallel() argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError) var gitGenerator = NewGitGenerator(&argoCDServiceMock) diff --git a/applicationset/generators/matrix_test.go b/applicationset/generators/matrix_test.go index 35748b98bcf19..21e88710ae618 100644 --- a/applicationset/generators/matrix_test.go +++ b/applicationset/generators/matrix_test.go @@ -1108,7 +1108,7 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) { } repoServiceMock := &mocks.Repos{} - repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{ + repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{ "some/path.json": []byte("test: content"), }, nil) gitGenerator := NewGitGenerator(repoServiceMock) diff --git a/applicationset/services/mocks/Repos.go b/applicationset/services/mocks/Repos.go index 776b104cae284..b7620b22f08bb 100644 --- a/applicationset/services/mocks/Repos.go +++ b/applicationset/services/mocks/Repos.go @@ -13,25 +13,25 @@ type Repos struct { mock.Mock } -// GetDirectories provides a mock function with given fields: ctx, repoURL, revision -func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision string) ([]string, error) { - ret := _m.Called(ctx, repoURL, revision) +// GetDirectories provides a mock function with given fields: ctx, repoURL, revision, noRevisionCache +func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache bool) ([]string, error) { + ret := _m.Called(ctx, repoURL, revision, noRevisionCache) var r0 []string var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, string) ([]string, error)); ok { - return rf(ctx, repoURL, revision) + if rf, ok := ret.Get(0).(func(context.Context, string, string, bool) ([]string, error)); ok { + return rf(ctx, repoURL, revision, noRevisionCache) } - if rf, ok := ret.Get(0).(func(context.Context, string, string) []string); ok { - r0 = rf(ctx, repoURL, revision) + if rf, ok := ret.Get(0).(func(context.Context, string, string, bool) []string); ok { + r0 = rf(ctx, repoURL, revision, noRevisionCache) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]string) } } - if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { - r1 = rf(ctx, repoURL, revision) + if rf, ok := ret.Get(1).(func(context.Context, string, string, bool) error); ok { + r1 = rf(ctx, repoURL, revision, noRevisionCache) } else { r1 = ret.Error(1) } @@ -39,25 +39,25 @@ func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision st return r0, r1 } -// GetFiles provides a mock function with given fields: ctx, repoURL, revision, pattern -func (_m *Repos) GetFiles(ctx context.Context, repoURL string, revision string, pattern string) (map[string][]byte, error) { - ret := _m.Called(ctx, repoURL, revision, pattern) +// GetFiles provides a mock function with given fields: ctx, repoURL, revision, pattern, noRevisionCache +func (_m *Repos) GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache bool) (map[string][]byte, error) { + ret := _m.Called(ctx, repoURL, revision, pattern, noRevisionCache) var r0 map[string][]byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, string) (map[string][]byte, error)); ok { - return rf(ctx, repoURL, revision, pattern) + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool) (map[string][]byte, error)); ok { + return rf(ctx, repoURL, revision, pattern, noRevisionCache) } - if rf, ok := ret.Get(0).(func(context.Context, string, string, string) map[string][]byte); ok { - r0 = rf(ctx, repoURL, revision, pattern) + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool) map[string][]byte); ok { + r0 = rf(ctx, repoURL, revision, pattern, noRevisionCache) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(map[string][]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, string, string, string) error); ok { - r1 = rf(ctx, repoURL, revision, pattern) + if rf, ok := ret.Get(1).(func(context.Context, string, string, string, bool) error); ok { + r1 = rf(ctx, repoURL, revision, pattern, noRevisionCache) } else { r1 = ret.Error(1) } diff --git a/applicationset/services/repo_service.go b/applicationset/services/repo_service.go index 8ad261fda11cd..64fedc34390b8 100644 --- a/applicationset/services/repo_service.go +++ b/applicationset/services/repo_service.go @@ -11,6 +11,8 @@ import ( "github.com/argoproj/argo-cd/v2/util/io" ) +//go:generate go run github.com/vektra/mockery/v2@v2.25.1 --name=RepositoryDB + // RepositoryDB Is a lean facade for ArgoDB, // Using a lean interface makes it easier to test the functionality of the git generator type RepositoryDB interface { @@ -25,13 +27,15 @@ type argoCDService struct { newFileGlobbingEnabled bool } +//go:generate go run github.com/vektra/mockery/v2@v2.25.1 --name=Repos + type Repos interface { // GetFiles returns content of files (not directories) within the target repo - GetFiles(ctx context.Context, repoURL string, revision string, pattern string) (map[string][]byte, error) + GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache bool) (map[string][]byte, error) // GetDirectories returns a list of directories (not files) within the target repo - GetDirectories(ctx context.Context, repoURL string, revision string) ([]string, error) + GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache bool) ([]string, error) } func NewArgoCDService(db db.ArgoDB, submoduleEnabled bool, repoClientset apiclient.Clientset, newFileGlobbingEnabled bool) (Repos, error) { @@ -43,7 +47,7 @@ func NewArgoCDService(db db.ArgoDB, submoduleEnabled bool, repoClientset apiclie }, nil } -func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision string, pattern string) (map[string][]byte, error) { +func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache bool) (map[string][]byte, error) { repo, err := a.repositoriesDB.GetRepository(ctx, repoURL) if err != nil { return nil, fmt.Errorf("error in GetRepository: %w", err) @@ -55,6 +59,7 @@ func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision s Revision: revision, Path: pattern, NewGitFileGlobbingEnabled: a.newFileGlobbingEnabled, + NoRevisionCache: noRevisionCache, } closer, client, err := a.repoServerClientSet.NewRepoServerClient() if err != nil { @@ -69,7 +74,7 @@ func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision s return fileResponse.GetMap(), nil } -func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revision string) ([]string, error) { +func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache bool) ([]string, error) { repo, err := a.repositoriesDB.GetRepository(ctx, repoURL) if err != nil { return nil, fmt.Errorf("error in GetRepository: %w", err) @@ -79,6 +84,7 @@ func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revi Repo: repo, SubmoduleEnabled: a.submoduleEnabled, Revision: revision, + NoRevisionCache: noRevisionCache, } closer, client, err := a.repoServerClientSet.NewRepoServerClient() diff --git a/applicationset/services/repo_service_test.go b/applicationset/services/repo_service_test.go index 62f8c11c172d0..040fe57f96958 100644 --- a/applicationset/services/repo_service_test.go +++ b/applicationset/services/repo_service_test.go @@ -25,9 +25,10 @@ func TestGetDirectories(t *testing.T) { repoServerClientFuncs []func(*repo_mocks.RepoServerServiceClient) } type args struct { - ctx context.Context - repoURL string - revision string + ctx context.Context + repoURL string + revision string + noRevisionCache bool } tests := []struct { name string @@ -88,11 +89,11 @@ func TestGetDirectories(t *testing.T) { submoduleEnabled: tt.fields.submoduleEnabled, repoServerClientSet: &repo_mocks.Clientset{RepoServerServiceClient: mockRepoClient}, } - got, err := a.GetDirectories(tt.args.ctx, tt.args.repoURL, tt.args.revision) - if !tt.wantErr(t, err, fmt.Sprintf("GetDirectories(%v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision)) { + got, err := a.GetDirectories(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache) + if !tt.wantErr(t, err, fmt.Sprintf("GetDirectories(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache)) { return } - assert.Equalf(t, tt.want, got, "GetDirectories(%v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision) + assert.Equalf(t, tt.want, got, "GetDirectories(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache) }) } } @@ -105,10 +106,11 @@ func TestGetFiles(t *testing.T) { repoServerClientFuncs []func(*repo_mocks.RepoServerServiceClient) } type args struct { - ctx context.Context - repoURL string - revision string - pattern string + ctx context.Context + repoURL string + revision string + pattern string + noRevisionCache bool } tests := []struct { name string @@ -175,11 +177,11 @@ func TestGetFiles(t *testing.T) { submoduleEnabled: tt.fields.submoduleEnabled, repoServerClientSet: &repo_mocks.Clientset{RepoServerServiceClient: mockRepoClient}, } - got, err := a.GetFiles(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern) - if !tt.wantErr(t, err, fmt.Sprintf("GetFiles(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern)) { + got, err := a.GetFiles(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache) + if !tt.wantErr(t, err, fmt.Sprintf("GetFiles(%v, %v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache)) { return } - assert.Equalf(t, tt.want, got, "GetFiles(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern) + assert.Equalf(t, tt.want, got, "GetFiles(%v, %v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache) }) } } diff --git a/applicationset/utils/utils.go b/applicationset/utils/utils.go index 3392d386f7426..2d128eb81a16c 100644 --- a/applicationset/utils/utils.go +++ b/applicationset/utils/utils.go @@ -41,6 +41,7 @@ func init() { type Renderer interface { RenderTemplateParams(tmpl *argoappsv1.Application, syncPolicy *argoappsv1.ApplicationSetSyncPolicy, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (*argoappsv1.Application, error) + Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) } type Render struct { diff --git a/assets/swagger.json b/assets/swagger.json index b7f0cdefabe1c..44e67d0b3923e 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -6143,6 +6143,9 @@ }, "template": { "$ref": "#/definitions/v1alpha1ApplicationSetTemplate" + }, + "templatePatch": { + "type": "string" } } }, diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 4f7e587e36564..74d0af45c9d7a 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -66,6 +66,8 @@ func NewCommand() *cobra.Command { repoServerPlaintext bool repoServerStrictTLS bool otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string otlpAttrs []string applicationNamespaces []string persistResourceHealth bool @@ -173,7 +175,7 @@ func NewCommand() *cobra.Command { stats.RegisterHeapDumper("memprofile") if otlpAddress != "" { - closeTracer, err := trace.InitTracer(ctx, "argocd-controller", otlpAddress, otlpAttrs) + closeTracer, err := trace.InitTracer(ctx, "argocd-controller", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } @@ -206,6 +208,8 @@ func NewCommand() *cobra.Command { command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server") command.Flags().StringSliceVar(&metricsAplicationLabels, "metrics-application-labels", []string{}, "List of Application labels that will be added to the argocd_application_labels metric") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") + command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") + command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces that applications are allowed to be reconciled from") command.Flags().BoolVar(&persistResourceHealth, "persist-resource-health", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH", true), "Enables storing the managed resources health in the Application CRD") diff --git a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go index 62f45b24aedb5..526a199cb5490 100644 --- a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go +++ b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go @@ -26,6 +26,8 @@ func NewCommand() *cobra.Command { var ( configFilePath string otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string otlpAttrs []string ) var command = cobra.Command{ @@ -56,7 +58,7 @@ func NewCommand() *cobra.Command { if otlpAddress != "" { var closer func() var err error - closer, err = traceutil.InitTracer(ctx, "argocd-cmp-server", otlpAddress, otlpAttrs) + closer, err = traceutil.InitTracer(ctx, "argocd-cmp-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } @@ -83,6 +85,8 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error") command.Flags().StringVar(&configFilePath, "config-dir-path", common.DefaultPluginConfigFilePath, "Config management plugin configuration file location, Default is '/home/argocd/cmp-server/config/'") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_CMP_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") + command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_CMP_SERVER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") + command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_CMP_SERVER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_CMP_SERVER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") return &command } diff --git a/cmd/argocd-notification/commands/controller.go b/cmd/argocd-notification/commands/controller.go index abd9a2e8475f0..cb30fd5277d4b 100644 --- a/cmd/argocd-notification/commands/controller.go +++ b/cmd/argocd-notification/commands/controller.go @@ -43,19 +43,20 @@ func addK8SFlagsToCmd(cmd *cobra.Command) clientcmd.ClientConfig { func NewCommand() *cobra.Command { var ( - clientConfig clientcmd.ClientConfig - processorsCount int - namespace string - appLabelSelector string - logLevel string - logFormat string - metricsPort int - argocdRepoServer string - argocdRepoServerPlaintext bool - argocdRepoServerStrictTLS bool - configMapName string - secretName string - applicationNamespaces []string + clientConfig clientcmd.ClientConfig + processorsCount int + namespace string + appLabelSelector string + logLevel string + logFormat string + metricsPort int + argocdRepoServer string + argocdRepoServerPlaintext bool + argocdRepoServerStrictTLS bool + configMapName string + secretName string + applicationNamespaces []string + selfServiceNotificationEnabled bool ) var command = cobra.Command{ Use: "controller", @@ -139,7 +140,7 @@ func NewCommand() *cobra.Command { log.Infof("serving metrics on port %d", metricsPort) log.Infof("loading configuration %d", metricsPort) - ctrl := notificationscontroller.NewController(k8sClient, dynamicClient, argocdService, namespace, applicationNamespaces, appLabelSelector, registry, secretName, configMapName) + ctrl := notificationscontroller.NewController(k8sClient, dynamicClient, argocdService, namespace, applicationNamespaces, appLabelSelector, registry, secretName, configMapName, selfServiceNotificationEnabled) err = ctrl.Init(ctx) if err != nil { return fmt.Errorf("failed to initialize controller: %w", err) @@ -163,5 +164,6 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&configMapName, "config-map-name", "argocd-notifications-cm", "Set notifications ConfigMap name") command.Flags().StringVar(&secretName, "secret-name", "argocd-notifications-secret", "Set notifications Secret name") command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces that this controller should send notifications for") + command.Flags().BoolVar(&selfServiceNotificationEnabled, "self-service-notification-enabled", env.ParseBoolFromEnv("ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED", false), "Allows the Argo CD notification controller to pull notification config from the namespace that the resource is in. This is useful for self-service notification.") return &command } diff --git a/cmd/argocd-repo-server/commands/argocd_repo_server.go b/cmd/argocd-repo-server/commands/argocd_repo_server.go index 69358d2a91efd..2a16d192e01bd 100644 --- a/cmd/argocd-repo-server/commands/argocd_repo_server.go +++ b/cmd/argocd-repo-server/commands/argocd_repo_server.go @@ -54,6 +54,8 @@ func NewCommand() *cobra.Command { metricsPort int metricsHost string otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string otlpAttrs []string cacheSrc func() (*reposervercache.Cache, error) tlsConfigCustomizer tls.ConfigCustomizer @@ -129,7 +131,7 @@ func NewCommand() *cobra.Command { if otlpAddress != "" { var closer func() var err error - closer, err = traceutil.InitTracer(ctx, "argocd-repo-server", otlpAddress, otlpAttrs) + closer, err = traceutil.InitTracer(ctx, "argocd-repo-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } @@ -196,6 +198,8 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&metricsHost, "metrics-address", env.StringFromEnv("ARGOCD_REPO_SERVER_METRICS_LISTEN_ADDRESS", common.DefaultAddressRepoServerMetrics), "Listen on given address for metrics") command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortRepoServerMetrics, "Start metrics server on given port") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_REPO_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") + command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") + command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_REPO_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_REPO_SERVER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_TLS", false), "Disable TLS on the gRPC endpoint") command.Flags().StringVar(&maxCombinedDirectoryManifestsSize, "max-combined-directory-manifests-size", env.StringFromEnv("ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE", "10M"), "Max combined size of manifest files in a directory-type Application") diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index 8709c7de09523..6eeb5b299ce0f 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -50,6 +50,8 @@ func NewCommand() *cobra.Command { metricsHost string metricsPort int otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string otlpAttrs []string glogLevel int clientConfig clientcmd.ClientConfig @@ -200,7 +202,7 @@ func NewCommand() *cobra.Command { var closer func() ctx, cancel := context.WithCancel(ctx) if otlpAddress != "" { - closer, err = traceutil.InitTracer(ctx, "argocd-server", otlpAddress, otlpAttrs) + closer, err = traceutil.InitTracer(ctx, "argocd-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } @@ -239,6 +241,8 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&metricsHost, env.StringFromEnv("ARGOCD_SERVER_METRICS_LISTEN_ADDRESS", "metrics-address"), common.DefaultAddressAPIServerMetrics, "Listen for metrics on given address") command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortArgoCDAPIServerMetrics, "Start metrics on given port") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") + command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_SERVER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") + command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_SERVER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_SERVER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") command.Flags().IntVar(&repoServerTimeoutSeconds, "repo-server-timeout-seconds", env.ParseNumFromEnv("ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS", 60, 0, math.MaxInt64), "Repo server RPC call timeout seconds.") command.Flags().StringVar(&frameOptions, "x-frame-options", env.StringFromEnv("ARGOCD_SERVER_X_FRAME_OPTIONS", "sameorigin"), "Set X-Frame-Options header in HTTP responses to `value`. To disable, set to \"\".") diff --git a/cmd/argocd/commands/admin/admin.go b/cmd/argocd/commands/admin/admin.go index 0615166175259..49c81e4da4bfe 100644 --- a/cmd/argocd/commands/admin/admin.go +++ b/cmd/argocd/commands/admin/admin.go @@ -138,7 +138,7 @@ $ argocd admin initial-password reset command.AddCommand(NewRepoCommand()) command.AddCommand(NewImportCommand()) command.AddCommand(NewExportCommand()) - command.AddCommand(NewDashboardCommand()) + command.AddCommand(NewDashboardCommand(clientOpts)) command.AddCommand(NewNotificationsCommand()) command.AddCommand(NewInitialPasswordCommand()) diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index a72aaebc201a0..5d14717a15e7d 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -44,6 +44,15 @@ func NewClusterCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clientc var command = &cobra.Command{ Use: "cluster", Short: "Manage clusters configuration", + Example: ` +#Generate declarative config for a cluster +argocd admin cluster generate-spec my-cluster -o yaml + +#Generate a kubeconfig for a cluster named "my-cluster" and display it in the console +argocd admin cluster kubeconfig my-cluster + +#Print information namespaces which Argo CD manages in each cluster +argocd admin cluster namespaces my-cluster `, Run: func(c *cobra.Command, args []string) { c.HelpFunc()(c, args) }, @@ -69,7 +78,7 @@ type ClusterWithInfo struct { Namespaces []string } -func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClient *versioned.Clientset, replicas int, namespace string, portForwardRedis bool, cacheSrc func() (*appstatecache.Cache, error), shard int, redisName string, redisHaProxyName string) ([]ClusterWithInfo, error) { +func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClient *versioned.Clientset, replicas int, namespace string, portForwardRedis bool, cacheSrc func() (*appstatecache.Cache, error), shard int, redisName string, redisHaProxyName string, redisCompressionStr string) ([]ClusterWithInfo, error) { settingsMgr := settings.NewSettingsManager(ctx, kubeClient, namespace) argoDB := db.NewDB(namespace, settingsMgr, kubeClient) @@ -88,7 +97,11 @@ func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClie return nil, err } client := redis.NewClient(&redis.Options{Addr: fmt.Sprintf("localhost:%d", port)}) - cache = appstatecache.NewCache(cacheutil.NewCache(cacheutil.NewRedisCache(client, time.Hour, cacheutil.RedisCompressionNone)), time.Hour) + compressionType, err := cacheutil.CompressionTypeFromString(redisCompressionStr) + if err != nil { + return nil, err + } + cache = appstatecache.NewCache(cacheutil.NewCache(cacheutil.NewRedisCache(client, time.Hour, compressionType)), time.Hour) } else { cache, err = cacheSrc() if err != nil { @@ -161,11 +174,12 @@ func getControllerReplicas(ctx context.Context, kubeClient *kubernetes.Clientset func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - shard int - replicas int - clientConfig clientcmd.ClientConfig - cacheSrc func() (*appstatecache.Cache, error) - portForwardRedis bool + shard int + replicas int + clientConfig clientcmd.ClientConfig + cacheSrc func() (*appstatecache.Cache, error) + portForwardRedis bool + redisCompressionStr string ) var command = cobra.Command{ Use: "shards", @@ -190,7 +204,7 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm return } - clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName) + clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr) errors.CheckError(err) if len(clusters) == 0 { return @@ -204,6 +218,12 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm command.Flags().IntVar(&replicas, "replicas", 0, "Application controller replicas count. Inferred from number of running controller pods if not specified") command.Flags().BoolVar(&portForwardRedis, "port-forward-redis", true, "Automatically port-forward ha proxy redis from current namespace?") cacheSrc = appstatecache.AddCacheFlagsToCmd(&command) + + // parse all added flags so far to get the redis-compression flag that was added by AddCacheFlagsToCmd() above + // we can ignore unchecked error here as the command will be parsed again and checked when command.Execute() is run later + // nolint:errcheck + command.ParseFlags(os.Args[1:]) + redisCompressionStr, _ = command.Flags().GetString(cacheutil.CLIFlagRedisCompress) return &command } @@ -439,15 +459,25 @@ func NewClusterDisableNamespacedMode() *cobra.Command { func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - shard int - replicas int - clientConfig clientcmd.ClientConfig - cacheSrc func() (*appstatecache.Cache, error) - portForwardRedis bool + shard int + replicas int + clientConfig clientcmd.ClientConfig + cacheSrc func() (*appstatecache.Cache, error) + portForwardRedis bool + redisCompressionStr string ) var command = cobra.Command{ Use: "stats", Short: "Prints information cluster statistics and inferred shard number", + Example: ` +#Display stats and shards for clusters +argocd admin cluster stats + +#Display Cluster Statistics for a Specific Shard +argocd admin cluster stats --shard=1 + +#In a multi-cluster environment to print stats for a specific cluster say(target-cluster) +argocd admin cluster stats target-cluster`, Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() @@ -464,7 +494,7 @@ func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma replicas, err = getControllerReplicas(ctx, kubeClient, namespace, clientOpts.AppControllerName) errors.CheckError(err) } - clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName) + clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr) errors.CheckError(err) w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) @@ -480,6 +510,12 @@ func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma command.Flags().IntVar(&replicas, "replicas", 0, "Application controller replicas count. Inferred from number of running controller pods if not specified") command.Flags().BoolVar(&portForwardRedis, "port-forward-redis", true, "Automatically port-forward ha proxy redis from current namespace?") cacheSrc = appstatecache.AddCacheFlagsToCmd(&command) + + // parse all added flags so far to get the redis-compression flag that was added by AddCacheFlagsToCmd() above + // we can ignore unchecked error here as the command will be parsed again and checked when command.Execute() is run later + // nolint:errcheck + command.ParseFlags(os.Args[1:]) + redisCompressionStr, _ = command.Flags().GetString(cacheutil.CLIFlagRedisCompress) return &command } @@ -492,6 +528,18 @@ func NewClusterConfig() *cobra.Command { Use: "kubeconfig CLUSTER_URL OUTPUT_PATH", Short: "Generates kubeconfig for the specified cluster", DisableAutoGenTag: true, + Example: ` +#Generate a kubeconfig for a cluster named "my-cluster" on console +argocd admin cluster kubeconfig my-cluster + +#Listing available kubeconfigs for clusters managed by argocd +argocd admin cluster kubeconfig + +#Removing a specific kubeconfig file +argocd admin cluster kubeconfig my-cluster --delete + +#Generate a Kubeconfig for a Cluster with TLS Verification Disabled +argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kubeconfig.yaml --insecure-skip-tls-verify`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/cmd/argocd/commands/admin/dashboard.go b/cmd/argocd/commands/admin/dashboard.go index 33d2866e1f1c0..21b621d264022 100644 --- a/cmd/argocd/commands/admin/dashboard.go +++ b/cmd/argocd/commands/admin/dashboard.go @@ -3,7 +3,9 @@ package admin import ( "fmt" + "github.com/argoproj/argo-cd/v2/util/cli" "github.com/spf13/cobra" + "k8s.io/client-go/tools/clientcmd" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/initialize" @@ -14,11 +16,12 @@ import ( "github.com/argoproj/argo-cd/v2/util/errors" ) -func NewDashboardCommand() *cobra.Command { +func NewDashboardCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( port int address string compressionStr string + clientConfig clientcmd.ClientConfig ) cmd := &cobra.Command{ Use: "dashboard", @@ -28,7 +31,8 @@ func NewDashboardCommand() *cobra.Command { compression, err := cache.CompressionTypeFromString(compressionStr) errors.CheckError(err) - errors.CheckError(headless.MaybeStartLocalServer(ctx, &argocdclient.ClientOptions{Core: true}, initialize.RetrieveContextIfChanged(cmd.Flag("context")), &port, &address, compression)) + clientOpts.Core = true + errors.CheckError(headless.MaybeStartLocalServer(ctx, clientOpts, initialize.RetrieveContextIfChanged(cmd.Flag("context")), &port, &address, compression, clientConfig)) println(fmt.Sprintf("Argo CD UI is available at http://%s:%d", address, port)) <-ctx.Done() }, @@ -42,7 +46,7 @@ $ argocd admin dashboard --port 8080 --address 127.0.0.1 $ argocd admin dashboard --redis-compress gzip `, } - initialize.InitCommand(cmd) + clientConfig = cli.AddKubectlFlagsToSet(cmd.Flags()) cmd.Flags().IntVar(&port, "port", common.DefaultPortAPIServer, "Listen on given port") cmd.Flags().StringVar(&address, "address", common.DefaultAddressAdminDashboard, "Listen on given address") cmd.Flags().StringVar(&compressionStr, "redis-compress", env.StringFromEnv("REDIS_COMPRESSION", string(cache.RedisCompressionGZip)), "Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none)") diff --git a/cmd/argocd/commands/admin/notifications.go b/cmd/argocd/commands/admin/notifications.go index a1234cc53b7fe..3cbac0a53b5c2 100644 --- a/cmd/argocd/commands/admin/notifications.go +++ b/cmd/argocd/commands/admin/notifications.go @@ -36,7 +36,7 @@ func NewNotificationsCommand() *cobra.Command { "notifications", "argocd admin notifications", applications, - settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), func(clientConfig clientcmd.ClientConfig) { + settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), func(clientConfig clientcmd.ClientConfig) { k8sCfg, err := clientConfig.ClientConfig() if err != nil { log.Fatalf("Failed to parse k8s config: %v", err) diff --git a/cmd/argocd/commands/headless/headless.go b/cmd/argocd/commands/headless/headless.go index 070d9c9c83bcb..5c9828fc9f131 100644 --- a/cmd/argocd/commands/headless/headless.go +++ b/cmd/argocd/commands/headless/headless.go @@ -153,9 +153,11 @@ func testAPI(ctx context.Context, clientOpts *apiclient.ClientOptions) error { // // If the clientOpts enables core mode, but the local config does not have core mode enabled, this function will // not start the local server. -func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions, ctxStr string, port *int, address *string, compression cache.RedisCompressionType) error { - flags := pflag.NewFlagSet("tmp", pflag.ContinueOnError) - clientConfig := cli.AddKubectlFlagsToSet(flags) +func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions, ctxStr string, port *int, address *string, compression cache.RedisCompressionType, clientConfig clientcmd.ClientConfig) error { + if clientConfig == nil { + flags := pflag.NewFlagSet("tmp", pflag.ContinueOnError) + clientConfig = cli.AddKubectlFlagsToSet(flags) + } startInProcessAPI := clientOpts.Core if !startInProcessAPI { // Core mode is enabled on client options. Check the local config to see if we should start the API server. @@ -244,6 +246,7 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti if !cache2.WaitForCacheSync(ctx.Done(), srv.Initialized) { log.Fatal("Timed out waiting for project cache to sync") } + tries := 5 for i := 0; i < tries; i++ { err = testAPI(ctx, clientOpts) @@ -265,7 +268,7 @@ func NewClientOrDie(opts *apiclient.ClientOptions, c *cobra.Command) apiclient.C ctxStr := initialize.RetrieveContextIfChanged(c.Flag("context")) // If we're in core mode, start the API server on the fly and configure the client `opts` to use it. // If we're not in core mode, this function call will do nothing. - err := MaybeStartLocalServer(ctx, opts, ctxStr, nil, nil, cache.RedisCompressionNone) + err := MaybeStartLocalServer(ctx, opts, ctxStr, nil, nil, cache.RedisCompressionNone, nil) if err != nil { log.Fatal(err) } diff --git a/cmd/argocd/commands/projectwindows.go b/cmd/argocd/commands/projectwindows.go index a46f9ece64c36..93843130ebb13 100644 --- a/cmd/argocd/commands/projectwindows.go +++ b/cmd/argocd/commands/projectwindows.go @@ -22,6 +22,18 @@ func NewProjectWindowsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com roleCommand := &cobra.Command{ Use: "windows", Short: "Manage a project's sync windows", + Example: ` +#Add a sync window to a project +argocd proj windows add my-project \ +--schedule "0 0 * * 1-5" \ +--duration 3600 \ +--prune + +#Delete a sync window from a project +argocd proj windows delete + +#List project sync windows +argocd proj windows list `, Run: func(c *cobra.Command, args []string) { c.HelpFunc()(c, args) os.Exit(1) @@ -42,6 +54,12 @@ func NewProjectWindowsDisableManualSyncCommand(clientOpts *argocdclient.ClientOp Use: "disable-manual-sync PROJECT ID", Short: "Disable manual sync for a sync window", Long: "Disable manual sync for a sync window. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", + Example: ` +#Disable manual sync for a sync window for the Project +argocd proj windows disable-manual-sync PROJECT ID + +#Disbaling manual sync for a windows set on the default project with Id 0 +argocd proj windows disable-manual-sync default 0`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -79,6 +97,15 @@ func NewProjectWindowsEnableManualSyncCommand(clientOpts *argocdclient.ClientOpt Use: "enable-manual-sync PROJECT ID", Short: "Enable manual sync for a sync window", Long: "Enable manual sync for a sync window. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", + Example: ` +#Enabling manual sync for a general case +argocd proj windows enable-manual-sync PROJECT ID + +#Enabling manual sync for a windows set on the default project with Id 2 +argocd proj windows enable-manual-sync default 2 + +#Enabling manual sync with a custom message +argocd proj windows enable-manual-sync my-app-project --message "Manual sync initiated by admin`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -125,14 +152,15 @@ func NewProjectWindowsAddWindowCommand(clientOpts *argocdclient.ClientOptions) * var command = &cobra.Command{ Use: "add PROJECT", Short: "Add a sync window to a project", - Example: `# Add a 1 hour allow sync window + Example: ` +#Add a 1 hour allow sync window argocd proj windows add PROJECT \ --kind allow \ --schedule "0 22 * * *" \ --duration 1h \ --applications "*" -# Add a deny sync window with the ability to manually sync. +#Add a deny sync window with the ability to manually sync. argocd proj windows add PROJECT \ --kind deny \ --schedule "30 10 * * *" \ @@ -180,6 +208,12 @@ func NewProjectWindowsDeleteCommand(clientOpts *argocdclient.ClientOptions) *cob var command = &cobra.Command{ Use: "delete PROJECT ID", Short: "Delete a sync window from a project. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", + Example: ` +#Delete a sync window from a project (default) with ID 0 +argocd proj windows delete default 0 + +#Delete a sync window from a project (new-project) with ID 1 +argocd proj windows delete new-project 1`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -274,12 +308,15 @@ func NewProjectWindowsListCommand(clientOpts *argocdclient.ClientOptions) *cobra var command = &cobra.Command{ Use: "list PROJECT", Short: "List project sync windows", - Example: `# List project windows + Example: ` +#List project windows argocd proj windows list PROJECT - -# List project windows in yaml format + +#List project windows in yaml format argocd proj windows list PROJECT -o yaml -`, + +#List project windows info for a project name (test-project) +argocd proj windows list test-project`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/controller/state.go b/controller/state.go index 15da3d2e624ed..59e7fa31248ae 100644 --- a/controller/state.go +++ b/controller/state.go @@ -116,6 +116,10 @@ type appStateManager struct { repoErrorGracePeriod time.Duration } +// getRepoObjs will generate the manifests for the given application delegating the +// task to the repo-server. It returns the list of generated manifests as unstructured +// objects. It also returns the full response from all calls to the repo server as the +// second argument. func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) { ts := stats.NewTimingStats() helmRepos, err := m.db.ListHelmRepositories(context.Background()) @@ -580,21 +584,16 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 manifestRevisions = append(manifestRevisions, manifestInfo.Revision) } - // restore comparison using cached diff result if previous comparison was performed for the same revision - revisionChanged := len(manifestInfos) != len(sources) || !reflect.DeepEqual(app.Status.Sync.Revisions, manifestRevisions) - specChanged := !reflect.DeepEqual(app.Status.Sync.ComparedTo, v1alpha1.ComparedTo{Source: app.Spec.GetSource(), Destination: app.Spec.Destination, Sources: sources, IgnoreDifferences: app.Spec.IgnoreDifferences}) - - _, refreshRequested := app.IsRefreshRequested() - noCache = noCache || refreshRequested || app.Status.Expired(m.statusRefreshTimeout) || specChanged || revisionChanged + useDiffCache := useDiffCache(noCache, manifestInfos, sources, app, manifestRevisions, m.statusRefreshTimeout, logCtx) diffConfigBuilder := argodiff.NewDiffConfigBuilder(). WithDiffSettings(app.Spec.IgnoreDifferences, resourceOverrides, compareOptions.IgnoreAggregatedRoles). WithTracking(appLabelKey, string(trackingMethod)) - if noCache { - diffConfigBuilder.WithNoCache() + if useDiffCache { + diffConfigBuilder.WithCache(m.cache, app.InstanceName(m.namespace)) } else { - diffConfigBuilder.WithCache(m.cache, app.GetName()) + diffConfigBuilder.WithNoCache() } gvkParser, err := m.getGVKParser(app.Spec.Destination.Server) @@ -801,6 +800,46 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 return &compRes, nil } +// useDiffCache will determine if the diff should be calculated based +// on the existing live state cache or not. +func useDiffCache(noCache bool, manifestInfos []*apiclient.ManifestResponse, sources []v1alpha1.ApplicationSource, app *v1alpha1.Application, manifestRevisions []string, statusRefreshTimeout time.Duration, log *log.Entry) bool { + + if noCache { + log.WithField("useDiffCache", "false").Debug("noCache is true") + return false + } + _, refreshRequested := app.IsRefreshRequested() + if refreshRequested { + log.WithField("useDiffCache", "false").Debug("refreshRequested") + return false + } + if app.Status.Expired(statusRefreshTimeout) { + log.WithField("useDiffCache", "false").Debug("app.status.expired") + return false + } + + if len(manifestInfos) != len(sources) { + log.WithField("useDiffCache", "false").Debug("manifestInfos len != sources len") + return false + } + + revisionChanged := !reflect.DeepEqual(app.Status.GetRevisions(), manifestRevisions) + if revisionChanged { + log.WithField("useDiffCache", "false").Debug("revisionChanged") + return false + } + + currentSpec := app.BuildComparedToStatus() + specChanged := !reflect.DeepEqual(app.Status.Sync.ComparedTo, currentSpec) + if specChanged { + log.WithField("useDiffCache", "false").Debug("specChanged") + return false + } + + log.WithField("useDiffCache", "true").Debug("using diff cache") + return true +} + func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revision string, source v1alpha1.ApplicationSource, revisions []string, sources []v1alpha1.ApplicationSource, hasMultipleSources bool, startedAt metav1.Time) error { var nextID int64 if len(app.Status.History) > 0 { diff --git a/controller/state_test.go b/controller/state_test.go index 6eb336cff2ffb..a240b30d688df 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -11,6 +11,9 @@ import ( synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" . "github.com/argoproj/gitops-engine/pkg/utils/testing" + "github.com/imdario/mergo" + "github.com/sirupsen/logrus" + logrustest "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -1393,3 +1396,252 @@ func TestIsLiveResourceManaged(t *testing.T) { assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation)) }) } + +func TestUseDiffCache(t *testing.T) { + type fixture struct { + testName string + noCache bool + manifestInfos []*apiclient.ManifestResponse + sources []argoappv1.ApplicationSource + app *argoappv1.Application + manifestRevisions []string + statusRefreshTimeout time.Duration + expectedUseCache bool + } + + manifestInfos := func(revision string) []*apiclient.ManifestResponse { + return []*apiclient.ManifestResponse{ + { + Manifests: []string{ + "{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"httpbin\"},\"name\":\"httpbin-svc\",\"namespace\":\"httpbin\"},\"spec\":{\"ports\":[{\"name\":\"http-port\",\"port\":7777,\"targetPort\":80},{\"name\":\"test\",\"port\":333}],\"selector\":{\"app\":\"httpbin\"}}}", + "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"httpbin\"},\"name\":\"httpbin-deployment\",\"namespace\":\"httpbin\"},\"spec\":{\"replicas\":2,\"selector\":{\"matchLabels\":{\"app\":\"httpbin\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"httpbin\"}},\"spec\":{\"containers\":[{\"image\":\"kennethreitz/httpbin\",\"imagePullPolicy\":\"Always\",\"name\":\"httpbin\",\"ports\":[{\"containerPort\":80}]}]}}}}", + }, + Namespace: "", + Server: "", + Revision: revision, + SourceType: "Kustomize", + VerifyResult: "", + }, + } + } + sources := func() []argoappv1.ApplicationSource { + return []argoappv1.ApplicationSource{ + { + RepoURL: "https://some-repo.com", + Path: "argocd/httpbin", + TargetRevision: "HEAD", + }, + } + } + + app := func(namespace string, revision string, refresh bool, a *argoappv1.Application) *argoappv1.Application { + app := &argoappv1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "httpbin", + Namespace: namespace, + }, + Spec: argoappv1.ApplicationSpec{ + Source: &argoappv1.ApplicationSource{ + RepoURL: "https://some-repo.com", + Path: "argocd/httpbin", + TargetRevision: "HEAD", + }, + Destination: argoappv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "httpbin", + }, + Project: "default", + SyncPolicy: &argoappv1.SyncPolicy{ + SyncOptions: []string{ + "CreateNamespace=true", + "ServerSideApply=true", + }, + }, + }, + Status: argoappv1.ApplicationStatus{ + Resources: []argoappv1.ResourceStatus{}, + Sync: argoappv1.SyncStatus{ + Status: argoappv1.SyncStatusCodeSynced, + ComparedTo: argoappv1.ComparedTo{ + Source: argoappv1.ApplicationSource{ + RepoURL: "https://some-repo.com", + Path: "argocd/httpbin", + TargetRevision: "HEAD", + }, + Destination: argoappv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "httpbin", + }, + }, + Revision: revision, + Revisions: []string{}, + }, + ReconciledAt: &metav1.Time{ + Time: time.Now().Add(-time.Hour), + }, + }, + } + if refresh { + annotations := make(map[string]string) + annotations[argoappv1.AnnotationKeyRefresh] = string(argoappv1.RefreshTypeNormal) + app.SetAnnotations(annotations) + } + if a != nil { + err := mergo.Merge(app, a, mergo.WithOverride, mergo.WithOverwriteWithEmptyValue) + if err != nil { + t.Fatalf("error merging app: %s", err) + } + } + return app + } + + cases := []fixture{ + { + testName: "will use diff cache", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: true, + }, + { + testName: "will use diff cache for multisource", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + Source: nil, + Sources: argoappv1.ApplicationSources{ + { + RepoURL: "multisource repo1", + }, + { + RepoURL: "multisource repo2", + }, + }, + }, + Status: argoappv1.ApplicationStatus{ + Resources: []argoappv1.ResourceStatus{}, + Sync: argoappv1.SyncStatus{ + Status: argoappv1.SyncStatusCodeSynced, + ComparedTo: argoappv1.ComparedTo{ + Source: argoappv1.ApplicationSource{}, + Sources: argoappv1.ApplicationSources{ + { + RepoURL: "multisource repo1", + }, + { + RepoURL: "multisource repo2", + }, + }, + }, + Revisions: []string{"rev1", "rev2"}, + }, + ReconciledAt: &metav1.Time{ + Time: time.Now().Add(-time.Hour), + }, + }, + }), + manifestRevisions: []string{"rev1", "rev2"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: true, + }, + { + testName: "will return false if nocache is true", + noCache: true, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + { + testName: "will return false if requested refresh", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", true, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + { + testName: "will return false if status expired", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Minute, + expectedUseCache: false, + }, + { + testName: "will return false if there is a new revision", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev2"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + { + testName: "will return false if app spec repo changed", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + Source: &argoappv1.ApplicationSource{ + RepoURL: "new-repo", + }, + }, + }), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + { + testName: "will return false if app spec IgnoreDifferences changed", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + IgnoreDifferences: []argoappv1.ResourceIgnoreDifferences{ + { + Group: "app/v1", + Kind: "application", + Name: "httpbin", + Namespace: "httpbin", + JQPathExpressions: []string{"."}, + }, + }, + }, + }), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.testName, func(t *testing.T) { + // Given + t.Parallel() + logger, _ := logrustest.NewNullLogger() + log := logrus.NewEntry(logger) + + // When + useDiffCache := useDiffCache(tc.noCache, tc.manifestInfos, tc.sources, tc.app, tc.manifestRevisions, tc.statusRefreshTimeout, log) + + // Then + assert.Equal(t, useDiffCache, tc.expectedUseCache) + }) + } +} diff --git a/docs/operator-manual/app-any-namespace.md b/docs/operator-manual/app-any-namespace.md index 21743b7bc003d..21bfa5c4f5a0b 100644 --- a/docs/operator-manual/app-any-namespace.md +++ b/docs/operator-manual/app-any-namespace.md @@ -15,7 +15,10 @@ Some manual steps will need to be performed by the Argo CD administrator in orde !!! note This feature is considered beta as of now. Some of the implementation details may change over the course of time until it is promoted to a stable status. We will be happy if early adopters use this feature and provide us with bug reports and feedback. - + + +One additional advantage of adopting applications in any namespace is to allow end-users to configure notifications for their Argo CD application in the namespace where Argo CD application is running in. See notifications [namespace based configuration](notifications/index.md#namespace-based-configuration) page for more information. + ## Prerequisites ### Cluster-scoped Argo CD installation diff --git a/docs/operator-manual/applicationset/Controlling-Resource-Modification.md b/docs/operator-manual/applicationset/Controlling-Resource-Modification.md index 44b6797b24d11..d72cee60ad401 100644 --- a/docs/operator-manual/applicationset/Controlling-Resource-Modification.md +++ b/docs/operator-manual/applicationset/Controlling-Resource-Modification.md @@ -32,15 +32,13 @@ spec: ``` -- Policy `create-only`: Prevents ApplicationSet controller from modifying or deleting Applications. -- Policy `create-update`: Prevents ApplicationSet controller from deleting Applications. Update is allowed. +- Policy `create-only`: Prevents ApplicationSet controller from modifying or deleting Applications. Prevents Application controller from deleting Applications according to [ownerReferences](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/). +- Policy `create-update`: Prevents ApplicationSet controller from deleting Applications. Update is allowed. Prevents Application controller from deleting Applications according to [ownerReferences](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/). - Policy `create-delete`: Prevents ApplicationSet controller from modifying Applications. Delete is allowed. - Policy `sync`: Update and Delete are allowed. If the controller parameter `--policy` is set, it takes precedence on the field `applicationsSync`. It is possible to allow per ApplicationSet sync policy by setting variable `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE` to argocd-cmd-params-cm `applicationsetcontroller.enable.policy.override` or directly with controller parameter `--enable-policy-override` (default to `false`). -This does not prevent deletion of Applications if the ApplicationSet is deleted - ### Controller parameter To allow the ApplicationSet controller to *create* `Application` resources, but prevent any further modification, such as deletion, or modification of Application fields, add this parameter in the ApplicationSet controller: diff --git a/docs/operator-manual/applicationset/Template.md b/docs/operator-manual/applicationset/Template.md index f66a403586bbd..573e297bff2e2 100644 --- a/docs/operator-manual/applicationset/Template.md +++ b/docs/operator-manual/applicationset/Template.md @@ -108,3 +108,69 @@ spec: (*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/template-override).*) In this example, the ApplicationSet controller will generate an `Application` resource using the `path` generated by the List generator, rather than the `path` value defined in `.spec.template`. + +## Template Patch + +Templating is only available on string type. However, some uses cases may require to apply templating on other types. + +Example: + +- Set the automated sync policy +- Switch prune boolean to true +- Add multiple helm value files + +Argo CD has a `templatePatch` feature to allow advanced templating. It supports both json and yaml. + + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: guestbook +spec: + goTemplate: true + generators: + - list: + elements: + - cluster: engineering-dev + url: https://kubernetes.default.svc + autoSync: true + prune: true + valueFiles: + - values.large.yaml + - values.debug.yaml + template: + metadata: + name: '{{.cluster}}-deployment' + spec: + project: "default" + source: + repoURL: https://github.com/infra-team/cluster-deployments.git + targetRevision: HEAD + path: guestbook/{{ .cluster }} + destination: + server: '{{.url}}' + namespace: guestbook + templatePatch: | + spec: + source: + helm: + valueFiles: + {{- range $valueFile := .valueFiles }} + - {{ $valueFile }} + {{- end }} + {{- if .autoSync }} + syncPolicy: + automated: + prune: {{ .prune }} + {{- end }} +``` + +!!! important + The `templatePatch` can apply arbitrary changes to the template. If parameters include untrustworthy user input, it + may be possible to inject malicious changes into the template. It is recommended to use `templatePatch` only with + trusted input or to carefully escape the input before using it in the template. Piping input to `toJson` should help + prevent, for example, a user from successfully injecting a string with newlines. + + The `spec.project` field is not supported in `templatePatch`. If you need to change the project, you can use the + `spec.project` field in the `template` field. diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index bb55c6fb213f3..5e8c04c7e50d6 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -17,7 +17,11 @@ data: redis.db: # Open-Telemetry collector address: (e.g. "otel-collector:4317") - otlp.address: + otlp.address: "" + # Open-Telemetry collector insecure: (e.g. "true") + otlp.insecure: "true" + # Open-Telemetry collector headers: (e.g. "key1=value1,key2=value2") + otlp.headers: "" # List of additional namespaces where applications may be created in and # reconciled from. The namespace where Argo CD is installed to will always @@ -206,3 +210,5 @@ data: notificationscontroller.log.level: "info" # Set the logging format. One of: text|json (default "text") notificationscontroller.log.format: "text" + # Enable self-service notifications config. Used in conjunction with apps-in-any-namespace. (default "false") + notificationscontroller.selfservice.enabled: "false" diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index a156f27589dbd..ee216a7118f7f 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -490,7 +490,7 @@ stringData: ### Legacy behaviour -In Argo CD version 2.0 and earlier, repositories where stored as part of the `argocd-cm` config map. For +In Argo CD version 2.0 and earlier, repositories were stored as part of the `argocd-cm` config map. For backward-compatibility, Argo CD will still honor repositories in the config map, but this style of repository configuration is deprecated and support for it will be removed in a future version. diff --git a/docs/operator-manual/notifications/index.md b/docs/operator-manual/notifications/index.md index c719d10e7611c..3609089e23d08 100644 --- a/docs/operator-manual/notifications/index.md +++ b/docs/operator-manual/notifications/index.md @@ -45,3 +45,71 @@ So you can just use them instead of reinventing new ones. ``` Try syncing an application to get notified when the sync is completed. + +## Namespace based configuration + +A common installation method for Argo CD Notifications is to install it in a dedicated namespace to manage a whole cluster. In this case, the administrator is the only +person who can configure notifications in that namespace generally. However, in some cases, it is required to allow end-users to configure notifications +for their Argo CD applications. For example, the end-user can configure notifications for their Argo CD application in the namespace where they have access to and their Argo CD application is running in. + +This feature is based on applications in any namespace. See [applications in any namespace](../app-any-namespace.md) page for more information. + +In order to enable this feature, the Argo CD administrator must reconfigure the argocd-notification-controller workloads to add `--application-namespaces` and `--self-service-notification-enabled` parameters to the container's startup command. +`--application-namespaces` controls the list of namespaces that Argo CD applications are in. `--self-service-notification-enabled` turns on this feature. + +The startup parameters for both can also be conveniently set up and kept in sync by specifying +the `application.namespaces` and `notificationscontroller.selfservice.enabled` in the argocd-cmd-params-cm ConfigMap instead of changing the manifests for the respective workloads. For example: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cmd-params-cm +data: + application.namespaces: app-team-one, app-team-two + notificationscontroller.selfservice.enabled: true +``` + +To use this feature, you can deploy configmap named `argocd-notifications-cm` and possibly a secret `argocd-notifications-secret` in the namespace where the Argo CD application lives. + +When it is configured this way the controller will send notifications using both the controller level configuration (the configmap located in the same namespaces as the controller) as well as +the configuration located in the same namespace where the Argo CD application is at. + +Example: Application team wants to receive notifications using PagerDutyV2, when the controller level configuration is only supporting Slack. + +The following two resources are deployed in the namespace where the Argo CD application lives. +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-notifications-cm +data: + service.pagerdutyv2: | + serviceKeys: + my-service: $pagerduty-key-my-service +... +``` +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: argo-cd-notification-secret +type: Opaque +data: + pagerduty-key-my-service: +``` + +When an Argo CD application has the following subscriptions, user receives application sync failure message from pager duty. +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + notifications.argoproj.io/subscribe.on-sync-failed.pagerdutyv2: "" +``` + +!!! note + When the same notification service and trigger are defined in controller level configuration and application level configuration, + both notifications will be sent according to its own configuration. + +[Defining and using secrets within notification templates](templates.md/#defining-and-using-secrets-within-notification-templates) function is not available when flag `--self-service-notification-enable` is on. diff --git a/docs/operator-manual/notifications/services/awssqs.md b/docs/operator-manual/notifications/services/awssqs.md index 6bbc47cbbc0b5..6b744f4744b93 100755 --- a/docs/operator-manual/notifications/services/awssqs.md +++ b/docs/operator-manual/notifications/services/awssqs.md @@ -4,10 +4,10 @@ This notification service is capable of sending simple messages to AWS SQS queue. -* `queue` - name of the queue you are intending to send messages to. Can be overwriten with target destination annotation. +* `queue` - name of the queue you are intending to send messages to. Can be overridden with target destination annotation. * `region` - region of the sqs queue can be provided via env variable AWS_DEFAULT_REGION * `key` - optional, aws access key must be either referenced from a secret via variable or via env variable AWS_ACCESS_KEY_ID -* `secret` - optional, aws access secret must be either referenced from a secret via variableor via env variable AWS_SECRET_ACCESS_KEY +* `secret` - optional, aws access secret must be either referenced from a secret via variable or via env variable AWS_SECRET_ACCESS_KEY * `account` optional, external accountId of the queue * `endpointUrl` optional, useful for development with localstack @@ -63,7 +63,7 @@ stringData: ### Minimal configuration using AWS Env variables -Ensure following list of enviromental variable is injected via OIDC, or other method. And assuming SQS is local to the account. +Ensure following list of environment variables are injected via OIDC, or other method. And assuming SQS is local to the account. You may skip usage of secret for sensitive data and omit other parameters. (Setting parameters via ConfigMap takes precedent.) Variables: diff --git a/docs/operator-manual/notifications/services/github.md b/docs/operator-manual/notifications/services/github.md index a3f89f8c87ef0..be76ab150d1a1 100755 --- a/docs/operator-manual/notifications/services/github.md +++ b/docs/operator-manual/notifications/services/github.md @@ -12,7 +12,7 @@ The GitHub notification service changes commit status using [GitHub Apps](https: ## Configuration 1. Create a GitHub Apps using https://github.com/settings/apps/new -2. Change repository permissions to enable write commit statuses and/or deployments +2. Change repository permissions to enable write commit statuses and/or deployments and/or pull requests comments ![2](https://user-images.githubusercontent.com/18019529/108397381-3ca57980-725b-11eb-8d17-5b8992dc009e.png) 3. Generate a private key, and download it automatically ![3](https://user-images.githubusercontent.com/18019529/108397926-d4a36300-725b-11eb-83fe-74795c8c3e03.png) @@ -76,6 +76,10 @@ template.app-deployed: | logURL: "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" requiredContexts: [] autoMerge: true + pullRequestComment: + content: | + Application {{.app.metadata.name}} is now running new version of deployments manifests. + See more here: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true ``` **Notes**: @@ -83,4 +87,5 @@ template.app-deployed: | - If `github.repoURLPath` and `github.revisionPath` are same as above, they can be omitted. - Automerge is optional and `true` by default for github deployments to ensure the requested ref is up to date with the default branch. Setting this option to `false` is required if you would like to deploy older refs in your default branch. - For more information see the [Github Deployment API Docs](https://docs.github.com/en/rest/deployments/deployments?apiVersion=2022-11-28#create-a-deployment). + For more information see the [GitHub Deployment API Docs](https://docs.github.com/en/rest/deployments/deployments?apiVersion=2022-11-28#create-a-deployment). +- If `github.pullRequestComment.content` is set to 65536 characters or more, it will be truncated. diff --git a/docs/operator-manual/notifications/services/googlechat.md b/docs/operator-manual/notifications/services/googlechat.md index 041ea6e022ef5..885ce685a4511 100755 --- a/docs/operator-manual/notifications/services/googlechat.md +++ b/docs/operator-manual/notifications/services/googlechat.md @@ -59,24 +59,27 @@ A card message can be defined as follows: ```yaml template.app-sync-succeeded: | googlechat: - cards: | + cardsV2: | - header: title: ArgoCD Bot Notification sections: - widgets: - - textParagraph: + - decoratedText: text: The app {{ .app.metadata.name }} has successfully synced! - widgets: - - keyValue: + - decoratedText: topLabel: Repository - content: {{ call .repo.RepoURLToHTTPS .app.spec.source.repoURL }} - - keyValue: + text: {{ call .repo.RepoURLToHTTPS .app.spec.source.repoURL }} + - decoratedText: topLabel: Revision - content: {{ .app.spec.source.targetRevision }} - - keyValue: + text: {{ .app.spec.source.targetRevision }} + - decoratedText: topLabel: Author - content: {{ (call .repo.GetCommitMetadata .app.status.sync.revision).Author }} + text: {{ (call .repo.GetCommitMetadata .app.status.sync.revision).Author }} ``` +All [Card fields](https://developers.google.com/chat/api/reference/rest/v1/cards#Card_1) are supported and can be used +in notifications. It is also possible to use the previous (now deprecated) `cards` key to use the legacy card fields, +but this is not recommended as Google has deprecated this field and recommends using the newer `cardsV2`. The card message can be written in JSON too. @@ -86,7 +89,7 @@ It is possible send both simple text and card messages in a chat thread by speci ```yaml template.app-sync-succeeded: | - message: The app {{ .app.metadata.name }} has succesfully synced! + message: The app {{ .app.metadata.name }} has successfully synced! googlechat: threadKey: {{ .app.metadata.name }} ``` diff --git a/docs/operator-manual/notifications/services/slack.md b/docs/operator-manual/notifications/services/slack.md index 15937597c19f2..0f3fdf1739210 100755 --- a/docs/operator-manual/notifications/services/slack.md +++ b/docs/operator-manual/notifications/services/slack.md @@ -6,11 +6,15 @@ If you want to send message using incoming webhook, you can use [webhook](./webh The Slack notification service configuration includes following settings: -* `token` - the app token -* `apiURL` - optional, the server url, e.g. https://example.com/api -* `username` - optional, the app username -* `icon` - optional, the app icon, e.g. :robot_face: or https://example.com/image.png -* `insecureSkipVerify` - optional bool, true or false +| **Option** | **Required** | **Type** | **Description** | **Example** | +| -------------------- | ------------ | -------------- | --------------- | ----------- | +| `apiURL` | False | `string` | The server URL. | `https://example.com/api` | +| `channels` | False | `list[string]` | | `["my-channel-1", "my-channel-2"]` | +| `icon` | False | `string` | The app icon. | `:robot_face:` or `https://example.com/image.png` | +| `insecureSkipVerify` | False | `bool` | | `true` | +| `signingSecret` | False | `string` | | `8f742231b10e8888abcd99yyyzzz85a5` | +| `token` | **True** | `string` | The app's OAuth access token. | `xoxb-1234567890-1234567890123-5n38u5ed63fgzqlvuyxvxcx6` | +| `username` | False | `string` | The app username. | `argocd` | ## Configuration diff --git a/docs/operator-manual/notifications/services/teams.md b/docs/operator-manual/notifications/services/teams.md index b5b9a228c43eb..8b8c6b819c795 100755 --- a/docs/operator-manual/notifications/services/teams.md +++ b/docs/operator-manual/notifications/services/teams.md @@ -113,7 +113,7 @@ template.app-sync-succeeded: | ### summary field -You can set a summary of the message that will be shown on Notifcation & Activity Feed +You can set a summary of the message that will be shown on Notification & Activity Feed ![](https://user-images.githubusercontent.com/6957724/116587921-84c4d480-a94d-11eb-9da4-f365151a12e7.jpg) diff --git a/docs/operator-manual/notifications/services/webhook.md b/docs/operator-manual/notifications/services/webhook.md index bd45b1f69e40b..965098402236f 100755 --- a/docs/operator-manual/notifications/services/webhook.md +++ b/docs/operator-manual/notifications/services/webhook.md @@ -1,7 +1,7 @@ # Webhook The webhook notification service allows sending a generic HTTP request using the templatized request body and URL. -Using Webhook you might trigger a Jenkins job, update Github commit status. +Using Webhook you might trigger a Jenkins job, update GitHub commit status. ## Parameters @@ -9,8 +9,17 @@ The Webhook notification service configuration includes following settings: - `url` - the url to send the webhook to - `headers` - optional, the headers to pass along with the webhook -- `basicAuth` - optional, the basic authentication to pass along with the webook +- `basicAuth` - optional, the basic authentication to pass along with the webhook - `insecureSkipVerify` - optional bool, true or false +- `retryWaitMin` - Optional, the minimum wait time between retries. Default value: 1s. +- `retryWaitMax` - Optional, the maximum wait time between retries. Default value: 5s. +- `retryMax` - Optional, the maximum number of retries. Default value: 3. + +## Retry Behavior + +The webhook service will automatically retry the request if it fails due to network errors or if the server returns a 5xx status code. The number of retries and the wait time between retries can be configured using the `retryMax`, `retryWaitMin`, and `retryWaitMax` parameters. + +The wait time between retries is between `retryWaitMin` and `retryWaitMax`. If all retries fail, the `Send` method will return an error. ## Configuration @@ -67,7 +76,7 @@ metadata: ## Examples -### Set Github commit status +### Set GitHub commit status ```yaml apiVersion: v1 diff --git a/docs/operator-manual/rbac.md b/docs/operator-manual/rbac.md index 0f15a18be1973..b1d386fb5eb8e 100644 --- a/docs/operator-manual/rbac.md +++ b/docs/operator-manual/rbac.md @@ -159,6 +159,7 @@ data: g, your-github-org:your-team, role:org-admin ``` + ---- Another `policy.csv` example might look as follows: diff --git a/docs/operator-manual/secret-management.md b/docs/operator-manual/secret-management.md index ab06a46014b20..aa224e20ff742 100644 --- a/docs/operator-manual/secret-management.md +++ b/docs/operator-manual/secret-management.md @@ -10,7 +10,7 @@ Here are some ways people are doing GitOps secrets: * [Bitnami Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets) * [External Secrets Operator](https://github.com/external-secrets/external-secrets) * [Hashicorp Vault](https://www.vaultproject.io) -* [Bank-Vaults]((https://bank-vaults.dev/)) +* [Bank-Vaults](https://bank-vaults.dev/) * [Helm Secrets](https://github.com/jkroepke/helm-secrets) * [Kustomize secret generator plugins](https://github.com/kubernetes-sigs/kustomize/blob/fd7a353df6cece4629b8e8ad56b71e30636f38fc/examples/kvSourceGoPlugin.md#secret-values-from-anywhere) * [aws-secret-operator](https://github.com/mumoshu/aws-secret-operator) diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index e03cf7fc51536..434c30621b8bd 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -44,6 +44,8 @@ argocd-application-controller [flags] --operation-processors int Number of application operation processors (default 10) --otlp-address string OpenTelemetry collector address to send traces to --otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value) + --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) + --otlp-insecure OpenTelemetry collector insecure mode (default true) --password string Password for basic authentication to the API server --persist-resource-health Enables storing the managed resources health in the Application CRD (default true) --proxy-url string If provided, this URL will be used to connect via proxy diff --git a/docs/operator-manual/server-commands/argocd-repo-server.md b/docs/operator-manual/server-commands/argocd-repo-server.md index 33ecaf7c76dd4..7be45fe18d26f 100644 --- a/docs/operator-manual/server-commands/argocd-repo-server.md +++ b/docs/operator-manual/server-commands/argocd-repo-server.md @@ -29,6 +29,8 @@ argocd-repo-server [flags] --metrics-port int Start metrics server on given port (default 8084) --otlp-address string OpenTelemetry collector address to send traces to --otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value) + --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) + --otlp-insecure OpenTelemetry collector insecure mode (default true) --parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit. --plugin-tar-exclude stringArray Globs to filter when sending tarballs to plugins. --port int Listen on given port for incoming connections (default 8081) diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index c33cf0bedcbcf..e3dcc937243df 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -61,6 +61,8 @@ argocd-server [flags] --oidc-cache-expiration duration Cache expiration for OIDC state (default 3m0s) --otlp-address string OpenTelemetry collector address to send traces to --otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value) + --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) + --otlp-insecure OpenTelemetry collector insecure mode (default true) --password string Password for basic authentication to the API server --port int Listen on given port (default 8080) --proxy-url string If provided, this URL will be used to connect via proxy diff --git a/docs/proposals/native-ocp-support.md b/docs/proposals/native-oci-support.md similarity index 100% rename from docs/proposals/native-ocp-support.md rename to docs/proposals/native-oci-support.md diff --git a/docs/user-guide/commands/argocd_admin_cluster.md b/docs/user-guide/commands/argocd_admin_cluster.md index 1a469c3f818ca..bad60a0dd32bf 100644 --- a/docs/user-guide/commands/argocd_admin_cluster.md +++ b/docs/user-guide/commands/argocd_admin_cluster.md @@ -8,6 +8,20 @@ Manage clusters configuration argocd admin cluster [flags] ``` +### Examples + +``` + +#Generate declarative config for a cluster +argocd admin cluster generate-spec my-cluster -o yaml + +#Generate a kubeconfig for a cluster named "my-cluster" and display it in the console +argocd admin cluster kubeconfig my-cluster + +#Print information namespaces which Argo CD manages in each cluster +argocd admin cluster namespaces my-cluster +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md index 8105605e80cd0..38f61ce5cd8a2 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md +++ b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md @@ -8,6 +8,23 @@ Generates kubeconfig for the specified cluster argocd admin cluster kubeconfig CLUSTER_URL OUTPUT_PATH [flags] ``` +### Examples + +``` + +#Generate a kubeconfig for a cluster named "my-cluster" on console +argocd admin cluster kubeconfig my-cluster + +#Listing available kubeconfigs for clusters managed by argocd +argocd admin cluster kubeconfig + +#Removing a specific kubeconfig file +argocd admin cluster kubeconfig my-cluster --delete + +#Generate a Kubeconfig for a Cluster with TLS Verification Disabled +argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kubeconfig.yaml --insecure-skip-tls-verify +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md index 9e916288adf7e..960fd12caaef1 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_stats.md +++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md @@ -8,6 +8,20 @@ Prints information cluster statistics and inferred shard number argocd admin cluster stats [flags] ``` +### Examples + +``` + +#Display stats and shards for clusters +argocd admin cluster stats + +#Display Cluster Statistics for a Specific Shard +argocd admin cluster stats --shard=1 + +#In a multi-cluster environment to print stats for a specific cluster say(target-cluster) +argocd admin cluster stats target-cluster +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_admin_dashboard.md b/docs/user-guide/commands/argocd_admin_dashboard.md index be4d5c18468ab..71e11a173906a 100644 --- a/docs/user-guide/commands/argocd_admin_dashboard.md +++ b/docs/user-guide/commands/argocd_admin_dashboard.md @@ -44,6 +44,7 @@ $ argocd admin dashboard --redis-compress gzip --proxy-url string If provided, this URL will be used to connect via proxy --redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip") --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --server string The address and port of the Kubernetes API server --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use @@ -73,7 +74,6 @@ $ argocd admin dashboard --redis-compress gzip --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") - --server string Argo CD server address --server-crt string Server certificate file --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") ``` diff --git a/docs/user-guide/commands/argocd_proj_windows.md b/docs/user-guide/commands/argocd_proj_windows.md index dc1b68bf0191b..0b22c2098dc82 100644 --- a/docs/user-guide/commands/argocd_proj_windows.md +++ b/docs/user-guide/commands/argocd_proj_windows.md @@ -8,6 +8,23 @@ Manage a project's sync windows argocd proj windows [flags] ``` +### Examples + +``` + +#Add a sync window to a project +argocd proj windows add my-project \ +--schedule "0 0 * * 1-5" \ +--duration 3600 \ +--prune + +#Delete a sync window from a project +argocd proj windows delete + +#List project sync windows +argocd proj windows list +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_add.md b/docs/user-guide/commands/argocd_proj_windows_add.md index 7f9eb50af8f5b..52fd3a8354ee3 100644 --- a/docs/user-guide/commands/argocd_proj_windows_add.md +++ b/docs/user-guide/commands/argocd_proj_windows_add.md @@ -11,14 +11,15 @@ argocd proj windows add PROJECT [flags] ### Examples ``` -# Add a 1 hour allow sync window + +#Add a 1 hour allow sync window argocd proj windows add PROJECT \ --kind allow \ --schedule "0 22 * * *" \ --duration 1h \ --applications "*" -# Add a deny sync window with the ability to manually sync. +#Add a deny sync window with the ability to manually sync. argocd proj windows add PROJECT \ --kind deny \ --schedule "30 10 * * *" \ diff --git a/docs/user-guide/commands/argocd_proj_windows_delete.md b/docs/user-guide/commands/argocd_proj_windows_delete.md index 316b25041fde2..6faf7dbeedc19 100644 --- a/docs/user-guide/commands/argocd_proj_windows_delete.md +++ b/docs/user-guide/commands/argocd_proj_windows_delete.md @@ -8,6 +8,17 @@ Delete a sync window from a project. Requires ID which can be found by running " argocd proj windows delete PROJECT ID [flags] ``` +### Examples + +``` + +#Delete a sync window from a project (default) with ID 0 +argocd proj windows delete default 0 + +#Delete a sync window from a project (new-project) with ID 1 +argocd proj windows delete new-project 1 +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md b/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md index 8951ad9371c90..e3b84ac38cc0e 100644 --- a/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md +++ b/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md @@ -12,6 +12,17 @@ Disable manual sync for a sync window. Requires ID which can be found by running argocd proj windows disable-manual-sync PROJECT ID [flags] ``` +### Examples + +``` + +#Disable manual sync for a sync window for the Project +argocd proj windows disable-manual-sync PROJECT ID + +#Disbaling manual sync for a windows set on the default project with Id 0 +argocd proj windows disable-manual-sync default 0 +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md b/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md index a1ca162840f7a..7ecbb50e6ac1b 100644 --- a/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md +++ b/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md @@ -12,6 +12,20 @@ Enable manual sync for a sync window. Requires ID which can be found by running argocd proj windows enable-manual-sync PROJECT ID [flags] ``` +### Examples + +``` + +#Enabling manual sync for a general case +argocd proj windows enable-manual-sync PROJECT ID + +#Enabling manual sync for a windows set on the default project with Id 2 +argocd proj windows enable-manual-sync default 2 + +#Enabling manual sync with a custom message +argocd proj windows enable-manual-sync my-app-project --message "Manual sync initiated by admin +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_list.md b/docs/user-guide/commands/argocd_proj_windows_list.md index 94073db4775b8..3c361f90d2a68 100644 --- a/docs/user-guide/commands/argocd_proj_windows_list.md +++ b/docs/user-guide/commands/argocd_proj_windows_list.md @@ -11,12 +11,15 @@ argocd proj windows list PROJECT [flags] ### Examples ``` -# List project windows + +#List project windows argocd proj windows list PROJECT - -# List project windows in yaml format + +#List project windows in yaml format argocd proj windows list PROJECT -o yaml +#List project windows info for a project name (test-project) +argocd proj windows list test-project ``` ### Options diff --git a/examples/k8s-rbac/argocd-server-applications/argocd-notifications-controller-rbac-clusterrole.yaml b/examples/k8s-rbac/argocd-server-applications/argocd-notifications-controller-rbac-clusterrole.yaml index 05f92abb11717..ecbf6de3efb01 100644 --- a/examples/k8s-rbac/argocd-server-applications/argocd-notifications-controller-rbac-clusterrole.yaml +++ b/examples/k8s-rbac/argocd-server-applications/argocd-notifications-controller-rbac-clusterrole.yaml @@ -16,4 +16,13 @@ rules: - list - watch - update - - patch \ No newline at end of file + - patch +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch \ No newline at end of file diff --git a/go.mod b/go.mod index f396b45234e25..03283f5c61f09 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/argoproj/argo-cd/v2 -go 1.19 +go 1.21 + +toolchain go1.21.0 require ( code.gitea.io/sdk/gitea v0.15.1 @@ -12,7 +14,7 @@ require ( github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48 - github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf + github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.44.317 github.com/bmatcuk/doublestar/v4 v4.6.0 @@ -27,7 +29,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e github.com/go-git/go-git/v5 v5.8.1 - github.com/go-logr/logr v1.2.4 + github.com/go-logr/logr v1.3.0 github.com/go-openapi/loads v0.21.2 github.com/go-openapi/runtime v0.26.0 github.com/go-playground/webhooks/v6 v6.3.0 @@ -41,7 +43,7 @@ require ( github.com/google/go-github/v35 v35.3.0 github.com/google/go-jsonnet v0.20.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/gorilla/handlers v1.5.1 github.com/gorilla/websocket v1.5.0 github.com/gosimple/slug v1.13.1 @@ -75,26 +77,26 @@ require ( github.com/xanzy/go-gitlab v0.91.1 github.com/yuin/gopher-lua v1.1.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 - go.opentelemetry.io/otel v1.16.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 - go.opentelemetry.io/otel/sdk v1.16.0 + go.opentelemetry.io/otel v1.21.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 + go.opentelemetry.io/otel/sdk v1.21.0 golang.org/x/crypto v0.14.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/oauth2 v0.11.0 golang.org/x/sync v0.3.0 golang.org/x/term v0.13.0 - google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 - google.golang.org/grpc v1.58.3 + google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d + google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.26.4 + k8s.io/api v0.26.11 k8s.io/apiextensions-apiserver v0.26.4 - k8s.io/apimachinery v0.26.4 - k8s.io/apiserver v0.26.4 - k8s.io/client-go v0.26.4 - k8s.io/code-generator v0.26.4 + k8s.io/apimachinery v0.26.11 + k8s.io/apiserver v0.26.11 + k8s.io/client-go v0.26.11 + k8s.io/code-generator v0.26.11 k8s.io/klog/v2 v2.100.1 k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f k8s.io/kubectl v0.26.4 @@ -126,20 +128,25 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.18.0 // indirect github.com/aws/smithy-go v1.13.5 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/google/s2a-go v0.1.4 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/tidwall/gjson v1.14.4 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect - google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + go.opencensus.io v0.24.0 // indirect + google.golang.org/api v0.132.0 // indirect + google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/retry.v1 v1.0.3 // indirect k8s.io/klog v1.0.0 // indirect nhooyr.io/websocket v1.8.7 // indirect ) require ( - cloud.google.com/go/compute v1.21.0 // indirect + cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect @@ -178,7 +185,7 @@ require ( github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.4.1 // indirect - github.com/go-jose/go-jose/v3 v3.0.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect @@ -189,7 +196,7 @@ require ( github.com/go-openapi/swag v0.22.3 // indirect github.com/go-openapi/validate v0.22.1 // indirect github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect - github.com/golang/glog v1.1.0 // indirect + github.com/golang/glog v1.1.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/btree v1.1.2 // indirect github.com/google/gnostic v0.6.9 // indirect @@ -200,7 +207,7 @@ require ( github.com/gosimple/unidecode v1.0.1 // indirect github.com/gregdel/pushover v1.2.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-version v1.2.1 // indirect github.com/huandu/xstrings v1.3.3 // indirect @@ -255,18 +262,17 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xlab/treeprint v1.1.0 // indirect go.mongodb.org/mongo-driver v1.11.3 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect - golang.org/x/mod v0.9.0 // indirect + golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.17.0 - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 - golang.org/x/tools v0.7.0 // indirect + golang.org/x/tools v0.12.0 // indirect gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect gomodules.xyz/notify v0.1.1 // indirect @@ -275,12 +281,12 @@ require ( gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - k8s.io/cli-runtime v0.26.4 // indirect - k8s.io/component-base v0.26.4 // indirect - k8s.io/component-helpers v0.26.4 // indirect + k8s.io/cli-runtime v0.26.11 // indirect + k8s.io/component-base v0.26.11 // indirect + k8s.io/component-helpers v0.26.11 // indirect k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect k8s.io/kube-aggregator v0.26.4 // indirect - k8s.io/kubernetes v1.26.4 // indirect + k8s.io/kubernetes v1.26.11 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.12.1 // indirect sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect @@ -299,34 +305,34 @@ replace ( // Avoid CVE-2022-28948 gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 - k8s.io/api => k8s.io/api v0.26.4 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.4 - k8s.io/apimachinery => k8s.io/apimachinery v0.26.4 - k8s.io/apiserver => k8s.io/apiserver v0.26.4 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.26.4 - k8s.io/client-go => k8s.io/client-go v0.26.4 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.26.4 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.26.4 - k8s.io/code-generator => k8s.io/code-generator v0.26.4 - k8s.io/component-base => k8s.io/component-base v0.26.4 - k8s.io/component-helpers => k8s.io/component-helpers v0.26.4 - k8s.io/controller-manager => k8s.io/controller-manager v0.26.4 - k8s.io/cri-api => k8s.io/cri-api v0.26.4 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.26.4 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.26.4 - k8s.io/kms => k8s.io/kms v0.26.4 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.26.4 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.26.4 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.26.4 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.26.4 - k8s.io/kubectl => k8s.io/kubectl v0.26.4 - k8s.io/kubelet => k8s.io/kubelet v0.26.4 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.26.4 - k8s.io/metrics => k8s.io/metrics v0.26.4 - k8s.io/mount-utils => k8s.io/mount-utils v0.26.4 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.26.4 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.26.4 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.26.4 - k8s.io/sample-controller => k8s.io/sample-controller v0.26.4 + k8s.io/api => k8s.io/api v0.26.11 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.11 + k8s.io/apimachinery => k8s.io/apimachinery v0.26.11 + k8s.io/apiserver => k8s.io/apiserver v0.26.11 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.26.11 + k8s.io/client-go => k8s.io/client-go v0.26.11 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.26.11 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.26.11 + k8s.io/code-generator => k8s.io/code-generator v0.26.11 + k8s.io/component-base => k8s.io/component-base v0.26.11 + k8s.io/component-helpers => k8s.io/component-helpers v0.26.11 + k8s.io/controller-manager => k8s.io/controller-manager v0.26.11 + k8s.io/cri-api => k8s.io/cri-api v0.26.11 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.26.11 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.26.11 + k8s.io/kms => k8s.io/kms v0.26.11 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.26.11 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.26.11 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.26.11 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.26.11 + k8s.io/kubectl => k8s.io/kubectl v0.26.11 + k8s.io/kubelet => k8s.io/kubelet v0.26.11 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.26.11 + k8s.io/metrics => k8s.io/metrics v0.26.11 + k8s.io/mount-utils => k8s.io/mount-utils v0.26.11 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.26.11 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.26.11 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.26.11 + k8s.io/sample-controller => k8s.io/sample-controller v0.26.11 ) diff --git a/go.sum b/go.sum index 08da01826154c..9f0d3f9a0976e 100644 --- a/go.sum +++ b/go.sum @@ -174,8 +174,8 @@ cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOV cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk= -cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= @@ -686,6 +686,7 @@ github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOS github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antonmedv/expr v1.15.2 h1:afFXpDWIC2n3bF+kTZE1JvFo+c34uaM3sTqh8z0xfdU= github.com/antonmedv/expr v1.15.2/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE= @@ -697,8 +698,8 @@ github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2 github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48 h1:vnXMrNkBFC0H0KBkH1Jno31OVgJQR4KSd0ypEcfzQRA= github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48/go.mod h1:1TchqKw9XmYYZluyEHa1dTJQoZgbV6PhabB/e8Wf3KY= -github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf h1:4wliaBwd6iKvT/5huDTJntaYtTSdwPLs00SOQwDSK6A= -github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf/go.mod h1:TuK0BNKo34DIUOyCCGOB9ij+smGCxeCgt9ZB+0fMWno= +github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 h1:1lt0VXzmLK7Vv0kaeal3S6/JIfzPyBORkUWXhiqF3l0= +github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9/go.mod h1:E/vv4+by868m0mmflaRfGBmKBtAupoF+mmyfekP8QCk= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -761,7 +762,9 @@ github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 h1:IRY7Xy588KylkoycsUhFpW7cdGpy5Y5BPsz4IfuJtGk= github.com/bradleyfalzon/ghinstallation/v2 v2.6.0/go.mod h1:oQ3etOwN3TRH4EwgW5/7MxSVMGlMlzG/O8TU7eYdoSk= github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= +github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= +github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= @@ -805,6 +808,7 @@ github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= @@ -833,6 +837,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= @@ -846,6 +851,7 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= +github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -868,6 +874,7 @@ github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= @@ -892,6 +899,7 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -907,6 +915,7 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= @@ -919,13 +928,14 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmS github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= -github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -942,11 +952,12 @@ github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -1057,8 +1068,9 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -1148,19 +1160,23 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= +github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -1175,6 +1191,8 @@ github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38 github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= @@ -1209,8 +1227,9 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -1327,6 +1346,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -1575,8 +1595,9 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -1724,27 +1745,27 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 h1:TVQp/bboR4mhZSav+MdgXB8FaRho1RC8UwVn3T0vjVc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd h1:Uo/x0Ir5vQJ+683GXB9Ug+4fcjsbp7z7Ul8UaZbhsRM= go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1753,7 +1774,8 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= @@ -1763,6 +1785,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1855,8 +1878,9 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2109,8 +2133,9 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2150,7 +2175,6 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= @@ -2235,8 +2259,9 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2322,6 +2347,8 @@ google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjY google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.132.0 h1:8t2/+qZ26kAOGSmOiHwVycqVaDg7q3JDILrNi/Z6rvc= +google.golang.org/api v0.132.0/go.mod h1:AeTBC6GpJnJSRJjktDcPX0QwtS8pGYZOV6MSuSCusw0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2471,21 +2498,21 @@ google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -2533,8 +2560,8 @@ google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= @@ -2581,6 +2608,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2590,24 +2618,24 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.26.4 h1:qSG2PmtcD23BkYiWfoYAcak870eF/hE7NNYBYavTT94= -k8s.io/api v0.26.4/go.mod h1:WwKEXU3R1rgCZ77AYa7DFksd9/BAIKyOmRlbVxgvjCk= -k8s.io/apiextensions-apiserver v0.26.4 h1:9D2RTxYGxrG5uYg6D7QZRcykXvavBvcA59j5kTaedQI= -k8s.io/apiextensions-apiserver v0.26.4/go.mod h1:cd4uGFGIgzEqUghWpRsr9KE8j2KNTjY8Ji8pnMMazyw= -k8s.io/apimachinery v0.26.4 h1:rZccKdBLg9vP6J09JD+z8Yr99Ce8gk3Lbi9TCx05Jzs= -k8s.io/apimachinery v0.26.4/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= -k8s.io/apiserver v0.26.4 h1:3Oq4mnJv0mzVX7BR/Nod+8KjlELf/3Ljvu9ZWDyLUoA= -k8s.io/apiserver v0.26.4/go.mod h1:yAY3O1vBM4/0OIGAGeWcdfzQvgdwJ188VirLcuSAVnw= -k8s.io/cli-runtime v0.26.4 h1:MgSU871KDzBDX7V9GtuqS6Ai9lhQCHgRzkurnXOWtZ0= -k8s.io/cli-runtime v0.26.4/go.mod h1:MjJ2DXMChw2zcG0/agzm17xwKpfVxOfuoCdfY9iOCOE= -k8s.io/client-go v0.26.4 h1:/7P/IbGBuT73A+G97trf44NTPSNqvuBREpOfdLbHvD4= -k8s.io/client-go v0.26.4/go.mod h1:6qOItWm3EwxJdl/8p5t7FWtWUOwyMdA8N9ekbW4idpI= -k8s.io/code-generator v0.26.4 h1:zgDD0qX13p/jtrAoYRRiYeQ5ibnriwmo2cMkMZAtJxc= -k8s.io/code-generator v0.26.4/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI= -k8s.io/component-base v0.26.4 h1:Bg2xzyXNKL3eAuiTEu3XE198d6z22ENgFgGQv2GGOUk= -k8s.io/component-base v0.26.4/go.mod h1:lTuWL1Xz/a4e80gmIC3YZG2JCO4xNwtKWHJWeJmsq20= -k8s.io/component-helpers v0.26.4 h1:qbZrh8QmfL+Yn7lWEI/BPrvITGgkBy33djP5Tzsu2hA= -k8s.io/component-helpers v0.26.4/go.mod h1:2Siz5eWmaKu0khASXMTCfJuASZAbCPX9mtjlCe5IWRs= +k8s.io/api v0.26.11 h1:hLhTZRdYc3vBBOY4wbEyTLWgMyieOAk2Ws9NG57QqO4= +k8s.io/api v0.26.11/go.mod h1:bSr/A0TKRt5W2OMDdexkM/ER1NxOxiQqNNFXW2nMZrM= +k8s.io/apiextensions-apiserver v0.26.11 h1:6/T0Jm9c+Aw1AYUflPOz2sAsty304/DDSkciTr8+HuE= +k8s.io/apiextensions-apiserver v0.26.11/go.mod h1:xMqWxAB+AvSTdmFRVWlpavY9bJl/3g6yWiPn/fwZbT0= +k8s.io/apimachinery v0.26.11 h1:w//840HHdwSRKqD15j9YX9HLlU6RPlfrvW0xEhLk2+0= +k8s.io/apimachinery v0.26.11/go.mod h1:2/HZp0l6coXtS26du1Bk36fCuAEr/lVs9Q9NbpBtd1Y= +k8s.io/apiserver v0.26.11 h1:JcrlATLu5xQVLV7/rfRFFl9ivvNLmZH0dM3DFFdFp+w= +k8s.io/apiserver v0.26.11/go.mod h1:htEG/Q3sI3+6Is3Z26QzBjaCGICsz/kFj+IhIP4oJuE= +k8s.io/cli-runtime v0.26.11 h1:HO3Sgf06XkT8/8wWnhskfz4+LMKrChRz+A13vDJSQrE= +k8s.io/cli-runtime v0.26.11/go.mod h1:D98GjQtDmqn7WDuKBgWivd6R8qEs3yzT19EmCM5pqBs= +k8s.io/client-go v0.26.11 h1:RjfZr5+vQjjTRmk4oCqHyC0cgrZXPjw+X+ge35sk4GI= +k8s.io/client-go v0.26.11/go.mod h1:+emNszw9va/uRJIM5ALTBtFnlZMTjwBrNjRfEh0iuw8= +k8s.io/code-generator v0.26.11 h1:S0PJxapUhG6LWYezYB/FVE5Gf4BxGY0fCwnLrwfQ/70= +k8s.io/code-generator v0.26.11/go.mod h1:Hjxj7hpvSxcNnYIWzCSuEdwN0/9aHlezQRKJXr0Kv8U= +k8s.io/component-base v0.26.11 h1:1/JmB6fexefGByfFyIK6aHksZZVtaDskttzXOzmZ6zA= +k8s.io/component-base v0.26.11/go.mod h1:jYNisnoM6iWFRUg51pxaQabzL5fBYTr5CMpsLjUYGp0= +k8s.io/component-helpers v0.26.11 h1:XD2/2lik/5n1WFepDvgHzIGL0tix/EU3GaxGJHdsgkA= +k8s.io/component-helpers v0.26.11/go.mod h1:lw3bchkI0NHMPmb+CE73GznPW0Mvqd/Y9UVMEqBkysE= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20220902162205-c0856e24416d h1:U9tB195lKdzwqicbJvyJeOXV7Klv+wNAWENRnXEGi08= k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= @@ -2619,15 +2647,15 @@ k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-aggregator v0.26.4 h1:iGljhq5exQkbuc3bnkwUx95RPCBDExg7DkX9XaYhg6w= -k8s.io/kube-aggregator v0.26.4/go.mod h1:eWfg4tU0+l57ebWiS5THOANIJUrKRxudSVDJ+63bqvQ= +k8s.io/kube-aggregator v0.26.11 h1:P46aQPWOE+8bTbK2cqxUFP1XwH4ShZEHnlk1T5QFT8U= +k8s.io/kube-aggregator v0.26.11/go.mod h1:XNGLFzn4Ex7qFVqpCnvLUr354EM4QhMFuFSoB6JHmL4= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/kubectl v0.26.4 h1:A0Oa0u/po4KxXnXsNCOwLojAe9cQR3TJNJabEIf7U1w= -k8s.io/kubectl v0.26.4/go.mod h1:cWtp/+I4p+h5En3s2zO1zCry9v3/6h37EQ2tF3jNRnM= -k8s.io/kubernetes v1.26.4 h1:/c00/JjOltBwhNOBs+hO433Q3fRyeWWtyYF6z2xtmag= -k8s.io/kubernetes v1.26.4/go.mod h1:NxzR7U7mS+OGa3J/qweI86Pek//mlfHqDgt6NNGdz8g= +k8s.io/kubectl v0.26.11 h1:cVPzYA4HKefU3tPiVK7hZpJ+5Lm04XoyvCCY5ODznpQ= +k8s.io/kubectl v0.26.11/go.mod h1:xjEX/AHtEQrGj2AGqVopyHr/JU1hLy1k7Yn48JuK9LQ= +k8s.io/kubernetes v1.26.11 h1:g3r1IAUqsaHnOG2jdpoagJ5W9UCXkR2ljQ/7BmCzPNg= +k8s.io/kubernetes v1.26.11/go.mod h1:z1URAaBJ+XnOTr3Q/l4umxRUxn/OyD2fbkUgS0Bl7u4= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= diff --git a/hack/update-kubernetes-version.sh b/hack/update-kubernetes-version.sh new file mode 100755 index 0000000000000..8d52033a601fc --- /dev/null +++ b/hack/update-kubernetes-version.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ -z "${1:-}" ]; then + echo "Example usage: ./hack/update-kubernetes-version.sh v1.26.11" + exit 1 +fi +VERSION=${1#"v"} +MODS=($( + curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod | + sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' +)) +for MOD in "${MODS[@]}"; do + echo "Updating $MOD..." >&2 + V=$( + go mod download -json "${MOD}@kubernetes-${VERSION}" | + sed -n 's|.*"Version": "\(.*\)".*|\1|p' + ) + go mod edit "-replace=${MOD}=${MOD}@${V}" +done +go get "k8s.io/kubernetes@v${VERSION}" +go mod tidy diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index 9b618d96367dc..4862721961f21 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -136,6 +136,18 @@ spec: name: argocd-cmd-params-cm key: otlp.address optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index 3c576a421a25c..f5e5c759e0750 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -143,6 +143,18 @@ spec: name: argocd-cmd-params-cm key: otlp.address optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/base/notification/argocd-notifications-controller-deployment.yaml b/manifests/base/notification/argocd-notifications-controller-deployment.yaml index 9cd1a068808b1..876a207c16e42 100644 --- a/manifests/base/notification/argocd-notifications-controller-deployment.yaml +++ b/manifests/base/notification/argocd-notifications-controller-deployment.yaml @@ -54,6 +54,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true workingDir: /app livenessProbe: tcpSocket: diff --git a/manifests/base/repo-server/argocd-repo-server-deployment.yaml b/manifests/base/repo-server/argocd-repo-server-deployment.yaml index 728c80c14bc2a..907bc80a34e56 100644 --- a/manifests/base/repo-server/argocd-repo-server-deployment.yaml +++ b/manifests/base/repo-server/argocd-repo-server-deployment.yaml @@ -120,6 +120,18 @@ spec: name: argocd-cmd-params-cm key: otlp.address optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: diff --git a/manifests/base/server/argocd-server-deployment.yaml b/manifests/base/server/argocd-server-deployment.yaml index b09891d26e529..6df5f9701713f 100644 --- a/manifests/base/server/argocd-server-deployment.yaml +++ b/manifests/base/server/argocd-server-deployment.yaml @@ -215,6 +215,18 @@ spec: name: argocd-cmd-params-cm key: otlp.address optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 2469f171351fe..5d2d225473452 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -20123,6 +20123,8 @@ spec: - metadata - spec type: object + templatePatch: + type: string required: - generators - template @@ -21262,6 +21264,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -21587,6 +21601,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index c324134df927b..758785832ea78 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -15183,6 +15183,8 @@ spec: - metadata - spec type: object + templatePatch: + type: string required: - generators - template diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 0f637cd786dc2..19f8015b04945 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -20123,6 +20123,8 @@ spec: - metadata - spec type: object + templatePatch: + type: string required: - generators - template @@ -22472,6 +22474,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -22749,6 +22757,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -23144,6 +23164,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -23402,6 +23434,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 33ada40e37004..2ecd016092f1b 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -1859,6 +1859,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -2136,6 +2142,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -2531,6 +2549,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -2789,6 +2819,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/install.yaml b/manifests/install.yaml index cb4cda559caf0..2f7da39bd9b12 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -20123,6 +20123,8 @@ spec: - metadata - spec type: object + templatePatch: + type: string required: - generators - template @@ -21567,6 +21569,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -21795,6 +21803,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -22188,6 +22208,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -22446,6 +22478,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 9e6f98030d89b..d74ca00b88e4c 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -954,6 +954,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -1182,6 +1188,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -1575,6 +1593,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -1833,6 +1863,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/notification_controller/controller/controller.go b/notification_controller/controller/controller.go index 32dfac2b75a3b..7d871af4c44a3 100644 --- a/notification_controller/controller/controller.go +++ b/notification_controller/controller/controller.go @@ -63,19 +63,27 @@ func NewController( registry *controller.MetricsRegistry, secretName string, configMapName string, + selfServiceNotificationEnabled bool, ) *notificationController { var appClient dynamic.ResourceInterface + namespaceableAppClient := client.Resource(applications) appClient = namespaceableAppClient + if len(applicationNamespaces) == 0 { appClient = namespaceableAppClient.Namespace(namespace) } - appInformer := newInformer(appClient, namespace, applicationNamespaces, appLabelSelector) appProjInformer := newInformer(newAppProjClient(client, namespace), namespace, []string{namespace}, "") - secretInformer := k8s.NewSecretInformer(k8sClient, namespace, secretName) - configMapInformer := k8s.NewConfigMapInformer(k8sClient, namespace, configMapName) - apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, secretName, configMapName), namespace, secretInformer, configMapInformer) + var notificationConfigNamespace string + if selfServiceNotificationEnabled { + notificationConfigNamespace = v1.NamespaceAll + } else { + notificationConfigNamespace = namespace + } + secretInformer := k8s.NewSecretInformer(k8sClient, notificationConfigNamespace, secretName) + configMapInformer := k8s.NewConfigMapInformer(k8sClient, notificationConfigNamespace, configMapName) + apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, secretName, configMapName, selfServiceNotificationEnabled), namespace, secretInformer, configMapInformer) res := ¬ificationController{ secretInformer: secretInformer, @@ -83,19 +91,30 @@ func NewController( appInformer: appInformer, appProjInformer: appProjInformer, apiFactory: apiFactory} - res.ctrl = controller.NewController(namespaceableAppClient, appInformer, apiFactory, - controller.WithSkipProcessing(func(obj v1.Object) (bool, string) { - app, ok := (obj).(*unstructured.Unstructured) - if !ok { - return false, "" - } - if checkAppNotInAdditionalNamespaces(app, namespace, applicationNamespaces) { - return true, "app is not in one of the application-namespaces, nor the notification controller namespace" - } - return !isAppSyncStatusRefreshed(app, log.WithField("app", obj.GetName())), "sync status out of date" - }), - controller.WithMetricsRegistry(registry), - controller.WithAlterDestinations(res.alterDestinations)) + skipProcessingOpt := controller.WithSkipProcessing(func(obj v1.Object) (bool, string) { + app, ok := (obj).(*unstructured.Unstructured) + if !ok { + return false, "" + } + if checkAppNotInAdditionalNamespaces(app, namespace, applicationNamespaces) { + return true, "app is not in one of the application-namespaces, nor the notification controller namespace" + } + return !isAppSyncStatusRefreshed(app, log.WithField("app", obj.GetName())), "sync status out of date" + }) + metricsRegistryOpt := controller.WithMetricsRegistry(registry) + alterDestinationsOpt := controller.WithAlterDestinations(res.alterDestinations) + + if !selfServiceNotificationEnabled { + res.ctrl = controller.NewController(namespaceableAppClient, appInformer, apiFactory, + skipProcessingOpt, + metricsRegistryOpt, + alterDestinationsOpt) + } else { + res.ctrl = controller.NewControllerWithNamespaceSupport(namespaceableAppClient, appInformer, apiFactory, + skipProcessingOpt, + metricsRegistryOpt, + alterDestinationsOpt) + } return res } @@ -118,6 +137,7 @@ func (c *notificationController) alterDestinations(obj v1.Object, destinations s } func newInformer(resClient dynamic.ResourceInterface, controllerNamespace string, applicationNamespaces []string, selector string) cache.SharedIndexInformer { + informer := cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { diff --git a/notification_controller/controller/controller_test.go b/notification_controller/controller/controller_test.go index 5ad1e520502a3..4eedb28f5e001 100644 --- a/notification_controller/controller/controller_test.go +++ b/notification_controller/controller/controller_test.go @@ -110,26 +110,30 @@ func TestInit(t *testing.T) { k8sClient := k8sfake.NewSimpleClientset() appLabelSelector := "app=test" - nc := NewController( - k8sClient, - dynamicClient, - nil, - "default", - []string{}, - appLabelSelector, - nil, - "my-secret", - "my-configmap", - ) - - assert.NotNil(t, nc) - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - err = nc.Init(ctx) - - assert.NoError(t, err) + selfServiceNotificationEnabledFlags := []bool{false, true} + for _, selfServiceNotificationEnabled := range selfServiceNotificationEnabledFlags { + nc := NewController( + k8sClient, + dynamicClient, + nil, + "default", + []string{}, + appLabelSelector, + nil, + "my-secret", + "my-configmap", + selfServiceNotificationEnabled, + ) + + assert.NotNil(t, nc) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + err = nc.Init(ctx) + + assert.NoError(t, err) + } } func TestInitTimeout(t *testing.T) { @@ -152,6 +156,7 @@ func TestInitTimeout(t *testing.T) { nil, "my-secret", "my-configmap", + false, ) assert.NotNil(t, nc) diff --git a/pkg/apis/application/v1alpha1/applicationset_types.go b/pkg/apis/application/v1alpha1/applicationset_types.go index 99db8124e51ea..41721d0c2287c 100644 --- a/pkg/apis/application/v1alpha1/applicationset_types.go +++ b/pkg/apis/application/v1alpha1/applicationset_types.go @@ -65,6 +65,7 @@ type ApplicationSetSpec struct { // ApplyNestedSelectors enables selectors defined within the generators of two level-nested matrix or merge generators ApplyNestedSelectors bool `json:"applyNestedSelectors,omitempty" protobuf:"bytes,8,name=applyNestedSelectors"` IgnoreApplicationDifferences ApplicationSetIgnoreDifferences `json:"ignoreApplicationDifferences,omitempty" protobuf:"bytes,9,name=ignoreApplicationDifferences"` + TemplatePatch *string `json:"templatePatch,omitempty" protobuf:"bytes,10,name=templatePatch"` } type ApplicationPreservedFields struct { diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index 777ef9fa49bcc..2a9c0f4789bb7 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -4448,693 +4448,694 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 10964 bytes of a gzipped FileDescriptorProto + // 10983 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x70, 0x1c, 0xc9, 0x75, 0x18, 0xae, 0xd9, 0x0f, 0x60, 0xf7, 0xe1, 0x83, 0x64, 0x93, 0xbc, 0x03, 0xa9, 0xbb, 0x03, - 0x3d, 0xf7, 0xf3, 0xe9, 0xfc, 0xd3, 0x1d, 0xe0, 0xa3, 0xee, 0x94, 0x8b, 0xce, 0x96, 0x8c, 0x0f, + 0x3d, 0xf7, 0xf3, 0xe9, 0xfc, 0xd3, 0x1d, 0xe0, 0xa3, 0xef, 0xe4, 0x8b, 0xce, 0x96, 0x8c, 0x0f, 0x12, 0x04, 0x09, 0x10, 0xb8, 0x06, 0x48, 0x4a, 0x27, 0x9f, 0x4e, 0x83, 0xdd, 0xc6, 0x62, 0x88, 0xd9, 0x99, 0xb9, 0x99, 0x59, 0x10, 0x38, 0x4b, 0xb2, 0x64, 0xc9, 0xb6, 0x12, 0x7d, 0x9c, 0x22, - 0x25, 0xe5, 0x73, 0x12, 0x39, 0xb2, 0xe5, 0xa4, 0xec, 0x4a, 0x54, 0x71, 0x92, 0x3f, 0xe2, 0xc4, + 0x25, 0xe5, 0x73, 0x12, 0x29, 0xb2, 0xe5, 0xa4, 0xec, 0x4a, 0x54, 0x71, 0x92, 0x3f, 0xe2, 0xc4, 0x49, 0xb9, 0x6c, 0xa7, 0x52, 0x4a, 0x29, 0x29, 0xbb, 0x52, 0x2e, 0xcb, 0x49, 0x6c, 0x44, 0x62, - 0xca, 0x95, 0x54, 0xaa, 0xe2, 0x2a, 0x27, 0xfe, 0x23, 0x61, 0xf2, 0x47, 0xaa, 0xbf, 0x7b, 0x66, + 0x2a, 0x95, 0x54, 0xaa, 0xe2, 0x2a, 0x27, 0xfe, 0x23, 0x61, 0xf2, 0x47, 0xaa, 0xbf, 0x7b, 0x66, 0x67, 0x81, 0x05, 0x30, 0x20, 0x29, 0xe5, 0xfe, 0xdb, 0xed, 0xf7, 0xe6, 0xbd, 0x9e, 0x9e, 0xee, 0xf7, 0x5e, 0xbf, 0x7e, 0xef, 0x35, 0x2c, 0xb4, 0xdc, 0x64, 0xa3, 0xb3, 0x36, 0xd1, 0x08, 0xda, 0x93, 0x4e, 0xd4, 0x0a, 0xc2, 0x28, 0xb8, 0xcd, 0x7e, 0x3c, 0xdb, 0x68, 0x4e, 0x6e, 0x5d, 0x9c, 0x0c, 0x37, 0x5b, 0x93, 0x4e, 0xe8, 0xc6, 0x93, 0x4e, 0x18, 0x7a, 0x6e, 0xc3, 0x49, 0xdc, 0xc0, 0x9f, 0xdc, 0x7a, 0xce, 0xf1, 0xc2, 0x0d, 0xe7, 0xb9, 0xc9, 0x16, 0xf1, 0x49, 0xe4, 0x24, 0xa4, - 0x39, 0x11, 0x46, 0x41, 0x12, 0xa0, 0x1f, 0xd1, 0xd4, 0x26, 0x24, 0x35, 0xf6, 0xe3, 0xb5, 0x46, + 0x39, 0x11, 0x46, 0x41, 0x12, 0xa0, 0x1f, 0xd3, 0xd4, 0x26, 0x24, 0x35, 0xf6, 0xe3, 0xb5, 0x46, 0x73, 0x62, 0xeb, 0xe2, 0x44, 0xb8, 0xd9, 0x9a, 0xa0, 0xd4, 0x26, 0x0c, 0x6a, 0x13, 0x92, 0xda, 0xf9, 0x67, 0x8d, 0xbe, 0xb4, 0x82, 0x56, 0x30, 0xc9, 0x88, 0xae, 0x75, 0xd6, 0xd9, 0x3f, 0xf6, 0x87, 0xfd, 0xe2, 0xcc, 0xce, 0xdb, 0x9b, 0x2f, 0xc6, 0x13, 0x6e, 0x40, 0xbb, 0x37, 0xd9, 0x08, 0x22, 0x32, 0xb9, 0xd5, 0xd5, 0xa1, 0xf3, 0x57, 0x34, 0x0e, 0xd9, 0x4e, 0x88, 0x1f, 0xbb, 0x81, 0x1f, 0x3f, 0x4b, 0xbb, 0x40, 0xa2, 0x2d, 0x12, 0x99, 0xaf, 0x67, 0x20, 0xe4, 0x51, 0x7a, 0x5e, 0x53, 0x6a, 0x3b, 0x8d, 0x0d, 0xd7, 0x27, 0xd1, 0x8e, 0x7e, 0xbc, 0x4d, 0x12, 0x27, 0xef, 0xa9, - 0xc9, 0x5e, 0x4f, 0x45, 0x1d, 0x3f, 0x71, 0xdb, 0xa4, 0xeb, 0x81, 0xf7, 0xee, 0xf7, 0x40, 0xdc, - 0xd8, 0x20, 0x6d, 0xa7, 0xeb, 0xb9, 0xf7, 0xf4, 0x7a, 0xae, 0x93, 0xb8, 0xde, 0xa4, 0xeb, 0x27, - 0x71, 0x12, 0x65, 0x1f, 0xb2, 0x5f, 0x87, 0x91, 0xa9, 0x5b, 0x2b, 0x53, 0x9d, 0x64, 0x63, 0x26, - 0xf0, 0xd7, 0xdd, 0x16, 0x7a, 0x01, 0x86, 0x1a, 0x5e, 0x27, 0x4e, 0x48, 0x74, 0xdd, 0x69, 0x93, - 0x31, 0xeb, 0x82, 0xf5, 0x74, 0x7d, 0xfa, 0xf4, 0x37, 0x77, 0xc7, 0xdf, 0x71, 0x77, 0x77, 0x7c, - 0x68, 0x46, 0x83, 0xb0, 0x89, 0x87, 0x7e, 0x08, 0x06, 0xa3, 0xc0, 0x23, 0x53, 0xf8, 0xfa, 0x58, - 0x89, 0x3d, 0x72, 0x42, 0x3c, 0x32, 0x88, 0x79, 0x33, 0x96, 0x70, 0xfb, 0x0f, 0x4a, 0x00, 0x53, - 0x61, 0xb8, 0x1c, 0x05, 0xb7, 0x49, 0x23, 0x41, 0x1f, 0x85, 0x1a, 0x1d, 0xba, 0xa6, 0x93, 0x38, - 0x8c, 0xdb, 0xd0, 0xc5, 0x1f, 0x9e, 0xe0, 0x6f, 0x32, 0x61, 0xbe, 0x89, 0x9e, 0x38, 0x14, 0x7b, - 0x62, 0xeb, 0xb9, 0x89, 0xa5, 0x35, 0xfa, 0xfc, 0x22, 0x49, 0x9c, 0x69, 0x24, 0x98, 0x81, 0x6e, - 0xc3, 0x8a, 0x2a, 0xf2, 0xa1, 0x12, 0x87, 0xa4, 0xc1, 0x3a, 0x36, 0x74, 0x71, 0x61, 0xe2, 0x28, - 0x33, 0x74, 0x42, 0xf7, 0x7c, 0x25, 0x24, 0x8d, 0xe9, 0x61, 0xc1, 0xb9, 0x42, 0xff, 0x61, 0xc6, - 0x07, 0x6d, 0xc1, 0x40, 0x9c, 0x38, 0x49, 0x27, 0x1e, 0x2b, 0x33, 0x8e, 0xd7, 0x0b, 0xe3, 0xc8, - 0xa8, 0x4e, 0x8f, 0x0a, 0x9e, 0x03, 0xfc, 0x3f, 0x16, 0xdc, 0xec, 0x3f, 0xb6, 0x60, 0x54, 0x23, - 0x2f, 0xb8, 0x71, 0x82, 0x7e, 0xbc, 0x6b, 0x70, 0x27, 0xfa, 0x1b, 0x5c, 0xfa, 0x34, 0x1b, 0xda, - 0x93, 0x82, 0x59, 0x4d, 0xb6, 0x18, 0x03, 0xdb, 0x86, 0xaa, 0x9b, 0x90, 0x76, 0x3c, 0x56, 0xba, - 0x50, 0x7e, 0x7a, 0xe8, 0xe2, 0x95, 0xa2, 0xde, 0x73, 0x7a, 0x44, 0x30, 0xad, 0xce, 0x53, 0xf2, - 0x98, 0x73, 0xb1, 0x7f, 0x75, 0xd8, 0x7c, 0x3f, 0x3a, 0xe0, 0xe8, 0x39, 0x18, 0x8a, 0x83, 0x4e, - 0xd4, 0x20, 0x98, 0x84, 0x41, 0x3c, 0x66, 0x5d, 0x28, 0xd3, 0xa9, 0x47, 0x67, 0xea, 0x8a, 0x6e, - 0xc6, 0x26, 0x0e, 0xfa, 0xa2, 0x05, 0xc3, 0x4d, 0x12, 0x27, 0xae, 0xcf, 0xf8, 0xcb, 0xce, 0xaf, - 0x1e, 0xb9, 0xf3, 0xb2, 0x71, 0x56, 0x13, 0x9f, 0x3e, 0x23, 0x5e, 0x64, 0xd8, 0x68, 0x8c, 0x71, - 0x8a, 0x3f, 0x5d, 0x71, 0x4d, 0x12, 0x37, 0x22, 0x37, 0xa4, 0xff, 0xd9, 0x9c, 0x31, 0x56, 0xdc, - 0xac, 0x06, 0x61, 0x13, 0x0f, 0xf9, 0x50, 0xa5, 0x2b, 0x2a, 0x1e, 0xab, 0xb0, 0xfe, 0xcf, 0x1f, - 0xad, 0xff, 0x62, 0x50, 0xe9, 0x62, 0xd5, 0xa3, 0x4f, 0xff, 0xc5, 0x98, 0xb3, 0x41, 0x5f, 0xb0, - 0x60, 0x4c, 0xac, 0x78, 0x4c, 0xf8, 0x80, 0xde, 0xda, 0x70, 0x13, 0xe2, 0xb9, 0x71, 0x32, 0x56, - 0x65, 0x7d, 0x98, 0xec, 0x6f, 0x6e, 0xcd, 0x45, 0x41, 0x27, 0xbc, 0xe6, 0xfa, 0xcd, 0xe9, 0x0b, - 0x82, 0xd3, 0xd8, 0x4c, 0x0f, 0xc2, 0xb8, 0x27, 0x4b, 0xf4, 0x15, 0x0b, 0xce, 0xfb, 0x4e, 0x9b, - 0xc4, 0xa1, 0x43, 0x3f, 0x2d, 0x07, 0x4f, 0x7b, 0x4e, 0x63, 0x93, 0xf5, 0x68, 0xe0, 0x70, 0x3d, - 0xb2, 0x45, 0x8f, 0xce, 0x5f, 0xef, 0x49, 0x1a, 0xef, 0xc1, 0x16, 0x7d, 0xdd, 0x82, 0x53, 0x41, - 0x14, 0x6e, 0x38, 0x3e, 0x69, 0x4a, 0x68, 0x3c, 0x36, 0xc8, 0x96, 0xde, 0x47, 0x8e, 0xf6, 0x89, - 0x96, 0xb2, 0x64, 0x17, 0x03, 0xdf, 0x4d, 0x82, 0x68, 0x85, 0x24, 0x89, 0xeb, 0xb7, 0xe2, 0xe9, - 0xb3, 0x77, 0x77, 0xc7, 0x4f, 0x75, 0x61, 0xe1, 0xee, 0xfe, 0xa0, 0x9f, 0x80, 0xa1, 0x78, 0xc7, - 0x6f, 0xdc, 0x72, 0xfd, 0x66, 0x70, 0x27, 0x1e, 0xab, 0x15, 0xb1, 0x7c, 0x57, 0x14, 0x41, 0xb1, - 0x00, 0x35, 0x03, 0x6c, 0x72, 0xcb, 0xff, 0x70, 0x7a, 0x2a, 0xd5, 0x8b, 0xfe, 0x70, 0x7a, 0x32, - 0xed, 0xc1, 0x16, 0xfd, 0xac, 0x05, 0x23, 0xb1, 0xdb, 0xf2, 0x9d, 0xa4, 0x13, 0x91, 0x6b, 0x64, - 0x27, 0x1e, 0x03, 0xd6, 0x91, 0xab, 0x47, 0x1c, 0x15, 0x83, 0xe4, 0xf4, 0x59, 0xd1, 0xc7, 0x11, - 0xb3, 0x35, 0xc6, 0x69, 0xbe, 0x79, 0x0b, 0x4d, 0x4f, 0xeb, 0xa1, 0x62, 0x17, 0x9a, 0x9e, 0xd4, - 0x3d, 0x59, 0xa2, 0x1f, 0x83, 0x93, 0xbc, 0x49, 0x8d, 0x6c, 0x3c, 0x36, 0xcc, 0x04, 0xed, 0x99, - 0xbb, 0xbb, 0xe3, 0x27, 0x57, 0x32, 0x30, 0xdc, 0x85, 0x8d, 0x5e, 0x87, 0xf1, 0x90, 0x44, 0x6d, - 0x37, 0x59, 0xf2, 0xbd, 0x1d, 0x29, 0xbe, 0x1b, 0x41, 0x48, 0x9a, 0xa2, 0x3b, 0xf1, 0xd8, 0xc8, - 0x05, 0xeb, 0xe9, 0xda, 0xf4, 0xbb, 0x44, 0x37, 0xc7, 0x97, 0xf7, 0x46, 0xc7, 0xfb, 0xd1, 0xb3, - 0xff, 0x55, 0x09, 0x4e, 0x66, 0x15, 0x27, 0xfa, 0x3b, 0x16, 0x9c, 0xb8, 0x7d, 0x27, 0x59, 0x0d, - 0x36, 0x89, 0x1f, 0x4f, 0xef, 0x50, 0xf1, 0xc6, 0x54, 0xc6, 0xd0, 0xc5, 0x46, 0xb1, 0x2a, 0x7a, - 0xe2, 0x6a, 0x9a, 0xcb, 0x25, 0x3f, 0x89, 0x76, 0xa6, 0x1f, 0x15, 0x6f, 0x77, 0xe2, 0xea, 0xad, - 0x55, 0x13, 0x8a, 0xb3, 0x9d, 0x3a, 0xff, 0x39, 0x0b, 0xce, 0xe4, 0x91, 0x40, 0x27, 0xa1, 0xbc, - 0x49, 0x76, 0xb8, 0x55, 0x86, 0xe9, 0x4f, 0xf4, 0x2a, 0x54, 0xb7, 0x1c, 0xaf, 0x43, 0x84, 0x75, - 0x33, 0x77, 0xb4, 0x17, 0x51, 0x3d, 0xc3, 0x9c, 0xea, 0xfb, 0x4a, 0x2f, 0x5a, 0xf6, 0xef, 0x96, - 0x61, 0xc8, 0xd0, 0x6f, 0xf7, 0xc1, 0x62, 0x0b, 0x52, 0x16, 0xdb, 0x62, 0x61, 0xaa, 0xb9, 0xa7, - 0xc9, 0x76, 0x27, 0x63, 0xb2, 0x2d, 0x15, 0xc7, 0x72, 0x4f, 0x9b, 0x0d, 0x25, 0x50, 0x0f, 0x42, - 0x6a, 0x91, 0x53, 0xd5, 0x5f, 0x29, 0xe2, 0x13, 0x2e, 0x49, 0x72, 0xd3, 0x23, 0x77, 0x77, 0xc7, - 0xeb, 0xea, 0x2f, 0xd6, 0x8c, 0xec, 0x6f, 0x5b, 0x70, 0xc6, 0xe8, 0xe3, 0x4c, 0xe0, 0x37, 0x5d, - 0xf6, 0x69, 0x2f, 0x40, 0x25, 0xd9, 0x09, 0xa5, 0xd9, 0xaf, 0x46, 0x6a, 0x75, 0x27, 0x24, 0x98, - 0x41, 0xa8, 0xa1, 0xdf, 0x26, 0x71, 0xec, 0xb4, 0x48, 0xd6, 0xd0, 0x5f, 0xe4, 0xcd, 0x58, 0xc2, - 0x51, 0x04, 0xc8, 0x73, 0xe2, 0x64, 0x35, 0x72, 0xfc, 0x98, 0x91, 0x5f, 0x75, 0xdb, 0x44, 0x0c, - 0xf0, 0xff, 0xdf, 0xdf, 0x8c, 0xa1, 0x4f, 0x4c, 0x3f, 0x72, 0x77, 0x77, 0x1c, 0x2d, 0x74, 0x51, - 0xc2, 0x39, 0xd4, 0xed, 0xaf, 0x58, 0xf0, 0x48, 0xbe, 0x2d, 0x86, 0x9e, 0x82, 0x01, 0xbe, 0xe5, - 0x13, 0x6f, 0xa7, 0x3f, 0x09, 0x6b, 0xc5, 0x02, 0x8a, 0x26, 0xa1, 0xae, 0xf4, 0x84, 0x78, 0xc7, - 0x53, 0x02, 0xb5, 0xae, 0x95, 0x8b, 0xc6, 0xa1, 0x83, 0x46, 0xff, 0x08, 0xcb, 0x4d, 0x0d, 0x1a, - 0xdb, 0x24, 0x31, 0x88, 0xfd, 0x1f, 0x2d, 0x38, 0x61, 0xf4, 0xea, 0x3e, 0x98, 0xe6, 0x7e, 0xda, - 0x34, 0x9f, 0x2f, 0x6c, 0x3e, 0xf7, 0xb0, 0xcd, 0xbf, 0x60, 0xc1, 0x79, 0x03, 0x6b, 0xd1, 0x49, - 0x1a, 0x1b, 0x97, 0xb6, 0xc3, 0x88, 0xc4, 0x74, 0x3b, 0x8d, 0x1e, 0x37, 0xe4, 0xd6, 0xf4, 0x90, - 0xa0, 0x50, 0xbe, 0x46, 0x76, 0xb8, 0x10, 0x7b, 0x06, 0x6a, 0x7c, 0x72, 0x06, 0x91, 0x18, 0x71, - 0xf5, 0x6e, 0x4b, 0xa2, 0x1d, 0x2b, 0x0c, 0x64, 0xc3, 0x00, 0x13, 0x4e, 0x74, 0xb1, 0x52, 0x35, - 0x04, 0xf4, 0x23, 0xde, 0x64, 0x2d, 0x58, 0x40, 0xec, 0x38, 0xd5, 0x9d, 0xe5, 0x88, 0xb0, 0x8f, - 0xdb, 0xbc, 0xec, 0x12, 0xaf, 0x19, 0xd3, 0x6d, 0x83, 0xe3, 0xfb, 0x41, 0x22, 0x76, 0x00, 0xc6, - 0xb6, 0x61, 0x4a, 0x37, 0x63, 0x13, 0x87, 0x32, 0xf5, 0x9c, 0x35, 0xe2, 0xf1, 0x11, 0x15, 0x4c, - 0x17, 0x58, 0x0b, 0x16, 0x10, 0xfb, 0x6e, 0x89, 0x6d, 0x50, 0xd4, 0xd2, 0x27, 0xf7, 0x63, 0x77, - 0x1b, 0xa5, 0x64, 0xe5, 0x72, 0x71, 0x82, 0x8b, 0xf4, 0xde, 0xe1, 0xbe, 0x91, 0x11, 0x97, 0xb8, - 0x50, 0xae, 0x7b, 0xef, 0x72, 0x7f, 0xab, 0x04, 0xe3, 0xe9, 0x07, 0xba, 0xa4, 0x2d, 0xdd, 0x52, - 0x19, 0x8c, 0xb2, 0x4e, 0x0c, 0x03, 0x1f, 0x9b, 0x78, 0x3d, 0x04, 0x56, 0xe9, 0x38, 0x05, 0x96, - 0x29, 0x4f, 0xcb, 0xfb, 0xc8, 0xd3, 0xa7, 0xd4, 0xa8, 0x57, 0x32, 0x02, 0x2c, 0xad, 0x53, 0x2e, - 0x40, 0x25, 0x4e, 0x48, 0x38, 0x56, 0x4d, 0xcb, 0xa3, 0x95, 0x84, 0x84, 0x98, 0x41, 0xec, 0xff, - 0x5a, 0x82, 0x47, 0xd3, 0x63, 0xa8, 0x55, 0xc0, 0x07, 0x52, 0x2a, 0xe0, 0xdd, 0xa6, 0x0a, 0xb8, - 0xb7, 0x3b, 0xfe, 0xce, 0x1e, 0x8f, 0x7d, 0xcf, 0x68, 0x08, 0x34, 0x97, 0x19, 0xc5, 0xc9, 0xf4, - 0x28, 0xde, 0xdb, 0x1d, 0x7f, 0xbc, 0xc7, 0x3b, 0x66, 0x86, 0xf9, 0x29, 0x18, 0x88, 0x88, 0x13, - 0x07, 0xbe, 0x18, 0x68, 0xf5, 0x39, 0x30, 0x6b, 0xc5, 0x02, 0x6a, 0xff, 0xdb, 0x7a, 0x76, 0xb0, - 0xe7, 0xb8, 0x13, 0x2e, 0x88, 0x90, 0x0b, 0x15, 0x66, 0xd6, 0x73, 0xd1, 0x70, 0xed, 0x68, 0xcb, - 0x88, 0xaa, 0x01, 0x45, 0x7a, 0xba, 0x46, 0xbf, 0x1a, 0x6d, 0xc2, 0x8c, 0x05, 0xda, 0x86, 0x5a, - 0x43, 0x5a, 0xdb, 0xa5, 0x22, 0xfc, 0x52, 0xc2, 0xd6, 0xd6, 0x1c, 0x87, 0xa9, 0xbc, 0x56, 0x26, - 0xba, 0xe2, 0x86, 0x08, 0x94, 0x5b, 0x6e, 0x22, 0x3e, 0xeb, 0x11, 0xf7, 0x53, 0x73, 0xae, 0xf1, - 0x8a, 0x83, 0x54, 0x89, 0xcc, 0xb9, 0x09, 0xa6, 0xf4, 0xd1, 0x4f, 0x5b, 0x30, 0x14, 0x37, 0xda, - 0xcb, 0x51, 0xb0, 0xe5, 0x36, 0x49, 0x24, 0xac, 0xa9, 0x23, 0x8a, 0xa6, 0x95, 0x99, 0x45, 0x49, - 0x50, 0xf3, 0xe5, 0xfb, 0x5b, 0x0d, 0xc1, 0x26, 0x5f, 0xba, 0xcb, 0x78, 0x54, 0xbc, 0xfb, 0x2c, - 0x69, 0xb8, 0x54, 0xff, 0xc9, 0x4d, 0x15, 0x9b, 0x29, 0x47, 0xb6, 0x2e, 0x67, 0x3b, 0x8d, 0x4d, - 0xba, 0xde, 0x74, 0x87, 0xde, 0x79, 0x77, 0x77, 0xfc, 0xd1, 0x99, 0x7c, 0x9e, 0xb8, 0x57, 0x67, - 0xd8, 0x80, 0x85, 0x1d, 0xcf, 0xc3, 0xe4, 0xf5, 0x0e, 0x61, 0x2e, 0x93, 0x02, 0x06, 0x6c, 0x59, - 0x13, 0xcc, 0x0c, 0x98, 0x01, 0xc1, 0x26, 0x5f, 0xf4, 0x3a, 0x0c, 0xb4, 0x9d, 0x24, 0x72, 0xb7, - 0x85, 0x9f, 0xe4, 0x88, 0xf6, 0xfe, 0x22, 0xa3, 0xa5, 0x99, 0x33, 0x4d, 0xcd, 0x1b, 0xb1, 0x60, - 0x84, 0xda, 0x50, 0x6d, 0x93, 0xa8, 0x45, 0xc6, 0x6a, 0x45, 0xf8, 0x84, 0x17, 0x29, 0x29, 0xcd, - 0xb0, 0x4e, 0xad, 0x23, 0xd6, 0x86, 0x39, 0x17, 0xf4, 0x2a, 0xd4, 0x62, 0xe2, 0x91, 0x06, 0xb5, - 0x6f, 0xea, 0x8c, 0xe3, 0x7b, 0xfa, 0xb4, 0xf5, 0xa8, 0x61, 0xb1, 0x22, 0x1e, 0xe5, 0x0b, 0x4c, - 0xfe, 0xc3, 0x8a, 0x24, 0x1d, 0xc0, 0xd0, 0xeb, 0xb4, 0x5c, 0x7f, 0x0c, 0x8a, 0x18, 0xc0, 0x65, - 0x46, 0x2b, 0x33, 0x80, 0xbc, 0x11, 0x0b, 0x46, 0xf6, 0x9f, 0x58, 0x80, 0xd2, 0x42, 0xed, 0x3e, - 0x18, 0xb5, 0xaf, 0xa7, 0x8d, 0xda, 0x85, 0x22, 0xad, 0x8e, 0x1e, 0x76, 0xed, 0x6f, 0xd4, 0x21, - 0xa3, 0x0e, 0xae, 0x93, 0x38, 0x21, 0xcd, 0xb7, 0x45, 0xf8, 0xdb, 0x22, 0xfc, 0x6d, 0x11, 0xae, - 0x44, 0xf8, 0x5a, 0x46, 0x84, 0xbf, 0xdf, 0x58, 0xf5, 0xfa, 0x50, 0xf5, 0x35, 0x75, 0xea, 0x6a, - 0xf6, 0xc0, 0x40, 0xa0, 0x92, 0xe0, 0xea, 0xca, 0xd2, 0xf5, 0x5c, 0x99, 0xfd, 0x5a, 0x5a, 0x66, - 0x1f, 0x95, 0xc5, 0xff, 0x0b, 0x52, 0xfa, 0x5f, 0x5a, 0xf0, 0xae, 0xb4, 0xf4, 0x92, 0x33, 0x67, - 0xbe, 0xe5, 0x07, 0x11, 0x99, 0x75, 0xd7, 0xd7, 0x49, 0x44, 0xfc, 0x06, 0x89, 0x95, 0x17, 0xc3, - 0xea, 0xe5, 0xc5, 0x40, 0xcf, 0xc3, 0xf0, 0xed, 0x38, 0xf0, 0x97, 0x03, 0xd7, 0x17, 0x22, 0x88, - 0x6e, 0x84, 0x4f, 0xde, 0xdd, 0x1d, 0x1f, 0xa6, 0x23, 0x2a, 0xdb, 0x71, 0x0a, 0x0b, 0xcd, 0xc0, - 0xa9, 0xdb, 0xaf, 0x2f, 0x3b, 0x89, 0xe1, 0x0e, 0x90, 0x1b, 0x77, 0x76, 0x60, 0x71, 0xf5, 0xe5, - 0x0c, 0x10, 0x77, 0xe3, 0xdb, 0x7f, 0xa3, 0x04, 0xe7, 0x32, 0x2f, 0x12, 0x78, 0x5e, 0xd0, 0x49, - 0xe8, 0xa6, 0x06, 0xfd, 0x82, 0x05, 0x27, 0xdb, 0x69, 0x8f, 0x43, 0x2c, 0x1c, 0xbb, 0x1f, 0x2c, - 0x4c, 0x47, 0x64, 0x5c, 0x1a, 0xd3, 0x63, 0x62, 0x84, 0x4e, 0x66, 0x00, 0x31, 0xee, 0xea, 0x0b, - 0x7a, 0x15, 0xea, 0x6d, 0x67, 0xfb, 0x46, 0xd8, 0x74, 0x12, 0xb9, 0x9f, 0xec, 0xed, 0x06, 0xe8, - 0x24, 0xae, 0x37, 0xc1, 0x8f, 0xeb, 0x27, 0xe6, 0xfd, 0x64, 0x29, 0x5a, 0x49, 0x22, 0xd7, 0x6f, - 0x71, 0x77, 0xde, 0xa2, 0x24, 0x83, 0x35, 0x45, 0xfb, 0xab, 0x56, 0x56, 0x49, 0xa9, 0xd1, 0x89, - 0x9c, 0x84, 0xb4, 0x76, 0xd0, 0xc7, 0xa0, 0x4a, 0x37, 0x7e, 0x72, 0x54, 0x6e, 0x15, 0xa9, 0x39, - 0x8d, 0x2f, 0xa1, 0x95, 0x28, 0xfd, 0x17, 0x63, 0xce, 0xd4, 0xfe, 0x93, 0x5a, 0xd6, 0x58, 0x60, - 0x87, 0xb7, 0x17, 0x01, 0x5a, 0xc1, 0x2a, 0x69, 0x87, 0x1e, 0x1d, 0x16, 0x8b, 0x9d, 0x00, 0x28, - 0x5f, 0xc7, 0x9c, 0x82, 0x60, 0x03, 0x0b, 0xfd, 0x25, 0x0b, 0xa0, 0x25, 0xe7, 0xbc, 0x34, 0x04, - 0x6e, 0x14, 0xf9, 0x3a, 0x7a, 0x45, 0xe9, 0xbe, 0x28, 0x86, 0xd8, 0x60, 0x8e, 0x7e, 0xca, 0x82, - 0x5a, 0x22, 0xbb, 0xcf, 0x55, 0xe3, 0x6a, 0x91, 0x3d, 0x91, 0x2f, 0xad, 0x6d, 0x22, 0x35, 0x24, - 0x8a, 0x2f, 0xfa, 0x19, 0x0b, 0x20, 0xde, 0xf1, 0x1b, 0xcb, 0x81, 0xe7, 0x36, 0x76, 0x84, 0xc6, - 0xbc, 0x59, 0xa8, 0x3f, 0x46, 0x51, 0x9f, 0x1e, 0xa5, 0xa3, 0xa1, 0xff, 0x63, 0x83, 0x33, 0xfa, - 0x04, 0xd4, 0x62, 0x31, 0xdd, 0x84, 0x8e, 0x5c, 0x2d, 0xd6, 0x2b, 0xc4, 0x69, 0x0b, 0xf1, 0x2a, - 0xfe, 0x61, 0xc5, 0x13, 0xfd, 0x9c, 0x05, 0x27, 0xc2, 0xb4, 0x9f, 0x4f, 0xa8, 0xc3, 0xe2, 0x64, - 0x40, 0xc6, 0x8f, 0x38, 0x7d, 0xfa, 0xee, 0xee, 0xf8, 0x89, 0x4c, 0x23, 0xce, 0xf6, 0x82, 0x4a, - 0x40, 0x3d, 0x83, 0x97, 0x42, 0xee, 0x73, 0x1c, 0xd4, 0x12, 0x70, 0x2e, 0x0b, 0xc4, 0xdd, 0xf8, - 0x68, 0x19, 0xce, 0xd0, 0xde, 0xed, 0x70, 0xf3, 0x53, 0xaa, 0x97, 0x98, 0x29, 0xc3, 0xda, 0xf4, - 0x63, 0x62, 0x86, 0x30, 0xaf, 0x7e, 0x16, 0x07, 0xe7, 0x3e, 0x89, 0x7e, 0xd7, 0x82, 0xc7, 0x5c, - 0xa6, 0x06, 0x4c, 0x87, 0xb9, 0xd6, 0x08, 0xe2, 0x24, 0x96, 0x14, 0x2a, 0x2b, 0x7a, 0xa9, 0x9f, - 0xe9, 0xff, 0x4f, 0xbc, 0xc1, 0x63, 0xf3, 0x7b, 0x74, 0x09, 0xef, 0xd9, 0x61, 0xfb, 0x5b, 0xa5, - 0xd4, 0xb1, 0x86, 0xf2, 0x25, 0x32, 0xa9, 0xd1, 0x90, 0x6e, 0x1c, 0x29, 0x04, 0x0b, 0x95, 0x1a, - 0xca, 0x49, 0xa4, 0xa5, 0x86, 0x6a, 0x8a, 0xb1, 0xc1, 0x9c, 0xda, 0x96, 0xa7, 0x9c, 0xac, 0xc7, - 0x52, 0x08, 0xb2, 0x57, 0x8b, 0xec, 0x52, 0xf7, 0x21, 0xd4, 0x39, 0xd1, 0xb5, 0x53, 0x5d, 0x20, - 0xdc, 0xdd, 0x25, 0xfb, 0x5b, 0xe9, 0xa3, 0x14, 0x63, 0x0d, 0xf6, 0x71, 0x4c, 0xf4, 0x45, 0x0b, - 0x86, 0xa2, 0xc0, 0xf3, 0x5c, 0xbf, 0x45, 0xe5, 0x85, 0x50, 0x7a, 0x1f, 0x3e, 0x16, 0xbd, 0x23, - 0x04, 0x03, 0xb3, 0x50, 0xb1, 0xe6, 0x89, 0xcd, 0x0e, 0xd8, 0x7f, 0x6c, 0xc1, 0x58, 0x2f, 0xb9, - 0x86, 0x08, 0xbc, 0x53, 0x2e, 0x5a, 0x15, 0x24, 0xb1, 0xe4, 0xcf, 0x12, 0x8f, 0x28, 0xff, 0x71, - 0x6d, 0xfa, 0x49, 0xf1, 0x9a, 0xef, 0x5c, 0xee, 0x8d, 0x8a, 0xf7, 0xa2, 0x83, 0x5e, 0x81, 0x93, - 0xc6, 0x7b, 0xc5, 0x6a, 0x60, 0xea, 0xd3, 0x13, 0xd4, 0x90, 0x98, 0xca, 0xc0, 0xee, 0xed, 0x8e, - 0x3f, 0x92, 0x6d, 0x13, 0x82, 0xb7, 0x8b, 0x8e, 0xfd, 0xcb, 0xa5, 0xec, 0xd7, 0x52, 0x3a, 0xf3, - 0x2d, 0xab, 0x6b, 0x57, 0xfe, 0xc1, 0xe3, 0xd0, 0x53, 0x6c, 0xff, 0xae, 0xe2, 0x30, 0x7a, 0xe3, - 0x3c, 0xc0, 0x83, 0x5e, 0xfb, 0x5f, 0x57, 0x60, 0x8f, 0x9e, 0xf5, 0x61, 0x04, 0x1f, 0xf8, 0x74, - 0xf0, 0xf3, 0x96, 0x3a, 0x39, 0x2a, 0xb3, 0x45, 0xde, 0x3c, 0xae, 0xb1, 0xe7, 0xfb, 0x90, 0x98, - 0x07, 0x1b, 0x28, 0x6f, 0x74, 0xfa, 0x8c, 0x0a, 0x7d, 0xcd, 0x4a, 0x9f, 0x7d, 0xf1, 0xe8, 0x31, - 0xf7, 0xd8, 0xfa, 0x64, 0x1c, 0xa8, 0xf1, 0x8e, 0xe9, 0x63, 0x98, 0x5e, 0x47, 0x6d, 0x13, 0x00, - 0xeb, 0xae, 0xef, 0x78, 0xee, 0x1b, 0x74, 0x97, 0x51, 0x65, 0x8a, 0x92, 0x59, 0x1e, 0x97, 0x55, - 0x2b, 0x36, 0x30, 0xce, 0xff, 0x45, 0x18, 0x32, 0xde, 0x3c, 0x27, 0x46, 0xe2, 0x8c, 0x19, 0x23, - 0x51, 0x37, 0x42, 0x1b, 0xce, 0xbf, 0x1f, 0x4e, 0x66, 0x3b, 0x78, 0x90, 0xe7, 0xed, 0xff, 0x39, - 0x98, 0x3d, 0x8c, 0x5a, 0x25, 0x51, 0x9b, 0x76, 0xed, 0x6d, 0x07, 0xd1, 0xdb, 0x0e, 0xa2, 0xb7, - 0x1d, 0x44, 0xa6, 0x8f, 0x5f, 0x38, 0x3f, 0x06, 0xef, 0x93, 0xf3, 0x23, 0xe5, 0xce, 0xa9, 0x15, - 0xee, 0xce, 0xb1, 0xef, 0x56, 0x21, 0x65, 0x47, 0xf1, 0xf1, 0xfe, 0x21, 0x18, 0x8c, 0x48, 0x18, - 0xdc, 0xc0, 0x0b, 0x42, 0x87, 0xe8, 0x38, 0x78, 0xde, 0x8c, 0x25, 0x9c, 0xea, 0x9a, 0xd0, 0x49, - 0x36, 0x84, 0x12, 0x51, 0xba, 0x66, 0xd9, 0x49, 0x36, 0x30, 0x83, 0xa0, 0xf7, 0xc3, 0x68, 0xe2, - 0x44, 0x2d, 0x6a, 0x36, 0x6f, 0xb1, 0xcf, 0x2a, 0x8e, 0x2c, 0x1f, 0x11, 0xb8, 0xa3, 0xab, 0x29, - 0x28, 0xce, 0x60, 0xa3, 0xd7, 0xa1, 0xb2, 0x41, 0xbc, 0xb6, 0x18, 0xf2, 0x95, 0xe2, 0x64, 0x3c, - 0x7b, 0xd7, 0x2b, 0xc4, 0x6b, 0x73, 0x09, 0x44, 0x7f, 0x61, 0xc6, 0x8a, 0xce, 0xb7, 0xfa, 0x66, - 0x27, 0x4e, 0x82, 0xb6, 0xfb, 0x86, 0xf4, 0xd4, 0x7d, 0xb0, 0x60, 0xc6, 0xd7, 0x24, 0x7d, 0xee, - 0x12, 0x51, 0x7f, 0xb1, 0xe6, 0xcc, 0xfa, 0xd1, 0x74, 0x23, 0xf6, 0xa9, 0x76, 0x84, 0xc3, 0xad, - 0xe8, 0x7e, 0xcc, 0x4a, 0xfa, 0xbc, 0x1f, 0xea, 0x2f, 0xd6, 0x9c, 0xd1, 0x8e, 0x9a, 0xf7, 0x43, - 0xac, 0x0f, 0x37, 0x0a, 0xee, 0x03, 0x9f, 0xf3, 0xb9, 0xf3, 0xff, 0x49, 0xa8, 0x36, 0x36, 0x9c, - 0x28, 0x19, 0x1b, 0x66, 0x93, 0x46, 0xb9, 0x66, 0x66, 0x68, 0x23, 0xe6, 0x30, 0xf4, 0x38, 0x94, - 0x23, 0xb2, 0xce, 0xc2, 0x2f, 0x8d, 0xc0, 0x1c, 0x4c, 0xd6, 0x31, 0x6d, 0xb7, 0x7f, 0xb1, 0x94, - 0x36, 0x97, 0xd2, 0xef, 0xcd, 0x67, 0x7b, 0xa3, 0x13, 0xc5, 0xd2, 0x7d, 0x63, 0xcc, 0x76, 0xd6, - 0x8c, 0x25, 0x1c, 0x7d, 0xca, 0x82, 0xc1, 0xdb, 0x71, 0xe0, 0xfb, 0x24, 0x11, 0xaa, 0xe9, 0x66, - 0xc1, 0x43, 0x71, 0x95, 0x53, 0xd7, 0x7d, 0x10, 0x0d, 0x58, 0xf2, 0xa5, 0xdd, 0x25, 0xdb, 0x0d, - 0xaf, 0xd3, 0xec, 0x8a, 0xb5, 0xb8, 0xc4, 0x9b, 0xb1, 0x84, 0x53, 0x54, 0xd7, 0xe7, 0xa8, 0x95, - 0x34, 0xea, 0xbc, 0x2f, 0x50, 0x05, 0xdc, 0xfe, 0x6b, 0x03, 0x70, 0x36, 0x77, 0x71, 0x50, 0x43, - 0x86, 0x99, 0x0a, 0x97, 0x5d, 0x8f, 0xc8, 0x28, 0x23, 0x66, 0xc8, 0xdc, 0x54, 0xad, 0xd8, 0xc0, - 0x40, 0x3f, 0x09, 0x10, 0x3a, 0x91, 0xd3, 0x26, 0xca, 0xbd, 0x7a, 0x64, 0x7b, 0x81, 0xf6, 0x63, - 0x59, 0xd2, 0xd4, 0x7b, 0x53, 0xd5, 0x14, 0x63, 0x83, 0x25, 0x7a, 0x01, 0x86, 0x22, 0xe2, 0x11, - 0x27, 0x66, 0xd1, 0xbb, 0xd9, 0x54, 0x04, 0xac, 0x41, 0xd8, 0xc4, 0x43, 0x4f, 0xa9, 0x80, 0xac, - 0x4c, 0x60, 0x4a, 0x3a, 0x28, 0x0b, 0xbd, 0x69, 0xc1, 0xe8, 0xba, 0xeb, 0x11, 0xcd, 0x5d, 0x24, - 0x0e, 0x2c, 0x1d, 0xfd, 0x25, 0x2f, 0x9b, 0x74, 0xb5, 0x84, 0x4c, 0x35, 0xc7, 0x38, 0xc3, 0x9e, - 0x7e, 0xe6, 0x2d, 0x12, 0x31, 0xd1, 0x3a, 0x90, 0xfe, 0xcc, 0x37, 0x79, 0x33, 0x96, 0x70, 0x34, - 0x05, 0x27, 0x42, 0x27, 0x8e, 0x67, 0x22, 0xd2, 0x24, 0x7e, 0xe2, 0x3a, 0x1e, 0x0f, 0xeb, 0xaf, - 0xe9, 0xb0, 0xde, 0xe5, 0x34, 0x18, 0x67, 0xf1, 0xd1, 0x87, 0xe0, 0x51, 0xee, 0xbf, 0x58, 0x74, - 0xe3, 0xd8, 0xf5, 0x5b, 0x7a, 0x1a, 0x08, 0x37, 0xce, 0xb8, 0x20, 0xf5, 0xe8, 0x7c, 0x3e, 0x1a, - 0xee, 0xf5, 0x3c, 0x7a, 0x06, 0x6a, 0xf1, 0xa6, 0x1b, 0xce, 0x44, 0xcd, 0x98, 0x9d, 0x5d, 0xd4, - 0xb4, 0xd3, 0x70, 0x45, 0xb4, 0x63, 0x85, 0x81, 0x1a, 0x30, 0xcc, 0x3f, 0x09, 0x8f, 0x28, 0x13, - 0xf2, 0xf1, 0xd9, 0x9e, 0xea, 0x51, 0x64, 0x9e, 0x4d, 0x60, 0xe7, 0xce, 0x25, 0x79, 0x92, 0xc2, - 0x1d, 0xff, 0x37, 0x0d, 0x32, 0x38, 0x45, 0xd4, 0xfe, 0xf9, 0x52, 0x7a, 0xc7, 0x6d, 0x2e, 0x52, - 0x14, 0xd3, 0xa5, 0x98, 0xdc, 0x74, 0x22, 0xe9, 0x8d, 0x39, 0x62, 0xf6, 0x81, 0xa0, 0x7b, 0xd3, - 0x89, 0xcc, 0x45, 0xcd, 0x18, 0x60, 0xc9, 0x09, 0xdd, 0x86, 0x4a, 0xe2, 0x39, 0x05, 0xa5, 0x2b, - 0x19, 0x1c, 0xb5, 0x03, 0x64, 0x61, 0x2a, 0xc6, 0x8c, 0x07, 0x7a, 0x8c, 0x5a, 0xfd, 0x6b, 0xf2, - 0xa4, 0x43, 0x18, 0xea, 0x6b, 0x31, 0x66, 0xad, 0xf6, 0xaf, 0x40, 0x8e, 0x5c, 0x55, 0x8a, 0x0c, - 0x5d, 0x04, 0xa0, 0x1b, 0xc8, 0xe5, 0x88, 0xac, 0xbb, 0xdb, 0xc2, 0x90, 0x50, 0x6b, 0xf7, 0xba, - 0x82, 0x60, 0x03, 0x4b, 0x3e, 0xb3, 0xd2, 0x59, 0xa7, 0xcf, 0x94, 0xba, 0x9f, 0xe1, 0x10, 0x6c, - 0x60, 0xa1, 0xe7, 0x61, 0xc0, 0x6d, 0x3b, 0x2d, 0x15, 0x49, 0xf9, 0x18, 0x5d, 0xb4, 0xf3, 0xac, - 0xe5, 0xde, 0xee, 0xf8, 0xa8, 0xea, 0x10, 0x6b, 0xc2, 0x02, 0x17, 0xfd, 0xb2, 0x05, 0xc3, 0x8d, - 0xa0, 0xdd, 0x0e, 0x7c, 0xbe, 0xed, 0x12, 0x7b, 0xc8, 0xdb, 0xc7, 0xa5, 0xe6, 0x27, 0x66, 0x0c, - 0x66, 0x7c, 0x13, 0xa9, 0xf2, 0xaa, 0x4c, 0x10, 0x4e, 0xf5, 0xca, 0x5c, 0xdb, 0xd5, 0x7d, 0xd6, - 0xf6, 0xaf, 0x5b, 0x70, 0x8a, 0x3f, 0x6b, 0xec, 0x06, 0x45, 0x0a, 0x51, 0x70, 0xcc, 0xaf, 0xd5, - 0xb5, 0x41, 0x56, 0x5e, 0xba, 0x2e, 0x38, 0xee, 0xee, 0x24, 0x9a, 0x83, 0x53, 0xeb, 0x41, 0xd4, - 0x20, 0xe6, 0x40, 0x08, 0xc1, 0xa4, 0x08, 0x5d, 0xce, 0x22, 0xe0, 0xee, 0x67, 0xd0, 0x4d, 0x78, - 0xc4, 0x68, 0x34, 0xc7, 0x81, 0xcb, 0xa6, 0x27, 0x04, 0xb5, 0x47, 0x2e, 0xe7, 0x62, 0xe1, 0x1e, - 0x4f, 0xa7, 0x1d, 0x26, 0xf5, 0x3e, 0x1c, 0x26, 0xaf, 0xc1, 0xb9, 0x46, 0xf7, 0xc8, 0x6c, 0xc5, - 0x9d, 0xb5, 0x98, 0x4b, 0xaa, 0xda, 0xf4, 0x0f, 0x08, 0x02, 0xe7, 0x66, 0x7a, 0x21, 0xe2, 0xde, - 0x34, 0xd0, 0xc7, 0xa0, 0x16, 0x11, 0xf6, 0x55, 0x62, 0x91, 0x4f, 0x73, 0xc4, 0x5d, 0xb2, 0xb6, - 0x40, 0x39, 0x59, 0x2d, 0x7b, 0x45, 0x43, 0x8c, 0x15, 0x47, 0x74, 0x07, 0x06, 0x43, 0x27, 0x69, - 0x6c, 0x88, 0x2c, 0x9a, 0x23, 0x87, 0xb1, 0x28, 0xe6, 0xcb, 0x94, 0xaa, 0x9e, 0xe4, 0xcb, 0x9c, - 0x09, 0x96, 0xdc, 0xa8, 0x35, 0xd2, 0x08, 0xda, 0x61, 0xe0, 0x13, 0x3f, 0x89, 0xc7, 0x46, 0xb4, - 0x35, 0x32, 0xa3, 0x5a, 0xb1, 0x81, 0x71, 0xfe, 0x03, 0x70, 0xaa, 0x6b, 0xe1, 0x1d, 0xc8, 0xb9, - 0x32, 0x0b, 0x8f, 0xe4, 0x4f, 0xf1, 0x03, 0xb9, 0x58, 0xfe, 0x51, 0x26, 0x56, 0xd5, 0x30, 0x7b, - 0xfb, 0x70, 0xd7, 0x39, 0x50, 0x26, 0xfe, 0x96, 0x90, 0xf8, 0x97, 0x8f, 0x36, 0xd2, 0x97, 0xfc, - 0x2d, 0xbe, 0x42, 0x99, 0x4f, 0xe2, 0x92, 0xbf, 0x85, 0x29, 0x6d, 0xf4, 0x65, 0x2b, 0x65, 0xb6, - 0x71, 0x27, 0xdf, 0x47, 0x8e, 0xc5, 0xce, 0xef, 0xdb, 0x92, 0xb3, 0xff, 0x4d, 0x09, 0x2e, 0xec, - 0x47, 0xa4, 0x8f, 0xe1, 0x7b, 0x12, 0x06, 0x62, 0x76, 0xfa, 0x2c, 0x44, 0xe8, 0x10, 0x9d, 0x59, - 0xfc, 0x3c, 0xfa, 0x35, 0x2c, 0x40, 0xc8, 0x83, 0x72, 0xdb, 0x09, 0x85, 0xef, 0x67, 0xfe, 0xa8, - 0xd9, 0x2b, 0xf4, 0xbf, 0xe3, 0x2d, 0x3a, 0x21, 0xf7, 0x28, 0x18, 0x0d, 0x98, 0xb2, 0x41, 0x09, - 0x54, 0x9d, 0x28, 0x72, 0xe4, 0x51, 0xe7, 0xb5, 0x62, 0xf8, 0x4d, 0x51, 0x92, 0xd3, 0xa7, 0xee, - 0xee, 0x8e, 0x8f, 0xa4, 0x9a, 0x30, 0x67, 0x66, 0x7f, 0x7e, 0x30, 0x95, 0xc1, 0xc1, 0xce, 0xaf, - 0x63, 0x18, 0x10, 0x2e, 0x1f, 0xab, 0xe8, 0xa4, 0x21, 0x9e, 0x82, 0xc7, 0x76, 0x75, 0x22, 0x91, - 0x59, 0xb0, 0x42, 0x9f, 0xb3, 0x58, 0xba, 0xb0, 0xcc, 0x6a, 0x11, 0x7b, 0xa9, 0xe3, 0xc9, 0x5e, - 0x36, 0x93, 0x90, 0x65, 0x23, 0x36, 0xb9, 0x53, 0x1d, 0x1b, 0xf2, 0xc4, 0xb7, 0xec, 0x8e, 0x4a, - 0x26, 0x14, 0x4b, 0x38, 0xda, 0xce, 0x39, 0xa7, 0x2e, 0x20, 0xe5, 0xb4, 0x8f, 0x93, 0xe9, 0xaf, - 0x59, 0x70, 0xca, 0xcd, 0x1e, 0x38, 0x8a, 0x9d, 0xc7, 0x11, 0x23, 0x21, 0x7a, 0x9f, 0x67, 0x2a, - 0xe5, 0xdb, 0x05, 0xc2, 0xdd, 0x9d, 0x41, 0x4d, 0xa8, 0xb8, 0xfe, 0x7a, 0x20, 0x4c, 0x8e, 0xe9, - 0xa3, 0x75, 0x6a, 0xde, 0x5f, 0x0f, 0xf4, 0x6a, 0xa6, 0xff, 0x30, 0xa3, 0x8e, 0x16, 0xe0, 0x4c, - 0x24, 0x7c, 0x43, 0x57, 0xdc, 0x98, 0xee, 0xe0, 0x17, 0xdc, 0xb6, 0x9b, 0x30, 0x73, 0xa1, 0x3c, - 0x3d, 0x76, 0x77, 0x77, 0xfc, 0x0c, 0xce, 0x81, 0xe3, 0xdc, 0xa7, 0xd0, 0x1b, 0x30, 0x28, 0xf3, - 0x9b, 0x6b, 0x45, 0xec, 0xe2, 0xba, 0xe7, 0xbf, 0x9a, 0x4c, 0x2b, 0x22, 0x95, 0x59, 0x32, 0xb4, - 0xdf, 0x1c, 0x82, 0xee, 0x43, 0x4c, 0xf4, 0x71, 0xa8, 0x47, 0x2a, 0xe7, 0xda, 0x2a, 0x42, 0xb9, - 0xca, 0xef, 0x2b, 0x0e, 0x50, 0x95, 0xe1, 0xa2, 0xb3, 0xab, 0x35, 0x47, 0xba, 0xbd, 0x88, 0xf5, - 0x59, 0x67, 0x01, 0x73, 0x5b, 0x70, 0xd5, 0xe7, 0x58, 0x3b, 0x7e, 0x03, 0x33, 0x1e, 0x28, 0x82, - 0x81, 0x0d, 0xe2, 0x78, 0xc9, 0x46, 0x31, 0x2e, 0xf7, 0x2b, 0x8c, 0x56, 0x36, 0xf3, 0x86, 0xb7, - 0x62, 0xc1, 0x09, 0x6d, 0xc3, 0xe0, 0x06, 0x9f, 0x00, 0xc2, 0xe2, 0x5f, 0x3c, 0xea, 0xe0, 0xa6, - 0x66, 0x95, 0xfe, 0xdc, 0xa2, 0x01, 0x4b, 0x76, 0x2c, 0xc8, 0xc5, 0x38, 0xbf, 0xe7, 0x4b, 0xb7, - 0xb8, 0xa4, 0xa3, 0xfe, 0x0f, 0xef, 0x3f, 0x0a, 0xc3, 0x11, 0x69, 0x04, 0x7e, 0xc3, 0xf5, 0x48, - 0x73, 0x4a, 0xba, 0xd3, 0x0f, 0x92, 0xaa, 0xc2, 0x76, 0xcd, 0xd8, 0xa0, 0x81, 0x53, 0x14, 0xd1, - 0x67, 0x2d, 0x18, 0x55, 0x89, 0x9a, 0xf4, 0x83, 0x10, 0xe1, 0xbe, 0x5d, 0x28, 0x28, 0x2d, 0x94, - 0xd1, 0x9c, 0x46, 0x77, 0x77, 0xc7, 0x47, 0xd3, 0x6d, 0x38, 0xc3, 0x17, 0xbd, 0x02, 0x10, 0xac, - 0xf1, 0x48, 0x96, 0xa9, 0x44, 0xf8, 0x72, 0x0f, 0xf2, 0xaa, 0xa3, 0x3c, 0x67, 0x4d, 0x52, 0xc0, - 0x06, 0x35, 0x74, 0x0d, 0x80, 0x2f, 0x9b, 0xd5, 0x9d, 0x50, 0x6e, 0x0b, 0x64, 0xae, 0x11, 0xac, - 0x28, 0xc8, 0xbd, 0xdd, 0xf1, 0x6e, 0xdf, 0x1a, 0x0b, 0x33, 0x30, 0x1e, 0x47, 0x3f, 0x01, 0x83, - 0x71, 0xa7, 0xdd, 0x76, 0x94, 0xa7, 0xb7, 0xc0, 0x2c, 0x38, 0x4e, 0xd7, 0x10, 0x45, 0xbc, 0x01, - 0x4b, 0x8e, 0xe8, 0x36, 0x15, 0xaa, 0xb1, 0x70, 0xfa, 0xb1, 0x55, 0xc4, 0x6d, 0x82, 0x21, 0xf6, - 0x4e, 0xef, 0x95, 0x81, 0x39, 0x38, 0x07, 0xe7, 0xde, 0xee, 0xf8, 0x23, 0xe9, 0xf6, 0x85, 0x40, - 0xe4, 0xa5, 0xe5, 0xd2, 0x44, 0x57, 0x65, 0xb9, 0x13, 0xfa, 0xda, 0x32, 0x0b, 0xff, 0x69, 0x5d, - 0xee, 0x84, 0x35, 0xf7, 0x1e, 0x33, 0xf3, 0x61, 0xb4, 0x08, 0xa7, 0x1b, 0x81, 0x9f, 0x44, 0x81, - 0xe7, 0xf1, 0x1a, 0x3e, 0x7c, 0x87, 0xc6, 0x3d, 0xc1, 0xef, 0x14, 0xdd, 0x3e, 0x3d, 0xd3, 0x8d, - 0x82, 0xf3, 0x9e, 0xb3, 0xfd, 0x74, 0x88, 0x9f, 0x18, 0x9c, 0xe7, 0x61, 0x98, 0x6c, 0x27, 0x24, - 0xf2, 0x1d, 0xef, 0x06, 0x5e, 0x90, 0x3e, 0x50, 0xb6, 0x06, 0x2e, 0x19, 0xed, 0x38, 0x85, 0x85, - 0x6c, 0xe5, 0x96, 0x30, 0x72, 0x2d, 0xb9, 0x5b, 0x42, 0x3a, 0x21, 0xec, 0xff, 0x55, 0x4a, 0x19, - 0x64, 0xab, 0x11, 0x21, 0x28, 0x80, 0xaa, 0x1f, 0x34, 0x95, 0xec, 0xbf, 0x5a, 0x8c, 0xec, 0xbf, - 0x1e, 0x34, 0x8d, 0x9a, 0x28, 0xf4, 0x5f, 0x8c, 0x39, 0x1f, 0x56, 0x34, 0x42, 0x56, 0xd7, 0x60, - 0x00, 0xb1, 0xd1, 0x28, 0x92, 0xb3, 0x2a, 0x1a, 0xb1, 0x64, 0x32, 0xc2, 0x69, 0xbe, 0x68, 0x13, - 0xaa, 0x1b, 0x41, 0x9c, 0xc8, 0xed, 0xc7, 0x11, 0x77, 0x3a, 0x57, 0x82, 0x38, 0x61, 0x56, 0x84, - 0x7a, 0x6d, 0xda, 0x12, 0x63, 0xce, 0xc3, 0xfe, 0xcf, 0x56, 0xca, 0xe3, 0x7d, 0x8b, 0x85, 0xbb, - 0x6e, 0x11, 0x9f, 0x2e, 0x6b, 0x33, 0x30, 0xe8, 0x2f, 0x64, 0x92, 0x07, 0xdf, 0xd5, 0xab, 0x42, - 0xd5, 0x1d, 0x4a, 0x61, 0x82, 0x91, 0x30, 0x62, 0x88, 0x3e, 0x69, 0xa5, 0xd3, 0x38, 0x4b, 0x45, - 0x6c, 0x30, 0xcc, 0x54, 0xe6, 0x7d, 0x33, 0x42, 0xed, 0x2f, 0x5b, 0x30, 0x38, 0xed, 0x34, 0x36, - 0x83, 0xf5, 0x75, 0xf4, 0x0c, 0xd4, 0x9a, 0x9d, 0xc8, 0xcc, 0x28, 0x55, 0xdb, 0xfc, 0x59, 0xd1, - 0x8e, 0x15, 0x06, 0x9d, 0xc3, 0xeb, 0x4e, 0x43, 0x26, 0x34, 0x97, 0xf9, 0x1c, 0xbe, 0xcc, 0x5a, - 0xb0, 0x80, 0xa0, 0x17, 0x60, 0xa8, 0xed, 0x6c, 0xcb, 0x87, 0xb3, 0xee, 0xf6, 0x45, 0x0d, 0xc2, - 0x26, 0x9e, 0xfd, 0x2f, 0x2c, 0x18, 0x9b, 0x76, 0x62, 0xb7, 0x31, 0xd5, 0x49, 0x36, 0xa6, 0xdd, - 0x64, 0xad, 0xd3, 0xd8, 0x24, 0x09, 0xcf, 0x62, 0xa7, 0xbd, 0xec, 0xc4, 0x74, 0x29, 0xa9, 0x7d, - 0x9d, 0xea, 0xe5, 0x0d, 0xd1, 0x8e, 0x15, 0x06, 0x7a, 0x03, 0x86, 0x42, 0x27, 0x8e, 0xef, 0x04, - 0x51, 0x13, 0x93, 0xf5, 0x62, 0x6a, 0x48, 0xac, 0x90, 0x46, 0x44, 0x12, 0x4c, 0xd6, 0xc5, 0x91, - 0xb0, 0xa6, 0x8f, 0x4d, 0x66, 0xf6, 0x17, 0x2d, 0x38, 0x37, 0x4d, 0x9c, 0x88, 0x44, 0xac, 0xe4, - 0x84, 0x7a, 0x91, 0x19, 0x2f, 0xe8, 0x34, 0xd1, 0xeb, 0x50, 0x4b, 0x68, 0x33, 0xed, 0x96, 0x55, - 0x6c, 0xb7, 0xd8, 0x89, 0xee, 0xaa, 0x20, 0x8e, 0x15, 0x1b, 0xfb, 0xaf, 0x5b, 0x30, 0xcc, 0x0e, - 0xc7, 0x66, 0x49, 0xe2, 0xb8, 0x5e, 0x57, 0x65, 0x26, 0xab, 0xcf, 0xca, 0x4c, 0x17, 0xa0, 0xb2, - 0x11, 0xb4, 0x49, 0xf6, 0x60, 0xf7, 0x4a, 0x40, 0xb7, 0xd5, 0x14, 0x82, 0x9e, 0xa3, 0x1f, 0xde, - 0xf5, 0x13, 0x87, 0x2e, 0x01, 0xe9, 0x7c, 0x3d, 0xc1, 0x3f, 0xba, 0x6a, 0xc6, 0x26, 0x8e, 0xfd, - 0x5b, 0x75, 0x18, 0x14, 0xa7, 0xff, 0x7d, 0x57, 0x32, 0x90, 0xfb, 0xfb, 0x52, 0xcf, 0xfd, 0x7d, - 0x0c, 0x03, 0x0d, 0x56, 0xf7, 0x4d, 0x98, 0x91, 0xd7, 0x0a, 0x09, 0x17, 0xe1, 0xa5, 0xe4, 0x74, - 0xb7, 0xf8, 0x7f, 0x2c, 0x58, 0xa1, 0x2f, 0x59, 0x70, 0xa2, 0x11, 0xf8, 0x3e, 0x69, 0x68, 0x1b, - 0xa7, 0x52, 0x44, 0x54, 0xc0, 0x4c, 0x9a, 0xa8, 0x3e, 0x99, 0xc9, 0x00, 0x70, 0x96, 0x3d, 0x7a, - 0x09, 0x46, 0xf8, 0x98, 0xdd, 0x4c, 0x79, 0x8c, 0x75, 0xc1, 0x1e, 0x13, 0x88, 0xd3, 0xb8, 0x68, - 0x82, 0x7b, 0xde, 0x45, 0x69, 0x9c, 0x01, 0xed, 0x58, 0x33, 0x8a, 0xe2, 0x18, 0x18, 0x28, 0x02, - 0x14, 0x91, 0xf5, 0x88, 0xc4, 0x1b, 0x22, 0x3a, 0x82, 0xd9, 0x57, 0x83, 0x87, 0xcb, 0x7a, 0xc6, - 0x5d, 0x94, 0x70, 0x0e, 0x75, 0xb4, 0x29, 0x36, 0x98, 0xb5, 0x22, 0x64, 0xa8, 0xf8, 0xcc, 0x3d, - 0xf7, 0x99, 0xe3, 0x50, 0x8d, 0x37, 0x9c, 0xa8, 0xc9, 0xec, 0xba, 0x32, 0xcf, 0xb4, 0x59, 0xa1, - 0x0d, 0x98, 0xb7, 0xa3, 0x59, 0x38, 0x99, 0x29, 0x37, 0x14, 0x0b, 0xcf, 0xae, 0xca, 0xaa, 0xc8, - 0x14, 0x2a, 0x8a, 0x71, 0xd7, 0x13, 0xa6, 0xf3, 0x61, 0x68, 0x1f, 0xe7, 0xc3, 0x8e, 0x8a, 0xc1, - 0xe3, 0x3e, 0xd7, 0x97, 0x0b, 0x19, 0x80, 0xbe, 0x02, 0xee, 0xbe, 0x90, 0x09, 0xb8, 0x1b, 0x61, - 0x1d, 0xb8, 0x59, 0x4c, 0x07, 0x0e, 0x1e, 0x5d, 0xf7, 0x20, 0xa3, 0xe5, 0xfe, 0xdc, 0x02, 0xf9, - 0x5d, 0x67, 0x9c, 0xc6, 0x06, 0xa1, 0x53, 0x06, 0xbd, 0x1f, 0x46, 0xd5, 0x16, 0x7a, 0x26, 0xe8, - 0xf8, 0x3c, 0x50, 0xae, 0xac, 0x8f, 0x70, 0x71, 0x0a, 0x8a, 0x33, 0xd8, 0x68, 0x12, 0xea, 0x74, - 0x9c, 0xf8, 0xa3, 0x5c, 0xd7, 0xaa, 0x6d, 0xfa, 0xd4, 0xf2, 0xbc, 0x78, 0x4a, 0xe3, 0xa0, 0x00, - 0x4e, 0x79, 0x4e, 0x9c, 0xb0, 0x1e, 0xd0, 0x1d, 0xf5, 0x21, 0x6b, 0x0e, 0xb0, 0xd0, 0xfd, 0x85, - 0x2c, 0x21, 0xdc, 0x4d, 0xdb, 0xfe, 0x76, 0x05, 0x46, 0x52, 0x92, 0xf1, 0x80, 0x4a, 0xfa, 0x19, - 0xa8, 0x49, 0xbd, 0x99, 0xad, 0x8e, 0xa2, 0x94, 0xab, 0xc2, 0xa0, 0x4a, 0x6b, 0x4d, 0x6b, 0xd5, - 0xac, 0x51, 0x61, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x9c, 0x78, 0xf1, 0x8c, 0xe7, 0x12, 0x3f, - 0xe1, 0xdd, 0x2c, 0x46, 0x28, 0xaf, 0x2e, 0xac, 0x98, 0x44, 0xb5, 0x50, 0xce, 0x00, 0x70, 0x96, - 0x3d, 0xfa, 0x8c, 0x05, 0x23, 0xce, 0x9d, 0x58, 0x17, 0x27, 0x15, 0xa1, 0x75, 0x47, 0x54, 0x52, - 0xa9, 0x7a, 0xa7, 0xdc, 0xe5, 0x9b, 0x6a, 0xc2, 0x69, 0xa6, 0xe8, 0x2d, 0x0b, 0x10, 0xd9, 0x26, - 0x0d, 0x19, 0xfc, 0x27, 0xfa, 0x32, 0x50, 0xc4, 0x4e, 0xf3, 0x52, 0x17, 0x5d, 0x2e, 0xd5, 0xbb, - 0xdb, 0x71, 0x4e, 0x1f, 0xec, 0x7f, 0x5a, 0x56, 0x0b, 0x4a, 0xc7, 0x9b, 0x3a, 0x46, 0xdc, 0x9b, - 0x75, 0xf8, 0xb8, 0x37, 0x1d, 0x3f, 0xd0, 0x9d, 0xca, 0x98, 0xca, 0x7c, 0x2a, 0x3d, 0xa0, 0xcc, - 0xa7, 0x9f, 0xb2, 0x52, 0x75, 0x80, 0x86, 0x2e, 0xbe, 0x52, 0x6c, 0xac, 0xeb, 0x04, 0x8f, 0x6d, - 0xc8, 0x48, 0xf7, 0x74, 0x48, 0x0b, 0x95, 0xa6, 0x06, 0xda, 0x81, 0xa4, 0xe1, 0xbf, 0x2f, 0xc3, - 0x90, 0xa1, 0x49, 0x73, 0xcd, 0x22, 0xeb, 0x21, 0x33, 0x8b, 0x4a, 0x07, 0x30, 0x8b, 0x7e, 0x12, - 0xea, 0x0d, 0x29, 0xe5, 0x8b, 0xa9, 0x84, 0x9b, 0xd5, 0x1d, 0x5a, 0xd0, 0xab, 0x26, 0xac, 0x79, - 0xa2, 0xb9, 0x54, 0xa2, 0x8d, 0xd0, 0x10, 0x15, 0xa6, 0x21, 0xf2, 0x32, 0x61, 0x84, 0xa6, 0xe8, - 0x7e, 0x86, 0x95, 0x8b, 0x0a, 0x5d, 0xf1, 0x5e, 0x32, 0x22, 0x9d, 0x97, 0x8b, 0x5a, 0x9e, 0x97, - 0xcd, 0xd8, 0xc4, 0xb1, 0xbf, 0x6d, 0xa9, 0x8f, 0x7b, 0x1f, 0x0a, 0x23, 0xdc, 0x4e, 0x17, 0x46, - 0xb8, 0x54, 0xc8, 0x30, 0xf7, 0xa8, 0x88, 0x70, 0x1d, 0x06, 0x67, 0x82, 0x76, 0xdb, 0xf1, 0x9b, - 0xe8, 0x07, 0x61, 0xb0, 0xc1, 0x7f, 0x0a, 0xc7, 0x0e, 0x3b, 0x1e, 0x14, 0x50, 0x2c, 0x61, 0xe8, - 0x31, 0xa8, 0x38, 0x51, 0x4b, 0x3a, 0x73, 0x58, 0x28, 0xcc, 0x54, 0xd4, 0x8a, 0x31, 0x6b, 0xb5, - 0xff, 0x61, 0x05, 0xd8, 0x09, 0xb4, 0x13, 0x91, 0xe6, 0x6a, 0xc0, 0x2a, 0xf1, 0x1d, 0xeb, 0xa1, - 0x9a, 0xde, 0x2c, 0x3d, 0xcc, 0x07, 0x6b, 0xc6, 0xe1, 0x4a, 0xf9, 0x3e, 0x1f, 0xae, 0xf4, 0x38, - 0x2f, 0xab, 0x3c, 0x44, 0xe7, 0x65, 0xf6, 0xe7, 0x2d, 0x40, 0x2a, 0x6c, 0x41, 0x1f, 0x68, 0x4f, - 0x42, 0x5d, 0x05, 0x30, 0x08, 0xc3, 0x4a, 0x8b, 0x08, 0x09, 0xc0, 0x1a, 0xa7, 0x8f, 0x1d, 0xf2, - 0x93, 0x52, 0x7e, 0x97, 0xd3, 0x51, 0xb4, 0x4c, 0xea, 0x0b, 0x71, 0x6e, 0xff, 0x76, 0x09, 0x1e, - 0xe1, 0x2a, 0x79, 0xd1, 0xf1, 0x9d, 0x16, 0x69, 0xd3, 0x5e, 0xf5, 0x1b, 0xa2, 0xd0, 0xa0, 0x5b, - 0x33, 0x57, 0x46, 0xc5, 0x1e, 0x75, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, 0xbc, 0xef, 0x26, 0x98, - 0x11, 0x47, 0x31, 0xd4, 0x64, 0xe9, 0x77, 0x21, 0x8b, 0x0b, 0x62, 0xa4, 0xc4, 0x92, 0xd0, 0x9b, - 0x04, 0x2b, 0x46, 0xd4, 0x70, 0xf5, 0x82, 0xc6, 0x26, 0x26, 0x61, 0xc0, 0xe4, 0xae, 0x11, 0x94, - 0xb8, 0x20, 0xda, 0xb1, 0xc2, 0xb0, 0x7f, 0xdb, 0x82, 0xac, 0x46, 0x32, 0x4a, 0x9e, 0x59, 0x7b, - 0x96, 0x3c, 0x3b, 0x40, 0xcd, 0xb1, 0x1f, 0x87, 0x21, 0x27, 0xa1, 0x46, 0x04, 0xdf, 0x76, 0x97, - 0x0f, 0x77, 0xac, 0xb1, 0x18, 0x34, 0xdd, 0x75, 0x97, 0x6d, 0xb7, 0x4d, 0x72, 0xf6, 0x7f, 0xaf, - 0xc0, 0xa9, 0xae, 0xdc, 0x0d, 0xf4, 0x22, 0x0c, 0x37, 0xc4, 0xf4, 0x08, 0xa5, 0x43, 0xab, 0x6e, - 0x06, 0xb1, 0x69, 0x18, 0x4e, 0x61, 0xf6, 0x31, 0x41, 0xe7, 0xe1, 0x74, 0x44, 0x37, 0xfa, 0x1d, - 0x32, 0xb5, 0x9e, 0x90, 0x68, 0x85, 0x34, 0x02, 0xbf, 0xc9, 0x0b, 0xf3, 0x95, 0xa7, 0x1f, 0xbd, - 0xbb, 0x3b, 0x7e, 0x1a, 0x77, 0x83, 0x71, 0xde, 0x33, 0x28, 0x84, 0x11, 0xcf, 0xb4, 0x01, 0xc5, - 0x06, 0xe0, 0x50, 0xe6, 0xa3, 0xb2, 0x11, 0x52, 0xcd, 0x38, 0xcd, 0x20, 0x6d, 0x48, 0x56, 0x1f, - 0x90, 0x21, 0xf9, 0x69, 0x6d, 0x48, 0xf2, 0xf3, 0xf7, 0x0f, 0x17, 0x9c, 0xbb, 0x73, 0xdc, 0x96, - 0xe4, 0xcb, 0x50, 0x93, 0xb1, 0x49, 0x7d, 0xc5, 0xf4, 0x98, 0x74, 0x7a, 0x48, 0xb4, 0x7b, 0x25, - 0xc8, 0xd9, 0x84, 0xd0, 0x75, 0xa6, 0x35, 0x7e, 0x6a, 0x9d, 0x1d, 0x4c, 0xeb, 0xa3, 0x6d, 0x1e, - 0x97, 0xc5, 0x75, 0xdb, 0x87, 0x8a, 0xde, 0x44, 0xe9, 0x50, 0x2d, 0x95, 0xd2, 0xa0, 0xc2, 0xb5, - 0x2e, 0x02, 0x68, 0x43, 0x4d, 0x04, 0xac, 0xab, 0x63, 0x5f, 0x6d, 0xcf, 0x61, 0x03, 0x8b, 0xee, - 0xa9, 0x5d, 0x3f, 0x4e, 0x1c, 0xcf, 0xbb, 0xe2, 0xfa, 0x89, 0x70, 0x0e, 0x2a, 0x25, 0x3e, 0xaf, - 0x41, 0xd8, 0xc4, 0x3b, 0xff, 0x5e, 0xe3, 0xbb, 0x1c, 0xe4, 0x7b, 0x6e, 0xc0, 0xb9, 0x39, 0x37, - 0x51, 0x69, 0x16, 0x6a, 0x1e, 0x51, 0x3b, 0x4c, 0xa5, 0x0d, 0x59, 0x3d, 0xd3, 0x86, 0x8c, 0x34, - 0x87, 0x52, 0x3a, 0x2b, 0x23, 0x9b, 0xe6, 0x60, 0xbf, 0x08, 0x67, 0xe6, 0xdc, 0xe4, 0xb2, 0xeb, - 0x91, 0x03, 0x32, 0xb1, 0x7f, 0x73, 0x00, 0x86, 0xcd, 0x44, 0xbd, 0x83, 0x64, 0x3e, 0x7d, 0x91, - 0x9a, 0x5a, 0xe2, 0xed, 0x5c, 0x75, 0x68, 0x76, 0xeb, 0xc8, 0x59, 0x83, 0xf9, 0x23, 0x66, 0x58, - 0x5b, 0x9a, 0x27, 0x36, 0x3b, 0x80, 0xee, 0x40, 0x75, 0x9d, 0x85, 0xe1, 0x97, 0x8b, 0x88, 0x2c, - 0xc8, 0x1b, 0x51, 0xbd, 0xcc, 0x78, 0x20, 0x3f, 0xe7, 0x47, 0x35, 0x64, 0x94, 0xce, 0xed, 0x32, - 0x42, 0x47, 0x45, 0x56, 0x97, 0xc2, 0xe8, 0x25, 0xea, 0xab, 0x87, 0x10, 0xf5, 0x29, 0xc1, 0x3b, - 0xf0, 0x80, 0x04, 0x2f, 0x4b, 0xa9, 0x48, 0x36, 0x98, 0xfd, 0x26, 0x62, 0xdd, 0x07, 0xd9, 0x20, - 0x18, 0x29, 0x15, 0x29, 0x30, 0xce, 0xe2, 0xa3, 0x4f, 0x28, 0xd1, 0x5d, 0x2b, 0xc2, 0xaf, 0x6a, - 0xce, 0xe8, 0xe3, 0x96, 0xda, 0x9f, 0x2f, 0xc1, 0xe8, 0x9c, 0xdf, 0x59, 0x9e, 0x5b, 0xee, 0xac, - 0x79, 0x6e, 0xe3, 0x1a, 0xd9, 0xa1, 0xa2, 0x79, 0x93, 0xec, 0xcc, 0xcf, 0x8a, 0x15, 0xa4, 0xe6, - 0xcc, 0x35, 0xda, 0x88, 0x39, 0x8c, 0x0a, 0xa3, 0x75, 0xd7, 0x6f, 0x91, 0x28, 0x8c, 0x5c, 0xe1, - 0xf2, 0x34, 0x84, 0xd1, 0x65, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, 0xf1, 0x49, 0x94, 0x35, - 0x64, 0x97, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x94, 0x44, 0x9d, 0x38, 0x11, 0x93, 0x51, 0x21, 0xad, - 0xd2, 0x46, 0xcc, 0x61, 0x74, 0xa5, 0xc7, 0x9d, 0x35, 0x16, 0xb8, 0x91, 0x09, 0xac, 0x5f, 0xe1, - 0xcd, 0x58, 0xc2, 0x29, 0xea, 0x26, 0xd9, 0x99, 0xa5, 0xbb, 0xde, 0x4c, 0x7e, 0xcd, 0x35, 0xde, - 0x8c, 0x25, 0x9c, 0x55, 0x14, 0x4c, 0x0f, 0xc7, 0xf7, 0x5c, 0x45, 0xc1, 0x74, 0xf7, 0x7b, 0xec, - 0x9f, 0x7f, 0xc9, 0x82, 0x61, 0x33, 0xdc, 0x0a, 0xb5, 0x32, 0x36, 0xee, 0x52, 0x57, 0x41, 0xda, - 0x1f, 0xcd, 0xbb, 0xa1, 0xab, 0xe5, 0x26, 0x41, 0x18, 0x3f, 0x4b, 0xfc, 0x96, 0xeb, 0x13, 0x76, - 0x8a, 0xce, 0xc3, 0xb4, 0x52, 0xb1, 0x5c, 0x33, 0x41, 0x93, 0x1c, 0xc2, 0x48, 0xb6, 0x6f, 0xc1, - 0xa9, 0xae, 0xa4, 0xaa, 0x3e, 0x4c, 0x8b, 0x7d, 0x53, 0x5a, 0x6d, 0x0c, 0x43, 0x94, 0xb0, 0xac, - 0x6a, 0x33, 0x03, 0xa7, 0xf8, 0x42, 0xa2, 0x9c, 0x56, 0x1a, 0x1b, 0xa4, 0xad, 0x12, 0xe5, 0x98, - 0x7f, 0xfd, 0x66, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x2f, 0x58, 0x30, 0x92, 0xca, 0x73, 0x2b, 0xc8, - 0x08, 0x62, 0x2b, 0x2d, 0x60, 0xd1, 0x7f, 0x2c, 0x04, 0xba, 0xcc, 0x94, 0xa9, 0x5e, 0x69, 0x1a, - 0x84, 0x4d, 0x3c, 0xfb, 0xcb, 0x25, 0xa8, 0xc9, 0x08, 0x8a, 0x3e, 0xba, 0xf2, 0x39, 0x0b, 0x46, - 0xd4, 0x99, 0x06, 0x73, 0x96, 0x95, 0x8a, 0x48, 0x4a, 0xa0, 0x3d, 0x50, 0xdb, 0x6d, 0x7f, 0x3d, - 0xd0, 0x16, 0x39, 0x36, 0x99, 0xe1, 0x34, 0x6f, 0x74, 0x13, 0x20, 0xde, 0x89, 0x13, 0xd2, 0x36, - 0xdc, 0x76, 0xb6, 0xb1, 0xe2, 0x26, 0x1a, 0x41, 0x44, 0xe8, 0xfa, 0xba, 0x1e, 0x34, 0xc9, 0x8a, - 0xc2, 0xd4, 0x26, 0x94, 0x6e, 0xc3, 0x06, 0x25, 0xfb, 0xef, 0x97, 0xe0, 0x64, 0xb6, 0x4b, 0xe8, - 0xc3, 0x30, 0x2c, 0xb9, 0x1b, 0xb7, 0x8d, 0xc9, 0xb0, 0x91, 0x61, 0x6c, 0xc0, 0xee, 0xed, 0x8e, - 0x8f, 0x77, 0xdf, 0xf6, 0x36, 0x61, 0xa2, 0xe0, 0x14, 0x31, 0x7e, 0xb0, 0x24, 0x4e, 0x40, 0xa7, - 0x77, 0xa6, 0xc2, 0x50, 0x9c, 0x0e, 0x19, 0x07, 0x4b, 0x26, 0x14, 0x67, 0xb0, 0xd1, 0x32, 0x9c, - 0x31, 0x5a, 0xae, 0x13, 0xb7, 0xb5, 0xb1, 0x16, 0x44, 0x72, 0x67, 0xf5, 0x98, 0x0e, 0xec, 0xea, - 0xc6, 0xc1, 0xb9, 0x4f, 0x52, 0x6d, 0xdf, 0x70, 0x42, 0xa7, 0xe1, 0x26, 0x3b, 0xc2, 0x0f, 0xa9, - 0x64, 0xd3, 0x8c, 0x68, 0xc7, 0x0a, 0xc3, 0x5e, 0x84, 0x4a, 0x9f, 0x33, 0xa8, 0x2f, 0x8b, 0xfe, - 0x65, 0xa8, 0x51, 0x72, 0xd2, 0xbc, 0x2b, 0x82, 0x64, 0x00, 0x35, 0x79, 0x61, 0x08, 0xb2, 0xa1, - 0xec, 0x3a, 0xf2, 0xec, 0x4e, 0xbd, 0xd6, 0x7c, 0x1c, 0x77, 0xd8, 0x26, 0x99, 0x02, 0xd1, 0x93, - 0x50, 0x26, 0xdb, 0x61, 0xf6, 0x90, 0xee, 0xd2, 0x76, 0xe8, 0x46, 0x24, 0xa6, 0x48, 0x64, 0x3b, - 0x44, 0xe7, 0xa1, 0xe4, 0x36, 0x85, 0x92, 0x02, 0x81, 0x53, 0x9a, 0x9f, 0xc5, 0x25, 0xb7, 0x69, - 0x6f, 0x43, 0x5d, 0xdd, 0x50, 0x82, 0x36, 0xa5, 0xec, 0xb6, 0x8a, 0x08, 0x79, 0x92, 0x74, 0x7b, - 0x48, 0xed, 0x0e, 0x80, 0x4e, 0xf8, 0x2b, 0x4a, 0xbe, 0x5c, 0x80, 0x4a, 0x23, 0x10, 0xc9, 0xc8, - 0x35, 0x4d, 0x86, 0x09, 0x6d, 0x06, 0xb1, 0x6f, 0xc1, 0xe8, 0x35, 0x3f, 0xb8, 0xc3, 0xca, 0xab, - 0xb3, 0x6a, 0x62, 0x94, 0xf0, 0x3a, 0xfd, 0x91, 0x35, 0x11, 0x18, 0x14, 0x73, 0x98, 0xaa, 0xcf, - 0x54, 0xea, 0x55, 0x9f, 0xc9, 0xfe, 0xa4, 0x05, 0xc3, 0x2a, 0x73, 0x68, 0x6e, 0x6b, 0x93, 0xd2, - 0x6d, 0x45, 0x41, 0x27, 0xcc, 0xd2, 0x65, 0x77, 0x08, 0x61, 0x0e, 0x33, 0x53, 0xea, 0x4a, 0xfb, - 0xa4, 0xd4, 0x5d, 0x80, 0xca, 0xa6, 0xeb, 0x37, 0xb3, 0x97, 0x62, 0x5c, 0x73, 0xfd, 0x26, 0x66, - 0x10, 0xda, 0x85, 0x93, 0xaa, 0x0b, 0x52, 0x21, 0xbc, 0x08, 0xc3, 0x6b, 0x1d, 0xd7, 0x6b, 0xca, - 0x32, 0x69, 0x19, 0x4f, 0xc9, 0xb4, 0x01, 0xc3, 0x29, 0x4c, 0xba, 0xaf, 0x5b, 0x73, 0x7d, 0x27, - 0xda, 0x59, 0xd6, 0x1a, 0x48, 0x09, 0xa5, 0x69, 0x05, 0xc1, 0x06, 0x96, 0xfd, 0x66, 0x19, 0x46, - 0xd3, 0xf9, 0x53, 0x7d, 0x6c, 0xaf, 0x9e, 0x84, 0x2a, 0x4b, 0xa9, 0xca, 0x7e, 0x5a, 0xf6, 0x3c, - 0xe6, 0x30, 0x14, 0xc3, 0x00, 0x2f, 0xc6, 0x50, 0xcc, 0x85, 0x32, 0xaa, 0x93, 0xca, 0xbf, 0xc2, - 0xe2, 0xc9, 0x44, 0xfd, 0x07, 0xc1, 0x0a, 0x7d, 0xc6, 0x82, 0xc1, 0x20, 0x34, 0xeb, 0xfa, 0x7c, - 0xa8, 0xc8, 0xdc, 0x32, 0x91, 0x2c, 0x23, 0x2c, 0x62, 0xf5, 0xe9, 0xe5, 0xe7, 0x90, 0xac, 0xcf, - 0xbf, 0x0f, 0x86, 0x4d, 0xcc, 0xfd, 0x8c, 0xe2, 0x9a, 0x69, 0x14, 0x7f, 0xce, 0x9c, 0x14, 0x22, - 0x7b, 0xae, 0x8f, 0xe5, 0x76, 0x03, 0xaa, 0x0d, 0x15, 0x00, 0x70, 0xa8, 0xe2, 0x9a, 0xaa, 0x3a, - 0x02, 0x3b, 0x04, 0xe2, 0xd4, 0xec, 0x6f, 0x5b, 0xc6, 0xfc, 0xc0, 0x24, 0x9e, 0x6f, 0xa2, 0x08, - 0xca, 0xad, 0xad, 0x4d, 0x61, 0x8a, 0x5e, 0x2d, 0x68, 0x78, 0xe7, 0xb6, 0x36, 0xf5, 0x1c, 0x37, - 0x5b, 0x31, 0x65, 0xd6, 0x87, 0x13, 0x30, 0x95, 0x64, 0x59, 0xde, 0x3f, 0xc9, 0xd2, 0x7e, 0xab, - 0x04, 0xa7, 0xba, 0x26, 0x15, 0x7a, 0x03, 0xaa, 0x11, 0x7d, 0x4b, 0xf1, 0x7a, 0x0b, 0x85, 0xa5, - 0x45, 0xc6, 0xf3, 0x4d, 0xad, 0x77, 0xd3, 0xed, 0x98, 0xb3, 0x44, 0x57, 0x01, 0xe9, 0x30, 0x15, - 0xe5, 0x81, 0xe4, 0xaf, 0x7c, 0x5e, 0x3c, 0x8a, 0xa6, 0xba, 0x30, 0x70, 0xce, 0x53, 0xe8, 0xa5, - 0xac, 0x23, 0xb3, 0x9c, 0x3e, 0xb7, 0xdc, 0xcb, 0x27, 0x69, 0xff, 0xb3, 0x12, 0x8c, 0xa4, 0xca, - 0x2c, 0x21, 0x0f, 0x6a, 0xc4, 0x63, 0x4e, 0x7d, 0xa9, 0x6c, 0x8e, 0x5a, 0x7c, 0x58, 0x29, 0xc8, - 0x4b, 0x82, 0x2e, 0x56, 0x1c, 0x1e, 0x8e, 0xc3, 0xf5, 0x17, 0x61, 0x58, 0x76, 0xe8, 0x43, 0x4e, - 0xdb, 0x13, 0x03, 0xa8, 0xe6, 0xe8, 0x25, 0x03, 0x86, 0x53, 0x98, 0xf6, 0xef, 0x94, 0x61, 0x8c, - 0x9f, 0x82, 0x34, 0xd5, 0xcc, 0x5b, 0x94, 0xfb, 0xad, 0xbf, 0xac, 0x8b, 0xa1, 0xf1, 0x81, 0x5c, - 0x3b, 0x6a, 0xad, 0xff, 0x7c, 0x46, 0x7d, 0x45, 0x66, 0xfd, 0x42, 0x26, 0x32, 0x8b, 0x9b, 0xdd, - 0xad, 0x63, 0xea, 0xd1, 0xf7, 0x56, 0xa8, 0xd6, 0xaf, 0x94, 0xe0, 0x44, 0xe6, 0x22, 0x05, 0xf4, - 0x66, 0xba, 0xf6, 0xae, 0x55, 0x84, 0xaf, 0x7c, 0xcf, 0xda, 0xfa, 0x07, 0xab, 0xc0, 0xfb, 0x80, - 0x96, 0x8a, 0xfd, 0xfb, 0x25, 0x18, 0x4d, 0xdf, 0x00, 0xf1, 0x10, 0x8e, 0xd4, 0xbb, 0xa1, 0xce, - 0x8a, 0x9c, 0xb3, 0x9b, 0x2d, 0xb9, 0x4b, 0x9e, 0xd7, 0x93, 0x96, 0x8d, 0x58, 0xc3, 0x1f, 0x8a, - 0xc2, 0xc6, 0xf6, 0xdf, 0xb5, 0xe0, 0x2c, 0x7f, 0xcb, 0xec, 0x3c, 0xfc, 0x2b, 0x79, 0xa3, 0xfb, - 0x6a, 0xb1, 0x1d, 0xcc, 0x14, 0xf1, 0xdb, 0x6f, 0x7c, 0xd9, 0x8d, 0x7a, 0xa2, 0xb7, 0xe9, 0xa9, - 0xf0, 0x10, 0x76, 0xf6, 0x40, 0x93, 0xc1, 0xfe, 0xfd, 0x32, 0xe8, 0x4b, 0x04, 0x91, 0x2b, 0x72, - 0x1c, 0x0b, 0x29, 0x66, 0xb8, 0xb2, 0xe3, 0x37, 0xf4, 0x75, 0x85, 0xb5, 0x4c, 0x8a, 0xe3, 0xcf, - 0x5a, 0x30, 0xe4, 0xfa, 0x6e, 0xe2, 0x3a, 0x6c, 0x1b, 0x5d, 0xcc, 0x05, 0x67, 0x8a, 0xdd, 0x3c, - 0xa7, 0x1c, 0x44, 0xe6, 0x39, 0x8e, 0x62, 0x86, 0x4d, 0xce, 0xe8, 0xa3, 0x22, 0x78, 0xba, 0x5c, - 0x58, 0x76, 0x6e, 0x2d, 0x13, 0x31, 0x1d, 0x52, 0xc3, 0x2b, 0x89, 0x0a, 0x4a, 0x6a, 0xc7, 0x94, - 0x94, 0xaa, 0x8b, 0xab, 0xaf, 0x73, 0xa6, 0xcd, 0x98, 0x33, 0xb2, 0x63, 0x40, 0xdd, 0x63, 0x71, - 0xc0, 0xc0, 0xd4, 0x49, 0xa8, 0x3b, 0x9d, 0x24, 0x68, 0xd3, 0x61, 0x12, 0x47, 0x4d, 0x3a, 0xf4, - 0x56, 0x02, 0xb0, 0xc6, 0xb1, 0xdf, 0xac, 0x42, 0x26, 0xe9, 0x10, 0x6d, 0x9b, 0x17, 0x60, 0x5a, - 0xc5, 0x5e, 0x80, 0xa9, 0x3a, 0x93, 0x77, 0x09, 0x26, 0x6a, 0x41, 0x35, 0xdc, 0x70, 0x62, 0x69, - 0x56, 0xbf, 0xac, 0xf6, 0x71, 0xb4, 0xf1, 0xde, 0xee, 0xf8, 0x8f, 0xf5, 0xe7, 0x75, 0xa5, 0x73, - 0x75, 0x92, 0x17, 0x1b, 0xd1, 0xac, 0x19, 0x0d, 0xcc, 0xe9, 0x1f, 0xe4, 0x8a, 0xb7, 0x4f, 0x89, - 0x6a, 0xee, 0x98, 0xc4, 0x1d, 0x2f, 0x11, 0xb3, 0xe1, 0xe5, 0x02, 0x57, 0x19, 0x27, 0xac, 0xd3, - 0xe5, 0xf9, 0x7f, 0x6c, 0x30, 0x45, 0x1f, 0x86, 0x7a, 0x9c, 0x38, 0x51, 0x72, 0xc8, 0x04, 0x57, - 0x35, 0xe8, 0x2b, 0x92, 0x08, 0xd6, 0xf4, 0xd0, 0x2b, 0xac, 0xb6, 0xab, 0x1b, 0x6f, 0x1c, 0x32, - 0xe7, 0x41, 0xd6, 0x81, 0x15, 0x14, 0xb0, 0x41, 0x0d, 0x5d, 0x04, 0x60, 0x73, 0x9b, 0x07, 0xfa, - 0xd5, 0x98, 0x97, 0x49, 0x89, 0x42, 0xac, 0x20, 0xd8, 0xc0, 0xb2, 0x7f, 0x18, 0xd2, 0xf5, 0x1e, - 0xd0, 0xb8, 0x2c, 0x2f, 0xc1, 0xbd, 0xd0, 0x2c, 0x77, 0x21, 0x55, 0x09, 0xe2, 0xd7, 0x2d, 0x30, - 0x8b, 0x52, 0xa0, 0xd7, 0x79, 0xf5, 0x0b, 0xab, 0x88, 0x93, 0x43, 0x83, 0xee, 0xc4, 0xa2, 0x13, - 0x66, 0x8e, 0xb0, 0x65, 0x09, 0x8c, 0xf3, 0xef, 0x85, 0x9a, 0x84, 0x1e, 0xc8, 0xa8, 0xfb, 0x04, - 0x9c, 0xce, 0x5e, 0x0f, 0x2e, 0x4e, 0x9d, 0xf6, 0x77, 0xfd, 0x48, 0x7f, 0x4e, 0xa9, 0x97, 0x3f, - 0xa7, 0x8f, 0x6b, 0x50, 0x7f, 0xc3, 0x82, 0x0b, 0xfb, 0xdd, 0x62, 0x8e, 0x1e, 0x83, 0xca, 0x1d, - 0x27, 0x92, 0x45, 0xb7, 0x99, 0xa0, 0xbc, 0xe5, 0x44, 0x3e, 0x66, 0xad, 0x68, 0x07, 0x06, 0x78, - 0x34, 0x98, 0xb0, 0xd6, 0x5f, 0x2e, 0xf6, 0x4e, 0xf5, 0x6b, 0xc4, 0xd8, 0x2e, 0xf0, 0x48, 0x34, - 0x2c, 0x18, 0xda, 0xdf, 0xb1, 0x00, 0x2d, 0x6d, 0x91, 0x28, 0x72, 0x9b, 0x46, 0xfc, 0x1a, 0xbb, - 0x15, 0xc5, 0xb8, 0xfd, 0xc4, 0x4c, 0x71, 0xcd, 0xdc, 0x8a, 0x62, 0xfc, 0xcb, 0xbf, 0x15, 0xa5, - 0x74, 0xb0, 0x5b, 0x51, 0xd0, 0x12, 0x9c, 0x6d, 0xf3, 0xed, 0x06, 0xbf, 0x69, 0x80, 0xef, 0x3d, - 0x54, 0x42, 0xd9, 0xb9, 0xbb, 0xbb, 0xe3, 0x67, 0x17, 0xf3, 0x10, 0x70, 0xfe, 0x73, 0xf6, 0x7b, - 0x01, 0xf1, 0xb0, 0xb5, 0x99, 0xbc, 0x18, 0xa4, 0x9e, 0xee, 0x17, 0xfb, 0xab, 0x55, 0x38, 0x91, - 0x29, 0xc9, 0x4a, 0xb7, 0x7a, 0xdd, 0x41, 0x4f, 0x47, 0xd6, 0xdf, 0xdd, 0xdd, 0xeb, 0x2b, 0x8c, - 0xca, 0x87, 0xaa, 0xeb, 0x87, 0x9d, 0xa4, 0x98, 0x1c, 0x52, 0xde, 0x89, 0x79, 0x4a, 0xd0, 0x70, - 0x17, 0xd3, 0xbf, 0x98, 0xb3, 0x29, 0x32, 0x28, 0x2b, 0x65, 0x8c, 0x57, 0x1e, 0x90, 0x3b, 0xe0, - 0x53, 0x3a, 0x44, 0xaa, 0x5a, 0x84, 0x63, 0x31, 0x33, 0x59, 0x8e, 0xfb, 0xa8, 0xfd, 0xd7, 0x4a, - 0x30, 0x64, 0x7c, 0x34, 0xf4, 0x8b, 0xe9, 0x92, 0x4d, 0x56, 0x71, 0xaf, 0xc4, 0xe8, 0x4f, 0xe8, - 0xa2, 0x4c, 0xfc, 0x95, 0x9e, 0xea, 0xae, 0xd6, 0x74, 0x6f, 0x77, 0xfc, 0x64, 0xa6, 0x1e, 0x53, - 0xaa, 0x82, 0xd3, 0xf9, 0x8f, 0xc3, 0x89, 0x0c, 0x99, 0x9c, 0x57, 0x5e, 0x4d, 0xdf, 0xfe, 0x7e, - 0x44, 0xb7, 0x94, 0x39, 0x64, 0xdf, 0xa0, 0x43, 0x26, 0xd2, 0xe8, 0x02, 0x8f, 0xf4, 0xe1, 0x83, - 0xcd, 0x64, 0xcb, 0x96, 0xfa, 0xcc, 0x96, 0x7d, 0x1a, 0x6a, 0x61, 0xe0, 0xb9, 0x0d, 0x57, 0x55, - 0x21, 0x64, 0xf9, 0xb9, 0xcb, 0xa2, 0x0d, 0x2b, 0x28, 0xba, 0x03, 0x75, 0x75, 0x51, 0xbe, 0xf0, - 0x6f, 0x17, 0x75, 0xe8, 0xa3, 0x8c, 0x16, 0x7d, 0x01, 0xbe, 0xe6, 0x85, 0x6c, 0x18, 0x60, 0x4a, - 0x50, 0x86, 0xfe, 0x33, 0xdf, 0x3b, 0xd3, 0x8e, 0x31, 0x16, 0x10, 0xfb, 0xeb, 0x75, 0x38, 0x93, - 0x57, 0x17, 0x1b, 0x7d, 0x0c, 0x06, 0x78, 0x1f, 0x8b, 0xb9, 0x7a, 0x21, 0x8f, 0xc7, 0x1c, 0x23, - 0x28, 0xba, 0xc5, 0x7e, 0x63, 0xc1, 0x53, 0x70, 0xf7, 0x9c, 0x35, 0x31, 0x43, 0x8e, 0x87, 0xfb, - 0x82, 0xa3, 0xb9, 0x2f, 0x38, 0x9c, 0xbb, 0xe7, 0xac, 0xa1, 0x6d, 0xa8, 0xb6, 0xdc, 0x84, 0x38, - 0xc2, 0x89, 0x70, 0xeb, 0x58, 0x98, 0x13, 0x87, 0x5b, 0x69, 0xec, 0x27, 0xe6, 0x0c, 0xd1, 0xd7, - 0x2c, 0x38, 0xb1, 0x96, 0x4e, 0x8d, 0x17, 0xc2, 0xd3, 0x39, 0x86, 0xda, 0xe7, 0x69, 0x46, 0xfc, - 0x5a, 0xa0, 0x4c, 0x23, 0xce, 0x76, 0x07, 0x7d, 0xda, 0x82, 0xc1, 0x75, 0xd7, 0x33, 0xca, 0xe0, - 0x1e, 0xc3, 0xc7, 0xb9, 0xcc, 0x18, 0xe8, 0x1d, 0x07, 0xff, 0x1f, 0x63, 0xc9, 0xb9, 0x97, 0xa6, - 0x1a, 0x38, 0xaa, 0xa6, 0x1a, 0x7c, 0x40, 0x9a, 0xea, 0xb3, 0x16, 0xd4, 0xd5, 0x48, 0x8b, 0x74, - 0xe7, 0x0f, 0x1f, 0xe3, 0x27, 0xe7, 0x9e, 0x13, 0xf5, 0x17, 0x6b, 0xe6, 0xe8, 0x4b, 0x16, 0x0c, - 0x39, 0x6f, 0x74, 0x22, 0xd2, 0x24, 0x5b, 0x41, 0x18, 0x8b, 0x3b, 0x05, 0x5f, 0x2d, 0xbe, 0x33, - 0x53, 0x94, 0xc9, 0x2c, 0xd9, 0x5a, 0x0a, 0x63, 0x91, 0x96, 0xa4, 0x1b, 0xb0, 0xd9, 0x05, 0x7b, - 0xb7, 0x04, 0xe3, 0xfb, 0x50, 0x40, 0x2f, 0xc2, 0x70, 0x10, 0xb5, 0x1c, 0xdf, 0x7d, 0xc3, 0xac, - 0x75, 0xa1, 0xac, 0xac, 0x25, 0x03, 0x86, 0x53, 0x98, 0x66, 0x42, 0x76, 0x69, 0x9f, 0x84, 0xec, - 0x0b, 0x50, 0x89, 0x48, 0x18, 0x64, 0x37, 0x0b, 0x2c, 0x25, 0x80, 0x41, 0xd0, 0xe3, 0x50, 0x76, - 0x42, 0x57, 0x04, 0xa2, 0xa9, 0x3d, 0xd0, 0xd4, 0xf2, 0x3c, 0xa6, 0xed, 0xa9, 0xfa, 0x10, 0xd5, - 0xfb, 0x52, 0x1f, 0x82, 0xaa, 0x01, 0x71, 0x76, 0x31, 0xa0, 0xd5, 0x40, 0xfa, 0x4c, 0xc1, 0x7e, - 0xab, 0x0c, 0x8f, 0xef, 0x39, 0x5f, 0x74, 0x1c, 0x9e, 0xb5, 0x47, 0x1c, 0x9e, 0x1c, 0x9e, 0xd2, - 0x7e, 0xc3, 0x53, 0xee, 0x31, 0x3c, 0x9f, 0xa6, 0xcb, 0x40, 0xd6, 0x08, 0x29, 0xe6, 0x56, 0xb8, - 0x5e, 0x25, 0x47, 0xc4, 0x0a, 0x90, 0x50, 0xac, 0xf9, 0xd2, 0x3d, 0x40, 0x2a, 0x19, 0xb9, 0x5a, - 0x84, 0x1a, 0xe8, 0x59, 0x33, 0x84, 0xcf, 0xfd, 0x5e, 0x19, 0xce, 0xf6, 0xcf, 0x95, 0xe0, 0xc9, - 0x3e, 0xa4, 0xb7, 0x39, 0x8b, 0xad, 0x3e, 0x67, 0xf1, 0xf7, 0xf6, 0x67, 0xb2, 0xff, 0xaa, 0x05, - 0xe7, 0x7b, 0x2b, 0x0f, 0xf4, 0x1c, 0x0c, 0xad, 0x45, 0x8e, 0xdf, 0xd8, 0x60, 0x37, 0x5d, 0xca, - 0x41, 0x61, 0x63, 0xad, 0x9b, 0xb1, 0x89, 0x43, 0xb7, 0xb7, 0x3c, 0x26, 0xc1, 0xc0, 0x90, 0xc9, - 0xa3, 0x74, 0x7b, 0xbb, 0x9a, 0x05, 0xe2, 0x6e, 0x7c, 0xfb, 0xcf, 0x4a, 0xf9, 0xdd, 0xe2, 0x46, - 0xc6, 0x41, 0xbe, 0x93, 0xf8, 0x0a, 0xa5, 0x3e, 0x64, 0x49, 0xf9, 0x7e, 0xcb, 0x92, 0x4a, 0x2f, - 0x59, 0x82, 0x66, 0xe1, 0xa4, 0x71, 0x85, 0x0a, 0x4f, 0x08, 0xe6, 0x01, 0xb7, 0xaa, 0x4a, 0xc6, - 0x72, 0x06, 0x8e, 0xbb, 0x9e, 0x40, 0xcf, 0x40, 0xcd, 0xf5, 0x63, 0xd2, 0xe8, 0x44, 0x3c, 0xd0, - 0xdb, 0x48, 0xc2, 0x9a, 0x17, 0xed, 0x58, 0x61, 0xd8, 0xbf, 0x54, 0x82, 0x73, 0x3d, 0xed, 0xac, - 0xfb, 0x24, 0xbb, 0xcc, 0xcf, 0x51, 0xb9, 0x3f, 0x9f, 0xc3, 0x1c, 0xa4, 0xea, 0xbe, 0x83, 0xf4, - 0x07, 0xbd, 0x27, 0x26, 0xb5, 0xb9, 0xbf, 0x6f, 0x47, 0xe9, 0x25, 0x18, 0x71, 0xc2, 0x90, 0xe3, - 0xb1, 0x78, 0xcd, 0x4c, 0x95, 0x9c, 0x29, 0x13, 0x88, 0xd3, 0xb8, 0x7d, 0x69, 0xcf, 0x3f, 0xb2, - 0xa0, 0x8e, 0xc9, 0x3a, 0x97, 0x0e, 0xe8, 0xb6, 0x18, 0x22, 0xab, 0x88, 0x7a, 0x9a, 0x74, 0x60, - 0x63, 0x97, 0xd5, 0x99, 0xcc, 0x1b, 0xec, 0xee, 0xab, 0x76, 0x4a, 0x07, 0xba, 0x6a, 0x47, 0x5d, - 0xb6, 0x52, 0xee, 0x7d, 0xd9, 0x8a, 0xfd, 0x8d, 0x41, 0xfa, 0x7a, 0x61, 0x30, 0x13, 0x91, 0x66, - 0x4c, 0xbf, 0x6f, 0x27, 0xf2, 0xc4, 0x24, 0x51, 0xdf, 0xf7, 0x06, 0x5e, 0xc0, 0xb4, 0x3d, 0x75, - 0x14, 0x53, 0x3a, 0x50, 0x8d, 0x90, 0xf2, 0xbe, 0x35, 0x42, 0x5e, 0x82, 0x91, 0x38, 0xde, 0x58, - 0x8e, 0xdc, 0x2d, 0x27, 0x21, 0xd7, 0xc8, 0x8e, 0xb0, 0xb2, 0x74, 0x5e, 0xff, 0xca, 0x15, 0x0d, - 0xc4, 0x69, 0x5c, 0x34, 0x07, 0xa7, 0x74, 0xa5, 0x0e, 0x12, 0x25, 0x2c, 0xba, 0x9f, 0xcf, 0x04, - 0x95, 0xc4, 0xab, 0x6b, 0x7b, 0x08, 0x04, 0xdc, 0xfd, 0x0c, 0x95, 0x6f, 0xa9, 0x46, 0xda, 0x91, - 0x81, 0xb4, 0x7c, 0x4b, 0xd1, 0xa1, 0x7d, 0xe9, 0x7a, 0x02, 0x2d, 0xc2, 0x69, 0x3e, 0x31, 0xa6, - 0xc2, 0xd0, 0x78, 0xa3, 0xc1, 0x74, 0x1d, 0xc3, 0xb9, 0x6e, 0x14, 0x9c, 0xf7, 0x1c, 0x7a, 0x01, - 0x86, 0x54, 0xf3, 0xfc, 0xac, 0x38, 0x45, 0x50, 0x5e, 0x0c, 0x45, 0x66, 0xbe, 0x89, 0x4d, 0x3c, - 0xf4, 0x21, 0x78, 0x54, 0xff, 0xe5, 0x29, 0x60, 0xfc, 0x68, 0x6d, 0x56, 0x14, 0x41, 0x52, 0x57, - 0x7b, 0xcc, 0xe5, 0xa2, 0x35, 0x71, 0xaf, 0xe7, 0xd1, 0x1a, 0x9c, 0x57, 0xa0, 0x4b, 0x7e, 0xc2, - 0xf2, 0x39, 0x62, 0x32, 0xed, 0xc4, 0xe4, 0x46, 0xe4, 0xb1, 0xb2, 0x49, 0x75, 0x7d, 0xeb, 0xe2, - 0x9c, 0x9b, 0x5c, 0xc9, 0xc3, 0xc4, 0x0b, 0x78, 0x0f, 0x2a, 0x68, 0x12, 0xea, 0xc4, 0x77, 0xd6, - 0x3c, 0xb2, 0x34, 0x33, 0xcf, 0x8a, 0x29, 0x19, 0x27, 0x79, 0x97, 0x24, 0x00, 0x6b, 0x1c, 0x15, - 0x61, 0x3a, 0xdc, 0xf3, 0x06, 0xd0, 0x65, 0x38, 0xd3, 0x6a, 0x84, 0xd4, 0xf6, 0x70, 0x1b, 0x64, - 0xaa, 0xc1, 0x02, 0xea, 0xe8, 0x87, 0xe1, 0x05, 0x26, 0x55, 0xf8, 0xf4, 0xdc, 0xcc, 0x72, 0x17, - 0x0e, 0xce, 0x7d, 0x92, 0x05, 0x5e, 0x46, 0xc1, 0xf6, 0xce, 0xd8, 0xe9, 0x4c, 0xe0, 0x25, 0x6d, - 0xc4, 0x1c, 0x86, 0xae, 0x02, 0x62, 0xb1, 0xf8, 0x57, 0x92, 0x24, 0x54, 0xc6, 0xce, 0xd8, 0x19, - 0xf6, 0x4a, 0x2a, 0x8c, 0xec, 0x72, 0x17, 0x06, 0xce, 0x79, 0xca, 0xfe, 0x0f, 0x16, 0x8c, 0xa8, - 0xf5, 0x7a, 0x1f, 0xb2, 0x51, 0xbc, 0x74, 0x36, 0xca, 0xdc, 0xd1, 0x25, 0x1e, 0xeb, 0x79, 0x8f, - 0x90, 0xe6, 0x9f, 0x1e, 0x02, 0xd0, 0x52, 0x51, 0x29, 0x24, 0xab, 0xa7, 0x42, 0x7a, 0x68, 0x25, - 0x52, 0x5e, 0xe5, 0x94, 0xea, 0x83, 0xad, 0x9c, 0xb2, 0x02, 0x67, 0xa5, 0xb9, 0xc0, 0xcf, 0x8a, - 0xae, 0x04, 0xb1, 0x12, 0x70, 0xb5, 0xe9, 0xc7, 0x05, 0xa1, 0xb3, 0xf3, 0x79, 0x48, 0x38, 0xff, - 0xd9, 0x94, 0x95, 0x32, 0xb8, 0x9f, 0x95, 0xa2, 0xd7, 0xf4, 0xc2, 0xba, 0xbc, 0xc3, 0x23, 0xb3, - 0xa6, 0x17, 0x2e, 0xaf, 0x60, 0x8d, 0x93, 0x2f, 0xd8, 0xeb, 0x05, 0x09, 0x76, 0x38, 0xb0, 0x60, - 0x97, 0x22, 0x66, 0xa8, 0xa7, 0x88, 0x91, 0x3e, 0xe9, 0xe1, 0x9e, 0x3e, 0xe9, 0xf7, 0xc3, 0xa8, - 0xeb, 0x6f, 0x90, 0xc8, 0x4d, 0x48, 0x93, 0xad, 0x05, 0x26, 0x7e, 0x6a, 0x5a, 0xad, 0xcf, 0xa7, - 0xa0, 0x38, 0x83, 0x9d, 0x96, 0x8b, 0xa3, 0x7d, 0xc8, 0xc5, 0x1e, 0xda, 0xe8, 0x44, 0x31, 0xda, - 0xe8, 0xe4, 0xd1, 0xb5, 0xd1, 0xa9, 0x63, 0xd5, 0x46, 0xa8, 0x10, 0x6d, 0xd4, 0x97, 0xa0, 0x37, - 0xb6, 0x7f, 0x67, 0xf6, 0xd9, 0xfe, 0xf5, 0x52, 0x45, 0x67, 0x0f, 0xad, 0x8a, 0xf2, 0xb5, 0xcc, - 0x23, 0x87, 0xd2, 0x32, 0x9f, 0x2d, 0xc1, 0x59, 0x2d, 0x87, 0xe9, 0xec, 0x77, 0xd7, 0xa9, 0x24, - 0x62, 0xd7, 0x40, 0xf1, 0x73, 0x1b, 0x23, 0x39, 0x4a, 0xe7, 0x59, 0x29, 0x08, 0x36, 0xb0, 0x58, - 0x8e, 0x11, 0x89, 0x58, 0x19, 0xdd, 0xac, 0x90, 0x9e, 0x11, 0xed, 0x58, 0x61, 0xd0, 0xf9, 0x45, - 0x7f, 0x8b, 0xbc, 0xcd, 0x6c, 0xb1, 0xb8, 0x19, 0x0d, 0xc2, 0x26, 0x1e, 0x7a, 0x9a, 0x33, 0x61, - 0x02, 0x82, 0x0a, 0xea, 0x61, 0x71, 0x2f, 0xac, 0x94, 0x09, 0x0a, 0x2a, 0xbb, 0xc3, 0x92, 0xc9, - 0xaa, 0xdd, 0xdd, 0x61, 0x21, 0x50, 0x0a, 0xc3, 0xfe, 0x1f, 0x16, 0x9c, 0xcb, 0x1d, 0x8a, 0xfb, - 0xa0, 0x7c, 0xb7, 0xd3, 0xca, 0x77, 0xa5, 0xa8, 0xed, 0x86, 0xf1, 0x16, 0x3d, 0x14, 0xf1, 0xbf, - 0xb3, 0x60, 0x54, 0xe3, 0xdf, 0x87, 0x57, 0x75, 0xd3, 0xaf, 0x5a, 0xdc, 0xce, 0xaa, 0xde, 0xf5, - 0x6e, 0xbf, 0x53, 0x02, 0x55, 0xc0, 0x71, 0xaa, 0x21, 0xcb, 0xe3, 0xee, 0x73, 0x92, 0xb8, 0x03, - 0x03, 0xec, 0x20, 0x34, 0x2e, 0x26, 0xc8, 0x23, 0xcd, 0x9f, 0x1d, 0xaa, 0xea, 0x43, 0x66, 0xf6, - 0x37, 0xc6, 0x82, 0x21, 0x2b, 0xf2, 0xec, 0xc6, 0x54, 0x9a, 0x37, 0x45, 0x5a, 0x96, 0x2e, 0xf2, - 0x2c, 0xda, 0xb1, 0xc2, 0xa0, 0xea, 0xc1, 0x6d, 0x04, 0xfe, 0x8c, 0xe7, 0xc4, 0xf2, 0xee, 0x43, - 0xa5, 0x1e, 0xe6, 0x25, 0x00, 0x6b, 0x1c, 0x76, 0x46, 0xea, 0xc6, 0xa1, 0xe7, 0xec, 0x18, 0xfb, - 0x67, 0xa3, 0x3e, 0x81, 0x02, 0x61, 0x13, 0xcf, 0x6e, 0xc3, 0x58, 0xfa, 0x25, 0x66, 0xc9, 0x3a, - 0x0b, 0x50, 0xec, 0x6b, 0x38, 0x27, 0xa1, 0xee, 0xb0, 0xa7, 0x16, 0x3a, 0x4e, 0xf6, 0xca, 0xf2, - 0x29, 0x09, 0xc0, 0x1a, 0xc7, 0xfe, 0x55, 0x0b, 0x4e, 0xe7, 0x0c, 0x5a, 0x81, 0x69, 0x6f, 0x89, - 0x96, 0x36, 0x79, 0x8a, 0xfd, 0x87, 0x60, 0xb0, 0x49, 0xd6, 0x1d, 0x19, 0x02, 0x67, 0xc8, 0xf6, - 0x59, 0xde, 0x8c, 0x25, 0xdc, 0xfe, 0x6f, 0x16, 0x9c, 0x48, 0xf7, 0x35, 0x66, 0xa9, 0x24, 0x7c, - 0x98, 0xdc, 0xb8, 0x11, 0x6c, 0x91, 0x68, 0x87, 0xbe, 0xb9, 0x95, 0x49, 0x25, 0xe9, 0xc2, 0xc0, - 0x39, 0x4f, 0xb1, 0xf2, 0xad, 0x4d, 0x35, 0xda, 0x72, 0x46, 0xde, 0x2c, 0x72, 0x46, 0xea, 0x8f, - 0x69, 0x1e, 0x97, 0x2b, 0x96, 0xd8, 0xe4, 0x6f, 0x7f, 0xa7, 0x02, 0x2a, 0x2f, 0x96, 0xc5, 0x1f, - 0x15, 0x14, 0xbd, 0x75, 0xd0, 0x0c, 0x22, 0x35, 0x19, 0x2a, 0x7b, 0x05, 0x04, 0x70, 0x2f, 0x89, - 0xe9, 0xba, 0x54, 0x6f, 0xb8, 0xaa, 0x41, 0xd8, 0xc4, 0xa3, 0x3d, 0xf1, 0xdc, 0x2d, 0xc2, 0x1f, - 0x1a, 0x48, 0xf7, 0x64, 0x41, 0x02, 0xb0, 0xc6, 0xa1, 0x3d, 0x69, 0xba, 0xeb, 0xeb, 0x62, 0xcb, - 0xaf, 0x7a, 0x42, 0x47, 0x07, 0x33, 0x08, 0xaf, 0xc8, 0x1d, 0x6c, 0x0a, 0x2b, 0xd8, 0xa8, 0xc8, - 0x1d, 0x6c, 0x62, 0x06, 0xa1, 0x76, 0x9b, 0x1f, 0x44, 0x6d, 0x76, 0xa5, 0x7c, 0x53, 0x71, 0x11, - 0xd6, 0xaf, 0xb2, 0xdb, 0xae, 0x77, 0xa3, 0xe0, 0xbc, 0xe7, 0xe8, 0x0c, 0x0c, 0x23, 0xd2, 0x74, - 0x1b, 0x89, 0x49, 0x0d, 0xd2, 0x33, 0x70, 0xb9, 0x0b, 0x03, 0xe7, 0x3c, 0x85, 0xa6, 0xe0, 0x84, - 0xcc, 0x6b, 0x96, 0x55, 0x6b, 0x86, 0xd2, 0x55, 0x32, 0x70, 0x1a, 0x8c, 0xb3, 0xf8, 0x54, 0xaa, - 0xb5, 0x45, 0xc1, 0x2a, 0x66, 0x2c, 0x1b, 0x52, 0x4d, 0x16, 0xb2, 0xc2, 0x0a, 0xc3, 0xfe, 0x54, - 0x99, 0x6a, 0xe1, 0x1e, 0x85, 0xda, 0xee, 0x5b, 0xb4, 0x60, 0x7a, 0x46, 0x56, 0xfa, 0x98, 0x91, - 0xcf, 0xc3, 0xf0, 0xed, 0x38, 0xf0, 0x55, 0x24, 0x5e, 0xb5, 0x67, 0x24, 0x9e, 0x81, 0x95, 0x1f, - 0x89, 0x37, 0x50, 0x54, 0x24, 0xde, 0xe0, 0x21, 0x23, 0xf1, 0xbe, 0x55, 0x05, 0x75, 0x35, 0xc8, - 0x75, 0x92, 0xdc, 0x09, 0xa2, 0x4d, 0xd7, 0x6f, 0xb1, 0x7c, 0xf0, 0xaf, 0x59, 0x30, 0xcc, 0xd7, - 0xcb, 0x82, 0x99, 0x49, 0xb5, 0x5e, 0xd0, 0x9d, 0x13, 0x29, 0x66, 0x13, 0xab, 0x06, 0xa3, 0xcc, - 0xd5, 0x9b, 0x26, 0x08, 0xa7, 0x7a, 0x84, 0x3e, 0x0e, 0x20, 0xfd, 0xa3, 0xeb, 0x52, 0x64, 0xce, - 0x17, 0xd3, 0x3f, 0x4c, 0xd6, 0xb5, 0x0d, 0xbc, 0xaa, 0x98, 0x60, 0x83, 0x21, 0xfa, 0xac, 0xce, - 0x32, 0xe3, 0x21, 0xfb, 0x1f, 0x3d, 0x96, 0xb1, 0xe9, 0x27, 0xc7, 0x0c, 0xc3, 0xa0, 0xeb, 0xb7, - 0xe8, 0x3c, 0x11, 0x11, 0x4b, 0xef, 0xca, 0xab, 0xa5, 0xb0, 0x10, 0x38, 0xcd, 0x69, 0xc7, 0x73, - 0xfc, 0x06, 0x89, 0xe6, 0x39, 0xba, 0x79, 0xe1, 0x34, 0x6b, 0xc0, 0x92, 0x50, 0xd7, 0xa5, 0x2a, - 0xd5, 0x7e, 0x2e, 0x55, 0x39, 0xff, 0x01, 0x38, 0xd5, 0xf5, 0x31, 0x0f, 0x94, 0x52, 0x76, 0xf8, - 0x6c, 0x34, 0xfb, 0x9f, 0x0f, 0x68, 0xa5, 0x75, 0x3d, 0x68, 0xf2, 0xab, 0x3d, 0x22, 0xfd, 0x45, - 0x85, 0x8d, 0x5b, 0xe0, 0x14, 0x31, 0x2e, 0xad, 0x56, 0x8d, 0xd8, 0x64, 0x49, 0xe7, 0x68, 0xe8, - 0x44, 0xc4, 0x3f, 0xee, 0x39, 0xba, 0xac, 0x98, 0x60, 0x83, 0x21, 0xda, 0x48, 0xe5, 0x94, 0x5c, - 0x3e, 0x7a, 0x4e, 0x09, 0xab, 0x32, 0x95, 0x57, 0x8d, 0xff, 0x4b, 0x16, 0x8c, 0xfa, 0xa9, 0x99, - 0x5b, 0x4c, 0x18, 0x69, 0xfe, 0xaa, 0xe0, 0x37, 0x4b, 0xa5, 0xdb, 0x70, 0x86, 0x7f, 0x9e, 0x4a, - 0xab, 0x1e, 0x50, 0xa5, 0xe9, 0x3b, 0x82, 0x06, 0x7a, 0xdd, 0x11, 0x84, 0x7c, 0x75, 0x49, 0xda, - 0x60, 0xe1, 0x97, 0xa4, 0x41, 0xce, 0x05, 0x69, 0xb7, 0xa0, 0xde, 0x88, 0x88, 0x93, 0x1c, 0xf2, - 0xbe, 0x2c, 0x76, 0x40, 0x3f, 0x23, 0x09, 0x60, 0x4d, 0xcb, 0xfe, 0xdf, 0x15, 0x38, 0x29, 0x47, - 0x44, 0x86, 0xa0, 0x53, 0xfd, 0xc8, 0xf9, 0x6a, 0xe3, 0x56, 0xe9, 0xc7, 0x2b, 0x12, 0x80, 0x35, - 0x0e, 0xb5, 0xc7, 0x3a, 0x31, 0x59, 0x0a, 0x89, 0xbf, 0xe0, 0xae, 0xc5, 0xe2, 0x9c, 0x53, 0x2d, - 0x94, 0x1b, 0x1a, 0x84, 0x4d, 0x3c, 0x6a, 0x8c, 0x73, 0xbb, 0x38, 0xce, 0xa6, 0xaf, 0x08, 0x7b, - 0x1b, 0x4b, 0x38, 0xfa, 0xf9, 0xdc, 0xca, 0xb1, 0xc5, 0x24, 0x6e, 0x75, 0x45, 0xde, 0x1f, 0xf0, - 0x8a, 0xc5, 0xbf, 0x6d, 0xc1, 0x59, 0xde, 0x2a, 0x47, 0xf2, 0x46, 0xd8, 0x74, 0x12, 0x12, 0x17, - 0x53, 0xc9, 0x3d, 0xa7, 0x7f, 0xda, 0xc9, 0x9b, 0xc7, 0x16, 0xe7, 0xf7, 0x06, 0xbd, 0x69, 0xc1, - 0x89, 0xcd, 0x54, 0xcd, 0x0f, 0xa9, 0x3a, 0x8e, 0x9a, 0x8e, 0x9f, 0x22, 0xaa, 0x97, 0x5a, 0xba, - 0x3d, 0xc6, 0x59, 0xee, 0xf6, 0x9f, 0x59, 0x60, 0x8a, 0xd1, 0xfb, 0x5f, 0x2a, 0xe4, 0xe0, 0xa6, - 0xa0, 0xb4, 0x2e, 0xab, 0x3d, 0xad, 0xcb, 0xc7, 0xa1, 0xdc, 0x71, 0x9b, 0x62, 0x7f, 0xa1, 0x4f, - 0x5f, 0xe7, 0x67, 0x31, 0x6d, 0xb7, 0xff, 0x49, 0x55, 0xfb, 0x2d, 0x44, 0x5e, 0xd4, 0xf7, 0xc5, - 0x6b, 0xaf, 0xab, 0x62, 0x63, 0xfc, 0xcd, 0xaf, 0x77, 0x15, 0x1b, 0xfb, 0x91, 0x83, 0xa7, 0xbd, - 0xf1, 0x01, 0xea, 0x55, 0x6b, 0x6c, 0x70, 0x9f, 0x9c, 0xb7, 0xdb, 0x50, 0xa3, 0x5b, 0x30, 0xe6, - 0x80, 0xac, 0xa5, 0x3a, 0x55, 0xbb, 0x22, 0xda, 0xef, 0xed, 0x8e, 0xbf, 0xef, 0xe0, 0xdd, 0x92, - 0x4f, 0x63, 0x45, 0x1f, 0xc5, 0x50, 0xa7, 0xbf, 0x59, 0x7a, 0x9e, 0xd8, 0xdc, 0xdd, 0x50, 0x32, - 0x53, 0x02, 0x0a, 0xc9, 0xfd, 0xd3, 0x7c, 0x90, 0x0f, 0x75, 0x76, 0x1b, 0x2d, 0x63, 0xca, 0xf7, - 0x80, 0xcb, 0x2a, 0x49, 0x4e, 0x02, 0xee, 0xed, 0x8e, 0xbf, 0x74, 0x70, 0xa6, 0xea, 0x71, 0xac, - 0x59, 0xd8, 0x5f, 0xae, 0xe8, 0xb9, 0x2b, 0x6a, 0xcc, 0x7d, 0x5f, 0xcc, 0xdd, 0x17, 0x33, 0x73, - 0xf7, 0x42, 0xd7, 0xdc, 0x1d, 0xd5, 0xb7, 0xa6, 0xa6, 0x66, 0xe3, 0xfd, 0x36, 0x04, 0xf6, 0xf7, - 0x37, 0x30, 0x0b, 0xe8, 0xf5, 0x8e, 0x1b, 0x91, 0x78, 0x39, 0xea, 0xf8, 0xae, 0xdf, 0x62, 0xd3, - 0xb1, 0x66, 0x5a, 0x40, 0x29, 0x30, 0xce, 0xe2, 0xd3, 0x4d, 0x3d, 0xfd, 0xe6, 0xb7, 0x9c, 0x2d, - 0x3e, 0xab, 0x8c, 0xb2, 0x5b, 0x2b, 0xa2, 0x1d, 0x2b, 0x0c, 0xfb, 0x1b, 0xec, 0x2c, 0xdb, 0xc8, - 0x0b, 0xa6, 0x73, 0xc2, 0x63, 0xd7, 0xff, 0xf2, 0x9a, 0x5d, 0x6a, 0x4e, 0xf0, 0x3b, 0x7f, 0x39, - 0x0c, 0xdd, 0x81, 0xc1, 0x35, 0x7e, 0xff, 0x5d, 0x31, 0xf5, 0xc9, 0xc5, 0x65, 0x7a, 0xec, 0x96, - 0x13, 0x79, 0xb3, 0xde, 0x3d, 0xfd, 0x13, 0x4b, 0x6e, 0xf6, 0x37, 0x2b, 0x70, 0x22, 0x73, 0x41, - 0x6c, 0xaa, 0x5a, 0x6a, 0x69, 0xdf, 0x6a, 0xa9, 0x1f, 0x01, 0x68, 0x92, 0xd0, 0x0b, 0x76, 0x98, - 0x39, 0x56, 0x39, 0xb0, 0x39, 0xa6, 0x2c, 0xf8, 0x59, 0x45, 0x05, 0x1b, 0x14, 0x45, 0xa1, 0x32, - 0x5e, 0x7c, 0x35, 0x53, 0xa8, 0xcc, 0xb8, 0xc5, 0x60, 0xe0, 0xfe, 0xde, 0x62, 0xe0, 0xc2, 0x09, - 0xde, 0x45, 0x95, 0x7d, 0x7b, 0x88, 0x24, 0x5b, 0x96, 0xbf, 0x30, 0x9b, 0x26, 0x83, 0xb3, 0x74, - 0x1f, 0xe4, 0xfd, 0xcf, 0xe8, 0xdd, 0x50, 0x97, 0xdf, 0x39, 0x1e, 0xab, 0xeb, 0x0a, 0x06, 0x72, - 0x1a, 0xb0, 0x7b, 0x99, 0xc5, 0x4f, 0xfb, 0x8b, 0x25, 0x6a, 0x3d, 0xf3, 0x7f, 0xaa, 0x12, 0xcd, - 0x53, 0x30, 0xe0, 0x74, 0x92, 0x8d, 0xa0, 0xeb, 0x0e, 0xbd, 0x29, 0xd6, 0x8a, 0x05, 0x14, 0x2d, - 0x40, 0xa5, 0xa9, 0xab, 0x8b, 0x1c, 0x64, 0x14, 0xb5, 0x23, 0xd2, 0x49, 0x08, 0x66, 0x54, 0xd0, - 0x63, 0x50, 0x49, 0x9c, 0x96, 0x4c, 0x74, 0x62, 0xc9, 0xad, 0xab, 0x4e, 0x2b, 0xc6, 0xac, 0xd5, - 0x54, 0x9a, 0x95, 0x7d, 0x94, 0xe6, 0x4b, 0x30, 0x12, 0xbb, 0x2d, 0xdf, 0x49, 0x3a, 0x11, 0x31, - 0x0e, 0xd7, 0x74, 0xbc, 0x84, 0x09, 0xc4, 0x69, 0x5c, 0xfb, 0x37, 0x87, 0xe1, 0xcc, 0xca, 0xcc, - 0xa2, 0xac, 0x99, 0x7d, 0x6c, 0xb9, 0x4a, 0x79, 0x3c, 0xee, 0x5f, 0xae, 0x52, 0x0f, 0xee, 0x9e, - 0x91, 0xab, 0xe4, 0x19, 0xb9, 0x4a, 0xe9, 0xc4, 0x91, 0x72, 0x11, 0x89, 0x23, 0x79, 0x3d, 0xe8, - 0x27, 0x71, 0xe4, 0xd8, 0x92, 0x97, 0xf6, 0xec, 0xd0, 0x81, 0x92, 0x97, 0x54, 0x66, 0x57, 0x21, - 0x21, 0xfd, 0x3d, 0x3e, 0x55, 0x6e, 0x66, 0x97, 0xca, 0xaa, 0xe1, 0xe9, 0x2a, 0x42, 0xc0, 0xbe, - 0x5a, 0x7c, 0x07, 0xfa, 0xc8, 0xaa, 0x11, 0x19, 0x33, 0x66, 0x26, 0xd7, 0x60, 0x11, 0x99, 0x5c, - 0x79, 0xdd, 0xd9, 0x37, 0x93, 0xeb, 0x25, 0x18, 0x69, 0x78, 0x81, 0x4f, 0x96, 0xa3, 0x20, 0x09, - 0x1a, 0x81, 0x27, 0x8c, 0x69, 0x25, 0x12, 0x66, 0x4c, 0x20, 0x4e, 0xe3, 0xf6, 0x4a, 0x03, 0xab, - 0x1f, 0x35, 0x0d, 0x0c, 0x1e, 0x50, 0x1a, 0xd8, 0xcf, 0xe8, 0x84, 0xe5, 0x21, 0xf6, 0x45, 0x3e, - 0x52, 0xfc, 0x17, 0xe9, 0x27, 0x6b, 0x19, 0xbd, 0xc5, 0x2f, 0xb1, 0xa3, 0xe6, 0xe8, 0x4c, 0xd0, - 0xa6, 0xe6, 0xd6, 0x30, 0x1b, 0x92, 0xd7, 0x8e, 0x61, 0xc2, 0xde, 0x5a, 0xd1, 0x6c, 0xd4, 0xc5, - 0x76, 0xba, 0x09, 0xa7, 0x3b, 0x72, 0x94, 0x84, 0xea, 0xaf, 0x96, 0xe0, 0x07, 0xf6, 0xed, 0x02, - 0xba, 0x03, 0x90, 0x38, 0x2d, 0x31, 0x51, 0xc5, 0x31, 0xc5, 0x11, 0x83, 0x1a, 0x57, 0x25, 0x3d, - 0x5e, 0x09, 0x44, 0xfd, 0x65, 0x07, 0x00, 0xf2, 0x37, 0x8b, 0x65, 0x0c, 0xbc, 0xae, 0x82, 0x89, - 0x38, 0xf0, 0x08, 0x66, 0x10, 0xaa, 0xfe, 0x23, 0xd2, 0xd2, 0xb7, 0x2e, 0xab, 0xcf, 0x87, 0x59, - 0x2b, 0x16, 0x50, 0xf4, 0x02, 0x0c, 0x39, 0x9e, 0xc7, 0xb3, 0x52, 0x48, 0x2c, 0x6e, 0xb1, 0xd1, - 0x95, 0xdb, 0x34, 0x08, 0x9b, 0x78, 0xf6, 0x9f, 0x96, 0x60, 0x7c, 0x1f, 0x99, 0xd2, 0x95, 0x67, - 0x57, 0xed, 0x3b, 0xcf, 0x4e, 0x64, 0x06, 0x0c, 0xf4, 0xc8, 0x0c, 0x78, 0x01, 0x86, 0x12, 0xe2, - 0xb4, 0x45, 0x18, 0x94, 0xd8, 0x7f, 0xeb, 0x73, 0x57, 0x0d, 0xc2, 0x26, 0x1e, 0x95, 0x62, 0xa3, - 0x4e, 0xa3, 0x41, 0xe2, 0x58, 0x86, 0xfe, 0x0b, 0x1f, 0x66, 0x61, 0x79, 0x05, 0xcc, 0x35, 0x3c, - 0x95, 0x62, 0x81, 0x33, 0x2c, 0xb3, 0x03, 0x5e, 0xef, 0x73, 0xc0, 0xbf, 0x5e, 0x82, 0xc7, 0xf7, - 0xd4, 0x6e, 0x7d, 0x67, 0x65, 0x74, 0x62, 0x12, 0x65, 0x27, 0xce, 0x8d, 0x98, 0x44, 0x98, 0x41, - 0xf8, 0x28, 0x85, 0xa1, 0x71, 0xab, 0x75, 0xd1, 0x29, 0x43, 0x7c, 0x94, 0x52, 0x2c, 0x70, 0x86, - 0xe5, 0x61, 0xa7, 0xe5, 0xdf, 0x2b, 0xc1, 0x93, 0x7d, 0xd8, 0x00, 0x05, 0xa6, 0x56, 0xa5, 0x13, - 0xdc, 0xca, 0x0f, 0x28, 0x0f, 0xf1, 0x90, 0xc3, 0xf5, 0x8d, 0x12, 0x9c, 0xef, 0xad, 0x8a, 0xd1, - 0x8f, 0xd2, 0x3d, 0xbc, 0x8c, 0x7d, 0x32, 0x73, 0xe3, 0x4e, 0xf3, 0xfd, 0x7b, 0x0a, 0x84, 0xb3, - 0xb8, 0x68, 0x02, 0x20, 0x74, 0x92, 0x8d, 0xf8, 0xd2, 0xb6, 0x1b, 0x27, 0xa2, 0xf6, 0xcb, 0x28, - 0x3f, 0x31, 0x92, 0xad, 0xd8, 0xc0, 0xa0, 0xec, 0xd8, 0xbf, 0xd9, 0xe0, 0x7a, 0x90, 0xf0, 0x87, - 0xf8, 0x36, 0xe2, 0xb4, 0xbc, 0x29, 0xc3, 0x00, 0xe1, 0x2c, 0x2e, 0x65, 0xc7, 0xce, 0x24, 0x79, - 0x47, 0xf9, 0xfe, 0x82, 0xb1, 0x5b, 0x50, 0xad, 0xd8, 0xc0, 0xc8, 0x66, 0xfd, 0x55, 0xf7, 0xcf, - 0xfa, 0xb3, 0xff, 0x71, 0x09, 0xce, 0xf5, 0x34, 0xe5, 0xfa, 0x5b, 0x80, 0x0f, 0x5f, 0xa6, 0xde, - 0xe1, 0xe6, 0xce, 0x01, 0x33, 0xca, 0xfe, 0xa8, 0xc7, 0x4c, 0x13, 0x19, 0x65, 0x87, 0x4f, 0xc9, - 0x7e, 0xf8, 0xc6, 0xb3, 0x2b, 0x89, 0xac, 0x72, 0x80, 0x24, 0xb2, 0xcc, 0xc7, 0xa8, 0xf6, 0xb9, - 0x90, 0xff, 0xbc, 0xdc, 0x73, 0x78, 0xe9, 0xd6, 0xaf, 0x2f, 0xef, 0xe8, 0x2c, 0x9c, 0x74, 0x7d, - 0x76, 0x6b, 0xd2, 0x4a, 0x67, 0x4d, 0x94, 0x03, 0x29, 0xa5, 0xef, 0x2c, 0x9f, 0xcf, 0xc0, 0x71, - 0xd7, 0x13, 0x0f, 0x61, 0x52, 0xdf, 0xe1, 0x86, 0xf4, 0x60, 0x69, 0xa5, 0x68, 0x09, 0xce, 0xca, - 0xa1, 0xd8, 0x70, 0x22, 0xd2, 0x14, 0x6a, 0x24, 0x16, 0x69, 0x0c, 0xe7, 0x78, 0x2a, 0x44, 0x0e, - 0x02, 0xce, 0x7f, 0x8e, 0x5d, 0x54, 0x13, 0x84, 0x6e, 0x43, 0x6c, 0x72, 0xf4, 0x45, 0x35, 0xb4, - 0x11, 0x73, 0x98, 0xfd, 0x11, 0xa8, 0xab, 0xf7, 0xe7, 0xc1, 0xd4, 0x6a, 0xd2, 0x75, 0x05, 0x53, - 0xab, 0x19, 0x67, 0x60, 0xd1, 0xaf, 0x45, 0x4d, 0xe2, 0xcc, 0xea, 0xb9, 0x46, 0x76, 0x98, 0x7d, - 0x6c, 0xbf, 0x07, 0x86, 0x95, 0x9f, 0xa5, 0xdf, 0xeb, 0x7b, 0xec, 0x2f, 0x0f, 0xc0, 0x48, 0xaa, - 0x24, 0x5f, 0xca, 0xad, 0x69, 0xed, 0xeb, 0xd6, 0x64, 0xc1, 0xf1, 0x1d, 0x5f, 0xde, 0xed, 0x65, - 0x04, 0xc7, 0x77, 0x7c, 0x82, 0x39, 0x8c, 0x9a, 0xb7, 0xcd, 0x68, 0x07, 0x77, 0x7c, 0x11, 0xc4, - 0xaa, 0xcc, 0xdb, 0x59, 0xd6, 0x8a, 0x05, 0x14, 0x7d, 0xd2, 0x82, 0xe1, 0x98, 0xf9, 0xcc, 0xb9, - 0x53, 0x58, 0x4c, 0xba, 0xab, 0x47, 0xaf, 0x38, 0xa8, 0xca, 0x4f, 0xb2, 0xb8, 0x14, 0xb3, 0x05, - 0xa7, 0x38, 0xa2, 0xcf, 0x58, 0x50, 0x57, 0x57, 0x90, 0x88, 0x0b, 0xf8, 0x56, 0x8a, 0xad, 0x78, - 0xc8, 0xbd, 0x89, 0xea, 0xf8, 0x41, 0x95, 0x9e, 0xc3, 0x9a, 0x31, 0x8a, 0x95, 0xc7, 0x76, 0xf0, - 0x78, 0x3c, 0xb6, 0x90, 0xe3, 0xad, 0x7d, 0x37, 0xd4, 0xdb, 0x8e, 0xef, 0xae, 0x93, 0x38, 0xe1, - 0x4e, 0x54, 0x59, 0x88, 0x55, 0x36, 0x62, 0x0d, 0xa7, 0x0a, 0x39, 0x66, 0x2f, 0x96, 0x18, 0x5e, - 0x4f, 0xa6, 0x90, 0x57, 0x74, 0x33, 0x36, 0x71, 0x4c, 0x17, 0x2d, 0x3c, 0x50, 0x17, 0xed, 0xd0, - 0x3e, 0x2e, 0xda, 0x7f, 0x60, 0xc1, 0xd9, 0xdc, 0xaf, 0xf6, 0xf0, 0x86, 0x1b, 0xda, 0x5f, 0xa9, - 0xc2, 0xe9, 0x9c, 0xda, 0x9a, 0x68, 0xc7, 0x9c, 0xcf, 0x56, 0x11, 0x27, 0xf7, 0xe9, 0x83, 0x68, - 0x39, 0x8c, 0x39, 0x93, 0xf8, 0x60, 0x07, 0x24, 0xfa, 0x90, 0xa2, 0x7c, 0x7f, 0x0f, 0x29, 0x8c, - 0x69, 0x59, 0x79, 0xa0, 0xd3, 0xb2, 0xba, 0xf7, 0xb4, 0x44, 0xbf, 0x66, 0xc1, 0x58, 0xbb, 0x47, - 0x41, 0x77, 0xe1, 0x78, 0xbc, 0x79, 0x3c, 0xe5, 0xe2, 0xa7, 0x1f, 0xbb, 0xbb, 0x3b, 0xde, 0xb3, - 0x8e, 0x3e, 0xee, 0xd9, 0x2b, 0xfb, 0x3b, 0x65, 0x60, 0x85, 0x5d, 0x59, 0xfd, 0xb4, 0x1d, 0xf4, - 0x09, 0xb3, 0x44, 0xaf, 0x55, 0x54, 0x39, 0x59, 0x4e, 0x5c, 0x95, 0xf8, 0xe5, 0x23, 0x98, 0x57, - 0xf1, 0x37, 0x2b, 0xb4, 0x4a, 0x7d, 0x08, 0x2d, 0x4f, 0xd6, 0x42, 0x2e, 0x17, 0x5f, 0x0b, 0xb9, - 0x9e, 0xad, 0x83, 0xbc, 0xf7, 0x27, 0xae, 0x3c, 0x94, 0x9f, 0xf8, 0x6f, 0x5a, 0x5c, 0xf0, 0x64, - 0xbe, 0x82, 0xb6, 0x0c, 0xac, 0x3d, 0x2c, 0x83, 0x67, 0xa0, 0x16, 0x13, 0x6f, 0xfd, 0x0a, 0x71, - 0x3c, 0x61, 0x41, 0xe8, 0x53, 0x63, 0xd1, 0x8e, 0x15, 0x06, 0xbb, 0x2c, 0xd5, 0xf3, 0x82, 0x3b, - 0x97, 0xda, 0x61, 0xb2, 0x23, 0x6c, 0x09, 0x7d, 0x59, 0xaa, 0x82, 0x60, 0x03, 0xcb, 0xfe, 0x5b, - 0x25, 0x3e, 0x03, 0x45, 0xe8, 0xc1, 0x8b, 0x99, 0xeb, 0xed, 0xfa, 0x3f, 0xb5, 0xff, 0x18, 0x40, - 0x43, 0x5d, 0x0c, 0x2f, 0xce, 0x84, 0xae, 0x1c, 0xf9, 0xd6, 0x6a, 0x41, 0x4f, 0xbf, 0x86, 0x6e, - 0xc3, 0x06, 0xbf, 0x94, 0x2c, 0x2d, 0xef, 0x2b, 0x4b, 0x53, 0x62, 0xa5, 0xb2, 0x8f, 0xb6, 0xfb, - 0x53, 0x0b, 0x52, 0x16, 0x11, 0x0a, 0xa1, 0x4a, 0xbb, 0xbb, 0x53, 0xcc, 0x9d, 0xf7, 0x26, 0x69, - 0x2a, 0x1a, 0xc5, 0xb4, 0x67, 0x3f, 0x31, 0x67, 0x84, 0x3c, 0x11, 0xa1, 0xc0, 0x47, 0xf5, 0x7a, - 0x71, 0x0c, 0xaf, 0x04, 0xc1, 0x26, 0x3f, 0xd8, 0xd4, 0xd1, 0x0e, 0xf6, 0x8b, 0x70, 0xaa, 0xab, - 0x53, 0xec, 0x26, 0xab, 0x40, 0x5e, 0xf4, 0x6f, 0x4c, 0x57, 0x96, 0x36, 0x89, 0x39, 0xcc, 0xfe, - 0x86, 0x05, 0x27, 0xb3, 0xe4, 0xd1, 0x5b, 0x16, 0x9c, 0x8a, 0xb3, 0xf4, 0x8e, 0x6b, 0xec, 0x54, - 0x94, 0x61, 0x17, 0x08, 0x77, 0x77, 0xc2, 0xfe, 0x3f, 0x62, 0xf2, 0xdf, 0x72, 0xfd, 0x66, 0x70, - 0x47, 0x19, 0x26, 0x56, 0x4f, 0xc3, 0x84, 0xae, 0xc7, 0xc6, 0x06, 0x69, 0x76, 0xbc, 0xae, 0x7c, - 0xcd, 0x15, 0xd1, 0x8e, 0x15, 0x06, 0x4b, 0x4f, 0xeb, 0x88, 0x62, 0xe9, 0x99, 0x49, 0x39, 0x2b, - 0xda, 0xb1, 0xc2, 0x40, 0xcf, 0xc3, 0xb0, 0xf1, 0x92, 0x72, 0x5e, 0x32, 0x83, 0xdc, 0x50, 0x99, - 0x31, 0x4e, 0x61, 0xa1, 0x09, 0x00, 0x65, 0xe4, 0x48, 0x15, 0xc9, 0x1c, 0x45, 0x4a, 0x12, 0xc5, - 0xd8, 0xc0, 0x60, 0xc9, 0xa0, 0x5e, 0x27, 0x66, 0x3e, 0xfe, 0x01, 0x5d, 0xc0, 0x73, 0x46, 0xb4, - 0x61, 0x05, 0xa5, 0xd2, 0xa4, 0xed, 0xf8, 0x1d, 0xc7, 0xa3, 0x23, 0x24, 0xb6, 0x7e, 0x6a, 0x19, - 0x2e, 0x2a, 0x08, 0x36, 0xb0, 0xe8, 0x1b, 0x27, 0x6e, 0x9b, 0xbc, 0x12, 0xf8, 0x32, 0x3a, 0x4c, - 0x1f, 0xfb, 0x88, 0x76, 0xac, 0x30, 0xec, 0xff, 0x62, 0xc1, 0x09, 0x9d, 0x5a, 0xce, 0xef, 0xac, - 0x36, 0x77, 0xaa, 0xd6, 0xbe, 0x3b, 0xd5, 0x74, 0xce, 0x6d, 0xa9, 0xaf, 0x9c, 0x5b, 0x33, 0x1d, - 0xb6, 0xbc, 0x67, 0x3a, 0xec, 0x0f, 0xea, 0xfb, 0x50, 0x79, 0xde, 0xec, 0x50, 0xde, 0x5d, 0xa8, - 0xc8, 0x86, 0x81, 0x86, 0xa3, 0xea, 0xaa, 0x0c, 0xf3, 0xbd, 0xc3, 0xcc, 0x14, 0x43, 0x12, 0x10, - 0x7b, 0x09, 0xea, 0xea, 0xf4, 0x43, 0x6e, 0x54, 0xad, 0xfc, 0x8d, 0x6a, 0x5f, 0x69, 0x79, 0xd3, - 0x6b, 0xdf, 0xfc, 0xee, 0x13, 0xef, 0xf8, 0xbd, 0xef, 0x3e, 0xf1, 0x8e, 0x3f, 0xfc, 0xee, 0x13, - 0xef, 0xf8, 0xe4, 0xdd, 0x27, 0xac, 0x6f, 0xde, 0x7d, 0xc2, 0xfa, 0xbd, 0xbb, 0x4f, 0x58, 0x7f, - 0x78, 0xf7, 0x09, 0xeb, 0x3b, 0x77, 0x9f, 0xb0, 0xbe, 0xf4, 0x9f, 0x9e, 0x78, 0xc7, 0x2b, 0xb9, - 0xe1, 0x81, 0xf4, 0xc7, 0xb3, 0x8d, 0xe6, 0xe4, 0xd6, 0x45, 0x16, 0xa1, 0x46, 0x97, 0xd7, 0xa4, - 0x31, 0xa7, 0x26, 0xe5, 0xf2, 0xfa, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa7, 0x24, 0x1a, 0xa3, - 0x6c, 0xe0, 0x00, 0x00, + 0xc9, 0x5e, 0x4f, 0x45, 0x1d, 0x3f, 0x71, 0xdb, 0xa4, 0xeb, 0x81, 0xf7, 0xec, 0xf7, 0x40, 0xdc, + 0xd8, 0x20, 0x6d, 0xa7, 0xeb, 0xb9, 0x1f, 0xe9, 0xf5, 0x5c, 0x27, 0x71, 0xbd, 0x49, 0xd7, 0x4f, + 0xe2, 0x24, 0xca, 0x3e, 0x64, 0xbf, 0x0e, 0x23, 0x53, 0xb7, 0x56, 0xa6, 0x3a, 0xc9, 0xc6, 0x4c, + 0xe0, 0xaf, 0xbb, 0x2d, 0xf4, 0x02, 0x0c, 0x35, 0xbc, 0x4e, 0x9c, 0x90, 0xe8, 0xba, 0xd3, 0x26, + 0x63, 0xd6, 0x05, 0xeb, 0xe9, 0xfa, 0xf4, 0xe9, 0x6f, 0xee, 0x8e, 0xbf, 0xe3, 0xee, 0xee, 0xf8, + 0xd0, 0x8c, 0x06, 0x61, 0x13, 0x0f, 0xfd, 0x10, 0x0c, 0x46, 0x81, 0x47, 0xa6, 0xf0, 0xf5, 0xb1, + 0x12, 0x7b, 0xe4, 0x84, 0x78, 0x64, 0x10, 0xf3, 0x66, 0x2c, 0xe1, 0xf6, 0x1f, 0x96, 0x00, 0xa6, + 0xc2, 0x70, 0x39, 0x0a, 0x6e, 0x93, 0x46, 0x82, 0x3e, 0x02, 0x35, 0x3a, 0x74, 0x4d, 0x27, 0x71, + 0x18, 0xb7, 0xa1, 0x8b, 0x3f, 0x3c, 0xc1, 0xdf, 0x64, 0xc2, 0x7c, 0x13, 0x3d, 0x71, 0x28, 0xf6, + 0xc4, 0xd6, 0x73, 0x13, 0x4b, 0x6b, 0xf4, 0xf9, 0x45, 0x92, 0x38, 0xd3, 0x48, 0x30, 0x03, 0xdd, + 0x86, 0x15, 0x55, 0xe4, 0x43, 0x25, 0x0e, 0x49, 0x83, 0x75, 0x6c, 0xe8, 0xe2, 0xc2, 0xc4, 0x51, + 0x66, 0xe8, 0x84, 0xee, 0xf9, 0x4a, 0x48, 0x1a, 0xd3, 0xc3, 0x82, 0x73, 0x85, 0xfe, 0xc3, 0x8c, + 0x0f, 0xda, 0x82, 0x81, 0x38, 0x71, 0x92, 0x4e, 0x3c, 0x56, 0x66, 0x1c, 0xaf, 0x17, 0xc6, 0x91, + 0x51, 0x9d, 0x1e, 0x15, 0x3c, 0x07, 0xf8, 0x7f, 0x2c, 0xb8, 0xd9, 0x7f, 0x62, 0xc1, 0xa8, 0x46, + 0x5e, 0x70, 0xe3, 0x04, 0xfd, 0x64, 0xd7, 0xe0, 0x4e, 0xf4, 0x37, 0xb8, 0xf4, 0x69, 0x36, 0xb4, + 0x27, 0x05, 0xb3, 0x9a, 0x6c, 0x31, 0x06, 0xb6, 0x0d, 0x55, 0x37, 0x21, 0xed, 0x78, 0xac, 0x74, + 0xa1, 0xfc, 0xf4, 0xd0, 0xc5, 0x2b, 0x45, 0xbd, 0xe7, 0xf4, 0x88, 0x60, 0x5a, 0x9d, 0xa7, 0xe4, + 0x31, 0xe7, 0x62, 0xff, 0xda, 0xb0, 0xf9, 0x7e, 0x74, 0xc0, 0xd1, 0x73, 0x30, 0x14, 0x07, 0x9d, + 0xa8, 0x41, 0x30, 0x09, 0x83, 0x78, 0xcc, 0xba, 0x50, 0xa6, 0x53, 0x8f, 0xce, 0xd4, 0x15, 0xdd, + 0x8c, 0x4d, 0x1c, 0xf4, 0x05, 0x0b, 0x86, 0x9b, 0x24, 0x4e, 0x5c, 0x9f, 0xf1, 0x97, 0x9d, 0x5f, + 0x3d, 0x72, 0xe7, 0x65, 0xe3, 0xac, 0x26, 0x3e, 0x7d, 0x46, 0xbc, 0xc8, 0xb0, 0xd1, 0x18, 0xe3, + 0x14, 0x7f, 0xba, 0xe2, 0x9a, 0x24, 0x6e, 0x44, 0x6e, 0x48, 0xff, 0xb3, 0x39, 0x63, 0xac, 0xb8, + 0x59, 0x0d, 0xc2, 0x26, 0x1e, 0xf2, 0xa1, 0x4a, 0x57, 0x54, 0x3c, 0x56, 0x61, 0xfd, 0x9f, 0x3f, + 0x5a, 0xff, 0xc5, 0xa0, 0xd2, 0xc5, 0xaa, 0x47, 0x9f, 0xfe, 0x8b, 0x31, 0x67, 0x83, 0x3e, 0x6f, + 0xc1, 0x98, 0x58, 0xf1, 0x98, 0xf0, 0x01, 0xbd, 0xb5, 0xe1, 0x26, 0xc4, 0x73, 0xe3, 0x64, 0xac, + 0xca, 0xfa, 0x30, 0xd9, 0xdf, 0xdc, 0x9a, 0x8b, 0x82, 0x4e, 0x78, 0xcd, 0xf5, 0x9b, 0xd3, 0x17, + 0x04, 0xa7, 0xb1, 0x99, 0x1e, 0x84, 0x71, 0x4f, 0x96, 0xe8, 0xcb, 0x16, 0x9c, 0xf7, 0x9d, 0x36, + 0x89, 0x43, 0x87, 0x7e, 0x5a, 0x0e, 0x9e, 0xf6, 0x9c, 0xc6, 0x26, 0xeb, 0xd1, 0xc0, 0xe1, 0x7a, + 0x64, 0x8b, 0x1e, 0x9d, 0xbf, 0xde, 0x93, 0x34, 0xde, 0x83, 0x2d, 0xfa, 0xba, 0x05, 0xa7, 0x82, + 0x28, 0xdc, 0x70, 0x7c, 0xd2, 0x94, 0xd0, 0x78, 0x6c, 0x90, 0x2d, 0xbd, 0x0f, 0x1f, 0xed, 0x13, + 0x2d, 0x65, 0xc9, 0x2e, 0x06, 0xbe, 0x9b, 0x04, 0xd1, 0x0a, 0x49, 0x12, 0xd7, 0x6f, 0xc5, 0xd3, + 0x67, 0xef, 0xee, 0x8e, 0x9f, 0xea, 0xc2, 0xc2, 0xdd, 0xfd, 0x41, 0x3f, 0x05, 0x43, 0xf1, 0x8e, + 0xdf, 0xb8, 0xe5, 0xfa, 0xcd, 0xe0, 0x4e, 0x3c, 0x56, 0x2b, 0x62, 0xf9, 0xae, 0x28, 0x82, 0x62, + 0x01, 0x6a, 0x06, 0xd8, 0xe4, 0x96, 0xff, 0xe1, 0xf4, 0x54, 0xaa, 0x17, 0xfd, 0xe1, 0xf4, 0x64, + 0xda, 0x83, 0x2d, 0xfa, 0x79, 0x0b, 0x46, 0x62, 0xb7, 0xe5, 0x3b, 0x49, 0x27, 0x22, 0xd7, 0xc8, + 0x4e, 0x3c, 0x06, 0xac, 0x23, 0x57, 0x8f, 0x38, 0x2a, 0x06, 0xc9, 0xe9, 0xb3, 0xa2, 0x8f, 0x23, + 0x66, 0x6b, 0x8c, 0xd3, 0x7c, 0xf3, 0x16, 0x9a, 0x9e, 0xd6, 0x43, 0xc5, 0x2e, 0x34, 0x3d, 0xa9, + 0x7b, 0xb2, 0x44, 0x3f, 0x01, 0x27, 0x79, 0x93, 0x1a, 0xd9, 0x78, 0x6c, 0x98, 0x09, 0xda, 0x33, + 0x77, 0x77, 0xc7, 0x4f, 0xae, 0x64, 0x60, 0xb8, 0x0b, 0x1b, 0xbd, 0x0e, 0xe3, 0x21, 0x89, 0xda, + 0x6e, 0xb2, 0xe4, 0x7b, 0x3b, 0x52, 0x7c, 0x37, 0x82, 0x90, 0x34, 0x45, 0x77, 0xe2, 0xb1, 0x91, + 0x0b, 0xd6, 0xd3, 0xb5, 0xe9, 0x77, 0x89, 0x6e, 0x8e, 0x2f, 0xef, 0x8d, 0x8e, 0xf7, 0xa3, 0x67, + 0xff, 0xcb, 0x12, 0x9c, 0xcc, 0x2a, 0x4e, 0xf4, 0xb7, 0x2d, 0x38, 0x71, 0xfb, 0x4e, 0xb2, 0x1a, + 0x6c, 0x12, 0x3f, 0x9e, 0xde, 0xa1, 0xe2, 0x8d, 0xa9, 0x8c, 0xa1, 0x8b, 0x8d, 0x62, 0x55, 0xf4, + 0xc4, 0xd5, 0x34, 0x97, 0x4b, 0x7e, 0x12, 0xed, 0x4c, 0x3f, 0x2a, 0xde, 0xee, 0xc4, 0xd5, 0x5b, + 0xab, 0x26, 0x14, 0x67, 0x3b, 0x75, 0xfe, 0xb3, 0x16, 0x9c, 0xc9, 0x23, 0x81, 0x4e, 0x42, 0x79, + 0x93, 0xec, 0x70, 0xab, 0x0c, 0xd3, 0x9f, 0xe8, 0x55, 0xa8, 0x6e, 0x39, 0x5e, 0x87, 0x08, 0xeb, + 0x66, 0xee, 0x68, 0x2f, 0xa2, 0x7a, 0x86, 0x39, 0xd5, 0xf7, 0x96, 0x5e, 0xb4, 0xec, 0xdf, 0x2b, + 0xc3, 0x90, 0xa1, 0xdf, 0xee, 0x83, 0xc5, 0x16, 0xa4, 0x2c, 0xb6, 0xc5, 0xc2, 0x54, 0x73, 0x4f, + 0x93, 0xed, 0x4e, 0xc6, 0x64, 0x5b, 0x2a, 0x8e, 0xe5, 0x9e, 0x36, 0x1b, 0x4a, 0xa0, 0x1e, 0x84, + 0xd4, 0x22, 0xa7, 0xaa, 0xbf, 0x52, 0xc4, 0x27, 0x5c, 0x92, 0xe4, 0xa6, 0x47, 0xee, 0xee, 0x8e, + 0xd7, 0xd5, 0x5f, 0xac, 0x19, 0xd9, 0xdf, 0xb6, 0xe0, 0x8c, 0xd1, 0xc7, 0x99, 0xc0, 0x6f, 0xba, + 0xec, 0xd3, 0x5e, 0x80, 0x4a, 0xb2, 0x13, 0x4a, 0xb3, 0x5f, 0x8d, 0xd4, 0xea, 0x4e, 0x48, 0x30, + 0x83, 0x50, 0x43, 0xbf, 0x4d, 0xe2, 0xd8, 0x69, 0x91, 0xac, 0xa1, 0xbf, 0xc8, 0x9b, 0xb1, 0x84, + 0xa3, 0x08, 0x90, 0xe7, 0xc4, 0xc9, 0x6a, 0xe4, 0xf8, 0x31, 0x23, 0xbf, 0xea, 0xb6, 0x89, 0x18, + 0xe0, 0xff, 0xbf, 0xbf, 0x19, 0x43, 0x9f, 0x98, 0x7e, 0xe4, 0xee, 0xee, 0x38, 0x5a, 0xe8, 0xa2, + 0x84, 0x73, 0xa8, 0xdb, 0x5f, 0xb6, 0xe0, 0x91, 0x7c, 0x5b, 0x0c, 0x3d, 0x05, 0x03, 0x7c, 0xcb, + 0x27, 0xde, 0x4e, 0x7f, 0x12, 0xd6, 0x8a, 0x05, 0x14, 0x4d, 0x42, 0x5d, 0xe9, 0x09, 0xf1, 0x8e, + 0xa7, 0x04, 0x6a, 0x5d, 0x2b, 0x17, 0x8d, 0x43, 0x07, 0x8d, 0xfe, 0x11, 0x96, 0x9b, 0x1a, 0x34, + 0xb6, 0x49, 0x62, 0x10, 0xfb, 0x3f, 0x58, 0x70, 0xc2, 0xe8, 0xd5, 0x7d, 0x30, 0xcd, 0xfd, 0xb4, + 0x69, 0x3e, 0x5f, 0xd8, 0x7c, 0xee, 0x61, 0x9b, 0x7f, 0xde, 0x82, 0xf3, 0x06, 0xd6, 0xa2, 0x93, + 0x34, 0x36, 0x2e, 0x6d, 0x87, 0x11, 0x89, 0xe9, 0x76, 0x1a, 0x3d, 0x6e, 0xc8, 0xad, 0xe9, 0x21, + 0x41, 0xa1, 0x7c, 0x8d, 0xec, 0x70, 0x21, 0xf6, 0x0c, 0xd4, 0xf8, 0xe4, 0x0c, 0x22, 0x31, 0xe2, + 0xea, 0xdd, 0x96, 0x44, 0x3b, 0x56, 0x18, 0xc8, 0x86, 0x01, 0x26, 0x9c, 0xe8, 0x62, 0xa5, 0x6a, + 0x08, 0xe8, 0x47, 0xbc, 0xc9, 0x5a, 0xb0, 0x80, 0xd8, 0x71, 0xaa, 0x3b, 0xcb, 0x11, 0x61, 0x1f, + 0xb7, 0x79, 0xd9, 0x25, 0x5e, 0x33, 0xa6, 0xdb, 0x06, 0xc7, 0xf7, 0x83, 0x44, 0xec, 0x00, 0x8c, + 0x6d, 0xc3, 0x94, 0x6e, 0xc6, 0x26, 0x0e, 0x65, 0xea, 0x39, 0x6b, 0xc4, 0xe3, 0x23, 0x2a, 0x98, + 0x2e, 0xb0, 0x16, 0x2c, 0x20, 0xf6, 0xdd, 0x12, 0xdb, 0xa0, 0xa8, 0xa5, 0x4f, 0xee, 0xc7, 0xee, + 0x36, 0x4a, 0xc9, 0xca, 0xe5, 0xe2, 0x04, 0x17, 0xe9, 0xbd, 0xc3, 0x7d, 0x23, 0x23, 0x2e, 0x71, + 0xa1, 0x5c, 0xf7, 0xde, 0xe5, 0xfe, 0x76, 0x09, 0xc6, 0xd3, 0x0f, 0x74, 0x49, 0x5b, 0xba, 0xa5, + 0x32, 0x18, 0x65, 0x9d, 0x18, 0x06, 0x3e, 0x36, 0xf1, 0x7a, 0x08, 0xac, 0xd2, 0x71, 0x0a, 0x2c, + 0x53, 0x9e, 0x96, 0xf7, 0x91, 0xa7, 0x4f, 0xa9, 0x51, 0xaf, 0x64, 0x04, 0x58, 0x5a, 0xa7, 0x5c, + 0x80, 0x4a, 0x9c, 0x90, 0x70, 0xac, 0x9a, 0x96, 0x47, 0x2b, 0x09, 0x09, 0x31, 0x83, 0xd8, 0xff, + 0xb5, 0x04, 0x8f, 0xa6, 0xc7, 0x50, 0xab, 0x80, 0xf7, 0xa7, 0x54, 0xc0, 0xbb, 0x4d, 0x15, 0x70, + 0x6f, 0x77, 0xfc, 0x9d, 0x3d, 0x1e, 0xfb, 0x9e, 0xd1, 0x10, 0x68, 0x2e, 0x33, 0x8a, 0x93, 0xe9, + 0x51, 0xbc, 0xb7, 0x3b, 0xfe, 0x78, 0x8f, 0x77, 0xcc, 0x0c, 0xf3, 0x53, 0x30, 0x10, 0x11, 0x27, + 0x0e, 0x7c, 0x31, 0xd0, 0xea, 0x73, 0x60, 0xd6, 0x8a, 0x05, 0xd4, 0xfe, 0x37, 0xf5, 0xec, 0x60, + 0xcf, 0x71, 0x27, 0x5c, 0x10, 0x21, 0x17, 0x2a, 0xcc, 0xac, 0xe7, 0xa2, 0xe1, 0xda, 0xd1, 0x96, + 0x11, 0x55, 0x03, 0x8a, 0xf4, 0x74, 0x8d, 0x7e, 0x35, 0xda, 0x84, 0x19, 0x0b, 0xb4, 0x0d, 0xb5, + 0x86, 0xb4, 0xb6, 0x4b, 0x45, 0xf8, 0xa5, 0x84, 0xad, 0xad, 0x39, 0x0e, 0x53, 0x79, 0xad, 0x4c, + 0x74, 0xc5, 0x0d, 0x11, 0x28, 0xb7, 0xdc, 0x44, 0x7c, 0xd6, 0x23, 0xee, 0xa7, 0xe6, 0x5c, 0xe3, + 0x15, 0x07, 0xa9, 0x12, 0x99, 0x73, 0x13, 0x4c, 0xe9, 0xa3, 0x9f, 0xb5, 0x60, 0x28, 0x6e, 0xb4, + 0x97, 0xa3, 0x60, 0xcb, 0x6d, 0x92, 0x48, 0x58, 0x53, 0x47, 0x14, 0x4d, 0x2b, 0x33, 0x8b, 0x92, + 0xa0, 0xe6, 0xcb, 0xf7, 0xb7, 0x1a, 0x82, 0x4d, 0xbe, 0x74, 0x97, 0xf1, 0xa8, 0x78, 0xf7, 0x59, + 0xd2, 0x70, 0xa9, 0xfe, 0x93, 0x9b, 0x2a, 0x36, 0x53, 0x8e, 0x6c, 0x5d, 0xce, 0x76, 0x1a, 0x9b, + 0x74, 0xbd, 0xe9, 0x0e, 0xbd, 0xf3, 0xee, 0xee, 0xf8, 0xa3, 0x33, 0xf9, 0x3c, 0x71, 0xaf, 0xce, + 0xb0, 0x01, 0x0b, 0x3b, 0x9e, 0x87, 0xc9, 0xeb, 0x1d, 0xc2, 0x5c, 0x26, 0x05, 0x0c, 0xd8, 0xb2, + 0x26, 0x98, 0x19, 0x30, 0x03, 0x82, 0x4d, 0xbe, 0xe8, 0x75, 0x18, 0x68, 0x3b, 0x49, 0xe4, 0x6e, + 0x0b, 0x3f, 0xc9, 0x11, 0xed, 0xfd, 0x45, 0x46, 0x4b, 0x33, 0x67, 0x9a, 0x9a, 0x37, 0x62, 0xc1, + 0x08, 0xb5, 0xa1, 0xda, 0x26, 0x51, 0x8b, 0x8c, 0xd5, 0x8a, 0xf0, 0x09, 0x2f, 0x52, 0x52, 0x9a, + 0x61, 0x9d, 0x5a, 0x47, 0xac, 0x0d, 0x73, 0x2e, 0xe8, 0x55, 0xa8, 0xc5, 0xc4, 0x23, 0x0d, 0x6a, + 0xdf, 0xd4, 0x19, 0xc7, 0x1f, 0xe9, 0xd3, 0xd6, 0xa3, 0x86, 0xc5, 0x8a, 0x78, 0x94, 0x2f, 0x30, + 0xf9, 0x0f, 0x2b, 0x92, 0x74, 0x00, 0x43, 0xaf, 0xd3, 0x72, 0xfd, 0x31, 0x28, 0x62, 0x00, 0x97, + 0x19, 0xad, 0xcc, 0x00, 0xf2, 0x46, 0x2c, 0x18, 0xd9, 0xff, 0xc9, 0x02, 0x94, 0x16, 0x6a, 0xf7, + 0xc1, 0xa8, 0x7d, 0x3d, 0x6d, 0xd4, 0x2e, 0x14, 0x69, 0x75, 0xf4, 0xb0, 0x6b, 0x7f, 0xb3, 0x0e, + 0x19, 0x75, 0x70, 0x9d, 0xc4, 0x09, 0x69, 0xbe, 0x2d, 0xc2, 0xdf, 0x16, 0xe1, 0x6f, 0x8b, 0x70, + 0x25, 0xc2, 0xd7, 0x32, 0x22, 0xfc, 0x7d, 0xc6, 0xaa, 0xd7, 0x87, 0xaa, 0xaf, 0xa9, 0x53, 0x57, + 0xb3, 0x07, 0x06, 0x02, 0x95, 0x04, 0x57, 0x57, 0x96, 0xae, 0xe7, 0xca, 0xec, 0xd7, 0xd2, 0x32, + 0xfb, 0xa8, 0x2c, 0xfe, 0x5f, 0x90, 0xd2, 0xff, 0xc2, 0x82, 0x77, 0xa5, 0xa5, 0x97, 0x9c, 0x39, + 0xf3, 0x2d, 0x3f, 0x88, 0xc8, 0xac, 0xbb, 0xbe, 0x4e, 0x22, 0xe2, 0x37, 0x48, 0xac, 0xbc, 0x18, + 0x56, 0x2f, 0x2f, 0x06, 0x7a, 0x1e, 0x86, 0x6f, 0xc7, 0x81, 0xbf, 0x1c, 0xb8, 0xbe, 0x10, 0x41, + 0x74, 0x23, 0x7c, 0xf2, 0xee, 0xee, 0xf8, 0x30, 0x1d, 0x51, 0xd9, 0x8e, 0x53, 0x58, 0x68, 0x06, + 0x4e, 0xdd, 0x7e, 0x7d, 0xd9, 0x49, 0x0c, 0x77, 0x80, 0xdc, 0xb8, 0xb3, 0x03, 0x8b, 0xab, 0x2f, + 0x67, 0x80, 0xb8, 0x1b, 0xdf, 0xfe, 0xeb, 0x25, 0x38, 0x97, 0x79, 0x91, 0xc0, 0xf3, 0x82, 0x4e, + 0x42, 0x37, 0x35, 0xe8, 0xab, 0x16, 0x9c, 0x6c, 0xa7, 0x3d, 0x0e, 0xb1, 0x70, 0xec, 0x7e, 0xa0, + 0x30, 0x1d, 0x91, 0x71, 0x69, 0x4c, 0x8f, 0x89, 0x11, 0x3a, 0x99, 0x01, 0xc4, 0xb8, 0xab, 0x2f, + 0xe8, 0x55, 0xa8, 0xb7, 0x9d, 0xed, 0x1b, 0x61, 0xd3, 0x49, 0xe4, 0x7e, 0xb2, 0xb7, 0x1b, 0xa0, + 0x93, 0xb8, 0xde, 0x04, 0x3f, 0xae, 0x9f, 0x98, 0xf7, 0x93, 0xa5, 0x68, 0x25, 0x89, 0x5c, 0xbf, + 0xc5, 0xdd, 0x79, 0x8b, 0x92, 0x0c, 0xd6, 0x14, 0xed, 0xaf, 0x58, 0x59, 0x25, 0xa5, 0x46, 0x27, + 0x72, 0x12, 0xd2, 0xda, 0x41, 0x1f, 0x85, 0x2a, 0xdd, 0xf8, 0xc9, 0x51, 0xb9, 0x55, 0xa4, 0xe6, + 0x34, 0xbe, 0x84, 0x56, 0xa2, 0xf4, 0x5f, 0x8c, 0x39, 0x53, 0xfb, 0xab, 0xf5, 0xac, 0xb1, 0xc0, + 0x0e, 0x6f, 0x2f, 0x02, 0xb4, 0x82, 0x55, 0xd2, 0x0e, 0x3d, 0x3a, 0x2c, 0x16, 0x3b, 0x01, 0x50, + 0xbe, 0x8e, 0x39, 0x05, 0xc1, 0x06, 0x16, 0xfa, 0x8b, 0x16, 0x40, 0x4b, 0xce, 0x79, 0x69, 0x08, + 0xdc, 0x28, 0xf2, 0x75, 0xf4, 0x8a, 0xd2, 0x7d, 0x51, 0x0c, 0xb1, 0xc1, 0x1c, 0xfd, 0x8c, 0x05, + 0xb5, 0x44, 0x76, 0x9f, 0xab, 0xc6, 0xd5, 0x22, 0x7b, 0x22, 0x5f, 0x5a, 0xdb, 0x44, 0x6a, 0x48, + 0x14, 0x5f, 0xf4, 0x73, 0x16, 0x40, 0xbc, 0xe3, 0x37, 0x96, 0x03, 0xcf, 0x6d, 0xec, 0x08, 0x8d, + 0x79, 0xb3, 0x50, 0x7f, 0x8c, 0xa2, 0x3e, 0x3d, 0x4a, 0x47, 0x43, 0xff, 0xc7, 0x06, 0x67, 0xf4, + 0x71, 0xa8, 0xc5, 0x62, 0xba, 0x09, 0x1d, 0xb9, 0x5a, 0xac, 0x57, 0x88, 0xd3, 0x16, 0xe2, 0x55, + 0xfc, 0xc3, 0x8a, 0x27, 0xfa, 0x05, 0x0b, 0x4e, 0x84, 0x69, 0x3f, 0x9f, 0x50, 0x87, 0xc5, 0xc9, + 0x80, 0x8c, 0x1f, 0x71, 0xfa, 0xf4, 0xdd, 0xdd, 0xf1, 0x13, 0x99, 0x46, 0x9c, 0xed, 0x05, 0x95, + 0x80, 0x7a, 0x06, 0x2f, 0x85, 0xdc, 0xe7, 0x38, 0xa8, 0x25, 0xe0, 0x5c, 0x16, 0x88, 0xbb, 0xf1, + 0xd1, 0x32, 0x9c, 0xa1, 0xbd, 0xdb, 0xe1, 0xe6, 0xa7, 0x54, 0x2f, 0x31, 0x53, 0x86, 0xb5, 0xe9, + 0xc7, 0xc4, 0x0c, 0x61, 0x5e, 0xfd, 0x2c, 0x0e, 0xce, 0x7d, 0x12, 0xfd, 0x9e, 0x05, 0x8f, 0xb9, + 0x4c, 0x0d, 0x98, 0x0e, 0x73, 0xad, 0x11, 0xc4, 0x49, 0x2c, 0x29, 0x54, 0x56, 0xf4, 0x52, 0x3f, + 0xd3, 0xff, 0x9f, 0x78, 0x83, 0xc7, 0xe6, 0xf7, 0xe8, 0x12, 0xde, 0xb3, 0xc3, 0xe8, 0x47, 0x61, + 0x44, 0xae, 0x8b, 0x65, 0x2a, 0x82, 0x99, 0xa2, 0xad, 0x4f, 0x9f, 0xba, 0xbb, 0x3b, 0x3e, 0xb2, + 0x6a, 0x02, 0x70, 0x1a, 0xcf, 0xfe, 0x56, 0x29, 0x75, 0x1e, 0xa2, 0x9c, 0x90, 0x4c, 0xdc, 0x34, + 0xa4, 0xff, 0x47, 0x4a, 0xcf, 0x42, 0xc5, 0x8d, 0xf2, 0x2e, 0x69, 0x71, 0xa3, 0x9a, 0x62, 0x6c, + 0x30, 0xa7, 0x46, 0xe9, 0x29, 0x27, 0xeb, 0xea, 0x14, 0x12, 0xf0, 0xd5, 0x22, 0xbb, 0xd4, 0x7d, + 0x7a, 0x75, 0x4e, 0x74, 0xed, 0x54, 0x17, 0x08, 0x77, 0x77, 0xc9, 0xfe, 0x56, 0xfa, 0x0c, 0xc6, + 0x58, 0xbc, 0x7d, 0x9c, 0x2f, 0x7d, 0xc1, 0x82, 0xa1, 0x28, 0xf0, 0x3c, 0xd7, 0x6f, 0x51, 0x41, + 0x23, 0xb4, 0xe5, 0x87, 0x8e, 0x45, 0x61, 0x09, 0x89, 0xc2, 0x4c, 0x5b, 0xac, 0x79, 0x62, 0xb3, + 0x03, 0xf6, 0x9f, 0x58, 0x30, 0xd6, 0x4b, 0x20, 0x22, 0x02, 0xef, 0x94, 0xab, 0x5d, 0x45, 0x57, + 0x2c, 0xf9, 0xb3, 0xc4, 0x23, 0xca, 0xf1, 0x5c, 0x9b, 0x7e, 0x52, 0xbc, 0xe6, 0x3b, 0x97, 0x7b, + 0xa3, 0xe2, 0xbd, 0xe8, 0xa0, 0x57, 0xe0, 0xa4, 0xf1, 0x5e, 0xb1, 0x1a, 0x98, 0xfa, 0xf4, 0x04, + 0xb5, 0x40, 0xa6, 0x32, 0xb0, 0x7b, 0xbb, 0xe3, 0x8f, 0x64, 0xdb, 0x84, 0xc4, 0xee, 0xa2, 0x63, + 0xff, 0x4a, 0x29, 0xfb, 0xb5, 0x94, 0xb2, 0x7d, 0xcb, 0xea, 0xda, 0xce, 0x7f, 0xe0, 0x38, 0x14, + 0x1c, 0xdb, 0xf8, 0xab, 0x00, 0x8e, 0xde, 0x38, 0x0f, 0xf0, 0x84, 0xd8, 0xfe, 0x57, 0x15, 0xd8, + 0xa3, 0x67, 0x7d, 0x58, 0xcf, 0x07, 0x3e, 0x56, 0xfc, 0x9c, 0xa5, 0x8e, 0x9c, 0xca, 0x6c, 0x91, + 0x37, 0x8f, 0x6b, 0xec, 0xf9, 0x06, 0x26, 0xe6, 0x51, 0x0a, 0xca, 0x8d, 0x9d, 0x3e, 0xdc, 0x42, + 0x5f, 0xb3, 0xd2, 0x87, 0x66, 0x3c, 0xec, 0xcc, 0x3d, 0xb6, 0x3e, 0x19, 0x27, 0x71, 0xbc, 0x63, + 0xfa, 0xfc, 0xa6, 0xd7, 0x19, 0xdd, 0x04, 0xc0, 0xba, 0xeb, 0x3b, 0x9e, 0xfb, 0x06, 0xdd, 0x9e, + 0x54, 0x99, 0x86, 0x65, 0x26, 0xcb, 0x65, 0xd5, 0x8a, 0x0d, 0x8c, 0xf3, 0x7f, 0x01, 0x86, 0x8c, + 0x37, 0xcf, 0x09, 0xae, 0x38, 0x63, 0x06, 0x57, 0xd4, 0x8d, 0x98, 0x88, 0xf3, 0xef, 0x83, 0x93, + 0xd9, 0x0e, 0x1e, 0xe4, 0x79, 0xfb, 0x7f, 0x0e, 0x66, 0x4f, 0xb1, 0x56, 0x49, 0xd4, 0xa6, 0x5d, + 0x7b, 0xdb, 0xb3, 0xf4, 0xb6, 0x67, 0xe9, 0x6d, 0xcf, 0x92, 0x79, 0x38, 0x20, 0xbc, 0x26, 0x83, + 0xf7, 0xc9, 0x6b, 0x92, 0xf2, 0x03, 0xd5, 0x0a, 0xf7, 0x03, 0xd9, 0x77, 0xab, 0x90, 0xb2, 0xa3, + 0xf8, 0x78, 0xff, 0x10, 0x0c, 0x46, 0x24, 0x0c, 0x6e, 0xe0, 0x05, 0xa1, 0x43, 0x74, 0x00, 0x3d, + 0x6f, 0xc6, 0x12, 0x4e, 0x75, 0x4d, 0xe8, 0x24, 0x1b, 0x42, 0x89, 0x28, 0x5d, 0xb3, 0xec, 0x24, + 0x1b, 0x98, 0x41, 0xd0, 0xfb, 0x60, 0x34, 0x71, 0xa2, 0x16, 0xb5, 0xb7, 0xb7, 0xd8, 0x67, 0x15, + 0x67, 0x9d, 0x8f, 0x08, 0xdc, 0xd1, 0xd5, 0x14, 0x14, 0x67, 0xb0, 0xd1, 0xeb, 0x50, 0xd9, 0x20, + 0x5e, 0x5b, 0x0c, 0xf9, 0x4a, 0x71, 0x32, 0x9e, 0xbd, 0xeb, 0x15, 0xe2, 0xb5, 0xb9, 0x04, 0xa2, + 0xbf, 0x30, 0x63, 0x45, 0xe7, 0x5b, 0x7d, 0xb3, 0x13, 0x27, 0x41, 0xdb, 0x7d, 0x43, 0xba, 0xf8, + 0x3e, 0x50, 0x30, 0xe3, 0x6b, 0x92, 0x3e, 0xf7, 0xa5, 0xa8, 0xbf, 0x58, 0x73, 0x66, 0xfd, 0x68, + 0xba, 0x11, 0xfb, 0x54, 0x3b, 0xc2, 0x53, 0x57, 0x74, 0x3f, 0x66, 0x25, 0x7d, 0xde, 0x0f, 0xf5, + 0x17, 0x6b, 0xce, 0x68, 0x47, 0xcd, 0xfb, 0x21, 0xd6, 0x87, 0x1b, 0x05, 0xf7, 0x81, 0xcf, 0xf9, + 0xdc, 0xf9, 0xff, 0x24, 0x54, 0x1b, 0x1b, 0x4e, 0x94, 0x8c, 0x0d, 0xb3, 0x49, 0xa3, 0x7c, 0x3a, + 0x33, 0xb4, 0x11, 0x73, 0x18, 0x7a, 0x1c, 0xca, 0x11, 0x59, 0x67, 0x71, 0x9b, 0x46, 0x44, 0x0f, + 0x26, 0xeb, 0x98, 0xb6, 0xdb, 0xbf, 0x54, 0x4a, 0x9b, 0x4b, 0xe9, 0xf7, 0xe6, 0xb3, 0xbd, 0xd1, + 0x89, 0x62, 0xe9, 0xf7, 0x31, 0x66, 0x3b, 0x6b, 0xc6, 0x12, 0x8e, 0x3e, 0x69, 0xc1, 0xe0, 0xed, + 0x38, 0xf0, 0x7d, 0x92, 0x08, 0xd5, 0x74, 0xb3, 0xe0, 0xa1, 0xb8, 0xca, 0xa9, 0xeb, 0x3e, 0x88, + 0x06, 0x2c, 0xf9, 0xd2, 0xee, 0x92, 0xed, 0x86, 0xd7, 0x69, 0x76, 0x05, 0x69, 0x5c, 0xe2, 0xcd, + 0x58, 0xc2, 0x29, 0xaa, 0xeb, 0x73, 0xd4, 0x4a, 0x1a, 0x75, 0xde, 0x17, 0xa8, 0x02, 0x6e, 0xff, + 0xd5, 0x01, 0x38, 0x9b, 0xbb, 0x38, 0xa8, 0x21, 0xc3, 0x4c, 0x85, 0xcb, 0xae, 0x47, 0x64, 0x78, + 0x12, 0x33, 0x64, 0x6e, 0xaa, 0x56, 0x6c, 0x60, 0xa0, 0x9f, 0x06, 0x08, 0x9d, 0xc8, 0x69, 0x13, + 0xe5, 0x97, 0x3d, 0xb2, 0xbd, 0x40, 0xfb, 0xb1, 0x2c, 0x69, 0xea, 0xbd, 0xa9, 0x6a, 0x8a, 0xb1, + 0xc1, 0x12, 0xbd, 0x00, 0x43, 0x11, 0xf1, 0x88, 0x13, 0xb3, 0xb0, 0xdf, 0x6c, 0x0e, 0x03, 0xd6, + 0x20, 0x6c, 0xe2, 0xa1, 0xa7, 0x54, 0x24, 0x57, 0x26, 0xa2, 0x25, 0x1d, 0xcd, 0x85, 0xde, 0xb4, + 0x60, 0x74, 0xdd, 0xf5, 0x88, 0xe6, 0x2e, 0x32, 0x0e, 0x96, 0x8e, 0xfe, 0x92, 0x97, 0x4d, 0xba, + 0x5a, 0x42, 0xa6, 0x9a, 0x63, 0x9c, 0x61, 0x4f, 0x3f, 0xf3, 0x16, 0x89, 0x98, 0x68, 0x1d, 0x48, + 0x7f, 0xe6, 0x9b, 0xbc, 0x19, 0x4b, 0x38, 0x9a, 0x82, 0x13, 0xa1, 0x13, 0xc7, 0x33, 0x11, 0x69, + 0x12, 0x3f, 0x71, 0x1d, 0x8f, 0xe7, 0x03, 0xd4, 0x74, 0x3c, 0xf0, 0x72, 0x1a, 0x8c, 0xb3, 0xf8, + 0xe8, 0x83, 0xf0, 0x28, 0x77, 0x7c, 0x2c, 0xba, 0x71, 0xec, 0xfa, 0x2d, 0x3d, 0x0d, 0x84, 0xff, + 0x67, 0x5c, 0x90, 0x7a, 0x74, 0x3e, 0x1f, 0x0d, 0xf7, 0x7a, 0x1e, 0x3d, 0x03, 0xb5, 0x78, 0xd3, + 0x0d, 0x67, 0xa2, 0x66, 0xcc, 0x0e, 0x3d, 0x6a, 0xda, 0xdb, 0xb8, 0x22, 0xda, 0xb1, 0xc2, 0x40, + 0x0d, 0x18, 0xe6, 0x9f, 0x84, 0x87, 0xa2, 0x09, 0xf9, 0xf8, 0x6c, 0x4f, 0xf5, 0x28, 0x52, 0xd6, + 0x26, 0xb0, 0x73, 0xe7, 0x92, 0x3c, 0x82, 0xe1, 0x27, 0x06, 0x37, 0x0d, 0x32, 0x38, 0x45, 0xd4, + 0xfe, 0xc5, 0x52, 0x7a, 0xc7, 0x6d, 0x2e, 0x52, 0x14, 0xd3, 0xa5, 0x98, 0xdc, 0x74, 0x22, 0xe9, + 0x8d, 0x39, 0x62, 0xda, 0x82, 0xa0, 0x7b, 0xd3, 0x89, 0xcc, 0x45, 0xcd, 0x18, 0x60, 0xc9, 0x09, + 0xdd, 0x86, 0x4a, 0xe2, 0x39, 0x05, 0xe5, 0x39, 0x19, 0x1c, 0xb5, 0x03, 0x64, 0x61, 0x2a, 0xc6, + 0x8c, 0x07, 0x7a, 0x8c, 0x5a, 0xfd, 0x6b, 0xf2, 0x88, 0x44, 0x18, 0xea, 0x6b, 0x31, 0x66, 0xad, + 0xf6, 0xaf, 0x42, 0x8e, 0x5c, 0x55, 0x8a, 0x0c, 0x5d, 0x04, 0xa0, 0x1b, 0xc8, 0xe5, 0x88, 0xac, + 0xbb, 0xdb, 0xc2, 0x90, 0x50, 0x6b, 0xf7, 0xba, 0x82, 0x60, 0x03, 0x4b, 0x3e, 0xb3, 0xd2, 0x59, + 0xa7, 0xcf, 0x94, 0xba, 0x9f, 0xe1, 0x10, 0x6c, 0x60, 0xa1, 0xe7, 0x61, 0xc0, 0x6d, 0x3b, 0x2d, + 0x15, 0x82, 0xf9, 0x18, 0x5d, 0xb4, 0xf3, 0xac, 0xe5, 0xde, 0xee, 0xf8, 0xa8, 0xea, 0x10, 0x6b, + 0xc2, 0x02, 0x17, 0xfd, 0x8a, 0x05, 0xc3, 0x8d, 0xa0, 0xdd, 0x0e, 0x7c, 0xbe, 0xed, 0x12, 0x7b, + 0xc8, 0xdb, 0xc7, 0xa5, 0xe6, 0x27, 0x66, 0x0c, 0x66, 0x7c, 0x13, 0xa9, 0x12, 0xb2, 0x4c, 0x10, + 0x4e, 0xf5, 0xca, 0x5c, 0xdb, 0xd5, 0x7d, 0xd6, 0xf6, 0x6f, 0x58, 0x70, 0x8a, 0x3f, 0x6b, 0xec, + 0x06, 0x45, 0xee, 0x51, 0x70, 0xcc, 0xaf, 0xd5, 0xb5, 0x41, 0x56, 0x5e, 0xba, 0x2e, 0x38, 0xee, + 0xee, 0x24, 0x9a, 0x83, 0x53, 0xeb, 0x41, 0xd4, 0x20, 0xe6, 0x40, 0x08, 0xc1, 0xa4, 0x08, 0x5d, + 0xce, 0x22, 0xe0, 0xee, 0x67, 0xd0, 0x4d, 0x78, 0xc4, 0x68, 0x34, 0xc7, 0x81, 0xcb, 0xa6, 0x27, + 0x04, 0xb5, 0x47, 0x2e, 0xe7, 0x62, 0xe1, 0x1e, 0x4f, 0xa7, 0x1d, 0x26, 0xf5, 0x3e, 0x1c, 0x26, + 0xaf, 0xc1, 0xb9, 0x46, 0xf7, 0xc8, 0x6c, 0xc5, 0x9d, 0xb5, 0x98, 0x4b, 0xaa, 0xda, 0xf4, 0x0f, + 0x08, 0x02, 0xe7, 0x66, 0x7a, 0x21, 0xe2, 0xde, 0x34, 0xd0, 0x47, 0xa1, 0x16, 0x11, 0xf6, 0x55, + 0x62, 0x91, 0x88, 0x73, 0xc4, 0x5d, 0xb2, 0xb6, 0x40, 0x39, 0x59, 0x2d, 0x7b, 0x45, 0x43, 0x8c, + 0x15, 0x47, 0x74, 0x07, 0x06, 0x43, 0x27, 0x69, 0x6c, 0x88, 0xf4, 0x9b, 0x23, 0xc7, 0xbf, 0x28, + 0xe6, 0xcc, 0x07, 0xae, 0x27, 0xf9, 0x32, 0x67, 0x82, 0x25, 0x37, 0x6a, 0x8d, 0x34, 0x82, 0x76, + 0x18, 0xf8, 0xc4, 0x4f, 0xe2, 0xb1, 0x11, 0x6d, 0x8d, 0xcc, 0xa8, 0x56, 0x6c, 0x60, 0x9c, 0x7f, + 0x3f, 0x9c, 0xea, 0x5a, 0x78, 0x07, 0x72, 0xae, 0xcc, 0xc2, 0x23, 0xf9, 0x53, 0xfc, 0x40, 0x2e, + 0x96, 0x7f, 0x98, 0x09, 0x72, 0x35, 0xcc, 0xde, 0x3e, 0xdc, 0x75, 0x0e, 0x94, 0x89, 0xbf, 0x25, + 0x24, 0xfe, 0xe5, 0xa3, 0x8d, 0xf4, 0x25, 0x7f, 0x8b, 0xaf, 0x50, 0xe6, 0x93, 0xb8, 0xe4, 0x6f, + 0x61, 0x4a, 0x1b, 0x7d, 0xc9, 0x4a, 0x99, 0x6d, 0xdc, 0xc9, 0xf7, 0xe1, 0x63, 0xb1, 0xf3, 0xfb, + 0xb6, 0xe4, 0xec, 0x7f, 0x5d, 0x82, 0x0b, 0xfb, 0x11, 0xe9, 0x63, 0xf8, 0x9e, 0x84, 0x81, 0x98, + 0x1d, 0x5b, 0x0b, 0x11, 0x3a, 0x44, 0x67, 0x16, 0x3f, 0xc8, 0x7e, 0x0d, 0x0b, 0x10, 0xf2, 0xa0, + 0xdc, 0x76, 0x42, 0xe1, 0xfb, 0x99, 0x3f, 0x6a, 0xda, 0x0b, 0xfd, 0xef, 0x78, 0x8b, 0x4e, 0xc8, + 0x3d, 0x0a, 0x46, 0x03, 0xa6, 0x6c, 0x50, 0x02, 0x55, 0x27, 0x8a, 0x1c, 0x79, 0x46, 0x7a, 0xad, + 0x18, 0x7e, 0x53, 0x94, 0x24, 0x3f, 0x62, 0x4a, 0x35, 0x61, 0xce, 0xcc, 0xfe, 0xdc, 0x60, 0x2a, + 0xf5, 0x83, 0x1d, 0x7c, 0xc7, 0x30, 0x20, 0x5c, 0x3e, 0x56, 0xd1, 0xd9, 0x46, 0x3c, 0x77, 0x8f, + 0xed, 0xea, 0x44, 0x06, 0xb4, 0x60, 0x85, 0x3e, 0x6b, 0xb1, 0x3c, 0x63, 0x99, 0x0e, 0x23, 0xf6, + 0x52, 0xc7, 0x93, 0xf6, 0x6c, 0x66, 0x2f, 0xcb, 0x46, 0x6c, 0x72, 0xa7, 0x3a, 0x36, 0xe4, 0x19, + 0x73, 0xd9, 0x1d, 0x95, 0xcc, 0x44, 0x96, 0x70, 0xb4, 0x9d, 0x73, 0xc0, 0x5d, 0x40, 0xae, 0x6a, + 0x1f, 0x47, 0xda, 0x5f, 0xb3, 0xe0, 0x94, 0x9b, 0x3d, 0xa9, 0x14, 0x3b, 0x8f, 0x23, 0x86, 0x50, + 0xf4, 0x3e, 0x08, 0x55, 0xca, 0xb7, 0x0b, 0x84, 0xbb, 0x3b, 0x83, 0x9a, 0x50, 0x71, 0xfd, 0xf5, + 0x40, 0x98, 0x1c, 0xd3, 0x47, 0xeb, 0xd4, 0xbc, 0xbf, 0x1e, 0xe8, 0xd5, 0x4c, 0xff, 0x61, 0x46, + 0x1d, 0x2d, 0xc0, 0x99, 0x48, 0xf8, 0x86, 0xae, 0xb8, 0x31, 0xdd, 0xc1, 0x2f, 0xb8, 0x6d, 0x37, + 0x61, 0xe6, 0x42, 0x79, 0x7a, 0xec, 0xee, 0xee, 0xf8, 0x19, 0x9c, 0x03, 0xc7, 0xb9, 0x4f, 0xa1, + 0x37, 0x60, 0x50, 0x26, 0x46, 0xd7, 0x8a, 0xd8, 0xc5, 0x75, 0xcf, 0x7f, 0x35, 0x99, 0x56, 0x44, + 0x0e, 0xb4, 0x64, 0x68, 0xbf, 0x39, 0x04, 0xdd, 0x87, 0x98, 0xe8, 0x63, 0x50, 0x8f, 0x54, 0xb2, + 0xb6, 0x55, 0x84, 0x72, 0x95, 0xdf, 0x57, 0x1c, 0xa0, 0x2a, 0xc3, 0x45, 0xa7, 0x65, 0x6b, 0x8e, + 0x74, 0x7b, 0x11, 0xeb, 0xb3, 0xce, 0x02, 0xe6, 0xb6, 0xe0, 0xaa, 0xcf, 0xb1, 0x76, 0xfc, 0x06, + 0x66, 0x3c, 0x50, 0x04, 0x03, 0x1b, 0xc4, 0xf1, 0x92, 0x8d, 0x62, 0x5c, 0xee, 0x57, 0x18, 0xad, + 0x6c, 0xca, 0x0e, 0x6f, 0xc5, 0x82, 0x13, 0xda, 0x86, 0xc1, 0x0d, 0x3e, 0x01, 0x84, 0xc5, 0xbf, + 0x78, 0xd4, 0xc1, 0x4d, 0xcd, 0x2a, 0xfd, 0xb9, 0x45, 0x03, 0x96, 0xec, 0x58, 0x74, 0x8c, 0x71, + 0x7e, 0xcf, 0x97, 0x6e, 0x71, 0xd9, 0x4a, 0xfd, 0x1f, 0xde, 0x7f, 0x04, 0x86, 0x23, 0xd2, 0x08, + 0xfc, 0x86, 0xeb, 0x91, 0xe6, 0x94, 0x74, 0xa7, 0x1f, 0x24, 0xc7, 0x85, 0xed, 0x9a, 0xb1, 0x41, + 0x03, 0xa7, 0x28, 0xa2, 0xcf, 0x58, 0x30, 0xaa, 0x32, 0x3c, 0xe9, 0x07, 0x21, 0xc2, 0x7d, 0xbb, + 0x50, 0x50, 0x3e, 0x29, 0xa3, 0x39, 0x8d, 0xee, 0xee, 0x8e, 0x8f, 0xa6, 0xdb, 0x70, 0x86, 0x2f, + 0x7a, 0x05, 0x20, 0x58, 0xe3, 0x21, 0x30, 0x53, 0x89, 0xf0, 0xe5, 0x1e, 0xe4, 0x55, 0x47, 0x79, + 0xb2, 0x9b, 0xa4, 0x80, 0x0d, 0x6a, 0xe8, 0x1a, 0x00, 0x5f, 0x36, 0xab, 0x3b, 0xa1, 0xdc, 0x16, + 0xc8, 0x24, 0x25, 0x58, 0x51, 0x90, 0x7b, 0xbb, 0xe3, 0xdd, 0xbe, 0x35, 0x16, 0x66, 0x60, 0x3c, + 0x8e, 0x7e, 0x0a, 0x06, 0xe3, 0x4e, 0xbb, 0xed, 0x28, 0x4f, 0x6f, 0x81, 0xe9, 0x73, 0x9c, 0xae, + 0x21, 0x8a, 0x78, 0x03, 0x96, 0x1c, 0xd1, 0x6d, 0x2a, 0x54, 0x63, 0xe1, 0xf4, 0x63, 0xab, 0x88, + 0xdb, 0x04, 0x43, 0xec, 0x9d, 0xde, 0x23, 0x23, 0x7a, 0x70, 0x0e, 0xce, 0xbd, 0xdd, 0xf1, 0x47, + 0xd2, 0xed, 0x0b, 0x81, 0x48, 0x68, 0xcb, 0xa5, 0x89, 0xae, 0xca, 0x3a, 0x29, 0xf4, 0xb5, 0x65, + 0xfa, 0xfe, 0xd3, 0xba, 0x4e, 0x0a, 0x6b, 0xee, 0x3d, 0x66, 0xe6, 0xc3, 0x68, 0x11, 0x4e, 0x37, + 0x02, 0x3f, 0x89, 0x02, 0xcf, 0xe3, 0xc5, 0x7f, 0xf8, 0x0e, 0x8d, 0x7b, 0x82, 0xdf, 0x29, 0xba, + 0x7d, 0x7a, 0xa6, 0x1b, 0x05, 0xe7, 0x3d, 0x67, 0xfb, 0xe9, 0xd8, 0x40, 0x31, 0x38, 0xcf, 0xc3, + 0x30, 0xd9, 0x4e, 0x48, 0xe4, 0x3b, 0xde, 0x0d, 0xbc, 0x20, 0x7d, 0xa0, 0x6c, 0x0d, 0x5c, 0x32, + 0xda, 0x71, 0x0a, 0x0b, 0xd9, 0xca, 0x2d, 0x61, 0x24, 0x69, 0x72, 0xb7, 0x84, 0x74, 0x42, 0xd8, + 0xff, 0xab, 0x94, 0x32, 0xc8, 0x56, 0x23, 0x42, 0x50, 0x00, 0x55, 0x3f, 0x68, 0x2a, 0xd9, 0x7f, + 0xb5, 0x18, 0xd9, 0x7f, 0x3d, 0x68, 0x1a, 0xc5, 0x54, 0xe8, 0xbf, 0x18, 0x73, 0x3e, 0xac, 0xda, + 0x84, 0x2c, 0xcb, 0xc1, 0x00, 0x62, 0xa3, 0x51, 0x24, 0x67, 0x55, 0x6d, 0x62, 0xc9, 0x64, 0x84, + 0xd3, 0x7c, 0xd1, 0x26, 0x54, 0x37, 0x82, 0x38, 0x91, 0xdb, 0x8f, 0x23, 0xee, 0x74, 0xae, 0x04, + 0x71, 0xc2, 0xac, 0x08, 0xf5, 0xda, 0xb4, 0x25, 0xc6, 0x9c, 0x87, 0xfd, 0x9f, 0xad, 0x94, 0xc7, + 0xfb, 0x16, 0x8b, 0x93, 0xdd, 0x22, 0x3e, 0x5d, 0xd6, 0x66, 0x60, 0xd0, 0x8f, 0x66, 0xb2, 0x0e, + 0xdf, 0xd5, 0xab, 0xb4, 0xd5, 0x1d, 0x4a, 0x61, 0x82, 0x91, 0x30, 0x62, 0x88, 0x3e, 0x61, 0xa5, + 0xf3, 0x3f, 0x4b, 0x45, 0x6c, 0x30, 0xcc, 0x1c, 0xe8, 0x7d, 0x53, 0x49, 0xed, 0x2f, 0x59, 0x30, + 0x38, 0xed, 0x34, 0x36, 0x83, 0xf5, 0x75, 0xf4, 0x0c, 0xd4, 0x9a, 0x9d, 0xc8, 0x4c, 0x45, 0x55, + 0xdb, 0xfc, 0x59, 0xd1, 0x8e, 0x15, 0x06, 0x9d, 0xc3, 0xeb, 0x4e, 0x43, 0x66, 0x42, 0x97, 0xf9, + 0x1c, 0xbe, 0xcc, 0x5a, 0xb0, 0x80, 0xa0, 0x17, 0x60, 0xa8, 0xed, 0x6c, 0xcb, 0x87, 0xb3, 0xee, + 0xf6, 0x45, 0x0d, 0xc2, 0x26, 0x9e, 0xfd, 0xcf, 0x2d, 0x18, 0x9b, 0x76, 0x62, 0xb7, 0x31, 0xd5, + 0x49, 0x36, 0xa6, 0xdd, 0x64, 0xad, 0xd3, 0xd8, 0x24, 0x09, 0x4f, 0x7f, 0xa7, 0xbd, 0xec, 0xc4, + 0x74, 0x29, 0xa9, 0x7d, 0x9d, 0xea, 0xe5, 0x0d, 0xd1, 0x8e, 0x15, 0x06, 0x7a, 0x03, 0x86, 0x42, + 0x27, 0x8e, 0xef, 0x04, 0x51, 0x13, 0x93, 0xf5, 0x62, 0x8a, 0x4f, 0xac, 0x90, 0x46, 0x44, 0x12, + 0x4c, 0xd6, 0xc5, 0x91, 0xb0, 0xa6, 0x8f, 0x4d, 0x66, 0xf6, 0x17, 0x2c, 0x38, 0x37, 0x4d, 0x9c, + 0x88, 0x44, 0xac, 0x56, 0x85, 0x7a, 0x91, 0x19, 0x2f, 0xe8, 0x34, 0xd1, 0xeb, 0x50, 0x4b, 0x68, + 0x33, 0xed, 0x96, 0x55, 0x6c, 0xb7, 0xd8, 0x89, 0xee, 0xaa, 0x20, 0x8e, 0x15, 0x1b, 0xfb, 0xaf, + 0x59, 0x30, 0xcc, 0x0e, 0xc7, 0x66, 0x49, 0xe2, 0xb8, 0x5e, 0x57, 0x49, 0x27, 0xab, 0xcf, 0x92, + 0x4e, 0x17, 0xa0, 0xb2, 0x11, 0xb4, 0x49, 0xf6, 0x60, 0xf7, 0x4a, 0x40, 0xb7, 0xd5, 0x14, 0x82, + 0x9e, 0xa3, 0x1f, 0xde, 0xf5, 0x13, 0x87, 0x2e, 0x01, 0xe9, 0x7c, 0x3d, 0xc1, 0x3f, 0xba, 0x6a, + 0xc6, 0x26, 0x8e, 0xfd, 0xdb, 0x75, 0x18, 0x14, 0xa7, 0xff, 0x7d, 0x97, 0x40, 0x90, 0xfb, 0xfb, + 0x52, 0xcf, 0xfd, 0x7d, 0x0c, 0x03, 0x0d, 0x56, 0x30, 0x4e, 0x98, 0x91, 0xd7, 0x0a, 0x09, 0x17, + 0xe1, 0x35, 0xe8, 0x74, 0xb7, 0xf8, 0x7f, 0x2c, 0x58, 0xa1, 0x2f, 0x5a, 0x70, 0xa2, 0x11, 0xf8, + 0x3e, 0x69, 0x68, 0x1b, 0xa7, 0x52, 0x44, 0x54, 0xc0, 0x4c, 0x9a, 0xa8, 0x3e, 0x99, 0xc9, 0x00, + 0x70, 0x96, 0x3d, 0x7a, 0x09, 0x46, 0xf8, 0x98, 0xdd, 0x4c, 0x79, 0x8c, 0x75, 0xa5, 0x1f, 0x13, + 0x88, 0xd3, 0xb8, 0x68, 0x82, 0x7b, 0xde, 0x45, 0x4d, 0x9d, 0x01, 0xed, 0x58, 0x33, 0xaa, 0xe9, + 0x18, 0x18, 0x28, 0x02, 0x14, 0x91, 0xf5, 0x88, 0xc4, 0x1b, 0x22, 0x3a, 0x82, 0xd9, 0x57, 0x83, + 0x87, 0x4b, 0x97, 0xc6, 0x5d, 0x94, 0x70, 0x0e, 0x75, 0xb4, 0x29, 0x36, 0x98, 0xb5, 0x22, 0x64, + 0xa8, 0xf8, 0xcc, 0x3d, 0xf7, 0x99, 0xe3, 0x50, 0x8d, 0x37, 0x9c, 0xa8, 0xc9, 0xec, 0xba, 0x32, + 0x4f, 0xd1, 0x59, 0xa1, 0x0d, 0x98, 0xb7, 0xa3, 0x59, 0x38, 0x99, 0xa9, 0x53, 0x14, 0x0b, 0xcf, + 0xae, 0x4a, 0xc7, 0xc8, 0x54, 0x38, 0x8a, 0x71, 0xd7, 0x13, 0xa6, 0xf3, 0x61, 0x68, 0x1f, 0xe7, + 0xc3, 0x8e, 0x8a, 0xc1, 0xe3, 0x3e, 0xd7, 0x97, 0x0b, 0x19, 0x80, 0xbe, 0x02, 0xee, 0x3e, 0x9f, + 0x09, 0xb8, 0x1b, 0x61, 0x1d, 0xb8, 0x59, 0x4c, 0x07, 0x0e, 0x1e, 0x5d, 0xf7, 0x20, 0xa3, 0xe5, + 0xfe, 0xdc, 0x02, 0xf9, 0x5d, 0x67, 0x9c, 0xc6, 0x06, 0xa1, 0x53, 0x06, 0xbd, 0x0f, 0x46, 0xd5, + 0x16, 0x7a, 0x26, 0xe8, 0xf8, 0x3c, 0x50, 0xae, 0xac, 0x8f, 0x70, 0x71, 0x0a, 0x8a, 0x33, 0xd8, + 0x68, 0x12, 0xea, 0x74, 0x9c, 0xf8, 0xa3, 0x5c, 0xd7, 0xaa, 0x6d, 0xfa, 0xd4, 0xf2, 0xbc, 0x78, + 0x4a, 0xe3, 0xa0, 0x00, 0x4e, 0x79, 0x4e, 0x9c, 0xb0, 0x1e, 0xd0, 0x1d, 0xf5, 0x21, 0x8b, 0x15, + 0xb0, 0x98, 0xff, 0x85, 0x2c, 0x21, 0xdc, 0x4d, 0xdb, 0xfe, 0x76, 0x05, 0x46, 0x52, 0x92, 0xf1, + 0x80, 0x4a, 0xfa, 0x19, 0xa8, 0x49, 0xbd, 0x99, 0x2d, 0xab, 0xa2, 0x94, 0xab, 0xc2, 0xa0, 0x4a, + 0x6b, 0x4d, 0x6b, 0xd5, 0xac, 0x51, 0x61, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x9c, 0x78, 0xf1, + 0x8c, 0xe7, 0x12, 0x3f, 0xe1, 0xdd, 0x2c, 0x46, 0x28, 0xaf, 0x2e, 0xac, 0x98, 0x44, 0xb5, 0x50, + 0xce, 0x00, 0x70, 0x96, 0x3d, 0xfa, 0xb4, 0x05, 0x23, 0xce, 0x9d, 0x58, 0x57, 0x35, 0x15, 0xa1, + 0x75, 0x47, 0x54, 0x52, 0xa9, 0x42, 0xa9, 0xdc, 0xe5, 0x9b, 0x6a, 0xc2, 0x69, 0xa6, 0xe8, 0x2d, + 0x0b, 0x10, 0xd9, 0x26, 0x0d, 0x19, 0xfc, 0x27, 0xfa, 0x32, 0x50, 0xc4, 0x4e, 0xf3, 0x52, 0x17, + 0x5d, 0x2e, 0xd5, 0xbb, 0xdb, 0x71, 0x4e, 0x1f, 0xec, 0x7f, 0x52, 0x56, 0x0b, 0x4a, 0xc7, 0x9b, + 0x3a, 0x46, 0xdc, 0x9b, 0x75, 0xf8, 0xb8, 0x37, 0x1d, 0x3f, 0xd0, 0x9d, 0x03, 0x99, 0x4a, 0x99, + 0x2a, 0x3d, 0xa0, 0x94, 0xa9, 0x9f, 0xb1, 0x52, 0x05, 0x84, 0x86, 0x2e, 0xbe, 0x52, 0x6c, 0xac, + 0xeb, 0x04, 0x8f, 0x6d, 0xc8, 0x48, 0xf7, 0x74, 0x48, 0x0b, 0x95, 0xa6, 0x06, 0xda, 0x81, 0xa4, + 0xe1, 0xbf, 0x2b, 0xc3, 0x90, 0xa1, 0x49, 0x73, 0xcd, 0x22, 0xeb, 0x21, 0x33, 0x8b, 0x4a, 0x07, + 0x30, 0x8b, 0x7e, 0x1a, 0xea, 0x0d, 0x29, 0xe5, 0x8b, 0x29, 0xa1, 0x9b, 0xd5, 0x1d, 0x5a, 0xd0, + 0xab, 0x26, 0xac, 0x79, 0xa2, 0xb9, 0x54, 0xa2, 0x8d, 0xd0, 0x10, 0x15, 0xa6, 0x21, 0xf2, 0x32, + 0x61, 0x84, 0xa6, 0xe8, 0x7e, 0x86, 0xd5, 0x99, 0x0a, 0x5d, 0xf1, 0x5e, 0x32, 0x22, 0x9d, 0xd7, + 0x99, 0x5a, 0x9e, 0x97, 0xcd, 0xd8, 0xc4, 0xb1, 0xbf, 0x6d, 0xa9, 0x8f, 0x7b, 0x1f, 0x2a, 0x2a, + 0xdc, 0x4e, 0x57, 0x54, 0xb8, 0x54, 0xc8, 0x30, 0xf7, 0x28, 0xa5, 0x70, 0x1d, 0x06, 0x67, 0x82, + 0x76, 0xdb, 0xf1, 0x9b, 0xe8, 0x07, 0x61, 0xb0, 0xc1, 0x7f, 0x0a, 0xc7, 0x0e, 0x3b, 0x1e, 0x14, + 0x50, 0x2c, 0x61, 0xe8, 0x31, 0xa8, 0x38, 0x51, 0x4b, 0x3a, 0x73, 0x58, 0x28, 0xcc, 0x54, 0xd4, + 0x8a, 0x31, 0x6b, 0xb5, 0xff, 0x41, 0x05, 0xd8, 0x09, 0xb4, 0x13, 0x91, 0xe6, 0x6a, 0xc0, 0x4a, + 0xf8, 0x1d, 0xeb, 0xa1, 0x9a, 0xde, 0x2c, 0x3d, 0xcc, 0x07, 0x6b, 0xc6, 0xe1, 0x4a, 0xf9, 0x3e, + 0x1f, 0xae, 0xf4, 0x38, 0x2f, 0xab, 0x3c, 0x44, 0xe7, 0x65, 0xf6, 0xe7, 0x2c, 0x40, 0x2a, 0x6c, + 0x41, 0x1f, 0x68, 0x4f, 0x42, 0x5d, 0x05, 0x30, 0x08, 0xc3, 0x4a, 0x8b, 0x08, 0x09, 0xc0, 0x1a, + 0xa7, 0x8f, 0x1d, 0xf2, 0x93, 0x52, 0x7e, 0x97, 0xd3, 0x51, 0xb4, 0x4c, 0xea, 0x0b, 0x71, 0x6e, + 0xff, 0x4e, 0x09, 0x1e, 0xe1, 0x2a, 0x79, 0xd1, 0xf1, 0x9d, 0x16, 0x69, 0xd3, 0x5e, 0xf5, 0x1b, + 0xa2, 0xd0, 0xa0, 0x5b, 0x33, 0x57, 0x46, 0xc5, 0x1e, 0x75, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, + 0xbc, 0xef, 0x26, 0x98, 0x11, 0x47, 0x31, 0xd4, 0x64, 0xcd, 0x78, 0x21, 0x8b, 0x0b, 0x62, 0xa4, + 0xc4, 0x92, 0xd0, 0x9b, 0x04, 0x2b, 0x46, 0xd4, 0x70, 0xf5, 0x82, 0xc6, 0x26, 0x26, 0x61, 0xc0, + 0xe4, 0xae, 0x11, 0x94, 0xb8, 0x20, 0xda, 0xb1, 0xc2, 0xb0, 0x7f, 0xc7, 0x82, 0xac, 0x46, 0x32, + 0x6a, 0xa5, 0x59, 0x7b, 0xd6, 0x4a, 0x3b, 0x40, 0xb1, 0xb2, 0x9f, 0x84, 0x21, 0x27, 0xa1, 0x46, + 0x04, 0xdf, 0x76, 0x97, 0x0f, 0x77, 0xac, 0xb1, 0x18, 0x34, 0xdd, 0x75, 0x97, 0x6d, 0xb7, 0x4d, + 0x72, 0xf6, 0x7f, 0xaf, 0xc0, 0xa9, 0xae, 0xdc, 0x0d, 0xf4, 0x22, 0x0c, 0x37, 0xc4, 0xf4, 0x08, + 0xa5, 0x43, 0xab, 0x6e, 0x06, 0xb1, 0x69, 0x18, 0x4e, 0x61, 0xf6, 0x31, 0x41, 0xe7, 0xe1, 0x74, + 0x44, 0x37, 0xfa, 0x1d, 0x32, 0xb5, 0x9e, 0x90, 0x68, 0x85, 0x34, 0x02, 0xbf, 0xc9, 0x2b, 0xfa, + 0x95, 0xa7, 0x1f, 0xbd, 0xbb, 0x3b, 0x7e, 0x1a, 0x77, 0x83, 0x71, 0xde, 0x33, 0x28, 0x84, 0x11, + 0xcf, 0xb4, 0x01, 0xc5, 0x06, 0xe0, 0x50, 0xe6, 0xa3, 0xb2, 0x11, 0x52, 0xcd, 0x38, 0xcd, 0x20, + 0x6d, 0x48, 0x56, 0x1f, 0x90, 0x21, 0xf9, 0x29, 0x6d, 0x48, 0xf2, 0xf3, 0xf7, 0x0f, 0x15, 0x9c, + 0xbb, 0x73, 0xdc, 0x96, 0xe4, 0xcb, 0x50, 0x93, 0xb1, 0x49, 0x7d, 0xc5, 0xf4, 0x98, 0x74, 0x7a, + 0x48, 0xb4, 0x7b, 0x25, 0xc8, 0xd9, 0x84, 0xd0, 0x75, 0xa6, 0x35, 0x7e, 0x6a, 0x9d, 0x1d, 0x4c, + 0xeb, 0xa3, 0x6d, 0x1e, 0x97, 0xc5, 0x75, 0xdb, 0x07, 0x8b, 0xde, 0x44, 0xe9, 0x50, 0x2d, 0x95, + 0xd2, 0xa0, 0xc2, 0xb5, 0x2e, 0x02, 0x68, 0x43, 0x4d, 0x04, 0xac, 0xab, 0x63, 0x5f, 0x6d, 0xcf, + 0x61, 0x03, 0x8b, 0xee, 0xa9, 0x5d, 0x3f, 0x4e, 0x1c, 0xcf, 0xbb, 0xe2, 0xfa, 0x89, 0x70, 0x0e, + 0x2a, 0x25, 0x3e, 0xaf, 0x41, 0xd8, 0xc4, 0x3b, 0xff, 0x1e, 0xe3, 0xbb, 0x1c, 0xe4, 0x7b, 0x6e, + 0xc0, 0xb9, 0x39, 0x37, 0x51, 0x69, 0x16, 0x6a, 0x1e, 0x51, 0x3b, 0x4c, 0xa5, 0x0d, 0x59, 0x3d, + 0xd3, 0x86, 0x8c, 0x34, 0x87, 0x52, 0x3a, 0x2b, 0x23, 0x9b, 0xe6, 0x60, 0xbf, 0x08, 0x67, 0xe6, + 0xdc, 0xe4, 0xb2, 0xeb, 0x91, 0x03, 0x32, 0xb1, 0x7f, 0x6b, 0x00, 0x86, 0xcd, 0x44, 0xbd, 0x83, + 0x64, 0x3e, 0x7d, 0x81, 0x9a, 0x5a, 0xe2, 0xed, 0x5c, 0x75, 0x68, 0x76, 0xeb, 0xc8, 0x59, 0x83, + 0xf9, 0x23, 0x66, 0x58, 0x5b, 0x9a, 0x27, 0x36, 0x3b, 0x80, 0xee, 0x40, 0x75, 0x9d, 0x85, 0xe1, + 0x97, 0x8b, 0x88, 0x2c, 0xc8, 0x1b, 0x51, 0xbd, 0xcc, 0x78, 0x20, 0x3f, 0xe7, 0x47, 0x35, 0x64, + 0x94, 0xce, 0xed, 0x32, 0x42, 0x47, 0x45, 0x56, 0x97, 0xc2, 0xe8, 0x25, 0xea, 0xab, 0x87, 0x10, + 0xf5, 0x29, 0xc1, 0x3b, 0xf0, 0x80, 0x04, 0x2f, 0x4b, 0xa9, 0x48, 0x36, 0x98, 0xfd, 0x26, 0x62, + 0xdd, 0x07, 0xd9, 0x20, 0x18, 0x29, 0x15, 0x29, 0x30, 0xce, 0xe2, 0xa3, 0x8f, 0x2b, 0xd1, 0x5d, + 0x2b, 0xc2, 0xaf, 0x6a, 0xce, 0xe8, 0xe3, 0x96, 0xda, 0x9f, 0x2b, 0xc1, 0xe8, 0x9c, 0xdf, 0x59, + 0x9e, 0x5b, 0xee, 0xac, 0x79, 0x6e, 0xe3, 0x1a, 0xd9, 0xa1, 0xa2, 0x79, 0x93, 0xec, 0xcc, 0xcf, + 0x8a, 0x15, 0xa4, 0xe6, 0xcc, 0x35, 0xda, 0x88, 0x39, 0x8c, 0x0a, 0xa3, 0x75, 0xd7, 0x6f, 0x91, + 0x28, 0x8c, 0x5c, 0xe1, 0xf2, 0x34, 0x84, 0xd1, 0x65, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, + 0xf1, 0x49, 0x94, 0x35, 0x64, 0x97, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x94, 0x44, 0x9d, 0x38, 0x11, + 0x93, 0x51, 0x21, 0xad, 0xd2, 0x46, 0xcc, 0x61, 0x74, 0xa5, 0xc7, 0x9d, 0x35, 0x16, 0xb8, 0x91, + 0x09, 0xac, 0x5f, 0xe1, 0xcd, 0x58, 0xc2, 0x29, 0xea, 0x26, 0xd9, 0x99, 0xa5, 0xbb, 0xde, 0x4c, + 0x7e, 0xcd, 0x35, 0xde, 0x8c, 0x25, 0x9c, 0x95, 0x22, 0x4c, 0x0f, 0xc7, 0xf7, 0x5c, 0x29, 0xc2, + 0x74, 0xf7, 0x7b, 0xec, 0x9f, 0x7f, 0xd9, 0x82, 0x61, 0x33, 0xdc, 0x0a, 0xb5, 0x32, 0x36, 0xee, + 0x52, 0x57, 0x25, 0xdb, 0x1f, 0xcf, 0xbb, 0xda, 0xab, 0xe5, 0x26, 0x41, 0x18, 0x3f, 0x4b, 0xfc, + 0x96, 0xeb, 0x13, 0x76, 0x8a, 0xce, 0xc3, 0xb4, 0x52, 0xb1, 0x5c, 0x33, 0x41, 0x93, 0x1c, 0xc2, + 0x48, 0xb6, 0x6f, 0xc1, 0xa9, 0xae, 0xa4, 0xaa, 0x3e, 0x4c, 0x8b, 0x7d, 0x53, 0x5a, 0x6d, 0x0c, + 0x43, 0x94, 0xb0, 0x2c, 0x87, 0x33, 0x03, 0xa7, 0xf8, 0x42, 0xa2, 0x9c, 0x56, 0x1a, 0x1b, 0xa4, + 0xad, 0x12, 0xe5, 0x98, 0x7f, 0xfd, 0x66, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0xcf, 0x5b, 0x30, 0x92, + 0xca, 0x73, 0x2b, 0xc8, 0x08, 0x62, 0x2b, 0x2d, 0x60, 0xd1, 0x7f, 0x2c, 0x04, 0xba, 0xcc, 0x94, + 0xa9, 0x5e, 0x69, 0x1a, 0x84, 0x4d, 0x3c, 0xfb, 0x4b, 0x25, 0xa8, 0xc9, 0x08, 0x8a, 0x3e, 0xba, + 0xf2, 0x59, 0x0b, 0x46, 0xd4, 0x99, 0x06, 0x73, 0x96, 0x95, 0x8a, 0x48, 0x4a, 0xa0, 0x3d, 0x50, + 0xdb, 0x6d, 0x7f, 0x3d, 0xd0, 0x16, 0x39, 0x36, 0x99, 0xe1, 0x34, 0x6f, 0x74, 0x13, 0x20, 0xde, + 0x89, 0x13, 0xd2, 0x36, 0xdc, 0x76, 0xb6, 0xb1, 0xe2, 0x26, 0x1a, 0x41, 0x44, 0xe8, 0xfa, 0xba, + 0x1e, 0x34, 0xc9, 0x8a, 0xc2, 0xd4, 0x26, 0x94, 0x6e, 0xc3, 0x06, 0x25, 0xfb, 0xef, 0x95, 0xe0, + 0x64, 0xb6, 0x4b, 0xe8, 0x43, 0x30, 0x2c, 0xb9, 0x1b, 0xd7, 0x94, 0xc9, 0xb0, 0x91, 0x61, 0x6c, + 0xc0, 0xee, 0xed, 0x8e, 0x8f, 0x77, 0x5f, 0x13, 0x37, 0x61, 0xa2, 0xe0, 0x14, 0x31, 0x7e, 0xb0, + 0x24, 0x4e, 0x40, 0xa7, 0x77, 0xa6, 0xc2, 0x50, 0x9c, 0x0e, 0x19, 0x07, 0x4b, 0x26, 0x14, 0x67, + 0xb0, 0xd1, 0x32, 0x9c, 0x31, 0x5a, 0xae, 0x13, 0xb7, 0xb5, 0xb1, 0x16, 0x44, 0x72, 0x67, 0xf5, + 0x98, 0x0e, 0xec, 0xea, 0xc6, 0xc1, 0xb9, 0x4f, 0x52, 0x6d, 0xdf, 0x70, 0x42, 0xa7, 0xe1, 0x26, + 0x3b, 0xc2, 0x0f, 0xa9, 0x64, 0xd3, 0x8c, 0x68, 0xc7, 0x0a, 0xc3, 0x5e, 0x84, 0x4a, 0x9f, 0x33, + 0xa8, 0x2f, 0x8b, 0xfe, 0x65, 0xa8, 0x51, 0x72, 0xd2, 0xbc, 0x2b, 0x82, 0x64, 0x00, 0x35, 0x79, + 0xd3, 0x08, 0xb2, 0xa1, 0xec, 0x3a, 0xf2, 0xec, 0x4e, 0xbd, 0xd6, 0x7c, 0x1c, 0x77, 0xd8, 0x26, + 0x99, 0x02, 0xd1, 0x93, 0x50, 0x26, 0xdb, 0x61, 0xf6, 0x90, 0xee, 0xd2, 0x76, 0xe8, 0x46, 0x24, + 0xa6, 0x48, 0x64, 0x3b, 0x44, 0xe7, 0xa1, 0xe4, 0x36, 0x85, 0x92, 0x02, 0x81, 0x53, 0x9a, 0x9f, + 0xc5, 0x25, 0xb7, 0x69, 0x6f, 0x43, 0x5d, 0x5d, 0x6d, 0x82, 0x36, 0xa5, 0xec, 0xb6, 0x8a, 0x08, + 0x79, 0x92, 0x74, 0x7b, 0x48, 0xed, 0x0e, 0x80, 0x4e, 0xf8, 0x2b, 0x4a, 0xbe, 0x5c, 0x80, 0x4a, + 0x23, 0x10, 0xc9, 0xc8, 0x35, 0x4d, 0x86, 0x09, 0x6d, 0x06, 0xb1, 0x6f, 0xc1, 0xe8, 0x35, 0x3f, + 0xb8, 0xc3, 0xea, 0xb2, 0xb3, 0x32, 0x64, 0x94, 0xf0, 0x3a, 0xfd, 0x91, 0x35, 0x11, 0x18, 0x14, + 0x73, 0x98, 0xaa, 0xcf, 0x54, 0xea, 0x55, 0x9f, 0xc9, 0xfe, 0x84, 0x05, 0xc3, 0x2a, 0x73, 0x68, + 0x6e, 0x6b, 0x93, 0xd2, 0x6d, 0x45, 0x41, 0x27, 0xcc, 0xd2, 0x65, 0x97, 0x0f, 0x61, 0x0e, 0x33, + 0x53, 0xea, 0x4a, 0xfb, 0xa4, 0xd4, 0x5d, 0x80, 0xca, 0xa6, 0xeb, 0x37, 0xb3, 0xb7, 0x69, 0x5c, + 0x73, 0xfd, 0x26, 0x66, 0x10, 0xda, 0x85, 0x93, 0xaa, 0x0b, 0x52, 0x21, 0xbc, 0x08, 0xc3, 0x6b, + 0x1d, 0xd7, 0x6b, 0xca, 0xfa, 0x6a, 0x19, 0x4f, 0xc9, 0xb4, 0x01, 0xc3, 0x29, 0x4c, 0xba, 0xaf, + 0x5b, 0x73, 0x7d, 0x27, 0xda, 0x59, 0xd6, 0x1a, 0x48, 0x09, 0xa5, 0x69, 0x05, 0xc1, 0x06, 0x96, + 0xfd, 0x66, 0x19, 0x46, 0xd3, 0xf9, 0x53, 0x7d, 0x6c, 0xaf, 0x9e, 0x84, 0x2a, 0x4b, 0xa9, 0xca, + 0x7e, 0x5a, 0x5e, 0x92, 0x8c, 0xc3, 0x50, 0x0c, 0x03, 0xbc, 0x18, 0x43, 0x31, 0x37, 0xd1, 0xa8, + 0x4e, 0x2a, 0xff, 0x0a, 0x8b, 0x27, 0x13, 0xf5, 0x1f, 0x04, 0x2b, 0xf4, 0x69, 0x0b, 0x06, 0x83, + 0xd0, 0xac, 0xeb, 0xf3, 0xc1, 0x22, 0x73, 0xcb, 0x44, 0xb2, 0x8c, 0xb0, 0x88, 0xd5, 0xa7, 0x97, + 0x9f, 0x43, 0xb2, 0x3e, 0xff, 0x5e, 0x18, 0x36, 0x31, 0xf7, 0x33, 0x8a, 0x6b, 0xa6, 0x51, 0xfc, + 0x59, 0x73, 0x52, 0x88, 0xec, 0xb9, 0x3e, 0x96, 0xdb, 0x0d, 0xa8, 0x36, 0x54, 0x00, 0xc0, 0xa1, + 0xaa, 0x72, 0xaa, 0xea, 0x08, 0xec, 0x10, 0x88, 0x53, 0xb3, 0xbf, 0x6d, 0x19, 0xf3, 0x03, 0x93, + 0x78, 0xbe, 0x89, 0x22, 0x28, 0xb7, 0xb6, 0x36, 0x85, 0x29, 0x7a, 0xb5, 0xa0, 0xe1, 0x9d, 0xdb, + 0xda, 0xd4, 0x73, 0xdc, 0x6c, 0xc5, 0x94, 0x59, 0x1f, 0x4e, 0xc0, 0x54, 0x92, 0x65, 0x79, 0xff, + 0x24, 0x4b, 0xfb, 0xad, 0x12, 0x9c, 0xea, 0x9a, 0x54, 0xe8, 0x0d, 0xa8, 0x46, 0xf4, 0x2d, 0xc5, + 0xeb, 0x2d, 0x14, 0x96, 0x16, 0x19, 0xcf, 0x37, 0xb5, 0xde, 0x4d, 0xb7, 0x63, 0xce, 0x12, 0x5d, + 0x05, 0xa4, 0xc3, 0x54, 0x94, 0x07, 0x92, 0xbf, 0xf2, 0x79, 0xf1, 0x28, 0x9a, 0xea, 0xc2, 0xc0, + 0x39, 0x4f, 0xa1, 0x97, 0xb2, 0x8e, 0xcc, 0x72, 0xfa, 0xdc, 0x72, 0x2f, 0x9f, 0xa4, 0xfd, 0x4f, + 0x4b, 0x30, 0x92, 0x2a, 0xb3, 0x84, 0x3c, 0xa8, 0x11, 0x8f, 0x39, 0xf5, 0xa5, 0xb2, 0x39, 0x6a, + 0xd5, 0x62, 0xa5, 0x20, 0x2f, 0x09, 0xba, 0x58, 0x71, 0x78, 0x38, 0x0e, 0xd7, 0x5f, 0x84, 0x61, + 0xd9, 0xa1, 0x0f, 0x3a, 0x6d, 0x4f, 0x0c, 0xa0, 0x9a, 0xa3, 0x97, 0x0c, 0x18, 0x4e, 0x61, 0xda, + 0xbf, 0x5b, 0x86, 0x31, 0x7e, 0x0a, 0xd2, 0x54, 0x33, 0x6f, 0x51, 0xee, 0xb7, 0xfe, 0x92, 0x2e, + 0x86, 0xc6, 0x07, 0x72, 0xed, 0xa8, 0x97, 0x04, 0xe4, 0x33, 0xea, 0x2b, 0x32, 0xeb, 0xab, 0x99, + 0xc8, 0x2c, 0x6e, 0x76, 0xb7, 0x8e, 0xa9, 0x47, 0xdf, 0x5b, 0xa1, 0x5a, 0xbf, 0x5a, 0x82, 0x13, + 0x99, 0x1b, 0x18, 0xd0, 0x9b, 0xe9, 0xa2, 0xbd, 0x56, 0x11, 0xbe, 0xf2, 0x3d, 0x8b, 0xf2, 0x1f, + 0xac, 0x74, 0xef, 0x03, 0x5a, 0x2a, 0xf6, 0x1f, 0x94, 0x60, 0x34, 0x7d, 0x75, 0xc4, 0x43, 0x38, + 0x52, 0xef, 0x86, 0x3a, 0xab, 0x8e, 0xce, 0xae, 0xc4, 0xe4, 0x2e, 0x79, 0x5e, 0x88, 0x5a, 0x36, + 0x62, 0x0d, 0x7f, 0x28, 0x2a, 0x22, 0xdb, 0x7f, 0xc7, 0x82, 0xb3, 0xfc, 0x2d, 0xb3, 0xf3, 0xf0, + 0x2f, 0xe7, 0x8d, 0xee, 0xab, 0xc5, 0x76, 0x30, 0x53, 0xc4, 0x6f, 0xbf, 0xf1, 0x65, 0x57, 0xf1, + 0x89, 0xde, 0xa6, 0xa7, 0xc2, 0x43, 0xd8, 0xd9, 0x03, 0x4d, 0x06, 0xfb, 0x0f, 0xca, 0xa0, 0x6f, + 0x1f, 0x44, 0xae, 0xc8, 0x71, 0x2c, 0xa4, 0x98, 0xe1, 0xca, 0x8e, 0xdf, 0xd0, 0xf7, 0x1c, 0xd6, + 0x32, 0x29, 0x8e, 0x3f, 0x6f, 0xc1, 0x90, 0xeb, 0xbb, 0x89, 0xeb, 0xb0, 0x6d, 0x74, 0x31, 0x37, + 0xa3, 0x29, 0x76, 0xf3, 0x9c, 0x72, 0x10, 0x99, 0xe7, 0x38, 0x8a, 0x19, 0x36, 0x39, 0xa3, 0x8f, + 0x88, 0xe0, 0xe9, 0x72, 0x61, 0xd9, 0xb9, 0xb5, 0x4c, 0xc4, 0x74, 0x48, 0x0d, 0xaf, 0x24, 0x2a, + 0x28, 0xa9, 0x1d, 0x53, 0x52, 0xaa, 0x2e, 0xae, 0xbe, 0x07, 0x9a, 0x36, 0x63, 0xce, 0xc8, 0x8e, + 0x01, 0x75, 0x8f, 0xc5, 0x01, 0x03, 0x53, 0x27, 0xa1, 0xee, 0x74, 0x92, 0xa0, 0x4d, 0x87, 0x49, + 0x1c, 0x35, 0xe9, 0xd0, 0x5b, 0x09, 0xc0, 0x1a, 0xc7, 0x7e, 0xb3, 0x0a, 0x99, 0xa4, 0x43, 0xb4, + 0x6d, 0xde, 0x9c, 0x69, 0x15, 0x7b, 0x73, 0xa6, 0xea, 0x4c, 0xde, 0xed, 0x99, 0xa8, 0x05, 0xd5, + 0x70, 0xc3, 0x89, 0xa5, 0x59, 0xfd, 0xb2, 0xda, 0xc7, 0xd1, 0xc6, 0x7b, 0xbb, 0xe3, 0x3f, 0xd1, + 0x9f, 0xd7, 0x95, 0xce, 0xd5, 0x49, 0x5e, 0x6c, 0x44, 0xb3, 0x66, 0x34, 0x30, 0xa7, 0x7f, 0x90, + 0xbb, 0xe1, 0x3e, 0x29, 0xca, 0xc0, 0x63, 0x12, 0x77, 0xbc, 0x44, 0xcc, 0x86, 0x97, 0x0b, 0x5c, + 0x65, 0x9c, 0xb0, 0x4e, 0x97, 0xe7, 0xff, 0xb1, 0xc1, 0x14, 0x7d, 0x08, 0xea, 0x71, 0xe2, 0x44, + 0xc9, 0x21, 0x13, 0x5c, 0xd5, 0xa0, 0xaf, 0x48, 0x22, 0x58, 0xd3, 0x43, 0xaf, 0xb0, 0xda, 0xae, + 0x6e, 0xbc, 0x71, 0xc8, 0x9c, 0x07, 0x59, 0x07, 0x56, 0x50, 0xc0, 0x06, 0x35, 0x74, 0x11, 0x80, + 0xcd, 0x6d, 0x1e, 0xe8, 0x57, 0x63, 0x5e, 0x26, 0x25, 0x0a, 0xb1, 0x82, 0x60, 0x03, 0xcb, 0xfe, + 0x61, 0x48, 0xd7, 0x7b, 0x40, 0xe3, 0xb2, 0xbc, 0x04, 0xf7, 0x42, 0xb3, 0xdc, 0x85, 0x54, 0x25, + 0x88, 0xdf, 0xb0, 0xc0, 0x2c, 0x4a, 0x81, 0x5e, 0xe7, 0xd5, 0x2f, 0xac, 0x22, 0x4e, 0x0e, 0x0d, + 0xba, 0x13, 0x8b, 0x4e, 0x98, 0x39, 0xc2, 0x96, 0x25, 0x30, 0xce, 0xbf, 0x07, 0x6a, 0x12, 0x7a, + 0x20, 0xa3, 0xee, 0xe3, 0x70, 0x3a, 0x7b, 0xaf, 0xb8, 0x38, 0x75, 0xda, 0xdf, 0xf5, 0x23, 0xfd, + 0x39, 0xa5, 0x5e, 0xfe, 0x9c, 0x3e, 0xee, 0x4f, 0xfd, 0x4d, 0x0b, 0x2e, 0xec, 0x77, 0xfd, 0x39, + 0x7a, 0x0c, 0x2a, 0x77, 0x9c, 0x48, 0x16, 0xdd, 0x66, 0x82, 0xf2, 0x96, 0x13, 0xf9, 0x98, 0xb5, + 0xa2, 0x1d, 0x18, 0xe0, 0xd1, 0x60, 0xc2, 0x5a, 0x7f, 0xb9, 0xd8, 0xcb, 0xd8, 0xaf, 0x11, 0x63, + 0xbb, 0xc0, 0x23, 0xd1, 0xb0, 0x60, 0x68, 0x7f, 0xc7, 0x02, 0xb4, 0xb4, 0x45, 0xa2, 0xc8, 0x6d, + 0x1a, 0xf1, 0x6b, 0xec, 0x3a, 0x15, 0xe3, 0xda, 0x14, 0x33, 0xc5, 0x35, 0x73, 0x9d, 0x8a, 0xf1, + 0x2f, 0xff, 0x3a, 0x95, 0xd2, 0xc1, 0xae, 0x53, 0x41, 0x4b, 0x70, 0xb6, 0xcd, 0xb7, 0x1b, 0xfc, + 0x8a, 0x02, 0xbe, 0xf7, 0x50, 0x09, 0x65, 0xe7, 0xee, 0xee, 0x8e, 0x9f, 0x5d, 0xcc, 0x43, 0xc0, + 0xf9, 0xcf, 0xd9, 0xef, 0x01, 0xc4, 0xc3, 0xd6, 0x66, 0xf2, 0x62, 0x90, 0x7a, 0xba, 0x5f, 0xec, + 0xaf, 0x54, 0xe1, 0x44, 0xa6, 0x24, 0x2b, 0xdd, 0xea, 0x75, 0x07, 0x3d, 0x1d, 0x59, 0x7f, 0x77, + 0x77, 0xaf, 0xaf, 0x30, 0x2a, 0x1f, 0xaa, 0xae, 0x1f, 0x76, 0x92, 0x62, 0x72, 0x48, 0x79, 0x27, + 0xe6, 0x29, 0x41, 0xc3, 0x5d, 0x4c, 0xff, 0x62, 0xce, 0xa6, 0xc8, 0xa0, 0xac, 0x94, 0x31, 0x5e, + 0x79, 0x40, 0xee, 0x80, 0x4f, 0xea, 0x10, 0xa9, 0x6a, 0x11, 0x8e, 0xc5, 0xcc, 0x64, 0x39, 0xee, + 0xa3, 0xf6, 0x5f, 0x2f, 0xc1, 0x90, 0xf1, 0xd1, 0xd0, 0x2f, 0xa5, 0x4b, 0x36, 0x59, 0xc5, 0xbd, + 0x12, 0xa3, 0x3f, 0xa1, 0x8b, 0x32, 0xf1, 0x57, 0x7a, 0xaa, 0xbb, 0x5a, 0xd3, 0xbd, 0xdd, 0xf1, + 0x93, 0x99, 0x7a, 0x4c, 0xa9, 0x0a, 0x4e, 0xe7, 0x3f, 0x06, 0x27, 0x32, 0x64, 0x72, 0x5e, 0x79, + 0x35, 0x7d, 0x6d, 0xfc, 0x11, 0xdd, 0x52, 0xe6, 0x90, 0x7d, 0x83, 0x0e, 0x99, 0x48, 0xa3, 0x0b, + 0x3c, 0xd2, 0x87, 0x0f, 0x36, 0x93, 0x2d, 0x5b, 0xea, 0x33, 0x5b, 0xf6, 0x69, 0xa8, 0x85, 0x81, + 0xe7, 0x36, 0x5c, 0x55, 0x85, 0x90, 0xe5, 0xe7, 0x2e, 0x8b, 0x36, 0xac, 0xa0, 0xe8, 0x0e, 0xd4, + 0xd5, 0x0d, 0xfb, 0xc2, 0xbf, 0x5d, 0xd4, 0xa1, 0x8f, 0x32, 0x5a, 0xf4, 0xcd, 0xf9, 0x9a, 0x17, + 0xb2, 0x61, 0x80, 0x29, 0x41, 0x19, 0xfa, 0xcf, 0x7c, 0xef, 0x4c, 0x3b, 0xc6, 0x58, 0x40, 0xec, + 0xaf, 0xd7, 0xe1, 0x4c, 0x5e, 0x5d, 0x6c, 0xf4, 0x51, 0x18, 0xe0, 0x7d, 0x2c, 0xe6, 0xea, 0x85, + 0x3c, 0x1e, 0x73, 0x8c, 0xa0, 0xe8, 0x16, 0xfb, 0x8d, 0x05, 0x4f, 0xc1, 0xdd, 0x73, 0xd6, 0xc4, + 0x0c, 0x39, 0x1e, 0xee, 0x0b, 0x8e, 0xe6, 0xbe, 0xe0, 0x70, 0xee, 0x9e, 0xb3, 0x86, 0xb6, 0xa1, + 0xda, 0x72, 0x13, 0xe2, 0x08, 0x27, 0xc2, 0xad, 0x63, 0x61, 0x4e, 0x1c, 0x6e, 0xa5, 0xb1, 0x9f, + 0x98, 0x33, 0x44, 0x5f, 0xb3, 0xe0, 0xc4, 0x5a, 0x3a, 0x35, 0x5e, 0x08, 0x4f, 0xe7, 0x18, 0x6a, + 0x9f, 0xa7, 0x19, 0xf1, 0xfb, 0x84, 0x32, 0x8d, 0x38, 0xdb, 0x1d, 0xf4, 0x29, 0x0b, 0x06, 0xd7, + 0x5d, 0xcf, 0x28, 0x83, 0x7b, 0x0c, 0x1f, 0xe7, 0x32, 0x63, 0xa0, 0x77, 0x1c, 0xfc, 0x7f, 0x8c, + 0x25, 0xe7, 0x5e, 0x9a, 0x6a, 0xe0, 0xa8, 0x9a, 0x6a, 0xf0, 0x01, 0x69, 0xaa, 0xcf, 0x58, 0x50, + 0x57, 0x23, 0x2d, 0xd2, 0x9d, 0x3f, 0x74, 0x8c, 0x9f, 0x9c, 0x7b, 0x4e, 0xd4, 0x5f, 0xac, 0x99, + 0xa3, 0x2f, 0x5a, 0x30, 0xe4, 0xbc, 0xd1, 0x89, 0x48, 0x93, 0x6c, 0x05, 0x61, 0x2c, 0x2e, 0x23, + 0x7c, 0xb5, 0xf8, 0xce, 0x4c, 0x51, 0x26, 0xb3, 0x64, 0x6b, 0x29, 0x8c, 0x45, 0x5a, 0x92, 0x6e, + 0xc0, 0x66, 0x17, 0xec, 0xdd, 0x12, 0x8c, 0xef, 0x43, 0x01, 0xbd, 0x08, 0xc3, 0x41, 0xd4, 0x72, + 0x7c, 0xf7, 0x0d, 0xb3, 0xd6, 0x85, 0xb2, 0xb2, 0x96, 0x0c, 0x18, 0x4e, 0x61, 0x9a, 0x09, 0xd9, + 0xa5, 0x7d, 0x12, 0xb2, 0x2f, 0x40, 0x25, 0x22, 0x61, 0x90, 0xdd, 0x2c, 0xb0, 0x94, 0x00, 0x06, + 0x41, 0x8f, 0x43, 0xd9, 0x09, 0x5d, 0x11, 0x88, 0xa6, 0xf6, 0x40, 0x53, 0xcb, 0xf3, 0x98, 0xb6, + 0xa7, 0xea, 0x43, 0x54, 0xef, 0x4b, 0x7d, 0x08, 0xaa, 0x06, 0xc4, 0xd9, 0xc5, 0x80, 0x56, 0x03, + 0xe9, 0x33, 0x05, 0xfb, 0xad, 0x32, 0x3c, 0xbe, 0xe7, 0x7c, 0xd1, 0x71, 0x78, 0xd6, 0x1e, 0x71, + 0x78, 0x72, 0x78, 0x4a, 0xfb, 0x0d, 0x4f, 0xb9, 0xc7, 0xf0, 0x7c, 0x8a, 0x2e, 0x03, 0x59, 0x23, + 0xa4, 0x98, 0xeb, 0xe4, 0x7a, 0x95, 0x1c, 0x11, 0x2b, 0x40, 0x42, 0xb1, 0xe6, 0x4b, 0xf7, 0x00, + 0xa9, 0x64, 0xe4, 0x6a, 0x11, 0x6a, 0xa0, 0x67, 0xcd, 0x10, 0x3e, 0xf7, 0x7b, 0x65, 0x38, 0xdb, + 0xbf, 0x50, 0x82, 0x27, 0xfb, 0x90, 0xde, 0xe6, 0x2c, 0xb6, 0xfa, 0x9c, 0xc5, 0xdf, 0xdb, 0x9f, + 0xc9, 0xfe, 0x2b, 0x16, 0x9c, 0xef, 0xad, 0x3c, 0xd0, 0x73, 0x30, 0xb4, 0x16, 0x39, 0x7e, 0x63, + 0x83, 0x5d, 0x91, 0x29, 0x07, 0x85, 0x8d, 0xb5, 0x6e, 0xc6, 0x26, 0x0e, 0xdd, 0xde, 0xf2, 0x98, + 0x04, 0x03, 0x43, 0x26, 0x8f, 0xd2, 0xed, 0xed, 0x6a, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x3f, 0x2b, + 0xe5, 0x77, 0x8b, 0x1b, 0x19, 0x07, 0xf9, 0x4e, 0xe2, 0x2b, 0x94, 0xfa, 0x90, 0x25, 0xe5, 0xfb, + 0x2d, 0x4b, 0x2a, 0xbd, 0x64, 0x09, 0x9a, 0x85, 0x93, 0xc6, 0x15, 0x2a, 0x3c, 0x21, 0x98, 0x07, + 0xdc, 0xaa, 0x2a, 0x19, 0xcb, 0x19, 0x38, 0xee, 0x7a, 0x02, 0x3d, 0x03, 0x35, 0xd7, 0x8f, 0x49, + 0xa3, 0x13, 0xf1, 0x40, 0x6f, 0x23, 0x09, 0x6b, 0x5e, 0xb4, 0x63, 0x85, 0x61, 0xff, 0x72, 0x09, + 0xce, 0xf5, 0xb4, 0xb3, 0xee, 0x93, 0xec, 0x32, 0x3f, 0x47, 0xe5, 0xfe, 0x7c, 0x0e, 0x73, 0x90, + 0xaa, 0xfb, 0x0e, 0xd2, 0x1f, 0xf6, 0x9e, 0x98, 0xd4, 0xe6, 0xfe, 0xbe, 0x1d, 0xa5, 0x97, 0x60, + 0xc4, 0x09, 0x43, 0x8e, 0xc7, 0xe2, 0x35, 0x33, 0x55, 0x72, 0xa6, 0x4c, 0x20, 0x4e, 0xe3, 0xf6, + 0xa5, 0x3d, 0xff, 0xd8, 0x82, 0x3a, 0x26, 0xeb, 0x5c, 0x3a, 0xa0, 0xdb, 0x62, 0x88, 0xac, 0x22, + 0xea, 0x69, 0xd2, 0x81, 0x8d, 0x5d, 0x56, 0x67, 0x32, 0x6f, 0xb0, 0xbb, 0xaf, 0xda, 0x29, 0x1d, + 0xe8, 0xaa, 0x1d, 0x75, 0xd9, 0x4a, 0xb9, 0xf7, 0x65, 0x2b, 0xf6, 0x37, 0x06, 0xe9, 0xeb, 0x85, + 0xc1, 0x4c, 0x44, 0x9a, 0x31, 0xfd, 0xbe, 0x9d, 0xc8, 0x13, 0x93, 0x44, 0x7d, 0xdf, 0x1b, 0x78, + 0x01, 0xd3, 0xf6, 0xd4, 0x51, 0x4c, 0xe9, 0x40, 0x35, 0x42, 0xca, 0xfb, 0xd6, 0x08, 0x79, 0x09, + 0x46, 0xe2, 0x78, 0x63, 0x39, 0x72, 0xb7, 0x9c, 0x84, 0x5c, 0x23, 0x3b, 0xc2, 0xca, 0xd2, 0x79, + 0xfd, 0x2b, 0x57, 0x34, 0x10, 0xa7, 0x71, 0xd1, 0x1c, 0x9c, 0xd2, 0x95, 0x3a, 0x48, 0x94, 0xb0, + 0xe8, 0x7e, 0x3e, 0x13, 0x54, 0x12, 0xaf, 0xae, 0xed, 0x21, 0x10, 0x70, 0xf7, 0x33, 0x54, 0xbe, + 0xa5, 0x1a, 0x69, 0x47, 0x06, 0xd2, 0xf2, 0x2d, 0x45, 0x87, 0xf6, 0xa5, 0xeb, 0x09, 0xb4, 0x08, + 0xa7, 0xf9, 0xc4, 0x98, 0x0a, 0x43, 0xe3, 0x8d, 0x06, 0xd3, 0x75, 0x0c, 0xe7, 0xba, 0x51, 0x70, + 0xde, 0x73, 0xe8, 0x05, 0x18, 0x52, 0xcd, 0xf3, 0xb3, 0xe2, 0x14, 0x41, 0x79, 0x31, 0x14, 0x99, + 0xf9, 0x26, 0x36, 0xf1, 0xd0, 0x07, 0xe1, 0x51, 0xfd, 0x97, 0xa7, 0x80, 0xf1, 0xa3, 0xb5, 0x59, + 0x51, 0x04, 0x49, 0x5d, 0xed, 0x31, 0x97, 0x8b, 0xd6, 0xc4, 0xbd, 0x9e, 0x47, 0x6b, 0x70, 0x5e, + 0x81, 0x2e, 0xf9, 0x09, 0xcb, 0xe7, 0x88, 0xc9, 0xb4, 0x13, 0x93, 0x1b, 0x91, 0x27, 0xee, 0x46, + 0x55, 0xb7, 0x2e, 0xce, 0xb9, 0xc9, 0x95, 0x3c, 0x4c, 0xbc, 0x80, 0xf7, 0xa0, 0x82, 0x26, 0xa1, + 0x4e, 0x7c, 0x67, 0xcd, 0x23, 0x4b, 0x33, 0xf3, 0xac, 0x98, 0x92, 0x71, 0x92, 0x77, 0x49, 0x02, + 0xb0, 0xc6, 0x51, 0x11, 0xa6, 0xc3, 0x3d, 0x6f, 0x00, 0x5d, 0x86, 0x33, 0xad, 0x46, 0x48, 0x6d, + 0x0f, 0xb7, 0x41, 0xa6, 0x1a, 0x2c, 0xa0, 0x8e, 0x7e, 0x18, 0x5e, 0x60, 0x52, 0x85, 0x4f, 0xcf, + 0xcd, 0x2c, 0x77, 0xe1, 0xe0, 0xdc, 0x27, 0x59, 0xe0, 0x65, 0x14, 0x6c, 0xef, 0x8c, 0x9d, 0xce, + 0x04, 0x5e, 0xd2, 0x46, 0xcc, 0x61, 0xe8, 0x2a, 0x20, 0x16, 0x8b, 0x7f, 0x25, 0x49, 0x42, 0x65, + 0xec, 0x8c, 0x9d, 0x61, 0xaf, 0xa4, 0xc2, 0xc8, 0x2e, 0x77, 0x61, 0xe0, 0x9c, 0xa7, 0xec, 0x7f, + 0x6f, 0xc1, 0x88, 0x5a, 0xaf, 0xf7, 0x21, 0x1b, 0xc5, 0x4b, 0x67, 0xa3, 0xcc, 0x1d, 0x5d, 0xe2, + 0xb1, 0x9e, 0xf7, 0x08, 0x69, 0xfe, 0xd9, 0x21, 0x00, 0x2d, 0x15, 0x95, 0x42, 0xb2, 0x7a, 0x2a, + 0xa4, 0x87, 0x56, 0x22, 0xe5, 0x55, 0x4e, 0xa9, 0x3e, 0xd8, 0xca, 0x29, 0x2b, 0x70, 0x56, 0x9a, + 0x0b, 0xfc, 0xac, 0xe8, 0x4a, 0x10, 0x2b, 0x01, 0x57, 0x9b, 0x7e, 0x5c, 0x10, 0x3a, 0x3b, 0x9f, + 0x87, 0x84, 0xf3, 0x9f, 0x4d, 0x59, 0x29, 0x83, 0xfb, 0x59, 0x29, 0x7a, 0x4d, 0x2f, 0xac, 0xcb, + 0x3b, 0x3c, 0x32, 0x6b, 0x7a, 0xe1, 0xf2, 0x0a, 0xd6, 0x38, 0xf9, 0x82, 0xbd, 0x5e, 0x90, 0x60, + 0x87, 0x03, 0x0b, 0x76, 0x29, 0x62, 0x86, 0x7a, 0x8a, 0x18, 0xe9, 0x93, 0x1e, 0xee, 0xe9, 0x93, + 0x7e, 0x1f, 0x8c, 0xba, 0xfe, 0x06, 0x89, 0xdc, 0x84, 0x34, 0xd9, 0x5a, 0x60, 0xe2, 0xa7, 0xa6, + 0xd5, 0xfa, 0x7c, 0x0a, 0x8a, 0x33, 0xd8, 0x69, 0xb9, 0x38, 0xda, 0x87, 0x5c, 0xec, 0xa1, 0x8d, + 0x4e, 0x14, 0xa3, 0x8d, 0x4e, 0x1e, 0x5d, 0x1b, 0x9d, 0x3a, 0x56, 0x6d, 0x84, 0x0a, 0xd1, 0x46, + 0x7d, 0x09, 0x7a, 0x63, 0xfb, 0x77, 0x66, 0x9f, 0xed, 0x5f, 0x2f, 0x55, 0x74, 0xf6, 0xd0, 0xaa, + 0x28, 0x5f, 0xcb, 0x3c, 0x72, 0x28, 0x2d, 0xf3, 0x99, 0x12, 0x9c, 0xd5, 0x72, 0x98, 0xce, 0x7e, + 0x77, 0x9d, 0x4a, 0x22, 0x76, 0x0d, 0x14, 0x3f, 0xb7, 0x31, 0x92, 0xa3, 0x74, 0x9e, 0x95, 0x82, + 0x60, 0x03, 0x8b, 0xe5, 0x18, 0x91, 0x88, 0x95, 0xd1, 0xcd, 0x0a, 0xe9, 0x19, 0xd1, 0x8e, 0x15, + 0x06, 0x9d, 0x5f, 0xf4, 0xb7, 0xc8, 0xdb, 0xcc, 0x16, 0x8b, 0x9b, 0xd1, 0x20, 0x6c, 0xe2, 0xa1, + 0xa7, 0x39, 0x13, 0x26, 0x20, 0xa8, 0xa0, 0x1e, 0x16, 0xf7, 0xc2, 0x4a, 0x99, 0xa0, 0xa0, 0xb2, + 0x3b, 0x2c, 0x99, 0xac, 0xda, 0xdd, 0x1d, 0x16, 0x02, 0xa5, 0x30, 0xec, 0xff, 0x61, 0xc1, 0xb9, + 0xdc, 0xa1, 0xb8, 0x0f, 0xca, 0x77, 0x3b, 0xad, 0x7c, 0x57, 0x8a, 0xda, 0x6e, 0x18, 0x6f, 0xd1, + 0x43, 0x11, 0xff, 0x5b, 0x0b, 0x46, 0x35, 0xfe, 0x7d, 0x78, 0x55, 0x37, 0xfd, 0xaa, 0xc5, 0xed, + 0xac, 0xea, 0x5d, 0xef, 0xf6, 0xbb, 0x25, 0x50, 0x05, 0x1c, 0xa7, 0x1a, 0xb2, 0x3c, 0xee, 0x3e, + 0x27, 0x89, 0x3b, 0x30, 0xc0, 0x0e, 0x42, 0xe3, 0x62, 0x82, 0x3c, 0xd2, 0xfc, 0xd9, 0xa1, 0xaa, + 0x3e, 0x64, 0x66, 0x7f, 0x63, 0x2c, 0x18, 0xb2, 0x22, 0xcf, 0x6e, 0x4c, 0xa5, 0x79, 0x53, 0xa4, + 0x65, 0xe9, 0x22, 0xcf, 0xa2, 0x1d, 0x2b, 0x0c, 0xaa, 0x1e, 0xdc, 0x46, 0xe0, 0xcf, 0x78, 0x4e, + 0x2c, 0xef, 0x3e, 0x54, 0xea, 0x61, 0x5e, 0x02, 0xb0, 0xc6, 0x61, 0x67, 0xa4, 0x6e, 0x1c, 0x7a, + 0xce, 0x8e, 0xb1, 0x7f, 0x36, 0xea, 0x13, 0x28, 0x10, 0x36, 0xf1, 0xec, 0x36, 0x8c, 0xa5, 0x5f, + 0x62, 0x96, 0xac, 0xb3, 0x00, 0xc5, 0xbe, 0x86, 0x73, 0x12, 0xea, 0x0e, 0x7b, 0x6a, 0xa1, 0xe3, + 0x64, 0xaf, 0x2c, 0x9f, 0x92, 0x00, 0xac, 0x71, 0xec, 0x5f, 0xb3, 0xe0, 0x74, 0xce, 0xa0, 0x15, + 0x98, 0xf6, 0x96, 0x68, 0x69, 0x93, 0xa7, 0xd8, 0x7f, 0x08, 0x06, 0x9b, 0x64, 0xdd, 0x91, 0x21, + 0x70, 0x86, 0x6c, 0x9f, 0xe5, 0xcd, 0x58, 0xc2, 0xed, 0xff, 0x66, 0xc1, 0x89, 0x74, 0x5f, 0x63, + 0x96, 0x4a, 0xc2, 0x87, 0xc9, 0x8d, 0x1b, 0xc1, 0x16, 0x89, 0x76, 0xe8, 0x9b, 0x5b, 0x99, 0x54, + 0x92, 0x2e, 0x0c, 0x9c, 0xf3, 0x14, 0x2b, 0xdf, 0xda, 0x54, 0xa3, 0x2d, 0x67, 0xe4, 0xcd, 0x22, + 0x67, 0xa4, 0xfe, 0x98, 0xe6, 0x71, 0xb9, 0x62, 0x89, 0x4d, 0xfe, 0xf6, 0x77, 0x2a, 0xa0, 0xf2, + 0x62, 0x59, 0xfc, 0x51, 0x41, 0xd1, 0x5b, 0x07, 0xcd, 0x20, 0x52, 0x93, 0xa1, 0xb2, 0x57, 0x40, + 0x00, 0xf7, 0x92, 0x98, 0xae, 0x4b, 0xf5, 0x86, 0xab, 0x1a, 0x84, 0x4d, 0x3c, 0xda, 0x13, 0xcf, + 0xdd, 0x22, 0xfc, 0xa1, 0x81, 0x74, 0x4f, 0x16, 0x24, 0x00, 0x6b, 0x1c, 0xda, 0x93, 0xa6, 0xbb, + 0xbe, 0x2e, 0xb6, 0xfc, 0xaa, 0x27, 0x74, 0x74, 0x30, 0x83, 0xf0, 0x8a, 0xdc, 0xc1, 0xa6, 0xb0, + 0x82, 0x8d, 0x8a, 0xdc, 0xc1, 0x26, 0x66, 0x10, 0x6a, 0xb7, 0xf9, 0x41, 0xd4, 0x66, 0x57, 0xca, + 0x37, 0x15, 0x17, 0x61, 0xfd, 0x2a, 0xbb, 0xed, 0x7a, 0x37, 0x0a, 0xce, 0x7b, 0x8e, 0xce, 0xc0, + 0x30, 0x22, 0x4d, 0xb7, 0x91, 0x98, 0xd4, 0x20, 0x3d, 0x03, 0x97, 0xbb, 0x30, 0x70, 0xce, 0x53, + 0x68, 0x0a, 0x4e, 0xc8, 0xbc, 0x66, 0x59, 0xb5, 0x66, 0x28, 0x5d, 0x25, 0x03, 0xa7, 0xc1, 0x38, + 0x8b, 0x4f, 0xa5, 0x5a, 0x5b, 0x14, 0xac, 0x62, 0xc6, 0xb2, 0x21, 0xd5, 0x64, 0x21, 0x2b, 0xac, + 0x30, 0xec, 0x4f, 0x96, 0xa9, 0x16, 0xee, 0x51, 0xa8, 0xed, 0xbe, 0x45, 0x0b, 0xa6, 0x67, 0x64, + 0xa5, 0x8f, 0x19, 0xf9, 0x3c, 0x0c, 0xdf, 0x8e, 0x03, 0x5f, 0x45, 0xe2, 0x55, 0x7b, 0x46, 0xe2, + 0x19, 0x58, 0xf9, 0x91, 0x78, 0x03, 0x45, 0x45, 0xe2, 0x0d, 0x1e, 0x32, 0x12, 0xef, 0x5b, 0x55, + 0x50, 0x57, 0x83, 0x5c, 0x27, 0xc9, 0x9d, 0x20, 0xda, 0x74, 0xfd, 0x16, 0xcb, 0x07, 0xff, 0x9a, + 0x05, 0xc3, 0x7c, 0xbd, 0x2c, 0x98, 0x99, 0x54, 0xeb, 0x05, 0xdd, 0x39, 0x91, 0x62, 0x36, 0xb1, + 0x6a, 0x30, 0xca, 0x5c, 0xbd, 0x69, 0x82, 0x70, 0xaa, 0x47, 0xe8, 0x63, 0x00, 0xd2, 0x3f, 0xba, + 0x2e, 0x45, 0xe6, 0x7c, 0x31, 0xfd, 0xc3, 0x64, 0x5d, 0xdb, 0xc0, 0xab, 0x8a, 0x09, 0x36, 0x18, + 0xa2, 0xcf, 0xe8, 0x2c, 0x33, 0x1e, 0xb2, 0xff, 0x91, 0x63, 0x19, 0x9b, 0x7e, 0x72, 0xcc, 0x30, + 0x0c, 0xba, 0x7e, 0x8b, 0xce, 0x13, 0x11, 0xb1, 0xf4, 0xae, 0xbc, 0x5a, 0x0a, 0x0b, 0x81, 0xd3, + 0x9c, 0x76, 0x3c, 0xc7, 0x6f, 0x90, 0x68, 0x9e, 0xa3, 0x9b, 0x17, 0x4e, 0xb3, 0x06, 0x2c, 0x09, + 0x75, 0x5d, 0xaa, 0x52, 0xed, 0xe7, 0x52, 0x95, 0xf3, 0xef, 0x87, 0x53, 0x5d, 0x1f, 0xf3, 0x40, + 0x29, 0x65, 0x87, 0xcf, 0x46, 0xb3, 0xff, 0xd9, 0x80, 0x56, 0x5a, 0xd7, 0x83, 0x26, 0xbf, 0xda, + 0x23, 0xd2, 0x5f, 0x54, 0xd8, 0xb8, 0x05, 0x4e, 0x11, 0xe3, 0xd2, 0x6a, 0xd5, 0x88, 0x4d, 0x96, + 0x74, 0x8e, 0x86, 0x4e, 0x44, 0xfc, 0xe3, 0x9e, 0xa3, 0xcb, 0x8a, 0x09, 0x36, 0x18, 0xa2, 0x8d, + 0x54, 0x4e, 0xc9, 0xe5, 0xa3, 0xe7, 0x94, 0xb0, 0x2a, 0x53, 0x79, 0xd5, 0xf8, 0xbf, 0x68, 0xc1, + 0xa8, 0x9f, 0x9a, 0xb9, 0xc5, 0x84, 0x91, 0xe6, 0xaf, 0x0a, 0x7e, 0xb3, 0x54, 0xba, 0x0d, 0x67, + 0xf8, 0xe7, 0xa9, 0xb4, 0xea, 0x01, 0x55, 0x9a, 0xbe, 0x23, 0x68, 0xa0, 0xd7, 0x1d, 0x41, 0xc8, + 0x57, 0x97, 0xa4, 0x0d, 0x16, 0x7e, 0x49, 0x1a, 0xe4, 0x5c, 0x90, 0x76, 0x0b, 0xea, 0x8d, 0x88, + 0x38, 0xc9, 0x21, 0xef, 0xcb, 0x62, 0x07, 0xf4, 0x33, 0x92, 0x00, 0xd6, 0xb4, 0xec, 0xff, 0x5d, + 0x81, 0x93, 0x72, 0x44, 0x64, 0x08, 0x3a, 0xd5, 0x8f, 0x9c, 0xaf, 0x36, 0x6e, 0x95, 0x7e, 0xbc, + 0x22, 0x01, 0x58, 0xe3, 0x50, 0x7b, 0xac, 0x13, 0x93, 0xa5, 0x90, 0xf8, 0x0b, 0xee, 0x5a, 0x2c, + 0xce, 0x39, 0xd5, 0x42, 0xb9, 0xa1, 0x41, 0xd8, 0xc4, 0xa3, 0xc6, 0x38, 0xb7, 0x8b, 0xe3, 0x6c, + 0xfa, 0x8a, 0xb0, 0xb7, 0xb1, 0x84, 0xa3, 0x5f, 0xcc, 0xad, 0x1c, 0x5b, 0x4c, 0xe2, 0x56, 0x57, + 0xe4, 0xfd, 0x01, 0xaf, 0x58, 0xfc, 0x5b, 0x16, 0x9c, 0xe5, 0xad, 0x72, 0x24, 0x6f, 0x84, 0x4d, + 0x27, 0x21, 0x71, 0x31, 0x95, 0xdc, 0x73, 0xfa, 0xa7, 0x9d, 0xbc, 0x79, 0x6c, 0x71, 0x7e, 0x6f, + 0xd0, 0x9b, 0x16, 0x9c, 0xd8, 0x4c, 0xd5, 0xfc, 0x90, 0xaa, 0xe3, 0xa8, 0xe9, 0xf8, 0x29, 0xa2, + 0x7a, 0xa9, 0xa5, 0xdb, 0x63, 0x9c, 0xe5, 0x6e, 0xff, 0x99, 0x05, 0xa6, 0x18, 0xbd, 0xff, 0xa5, + 0x42, 0x0e, 0x6e, 0x0a, 0x4a, 0xeb, 0xb2, 0xda, 0xd3, 0xba, 0x7c, 0x1c, 0xca, 0x1d, 0xb7, 0x29, + 0xf6, 0x17, 0xfa, 0xf4, 0x75, 0x7e, 0x16, 0xd3, 0x76, 0xfb, 0x1f, 0x57, 0xb5, 0xdf, 0x42, 0xe4, + 0x45, 0x7d, 0x5f, 0xbc, 0xf6, 0xba, 0x2a, 0x36, 0xc6, 0xdf, 0xfc, 0x7a, 0x57, 0xb1, 0xb1, 0x1f, + 0x3b, 0x78, 0xda, 0x1b, 0x1f, 0xa0, 0x5e, 0xb5, 0xc6, 0x06, 0xf7, 0xc9, 0x79, 0xbb, 0x0d, 0x35, + 0xba, 0x05, 0x63, 0x0e, 0xc8, 0x5a, 0xaa, 0x53, 0xb5, 0x2b, 0xa2, 0xfd, 0xde, 0xee, 0xf8, 0x7b, + 0x0f, 0xde, 0x2d, 0xf9, 0x34, 0x56, 0xf4, 0x51, 0x0c, 0x75, 0xfa, 0x9b, 0xa5, 0xe7, 0x89, 0xcd, + 0xdd, 0x0d, 0x25, 0x33, 0x25, 0xa0, 0x90, 0xdc, 0x3f, 0xcd, 0x07, 0xf9, 0x50, 0x67, 0xb7, 0xd1, + 0x32, 0xa6, 0x7c, 0x0f, 0xb8, 0xac, 0x92, 0xe4, 0x24, 0xe0, 0xde, 0xee, 0xf8, 0x4b, 0x07, 0x67, + 0xaa, 0x1e, 0xc7, 0x9a, 0x85, 0xfd, 0xa5, 0x8a, 0x9e, 0xbb, 0xa2, 0xc6, 0xdc, 0xf7, 0xc5, 0xdc, + 0x7d, 0x31, 0x33, 0x77, 0x2f, 0x74, 0xcd, 0xdd, 0x51, 0x7d, 0x6b, 0x6a, 0x6a, 0x36, 0xde, 0x6f, + 0x43, 0x60, 0x7f, 0x7f, 0x03, 0xb3, 0x80, 0x5e, 0xef, 0xb8, 0x11, 0x89, 0x97, 0xa3, 0x8e, 0xef, + 0xfa, 0x2d, 0x36, 0x1d, 0x6b, 0xa6, 0x05, 0x94, 0x02, 0xe3, 0x2c, 0x3e, 0xdd, 0xd4, 0xd3, 0x6f, + 0x7e, 0xcb, 0xd9, 0xe2, 0xb3, 0xca, 0x28, 0xbb, 0xb5, 0x22, 0xda, 0xb1, 0xc2, 0xb0, 0xbf, 0xc1, + 0xce, 0xb2, 0x8d, 0xbc, 0x60, 0x3a, 0x27, 0x3c, 0x76, 0xfd, 0x2f, 0xaf, 0xd9, 0xa5, 0xe6, 0x04, + 0xbf, 0xf3, 0x97, 0xc3, 0xd0, 0x1d, 0x18, 0x5c, 0xe3, 0xf7, 0xdf, 0x15, 0x53, 0x9f, 0x5c, 0x5c, + 0xa6, 0xc7, 0x6e, 0x39, 0x91, 0x37, 0xeb, 0xdd, 0xd3, 0x3f, 0xb1, 0xe4, 0x66, 0x7f, 0xb3, 0x02, + 0x27, 0x32, 0x17, 0xc4, 0xa6, 0xaa, 0xa5, 0x96, 0xf6, 0xad, 0x96, 0xfa, 0x61, 0x80, 0x26, 0x09, + 0xbd, 0x60, 0x87, 0x99, 0x63, 0x95, 0x03, 0x9b, 0x63, 0xca, 0x82, 0x9f, 0x55, 0x54, 0xb0, 0x41, + 0x51, 0x14, 0x2a, 0xe3, 0xc5, 0x57, 0x33, 0x85, 0xca, 0x8c, 0x5b, 0x0c, 0x06, 0xee, 0xef, 0x2d, + 0x06, 0x2e, 0x9c, 0xe0, 0x5d, 0x54, 0xd9, 0xb7, 0x87, 0x48, 0xb2, 0x65, 0xf9, 0x0b, 0xb3, 0x69, + 0x32, 0x38, 0x4b, 0xf7, 0x41, 0xde, 0xff, 0x8c, 0xde, 0x0d, 0x75, 0xf9, 0x9d, 0xe3, 0xb1, 0xba, + 0xae, 0x60, 0x20, 0xa7, 0x01, 0xbb, 0x97, 0x59, 0xfc, 0xb4, 0xbf, 0x50, 0xa2, 0xd6, 0x33, 0xff, + 0xa7, 0x2a, 0xd1, 0x3c, 0x05, 0x03, 0x4e, 0x27, 0xd9, 0x08, 0xba, 0xee, 0xd0, 0x9b, 0x62, 0xad, + 0x58, 0x40, 0xd1, 0x02, 0x54, 0x9a, 0xba, 0xba, 0xc8, 0x41, 0x46, 0x51, 0x3b, 0x22, 0x9d, 0x84, + 0x60, 0x46, 0x05, 0x3d, 0x06, 0x95, 0xc4, 0x69, 0xc9, 0x44, 0x27, 0x96, 0xdc, 0xba, 0xea, 0xb4, + 0x62, 0xcc, 0x5a, 0x4d, 0xa5, 0x59, 0xd9, 0x47, 0x69, 0xbe, 0x04, 0x23, 0xb1, 0xdb, 0xf2, 0x9d, + 0xa4, 0x13, 0x11, 0xe3, 0x70, 0x4d, 0xc7, 0x4b, 0x98, 0x40, 0x9c, 0xc6, 0xb5, 0x7f, 0x6b, 0x18, + 0xce, 0xac, 0xcc, 0x2c, 0xca, 0x9a, 0xd9, 0xc7, 0x96, 0xab, 0x94, 0xc7, 0xe3, 0xfe, 0xe5, 0x2a, + 0xf5, 0xe0, 0xee, 0x19, 0xb9, 0x4a, 0x9e, 0x91, 0xab, 0x94, 0x4e, 0x1c, 0x29, 0x17, 0x91, 0x38, + 0x92, 0xd7, 0x83, 0x7e, 0x12, 0x47, 0x8e, 0x2d, 0x79, 0x69, 0xcf, 0x0e, 0x1d, 0x28, 0x79, 0x49, + 0x65, 0x76, 0x15, 0x12, 0xd2, 0xdf, 0xe3, 0x53, 0xe5, 0x66, 0x76, 0xa9, 0xac, 0x1a, 0x9e, 0xae, + 0x22, 0x04, 0xec, 0xab, 0xc5, 0x77, 0xa0, 0x8f, 0xac, 0x1a, 0x91, 0x31, 0x63, 0x66, 0x72, 0x0d, + 0x16, 0x91, 0xc9, 0x95, 0xd7, 0x9d, 0x7d, 0x33, 0xb9, 0x5e, 0x82, 0x91, 0x86, 0x17, 0xf8, 0x64, + 0x39, 0x0a, 0x92, 0xa0, 0x11, 0x78, 0xc2, 0x98, 0x56, 0x22, 0x61, 0xc6, 0x04, 0xe2, 0x34, 0x6e, + 0xaf, 0x34, 0xb0, 0xfa, 0x51, 0xd3, 0xc0, 0xe0, 0x01, 0xa5, 0x81, 0xfd, 0x9c, 0x4e, 0x58, 0x1e, + 0x62, 0x5f, 0xe4, 0xc3, 0xc5, 0x7f, 0x91, 0x7e, 0xb2, 0x96, 0xd1, 0x5b, 0xfc, 0x12, 0x3b, 0x6a, + 0x8e, 0xce, 0x04, 0x6d, 0x6a, 0x6e, 0x0d, 0xb3, 0x21, 0x79, 0xed, 0x18, 0x26, 0xec, 0xad, 0x15, + 0xcd, 0x46, 0x5d, 0x6c, 0xa7, 0x9b, 0x70, 0xba, 0x23, 0x47, 0x49, 0xa8, 0xfe, 0x4a, 0x09, 0x7e, + 0x60, 0xdf, 0x2e, 0xa0, 0x3b, 0x00, 0x89, 0xd3, 0x12, 0x13, 0x55, 0x1c, 0x53, 0x1c, 0x31, 0xa8, + 0x71, 0x55, 0xd2, 0xe3, 0x95, 0x40, 0xd4, 0x5f, 0x76, 0x00, 0x20, 0x7f, 0xb3, 0x58, 0xc6, 0xc0, + 0xeb, 0x2a, 0x98, 0x88, 0x03, 0x8f, 0x60, 0x06, 0xa1, 0xea, 0x3f, 0x22, 0x2d, 0x7d, 0xeb, 0xb2, + 0xfa, 0x7c, 0x98, 0xb5, 0x62, 0x01, 0x45, 0x2f, 0xc0, 0x90, 0xe3, 0x79, 0x3c, 0x2b, 0x85, 0xc4, + 0xe2, 0x16, 0x1b, 0x5d, 0xb9, 0x4d, 0x83, 0xb0, 0x89, 0x67, 0xff, 0x69, 0x09, 0xc6, 0xf7, 0x91, + 0x29, 0x5d, 0x79, 0x76, 0xd5, 0xbe, 0xf3, 0xec, 0x44, 0x66, 0xc0, 0x40, 0x8f, 0xcc, 0x80, 0x17, + 0x60, 0x28, 0x21, 0x4e, 0x5b, 0x84, 0x41, 0x89, 0xfd, 0xb7, 0x3e, 0x77, 0xd5, 0x20, 0x6c, 0xe2, + 0x51, 0x29, 0x36, 0xea, 0x34, 0x1a, 0x24, 0x8e, 0x65, 0xe8, 0xbf, 0xf0, 0x61, 0x16, 0x96, 0x57, + 0xc0, 0x5c, 0xc3, 0x53, 0x29, 0x16, 0x38, 0xc3, 0x32, 0x3b, 0xe0, 0xf5, 0x3e, 0x07, 0xfc, 0xeb, + 0x25, 0x78, 0x7c, 0x4f, 0xed, 0xd6, 0x77, 0x56, 0x46, 0x27, 0x26, 0x51, 0x76, 0xe2, 0xdc, 0x88, + 0x49, 0x84, 0x19, 0x84, 0x8f, 0x52, 0x18, 0x1a, 0xb7, 0x5a, 0x17, 0x9d, 0x32, 0xc4, 0x47, 0x29, + 0xc5, 0x02, 0x67, 0x58, 0x1e, 0x76, 0x5a, 0xfe, 0xdd, 0x12, 0x3c, 0xd9, 0x87, 0x0d, 0x50, 0x60, + 0x6a, 0x55, 0x3a, 0xc1, 0xad, 0xfc, 0x80, 0xf2, 0x10, 0x0f, 0x39, 0x5c, 0xdf, 0x28, 0xc1, 0xf9, + 0xde, 0xaa, 0x18, 0xfd, 0x38, 0xdd, 0xc3, 0xcb, 0xd8, 0x27, 0x33, 0x37, 0xee, 0x34, 0xdf, 0xbf, + 0xa7, 0x40, 0x38, 0x8b, 0x8b, 0x26, 0x00, 0x42, 0x27, 0xd9, 0x88, 0x2f, 0x6d, 0xbb, 0x71, 0x22, + 0x6a, 0xbf, 0x8c, 0xf2, 0x13, 0x23, 0xd9, 0x8a, 0x0d, 0x0c, 0xca, 0x8e, 0xfd, 0x9b, 0x0d, 0xae, + 0x07, 0x09, 0x7f, 0x88, 0x6f, 0x23, 0x4e, 0xcb, 0x9b, 0x32, 0x0c, 0x10, 0xce, 0xe2, 0x52, 0x76, + 0xec, 0x4c, 0x92, 0x77, 0x94, 0xef, 0x2f, 0x18, 0xbb, 0x05, 0xd5, 0x8a, 0x0d, 0x8c, 0x6c, 0xd6, + 0x5f, 0x75, 0xff, 0xac, 0x3f, 0xfb, 0x1f, 0x95, 0xe0, 0x5c, 0x4f, 0x53, 0xae, 0xbf, 0x05, 0xf8, + 0xf0, 0x65, 0xea, 0x1d, 0x6e, 0xee, 0x1c, 0x30, 0xa3, 0xec, 0x8f, 0x7b, 0xcc, 0x34, 0x91, 0x51, + 0x76, 0xf8, 0x94, 0xec, 0x87, 0x6f, 0x3c, 0xbb, 0x92, 0xc8, 0x2a, 0x07, 0x48, 0x22, 0xcb, 0x7c, + 0x8c, 0x6a, 0x9f, 0x0b, 0xf9, 0xcf, 0xcb, 0x3d, 0x87, 0x97, 0x6e, 0xfd, 0xfa, 0xf2, 0x8e, 0xce, + 0xc2, 0x49, 0xd7, 0x67, 0xb7, 0x26, 0xad, 0x74, 0xd6, 0x44, 0x39, 0x90, 0x52, 0xfa, 0xce, 0xf2, + 0xf9, 0x0c, 0x1c, 0x77, 0x3d, 0xf1, 0x10, 0x26, 0xf5, 0x1d, 0x6e, 0x48, 0x0f, 0x96, 0x56, 0x8a, + 0x96, 0xe0, 0xac, 0x1c, 0x8a, 0x0d, 0x27, 0x22, 0x4d, 0xa1, 0x46, 0x62, 0x91, 0xc6, 0x70, 0x8e, + 0xa7, 0x42, 0xe4, 0x20, 0xe0, 0xfc, 0xe7, 0xd8, 0x45, 0x35, 0x41, 0xe8, 0x36, 0xc4, 0x26, 0x47, + 0x5f, 0x54, 0x43, 0x1b, 0x31, 0x87, 0xd9, 0x1f, 0x86, 0xba, 0x7a, 0x7f, 0x1e, 0x4c, 0xad, 0x26, + 0x5d, 0x57, 0x30, 0xb5, 0x9a, 0x71, 0x06, 0x16, 0xfd, 0x5a, 0xd4, 0x24, 0xce, 0xac, 0x9e, 0x6b, + 0x64, 0x87, 0xd9, 0xc7, 0xf6, 0x8f, 0xc0, 0xb0, 0xf2, 0xb3, 0xf4, 0x7b, 0x7d, 0x8f, 0xfd, 0xa5, + 0x01, 0x18, 0x49, 0x95, 0xe4, 0x4b, 0xb9, 0x35, 0xad, 0x7d, 0xdd, 0x9a, 0x2c, 0x38, 0xbe, 0xe3, + 0xcb, 0xbb, 0xbd, 0x8c, 0xe0, 0xf8, 0x8e, 0x4f, 0x30, 0x87, 0x51, 0xf3, 0xb6, 0x19, 0xed, 0xe0, + 0x8e, 0x2f, 0x82, 0x58, 0x95, 0x79, 0x3b, 0xcb, 0x5a, 0xb1, 0x80, 0xa2, 0x4f, 0x58, 0x30, 0x1c, + 0x33, 0x9f, 0x39, 0x77, 0x0a, 0x8b, 0x49, 0x77, 0xf5, 0xe8, 0x15, 0x07, 0x55, 0xf9, 0x49, 0x16, + 0x97, 0x62, 0xb6, 0xe0, 0x14, 0x47, 0xf4, 0x69, 0x0b, 0xea, 0xea, 0x0a, 0x12, 0x71, 0x01, 0xdf, + 0x4a, 0xb1, 0x15, 0x0f, 0xb9, 0x37, 0x51, 0x1d, 0x3f, 0xa8, 0xd2, 0x73, 0x58, 0x33, 0x46, 0xb1, + 0xf2, 0xd8, 0x0e, 0x1e, 0x8f, 0xc7, 0x16, 0x72, 0xbc, 0xb5, 0xef, 0x86, 0x7a, 0xdb, 0xf1, 0xdd, + 0x75, 0x12, 0x27, 0xdc, 0x89, 0x2a, 0x0b, 0xb1, 0xca, 0x46, 0xac, 0xe1, 0x54, 0x21, 0xc7, 0xec, + 0xc5, 0x12, 0xc3, 0xeb, 0xc9, 0x14, 0xf2, 0x8a, 0x6e, 0xc6, 0x26, 0x8e, 0xe9, 0xa2, 0x85, 0x07, + 0xea, 0xa2, 0x1d, 0xda, 0xc7, 0x45, 0xfb, 0xf7, 0x2d, 0x38, 0x9b, 0xfb, 0xd5, 0x1e, 0xde, 0x70, + 0x43, 0xfb, 0xcb, 0x55, 0x38, 0x9d, 0x53, 0x5b, 0x13, 0xed, 0x98, 0xf3, 0xd9, 0x2a, 0xe2, 0xe4, + 0x3e, 0x7d, 0x10, 0x2d, 0x87, 0x31, 0x67, 0x12, 0x1f, 0xec, 0x80, 0x44, 0x1f, 0x52, 0x94, 0xef, + 0xef, 0x21, 0x85, 0x31, 0x2d, 0x2b, 0x0f, 0x74, 0x5a, 0x56, 0xf7, 0x9e, 0x96, 0xe8, 0xd7, 0x2d, + 0x18, 0x6b, 0xf7, 0x28, 0xe8, 0x2e, 0x1c, 0x8f, 0x37, 0x8f, 0xa7, 0x5c, 0xfc, 0xf4, 0x63, 0x77, + 0x77, 0xc7, 0x7b, 0xd6, 0xd1, 0xc7, 0x3d, 0x7b, 0x65, 0x7f, 0xa7, 0x0c, 0xac, 0xb0, 0x2b, 0xab, + 0x9f, 0xb6, 0x83, 0x3e, 0x6e, 0x96, 0xe8, 0xb5, 0x8a, 0x2a, 0x27, 0xcb, 0x89, 0xab, 0x12, 0xbf, + 0x7c, 0x04, 0xf3, 0x2a, 0xfe, 0x66, 0x85, 0x56, 0xa9, 0x0f, 0xa1, 0xe5, 0xc9, 0x5a, 0xc8, 0xe5, + 0xe2, 0x6b, 0x21, 0xd7, 0xb3, 0x75, 0x90, 0xf7, 0xfe, 0xc4, 0x95, 0x87, 0xf2, 0x13, 0xff, 0x0d, + 0x8b, 0x0b, 0x9e, 0xcc, 0x57, 0xd0, 0x96, 0x81, 0xb5, 0x87, 0x65, 0xf0, 0x0c, 0xd4, 0x62, 0xe2, + 0xad, 0x5f, 0x21, 0x8e, 0x27, 0x2c, 0x08, 0x7d, 0x6a, 0x2c, 0xda, 0xb1, 0xc2, 0x60, 0x97, 0xa5, + 0x7a, 0x5e, 0x70, 0xe7, 0x52, 0x3b, 0x4c, 0x76, 0x84, 0x2d, 0xa1, 0x2f, 0x4b, 0x55, 0x10, 0x6c, + 0x60, 0xd9, 0x7f, 0xb3, 0xc4, 0x67, 0xa0, 0x08, 0x3d, 0x78, 0x31, 0x73, 0xbd, 0x5d, 0xff, 0xa7, + 0xf6, 0x1f, 0x05, 0x68, 0xa8, 0x8b, 0xe1, 0xc5, 0x99, 0xd0, 0x95, 0x23, 0xdf, 0x5a, 0x2d, 0xe8, + 0xe9, 0xd7, 0xd0, 0x6d, 0xd8, 0xe0, 0x97, 0x92, 0xa5, 0xe5, 0x7d, 0x65, 0x69, 0x4a, 0xac, 0x54, + 0xf6, 0xd1, 0x76, 0x7f, 0x6a, 0x41, 0xca, 0x22, 0x42, 0x21, 0x54, 0x69, 0x77, 0x77, 0x8a, 0xb9, + 0xf3, 0xde, 0x24, 0x4d, 0x45, 0xa3, 0x98, 0xf6, 0xec, 0x27, 0xe6, 0x8c, 0x90, 0x27, 0x22, 0x14, + 0xf8, 0xa8, 0x5e, 0x2f, 0x8e, 0xe1, 0x95, 0x20, 0xd8, 0xe4, 0x07, 0x9b, 0x3a, 0xda, 0xc1, 0x7e, + 0x11, 0x4e, 0x75, 0x75, 0x8a, 0xdd, 0x64, 0x15, 0xc8, 0x8b, 0xfe, 0x8d, 0xe9, 0xca, 0xd2, 0x26, + 0x31, 0x87, 0xd9, 0xdf, 0xb0, 0xe0, 0x64, 0x96, 0x3c, 0x7a, 0xcb, 0x82, 0x53, 0x71, 0x96, 0xde, + 0x71, 0x8d, 0x9d, 0x8a, 0x32, 0xec, 0x02, 0xe1, 0xee, 0x4e, 0xd8, 0xff, 0x47, 0x4c, 0xfe, 0x5b, + 0xae, 0xdf, 0x0c, 0xee, 0x28, 0xc3, 0xc4, 0xea, 0x69, 0x98, 0xd0, 0xf5, 0xd8, 0xd8, 0x20, 0xcd, + 0x8e, 0xd7, 0x95, 0xaf, 0xb9, 0x22, 0xda, 0xb1, 0xc2, 0x60, 0xe9, 0x69, 0x1d, 0x51, 0x2c, 0x3d, + 0x33, 0x29, 0x67, 0x45, 0x3b, 0x56, 0x18, 0xe8, 0x79, 0x18, 0x36, 0x5e, 0x52, 0xce, 0x4b, 0x66, + 0x90, 0x1b, 0x2a, 0x33, 0xc6, 0x29, 0x2c, 0x34, 0x01, 0xa0, 0x8c, 0x1c, 0xa9, 0x22, 0x99, 0xa3, + 0x48, 0x49, 0xa2, 0x18, 0x1b, 0x18, 0x2c, 0x19, 0xd4, 0xeb, 0xc4, 0xcc, 0xc7, 0x3f, 0xa0, 0x0b, + 0x78, 0xce, 0x88, 0x36, 0xac, 0xa0, 0x54, 0x9a, 0xb4, 0x1d, 0xbf, 0xe3, 0x78, 0x74, 0x84, 0xc4, + 0xd6, 0x4f, 0x2d, 0xc3, 0x45, 0x05, 0xc1, 0x06, 0x16, 0x7d, 0xe3, 0xc4, 0x6d, 0x93, 0x57, 0x02, + 0x5f, 0x46, 0x87, 0xe9, 0x63, 0x1f, 0xd1, 0x8e, 0x15, 0x86, 0xfd, 0x5f, 0x2c, 0x38, 0xa1, 0x53, + 0xcb, 0xf9, 0x9d, 0xd5, 0xe6, 0x4e, 0xd5, 0xda, 0x77, 0xa7, 0x9a, 0xce, 0xb9, 0x2d, 0xf5, 0x95, + 0x73, 0x6b, 0xa6, 0xc3, 0x96, 0xf7, 0x4c, 0x87, 0xfd, 0x41, 0x7d, 0x1f, 0x2a, 0xcf, 0x9b, 0x1d, + 0xca, 0xbb, 0x0b, 0x15, 0xd9, 0x30, 0xd0, 0x70, 0x54, 0x5d, 0x95, 0x61, 0xbe, 0x77, 0x98, 0x99, + 0x62, 0x48, 0x02, 0x62, 0x2f, 0x41, 0x5d, 0x9d, 0x7e, 0xc8, 0x8d, 0xaa, 0x95, 0xbf, 0x51, 0xed, + 0x2b, 0x2d, 0x6f, 0x7a, 0xed, 0x9b, 0xdf, 0x7d, 0xe2, 0x1d, 0xbf, 0xff, 0xdd, 0x27, 0xde, 0xf1, + 0x47, 0xdf, 0x7d, 0xe2, 0x1d, 0x9f, 0xb8, 0xfb, 0x84, 0xf5, 0xcd, 0xbb, 0x4f, 0x58, 0xbf, 0x7f, + 0xf7, 0x09, 0xeb, 0x8f, 0xee, 0x3e, 0x61, 0x7d, 0xe7, 0xee, 0x13, 0xd6, 0x17, 0xff, 0xe3, 0x13, + 0xef, 0x78, 0x25, 0x37, 0x3c, 0x90, 0xfe, 0x78, 0xb6, 0xd1, 0x9c, 0xdc, 0xba, 0xc8, 0x22, 0xd4, + 0xe8, 0xf2, 0x9a, 0x34, 0xe6, 0xd4, 0xa4, 0x5c, 0x5e, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x90, + 0x85, 0x5a, 0x45, 0xa5, 0xe0, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -6426,6 +6427,13 @@ func (m *ApplicationSetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TemplatePatch != nil { + i -= len(*m.TemplatePatch) + copy(dAtA[i:], *m.TemplatePatch) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.TemplatePatch))) + i-- + dAtA[i] = 0x52 + } if len(m.IgnoreApplicationDifferences) > 0 { for iNdEx := len(m.IgnoreApplicationDifferences) - 1; iNdEx >= 0; iNdEx-- { { @@ -14845,6 +14853,10 @@ func (m *ApplicationSetSpec) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.TemplatePatch != nil { + l = len(*m.TemplatePatch) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -18133,6 +18145,7 @@ func (this *ApplicationSetSpec) String() string { `GoTemplateOptions:` + fmt.Sprintf("%v", this.GoTemplateOptions) + `,`, `ApplyNestedSelectors:` + fmt.Sprintf("%v", this.ApplyNestedSelectors) + `,`, `IgnoreApplicationDifferences:` + repeatedStringForIgnoreApplicationDifferences + `,`, + `TemplatePatch:` + valueToStringGenerated(this.TemplatePatch) + `,`, `}`, }, "") return s @@ -24402,6 +24415,39 @@ func (m *ApplicationSetSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TemplatePatch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.TemplatePatch = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index ac1415786d032..c080c04c3a088 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -316,6 +316,8 @@ message ApplicationSetSpec { optional bool applyNestedSelectors = 8; repeated ApplicationSetResourceIgnoreDifferences ignoreApplicationDifferences = 9; + + optional string templatePatch = 10; } // ApplicationSetStatus defines the observed state of ApplicationSet diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index 5dff99db45d12..723ea884cb75b 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -1281,6 +1281,12 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetSpec(ref common.Referenc }, }, }, + "templatePatch": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"generators", "template"}, }, diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 1957ec59a341e..dc6a73f05dee5 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -955,6 +955,35 @@ type ApplicationStatus struct { ControllerNamespace string `json:"controllerNamespace,omitempty" protobuf:"bytes,13,opt,name=controllerNamespace"` } +// GetRevisions will return the current revision associated with the Application. +// If app has multisources, it will return all corresponding revisions preserving +// order from the app.spec.sources. If app has only one source, it will return a +// single revision in the list. +func (a *ApplicationStatus) GetRevisions() []string { + revisions := []string{} + if len(a.Sync.Revisions) > 0 { + revisions = a.Sync.Revisions + } else if a.Sync.Revision != "" { + revisions = append(revisions, a.Sync.Revision) + } + return revisions +} + +// BuildComparedToStatus will build a ComparedTo object based on the current +// Application state. +func (app *Application) BuildComparedToStatus() ComparedTo { + ct := ComparedTo{ + Destination: app.Spec.Destination, + IgnoreDifferences: app.Spec.IgnoreDifferences, + } + if app.Spec.HasMultipleSources() { + ct.Sources = app.Spec.Sources + } else { + ct.Source = app.Spec.GetSource() + } + return ct +} + // JWTTokens represents a list of JWT tokens type JWTTokens struct { Items []JWTToken `json:"items,omitempty" protobuf:"bytes,1,opt,name=items"` diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index 48e7e601670be..c10b610cbd5a7 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -733,6 +733,11 @@ func (in *ApplicationSetSpec) DeepCopyInto(out *ApplicationSetSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.TemplatePatch != nil { + in, out := &in.TemplatePatch, &out.TemplatePatch + *out = new(string) + **out = **in + } return } diff --git a/reposerver/apiclient/repository.pb.go b/reposerver/apiclient/repository.pb.go index 4c05248b87e16..914a967db3dfc 100644 --- a/reposerver/apiclient/repository.pb.go +++ b/reposerver/apiclient/repository.pb.go @@ -1910,6 +1910,7 @@ type GitFilesRequest struct { Revision string `protobuf:"bytes,3,opt,name=revision,proto3" json:"revision,omitempty"` Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"` NewGitFileGlobbingEnabled bool `protobuf:"varint,5,opt,name=NewGitFileGlobbingEnabled,proto3" json:"NewGitFileGlobbingEnabled,omitempty"` + NoRevisionCache bool `protobuf:"varint,6,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1983,6 +1984,13 @@ func (m *GitFilesRequest) GetNewGitFileGlobbingEnabled() bool { return false } +func (m *GitFilesRequest) GetNoRevisionCache() bool { + if m != nil { + return m.NoRevisionCache + } + return false +} + type GitFilesResponse struct { // Map consisting of path of the path to its contents in bytes Map map[string][]byte `protobuf:"bytes,1,rep,name=map,proto3" json:"map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` @@ -2035,6 +2043,7 @@ type GitDirectoriesRequest struct { Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"` SubmoduleEnabled bool `protobuf:"varint,2,opt,name=submoduleEnabled,proto3" json:"submoduleEnabled,omitempty"` Revision string `protobuf:"bytes,3,opt,name=revision,proto3" json:"revision,omitempty"` + NoRevisionCache bool `protobuf:"varint,4,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2094,6 +2103,13 @@ func (m *GitDirectoriesRequest) GetRevision() string { return "" } +func (m *GitDirectoriesRequest) GetNoRevisionCache() bool { + if m != nil { + return m.NoRevisionCache + } + return false +} + type GitDirectoriesResponse struct { // A set of directory paths Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"` @@ -2189,140 +2205,140 @@ func init() { } var fileDescriptor_dd8723cfcc820480 = []byte{ - // 2114 bytes of a gzipped FileDescriptorProto + // 2127 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5a, 0x5b, 0x6f, 0x1b, 0xc7, - 0x15, 0xe6, 0x92, 0xba, 0x90, 0x47, 0xb2, 0x44, 0x8d, 0x75, 0x59, 0x31, 0x8e, 0xa0, 0x6c, 0x6b, - 0x43, 0xb5, 0x13, 0x12, 0x92, 0x91, 0xb8, 0x70, 0xd2, 0x14, 0x8a, 0x62, 0x4b, 0x8e, 0x2d, 0x5b, - 0x5d, 0xbb, 0x2d, 0xd2, 0xba, 0x2d, 0x86, 0xcb, 0x21, 0xb9, 0xe1, 0x5e, 0xc6, 0xbb, 0xb3, 0x0a, - 0x64, 0xa0, 0x0f, 0x45, 0x8b, 0x02, 0xfd, 0x03, 0x7d, 0xe8, 0xff, 0x28, 0xfa, 0x54, 0xf4, 0xa9, - 0x97, 0xc7, 0xa0, 0x7f, 0xa0, 0x85, 0x1f, 0xfb, 0x2b, 0x8a, 0xb9, 0xec, 0x95, 0x2b, 0xd9, 0x29, - 0x65, 0x19, 0xcd, 0x8b, 0xbd, 0x73, 0xe6, 0xcc, 0x39, 0x67, 0xce, 0x9c, 0xcb, 0x37, 0x43, 0xc1, - 0xb5, 0x80, 0x50, 0x3f, 0x24, 0xc1, 0x31, 0x09, 0x3a, 0xe2, 0xd3, 0x66, 0x7e, 0x70, 0x92, 0xf9, - 0x6c, 0xd3, 0xc0, 0x67, 0x3e, 0x82, 0x94, 0xd2, 0x7a, 0x30, 0xb0, 0xd9, 0x30, 0xea, 0xb6, 0x2d, - 0xdf, 0xed, 0xe0, 0x60, 0xe0, 0xd3, 0xc0, 0xff, 0x42, 0x7c, 0xbc, 0x67, 0xf5, 0x3a, 0xc7, 0x3b, - 0x1d, 0x3a, 0x1a, 0x74, 0x30, 0xb5, 0xc3, 0x0e, 0xa6, 0xd4, 0xb1, 0x2d, 0xcc, 0x6c, 0xdf, 0xeb, - 0x1c, 0x6f, 0x63, 0x87, 0x0e, 0xf1, 0x76, 0x67, 0x40, 0x3c, 0x12, 0x60, 0x46, 0x7a, 0x52, 0x72, - 0xeb, 0xad, 0x81, 0xef, 0x0f, 0x1c, 0xd2, 0x11, 0xa3, 0x6e, 0xd4, 0xef, 0x10, 0x97, 0x32, 0xa5, - 0xd6, 0xf8, 0xcf, 0x3c, 0x2c, 0x1e, 0x62, 0xcf, 0xee, 0x93, 0x90, 0x99, 0xe4, 0x59, 0x44, 0x42, - 0x86, 0x9e, 0xc2, 0x14, 0x37, 0x46, 0xd7, 0x36, 0xb5, 0xad, 0xb9, 0x9d, 0x83, 0x76, 0x6a, 0x4d, - 0x3b, 0xb6, 0x46, 0x7c, 0xfc, 0xc2, 0xea, 0xb5, 0x8f, 0x77, 0xda, 0x74, 0x34, 0x68, 0x73, 0x6b, - 0xda, 0x19, 0x6b, 0xda, 0xb1, 0x35, 0x6d, 0x33, 0xd9, 0x96, 0x29, 0xa4, 0xa2, 0x16, 0xd4, 0x03, - 0x72, 0x6c, 0x87, 0xb6, 0xef, 0xe9, 0xd5, 0x4d, 0x6d, 0xab, 0x61, 0x26, 0x63, 0xa4, 0xc3, 0xac, - 0xe7, 0xef, 0x61, 0x6b, 0x48, 0xf4, 0xda, 0xa6, 0xb6, 0x55, 0x37, 0xe3, 0x21, 0xda, 0x84, 0x39, - 0x4c, 0xe9, 0x03, 0xdc, 0x25, 0xce, 0x7d, 0x72, 0xa2, 0x4f, 0x89, 0x85, 0x59, 0x12, 0x5f, 0x8b, - 0x29, 0x7d, 0x88, 0x5d, 0xa2, 0x4f, 0x8b, 0xd9, 0x78, 0x88, 0xae, 0x40, 0xc3, 0xc3, 0x2e, 0x09, - 0x29, 0xb6, 0x88, 0x5e, 0x17, 0x73, 0x29, 0x01, 0xfd, 0x12, 0x96, 0x32, 0x86, 0x3f, 0xf6, 0xa3, - 0xc0, 0x22, 0x3a, 0x88, 0xad, 0x3f, 0x9a, 0x6c, 0xeb, 0xbb, 0x45, 0xb1, 0xe6, 0xb8, 0x26, 0xf4, - 0x73, 0x98, 0x16, 0x27, 0xaf, 0xcf, 0x6d, 0xd6, 0xce, 0xd5, 0xdb, 0x52, 0x2c, 0xf2, 0x60, 0x96, - 0x3a, 0xd1, 0xc0, 0xf6, 0x42, 0x7d, 0x5e, 0x68, 0x78, 0x32, 0x99, 0x86, 0x3d, 0xdf, 0xeb, 0xdb, - 0x83, 0x43, 0xec, 0xe1, 0x01, 0x71, 0x89, 0xc7, 0x8e, 0x84, 0x70, 0x33, 0x56, 0x82, 0x9e, 0x43, - 0x73, 0x14, 0x85, 0xcc, 0x77, 0xed, 0xe7, 0xe4, 0x11, 0xe5, 0x6b, 0x43, 0xfd, 0x92, 0xf0, 0xe6, - 0xc3, 0xc9, 0x14, 0xdf, 0x2f, 0x48, 0x35, 0xc7, 0xf4, 0xf0, 0x20, 0x19, 0x45, 0x5d, 0xf2, 0x23, - 0x12, 0x88, 0xe8, 0x5a, 0x90, 0x41, 0x92, 0x21, 0xc9, 0x30, 0xb2, 0xd5, 0x28, 0xd4, 0x17, 0x37, - 0x6b, 0x32, 0x8c, 0x12, 0x12, 0xda, 0x82, 0xc5, 0x63, 0x12, 0xd8, 0xfd, 0x93, 0xc7, 0xf6, 0xc0, - 0xc3, 0x2c, 0x0a, 0x88, 0xde, 0x14, 0xa1, 0x58, 0x24, 0x23, 0x17, 0x2e, 0x0d, 0x89, 0xe3, 0x72, - 0x97, 0xef, 0x05, 0xa4, 0x17, 0xea, 0x4b, 0xc2, 0xbf, 0xfb, 0x93, 0x9f, 0xa0, 0x10, 0x67, 0xe6, - 0xa5, 0x73, 0xc3, 0x3c, 0xdf, 0x54, 0x99, 0x22, 0x73, 0x04, 0x49, 0xc3, 0x0a, 0x64, 0x74, 0x0d, - 0x16, 0x58, 0x80, 0xad, 0x91, 0xed, 0x0d, 0x0e, 0x09, 0x1b, 0xfa, 0x3d, 0xfd, 0xb2, 0xf0, 0x44, - 0x81, 0x8a, 0x2c, 0x40, 0xc4, 0xc3, 0x5d, 0x87, 0xf4, 0x64, 0x2c, 0x3e, 0x39, 0xa1, 0x24, 0xd4, - 0x97, 0xc5, 0x2e, 0x6e, 0xb6, 0x33, 0x15, 0xaa, 0x50, 0x20, 0xda, 0x77, 0xc6, 0x56, 0xdd, 0xf1, - 0x58, 0x70, 0x62, 0x96, 0x88, 0x43, 0x23, 0x98, 0xe3, 0xfb, 0x88, 0x43, 0x61, 0x45, 0x84, 0xc2, - 0xbd, 0xc9, 0x7c, 0x74, 0x90, 0x0a, 0x34, 0xb3, 0xd2, 0x51, 0x1b, 0xd0, 0x10, 0x87, 0x87, 0x91, - 0xc3, 0x6c, 0xea, 0x10, 0x69, 0x46, 0xa8, 0xaf, 0x0a, 0x37, 0x95, 0xcc, 0xa0, 0xfb, 0x00, 0x01, - 0xe9, 0xc7, 0x7c, 0x6b, 0x62, 0xe7, 0x37, 0xce, 0xda, 0xb9, 0x99, 0x70, 0xcb, 0x1d, 0x67, 0x96, - 0x73, 0xe5, 0x7c, 0x1b, 0xc4, 0x62, 0x2a, 0xdb, 0x45, 0x5a, 0xeb, 0x22, 0xc4, 0x4a, 0x66, 0x78, - 0x2c, 0x2a, 0xaa, 0x28, 0x5a, 0xeb, 0x32, 0x5a, 0x33, 0xa4, 0xd6, 0x1d, 0x58, 0x3b, 0xc5, 0xd5, - 0xa8, 0x09, 0xb5, 0x11, 0x39, 0x11, 0x25, 0xba, 0x61, 0xf2, 0x4f, 0xb4, 0x0c, 0xd3, 0xc7, 0xd8, - 0x89, 0x88, 0x28, 0xaa, 0x75, 0x53, 0x0e, 0x6e, 0x57, 0xbf, 0xab, 0xb5, 0x7e, 0xab, 0xc1, 0x62, - 0xc1, 0xf0, 0x92, 0xf5, 0x3f, 0xcb, 0xae, 0x3f, 0x87, 0x30, 0xee, 0x3f, 0xc1, 0xc1, 0x80, 0xb0, - 0x8c, 0x21, 0xc6, 0x3f, 0x35, 0xd0, 0x0b, 0x1e, 0xfd, 0xb1, 0xcd, 0x86, 0x77, 0x6d, 0x87, 0x84, - 0xe8, 0x16, 0xcc, 0x06, 0x92, 0xa6, 0x1a, 0xcf, 0x5b, 0x67, 0x1c, 0xc4, 0x41, 0xc5, 0x8c, 0xb9, - 0xd1, 0xc7, 0x50, 0x77, 0x09, 0xc3, 0x3d, 0xcc, 0xb0, 0xb2, 0x7d, 0xb3, 0x6c, 0x25, 0xd7, 0x72, - 0xa8, 0xf8, 0x0e, 0x2a, 0x66, 0xb2, 0x06, 0xbd, 0x0f, 0xd3, 0xd6, 0x30, 0xf2, 0x46, 0xa2, 0xe5, - 0xcc, 0xed, 0xbc, 0x7d, 0xda, 0xe2, 0x3d, 0xce, 0x74, 0x50, 0x31, 0x25, 0xf7, 0x27, 0x33, 0x30, - 0x45, 0x71, 0xc0, 0x8c, 0xbb, 0xb0, 0x5c, 0xa6, 0x82, 0xf7, 0x39, 0x6b, 0x48, 0xac, 0x51, 0x18, - 0xb9, 0xca, 0xcd, 0xc9, 0x18, 0x21, 0x98, 0x0a, 0xed, 0xe7, 0xd2, 0xd5, 0x35, 0x53, 0x7c, 0x1b, - 0xdf, 0x81, 0xa5, 0x31, 0x6d, 0xfc, 0x50, 0xa5, 0x6d, 0x5c, 0xc2, 0xbc, 0x52, 0x6d, 0x44, 0xb0, - 0xf2, 0x44, 0xf8, 0x22, 0x29, 0xf6, 0x17, 0xd1, 0xb9, 0x8d, 0x03, 0x58, 0x2d, 0xaa, 0x0d, 0xa9, - 0xef, 0x85, 0x84, 0x87, 0xbe, 0xa8, 0x8e, 0x36, 0xe9, 0xa5, 0xb3, 0xc2, 0x8a, 0xba, 0x59, 0x32, - 0x63, 0xfc, 0xaa, 0x0a, 0xab, 0x26, 0x09, 0x7d, 0xe7, 0x98, 0xc4, 0xa5, 0xeb, 0x62, 0xc0, 0xc7, - 0x4f, 0xa1, 0x86, 0x29, 0x55, 0x61, 0x72, 0xef, 0xdc, 0xda, 0xbb, 0xc9, 0xa5, 0xa2, 0x77, 0x61, - 0x09, 0xbb, 0x5d, 0x7b, 0x10, 0xf9, 0x51, 0x18, 0x6f, 0x4b, 0x04, 0x55, 0xc3, 0x1c, 0x9f, 0x30, - 0x2c, 0x58, 0x1b, 0x73, 0x81, 0x72, 0x67, 0x16, 0x22, 0x69, 0x05, 0x88, 0x54, 0xaa, 0xa4, 0x7a, - 0x9a, 0x92, 0xbf, 0x69, 0xd0, 0x4c, 0x53, 0x47, 0x89, 0xbf, 0x02, 0x0d, 0x57, 0xd1, 0x42, 0x5d, - 0x13, 0xf5, 0x29, 0x25, 0xe4, 0xd1, 0x52, 0xb5, 0x88, 0x96, 0x56, 0x61, 0x46, 0x82, 0x59, 0xb5, - 0x31, 0x35, 0xca, 0x99, 0x3c, 0x55, 0x30, 0x79, 0x03, 0x20, 0x4c, 0xea, 0x97, 0x3e, 0x23, 0x66, - 0x33, 0x14, 0x64, 0xc0, 0xbc, 0xec, 0xad, 0x26, 0x09, 0x23, 0x87, 0xe9, 0xb3, 0x82, 0x23, 0x47, - 0x33, 0x7c, 0x58, 0x7c, 0x60, 0xf3, 0x3d, 0xf4, 0xc3, 0x8b, 0x09, 0xf6, 0x0f, 0x60, 0x8a, 0x2b, - 0xe3, 0x1b, 0xeb, 0x06, 0xd8, 0xb3, 0x86, 0x24, 0xf6, 0x55, 0x32, 0xe6, 0x69, 0xcc, 0xf0, 0x20, - 0xd4, 0xab, 0x82, 0x2e, 0xbe, 0x8d, 0x3f, 0x55, 0xa5, 0xa5, 0xbb, 0x94, 0x86, 0x6f, 0x1e, 0x50, - 0x97, 0xb7, 0xf8, 0xda, 0x78, 0x8b, 0x2f, 0x98, 0xfc, 0x75, 0x5a, 0xfc, 0x39, 0xb5, 0x29, 0x23, - 0x82, 0xd9, 0x5d, 0x4a, 0xb9, 0x21, 0x68, 0x1b, 0xa6, 0x30, 0xa5, 0xd2, 0xe1, 0x85, 0x8a, 0xac, - 0x58, 0xf8, 0xff, 0xca, 0x24, 0xc1, 0xda, 0xba, 0x05, 0x8d, 0x84, 0xf4, 0x32, 0xb5, 0x8d, 0xac, - 0xda, 0x4d, 0x00, 0x89, 0x61, 0xef, 0x79, 0x7d, 0x9f, 0x1f, 0x29, 0x0f, 0x76, 0xb5, 0x54, 0x7c, - 0x1b, 0xb7, 0x63, 0x0e, 0x61, 0xdb, 0xbb, 0x30, 0x6d, 0x33, 0xe2, 0xc6, 0xc6, 0xad, 0x66, 0x8d, - 0x4b, 0x05, 0x99, 0x92, 0xc9, 0xf8, 0x7b, 0x1d, 0xd6, 0xf9, 0x89, 0x3d, 0x16, 0x69, 0xb2, 0x4b, - 0xe9, 0xa7, 0x84, 0x61, 0xdb, 0x09, 0x7f, 0x10, 0x91, 0xe0, 0xe4, 0x35, 0x07, 0xc6, 0x00, 0x66, - 0x64, 0x96, 0xa9, 0x7a, 0x77, 0xee, 0xd7, 0x19, 0x25, 0x3e, 0xbd, 0xc3, 0xd4, 0x5e, 0xcf, 0x1d, - 0xa6, 0xec, 0x4e, 0x31, 0x75, 0x41, 0x77, 0x8a, 0xd3, 0xaf, 0x95, 0x99, 0xcb, 0xea, 0x4c, 0xfe, - 0xb2, 0x5a, 0x02, 0xd5, 0x67, 0x5f, 0x15, 0xaa, 0xd7, 0x4b, 0xa1, 0xba, 0x5b, 0x9a, 0xc7, 0x0d, - 0xe1, 0xee, 0xef, 0x65, 0x23, 0xf0, 0xd4, 0x58, 0x9b, 0x04, 0xb4, 0xc3, 0x6b, 0x05, 0xed, 0x3f, - 0xcc, 0x81, 0x70, 0x79, 0x0d, 0x7e, 0xff, 0xd5, 0xf6, 0x74, 0x06, 0x1c, 0xff, 0xc6, 0x81, 0xe7, - 0xdf, 0x08, 0xcc, 0x44, 0xfd, 0xd4, 0x07, 0x49, 0x43, 0xe7, 0x7d, 0x88, 0xb7, 0x56, 0x55, 0xb4, - 0xf8, 0x37, 0xba, 0x01, 0x53, 0xdc, 0xc9, 0x0a, 0xd4, 0xae, 0x65, 0xfd, 0xc9, 0x4f, 0x62, 0x97, - 0xd2, 0xc7, 0x94, 0x58, 0xa6, 0x60, 0x42, 0xb7, 0xa1, 0x91, 0x04, 0xbe, 0xca, 0xac, 0x2b, 0xd9, - 0x15, 0x49, 0x9e, 0xc4, 0xcb, 0x52, 0x76, 0xbe, 0xb6, 0x67, 0x07, 0xc4, 0x12, 0x90, 0x6f, 0x7a, - 0x7c, 0xed, 0xa7, 0xf1, 0x64, 0xb2, 0x36, 0x61, 0x47, 0xdb, 0x30, 0x23, 0xdf, 0x0d, 0x44, 0x06, - 0xcd, 0xed, 0xac, 0x8f, 0x17, 0xd3, 0x78, 0x95, 0x62, 0x34, 0xfe, 0xaa, 0xc1, 0x3b, 0x69, 0x40, - 0xc4, 0xd9, 0x14, 0xa3, 0xee, 0x37, 0xdf, 0x71, 0xaf, 0xc1, 0x82, 0x80, 0xf9, 0xe9, 0xf3, 0x81, - 0x7c, 0xc9, 0x2a, 0x50, 0x8d, 0x3f, 0x6a, 0x70, 0x75, 0x7c, 0x1f, 0x7b, 0x43, 0x1c, 0xb0, 0xe4, - 0x78, 0x2f, 0x62, 0x2f, 0x71, 0xc3, 0xab, 0xa6, 0x0d, 0x2f, 0xb7, 0xbf, 0x5a, 0x7e, 0x7f, 0xc6, - 0x5f, 0xaa, 0x30, 0x97, 0x09, 0xa0, 0xb2, 0x86, 0xc9, 0x01, 0x9f, 0x88, 0x5b, 0x71, 0xb1, 0x13, - 0x4d, 0xa1, 0x61, 0x66, 0x28, 0x68, 0x04, 0x40, 0x71, 0x80, 0x5d, 0xc2, 0x48, 0xc0, 0x2b, 0x39, - 0xcf, 0xf8, 0xfb, 0x93, 0x57, 0x97, 0xa3, 0x58, 0xa6, 0x99, 0x11, 0xcf, 0x11, 0xab, 0x50, 0x1d, - 0xaa, 0xfa, 0xad, 0x46, 0xe8, 0x4b, 0x58, 0xe8, 0xdb, 0x0e, 0x39, 0x4a, 0x0d, 0x99, 0x11, 0x86, - 0x3c, 0x9a, 0xdc, 0x90, 0xbb, 0x59, 0xb9, 0x66, 0x41, 0x8d, 0x71, 0x1d, 0x9a, 0xc5, 0x7c, 0xe2, - 0x46, 0xda, 0x2e, 0x1e, 0x24, 0xde, 0x52, 0x23, 0x03, 0x41, 0xb3, 0x98, 0x3f, 0xc6, 0xbf, 0xaa, - 0xb0, 0x92, 0x88, 0xdb, 0xf5, 0x3c, 0x3f, 0xf2, 0x2c, 0xf1, 0x14, 0x57, 0x7a, 0x16, 0xcb, 0x30, - 0xcd, 0x6c, 0xe6, 0x24, 0xc0, 0x47, 0x0c, 0x78, 0xef, 0x62, 0xbe, 0xef, 0x30, 0x9b, 0xaa, 0x03, - 0x8e, 0x87, 0xf2, 0xec, 0x9f, 0x45, 0x76, 0x40, 0x7a, 0xa2, 0x12, 0xd4, 0xcd, 0x64, 0xcc, 0xe7, - 0x38, 0xaa, 0x11, 0x30, 0x5e, 0x3a, 0x33, 0x19, 0x8b, 0xb8, 0xf7, 0x1d, 0x87, 0x58, 0xdc, 0x1d, - 0x19, 0xa0, 0x5f, 0xa0, 0x8a, 0x0b, 0x04, 0x0b, 0x6c, 0x6f, 0xa0, 0x60, 0xbe, 0x1a, 0x71, 0x3b, - 0x71, 0x10, 0xe0, 0x13, 0xbd, 0x2e, 0x1c, 0x20, 0x07, 0xe8, 0x23, 0xa8, 0xb9, 0x98, 0xaa, 0x46, - 0x77, 0x3d, 0x57, 0x1d, 0xca, 0x3c, 0xd0, 0x3e, 0xc4, 0x54, 0x76, 0x02, 0xbe, 0xac, 0xf5, 0x01, - 0xd4, 0x63, 0xc2, 0xd7, 0x82, 0x84, 0x5f, 0xc0, 0xa5, 0x5c, 0xf1, 0x41, 0x9f, 0xc3, 0x6a, 0x1a, - 0x51, 0x59, 0x85, 0x0a, 0x04, 0xbe, 0xf3, 0x52, 0xcb, 0xcc, 0x53, 0x04, 0x18, 0xcf, 0x60, 0x89, - 0x87, 0x8c, 0x48, 0xfc, 0x0b, 0xba, 0xda, 0x7c, 0x08, 0x8d, 0x44, 0x65, 0x69, 0xcc, 0xb4, 0xa0, - 0x7e, 0x1c, 0x3f, 0x91, 0xca, 0xbb, 0x4d, 0x32, 0x36, 0x76, 0x01, 0x65, 0xed, 0x55, 0x1d, 0xe8, - 0x46, 0x1e, 0x14, 0xaf, 0x14, 0xdb, 0x8d, 0x60, 0x8f, 0x31, 0xf1, 0xef, 0xaa, 0xb0, 0xb8, 0x6f, - 0x8b, 0x57, 0x8e, 0x0b, 0x2a, 0x72, 0xd7, 0xa1, 0x19, 0x46, 0x5d, 0xd7, 0xef, 0x45, 0x0e, 0x51, - 0xa0, 0x40, 0x75, 0xfa, 0x31, 0xfa, 0x59, 0xc5, 0x8f, 0x3b, 0x8b, 0x62, 0x36, 0x54, 0x37, 0x5c, - 0xf1, 0x8d, 0x3e, 0x82, 0xf5, 0x87, 0xe4, 0x4b, 0xb5, 0x9f, 0x7d, 0xc7, 0xef, 0x76, 0x6d, 0x6f, - 0x10, 0x2b, 0x99, 0x16, 0x4a, 0x4e, 0x67, 0x30, 0x7e, 0xad, 0x41, 0x33, 0xf5, 0x85, 0xf2, 0xe6, - 0x2d, 0x19, 0xf5, 0xd2, 0x97, 0x57, 0xb3, 0xbe, 0x2c, 0xb2, 0xfe, 0xef, 0x01, 0x3f, 0x9f, 0x0d, - 0xf8, 0x3f, 0x6b, 0xb0, 0xb2, 0x6f, 0xb3, 0xb8, 0xd4, 0xd8, 0xff, 0x67, 0xe7, 0x62, 0xb4, 0x61, - 0xb5, 0x68, 0xbe, 0x72, 0xe5, 0x32, 0x4c, 0xf3, 0x53, 0x8a, 0xef, 0xee, 0x72, 0xb0, 0xf3, 0x55, - 0x03, 0x96, 0xd2, 0xe6, 0xcb, 0xff, 0xb5, 0x2d, 0x82, 0x1e, 0x41, 0x73, 0x5f, 0xfd, 0x76, 0x16, - 0xbf, 0x99, 0xa0, 0xb3, 0x1e, 0x21, 0x5b, 0x57, 0xca, 0x27, 0xa5, 0x6a, 0xa3, 0x82, 0x2c, 0x58, - 0x2f, 0x0a, 0x4c, 0xdf, 0x3b, 0xbf, 0x7d, 0x86, 0xe4, 0x84, 0xeb, 0x65, 0x2a, 0xb6, 0x34, 0xf4, - 0x39, 0x2c, 0xe4, 0x5f, 0xe5, 0x50, 0xae, 0x1a, 0x95, 0x3e, 0x14, 0xb6, 0x8c, 0xb3, 0x58, 0x12, - 0xfb, 0x9f, 0x72, 0xe8, 0x9b, 0x7b, 0xa2, 0x42, 0x46, 0x1e, 0x98, 0x97, 0x3d, 0xe1, 0xb5, 0xbe, - 0x75, 0x26, 0x4f, 0x22, 0xfd, 0x43, 0xa8, 0xc7, 0x4f, 0x3a, 0x79, 0x37, 0x17, 0x1e, 0x7a, 0x5a, - 0xcd, 0xbc, 0xbc, 0x7e, 0x68, 0x54, 0xd0, 0xc7, 0x72, 0x31, 0xbf, 0xf2, 0x8f, 0x2f, 0xce, 0x3c, - 0x64, 0xb4, 0x2e, 0x97, 0x3c, 0x1e, 0x18, 0x15, 0xf4, 0x7d, 0x98, 0xe3, 0x5f, 0x47, 0xea, 0x57, - 0xab, 0xd5, 0xb6, 0xfc, 0x91, 0xb4, 0x1d, 0xff, 0x48, 0xda, 0xbe, 0xe3, 0x52, 0x76, 0xd2, 0x2a, - 0xb9, 0xdd, 0x2b, 0x01, 0x4f, 0xe1, 0xd2, 0x3e, 0x61, 0x29, 0x18, 0x47, 0x57, 0x5f, 0xe9, 0xca, - 0xd2, 0x32, 0x8a, 0x6c, 0xe3, 0x78, 0xde, 0xa8, 0xa0, 0xdf, 0x6b, 0x70, 0x79, 0x9f, 0xb0, 0x22, - 0xbc, 0x45, 0xef, 0x95, 0x2b, 0x39, 0x05, 0x06, 0xb7, 0x1e, 0x4e, 0x9a, 0xaf, 0x79, 0xb1, 0x46, - 0x05, 0xfd, 0x41, 0x83, 0xb5, 0x8c, 0x61, 0x59, 0xbc, 0x8a, 0xb6, 0xcf, 0x36, 0xae, 0x04, 0xdb, - 0xb6, 0x3e, 0x9b, 0xf0, 0xc7, 0xc8, 0x8c, 0x48, 0xa3, 0x82, 0x8e, 0xc4, 0x99, 0xa4, 0xed, 0x09, - 0xbd, 0x5d, 0xda, 0x87, 0x12, 0xed, 0x1b, 0xa7, 0x4d, 0x27, 0xe7, 0xf0, 0x19, 0xcc, 0xed, 0x13, - 0x16, 0x57, 0xdd, 0x7c, 0xa4, 0x15, 0x5a, 0x58, 0x3e, 0x55, 0x8b, 0x85, 0x5a, 0x44, 0xcc, 0x92, - 0x94, 0x95, 0xa9, 0x53, 0xf9, 0x5c, 0x2d, 0x2d, 0xc1, 0xf9, 0x88, 0x29, 0x2f, 0x73, 0x46, 0xe5, - 0x93, 0xdd, 0x7f, 0xbc, 0xd8, 0xd0, 0xbe, 0x7a, 0xb1, 0xa1, 0xfd, 0xfb, 0xc5, 0x86, 0xf6, 0x93, - 0x9b, 0x2f, 0xf9, 0x0b, 0x82, 0xcc, 0x1f, 0x25, 0x60, 0x6a, 0x5b, 0x8e, 0x4d, 0x3c, 0xd6, 0x9d, - 0x11, 0xc1, 0x7f, 0xf3, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x86, 0xe4, 0x0d, 0xb3, 0x20, - 0x00, 0x00, + 0xf5, 0xe7, 0x92, 0x94, 0x44, 0x1e, 0xd9, 0x12, 0x35, 0xd6, 0x65, 0xc5, 0x38, 0x82, 0xb2, 0xff, + 0xbf, 0x0d, 0xd5, 0x4e, 0x48, 0x48, 0x46, 0xe2, 0xc2, 0x49, 0x53, 0x28, 0x8a, 0x2d, 0x39, 0xb6, + 0x6c, 0x75, 0xed, 0xb6, 0x48, 0xeb, 0xb6, 0x18, 0x2e, 0x87, 0xe4, 0x86, 0x7b, 0x19, 0xef, 0xce, + 0x2a, 0x90, 0x81, 0x3e, 0x14, 0x2d, 0xfa, 0x11, 0xfa, 0xd0, 0xaf, 0x51, 0x14, 0x7d, 0xec, 0x53, + 0x2f, 0x8f, 0x41, 0xbf, 0x40, 0x0b, 0xbf, 0x14, 0xe8, 0xa7, 0x28, 0xe6, 0xb2, 0x57, 0xae, 0x64, + 0xa7, 0x94, 0x15, 0xb4, 0x2f, 0xf6, 0xce, 0x99, 0x33, 0xe7, 0x9c, 0x39, 0x73, 0x2e, 0xbf, 0x19, + 0x0a, 0xae, 0x07, 0x84, 0xfa, 0x21, 0x09, 0x8e, 0x49, 0xd0, 0x15, 0x9f, 0x36, 0xf3, 0x83, 0x93, + 0xcc, 0x67, 0x87, 0x06, 0x3e, 0xf3, 0x11, 0xa4, 0x94, 0xf6, 0xc3, 0xa1, 0xcd, 0x46, 0x51, 0xaf, + 0x63, 0xf9, 0x6e, 0x17, 0x07, 0x43, 0x9f, 0x06, 0xfe, 0x17, 0xe2, 0xe3, 0x3d, 0xab, 0xdf, 0x3d, + 0xde, 0xe9, 0xd2, 0xf1, 0xb0, 0x8b, 0xa9, 0x1d, 0x76, 0x31, 0xa5, 0x8e, 0x6d, 0x61, 0x66, 0xfb, + 0x5e, 0xf7, 0x78, 0x1b, 0x3b, 0x74, 0x84, 0xb7, 0xbb, 0x43, 0xe2, 0x91, 0x00, 0x33, 0xd2, 0x97, + 0x92, 0xdb, 0x6f, 0x0d, 0x7d, 0x7f, 0xe8, 0x90, 0xae, 0x18, 0xf5, 0xa2, 0x41, 0x97, 0xb8, 0x94, + 0x29, 0xb5, 0xc6, 0xbf, 0x2e, 0xc1, 0xe2, 0x21, 0xf6, 0xec, 0x01, 0x09, 0x99, 0x49, 0x9e, 0x47, + 0x24, 0x64, 0xe8, 0x19, 0xd4, 0xb9, 0x31, 0xba, 0xb6, 0xa9, 0x6d, 0xcd, 0xef, 0x1c, 0x74, 0x52, + 0x6b, 0x3a, 0xb1, 0x35, 0xe2, 0xe3, 0x67, 0x56, 0xbf, 0x73, 0xbc, 0xd3, 0xa1, 0xe3, 0x61, 0x87, + 0x5b, 0xd3, 0xc9, 0x58, 0xd3, 0x89, 0xad, 0xe9, 0x98, 0xc9, 0xb6, 0x4c, 0x21, 0x15, 0xb5, 0xa1, + 0x11, 0x90, 0x63, 0x3b, 0xb4, 0x7d, 0x4f, 0xaf, 0x6e, 0x6a, 0x5b, 0x4d, 0x33, 0x19, 0x23, 0x1d, + 0xe6, 0x3c, 0x7f, 0x0f, 0x5b, 0x23, 0xa2, 0xd7, 0x36, 0xb5, 0xad, 0x86, 0x19, 0x0f, 0xd1, 0x26, + 0xcc, 0x63, 0x4a, 0x1f, 0xe2, 0x1e, 0x71, 0x1e, 0x90, 0x13, 0xbd, 0x2e, 0x16, 0x66, 0x49, 0x7c, + 0x2d, 0xa6, 0xf4, 0x11, 0x76, 0x89, 0x3e, 0x23, 0x66, 0xe3, 0x21, 0xba, 0x0a, 0x4d, 0x0f, 0xbb, + 0x24, 0xa4, 0xd8, 0x22, 0x7a, 0x43, 0xcc, 0xa5, 0x04, 0xf4, 0x73, 0x58, 0xca, 0x18, 0xfe, 0xc4, + 0x8f, 0x02, 0x8b, 0xe8, 0x20, 0xb6, 0xfe, 0x78, 0xba, 0xad, 0xef, 0x16, 0xc5, 0x9a, 0x93, 0x9a, + 0xd0, 0x4f, 0x61, 0x46, 0x9c, 0xbc, 0x3e, 0xbf, 0x59, 0x3b, 0x57, 0x6f, 0x4b, 0xb1, 0xc8, 0x83, + 0x39, 0xea, 0x44, 0x43, 0xdb, 0x0b, 0xf5, 0x4b, 0x42, 0xc3, 0xd3, 0xe9, 0x34, 0xec, 0xf9, 0xde, + 0xc0, 0x1e, 0x1e, 0x62, 0x0f, 0x0f, 0x89, 0x4b, 0x3c, 0x76, 0x24, 0x84, 0x9b, 0xb1, 0x12, 0xf4, + 0x02, 0x5a, 0xe3, 0x28, 0x64, 0xbe, 0x6b, 0xbf, 0x20, 0x8f, 0x29, 0x5f, 0x1b, 0xea, 0x97, 0x85, + 0x37, 0x1f, 0x4d, 0xa7, 0xf8, 0x41, 0x41, 0xaa, 0x39, 0xa1, 0x87, 0x07, 0xc9, 0x38, 0xea, 0x91, + 0x1f, 0x90, 0x40, 0x44, 0xd7, 0x82, 0x0c, 0x92, 0x0c, 0x49, 0x86, 0x91, 0xad, 0x46, 0xa1, 0xbe, + 0xb8, 0x59, 0x93, 0x61, 0x94, 0x90, 0xd0, 0x16, 0x2c, 0x1e, 0x93, 0xc0, 0x1e, 0x9c, 0x3c, 0xb1, + 0x87, 0x1e, 0x66, 0x51, 0x40, 0xf4, 0x96, 0x08, 0xc5, 0x22, 0x19, 0xb9, 0x70, 0x79, 0x44, 0x1c, + 0x97, 0xbb, 0x7c, 0x2f, 0x20, 0xfd, 0x50, 0x5f, 0x12, 0xfe, 0xdd, 0x9f, 0xfe, 0x04, 0x85, 0x38, + 0x33, 0x2f, 0x9d, 0x1b, 0xe6, 0xf9, 0xa6, 0xca, 0x14, 0x99, 0x23, 0x48, 0x1a, 0x56, 0x20, 0xa3, + 0xeb, 0xb0, 0xc0, 0x02, 0x6c, 0x8d, 0x6d, 0x6f, 0x78, 0x48, 0xd8, 0xc8, 0xef, 0xeb, 0x57, 0x84, + 0x27, 0x0a, 0x54, 0x64, 0x01, 0x22, 0x1e, 0xee, 0x39, 0xa4, 0x2f, 0x63, 0xf1, 0xe9, 0x09, 0x25, + 0xa1, 0xbe, 0x2c, 0x76, 0x71, 0xab, 0x93, 0xa9, 0x50, 0x85, 0x02, 0xd1, 0xb9, 0x3b, 0xb1, 0xea, + 0xae, 0xc7, 0x82, 0x13, 0xb3, 0x44, 0x1c, 0x1a, 0xc3, 0x3c, 0xdf, 0x47, 0x1c, 0x0a, 0x2b, 0x22, + 0x14, 0xee, 0x4f, 0xe7, 0xa3, 0x83, 0x54, 0xa0, 0x99, 0x95, 0x8e, 0x3a, 0x80, 0x46, 0x38, 0x3c, + 0x8c, 0x1c, 0x66, 0x53, 0x87, 0x48, 0x33, 0x42, 0x7d, 0x55, 0xb8, 0xa9, 0x64, 0x06, 0x3d, 0x00, + 0x08, 0xc8, 0x20, 0xe6, 0x5b, 0x13, 0x3b, 0xbf, 0x79, 0xd6, 0xce, 0xcd, 0x84, 0x5b, 0xee, 0x38, + 0xb3, 0x9c, 0x2b, 0xe7, 0xdb, 0x20, 0x16, 0x53, 0xd9, 0x2e, 0xd2, 0x5a, 0x17, 0x21, 0x56, 0x32, + 0xc3, 0x63, 0x51, 0x51, 0x45, 0xd1, 0x5a, 0x97, 0xd1, 0x9a, 0x21, 0xb5, 0xef, 0xc2, 0xda, 0x29, + 0xae, 0x46, 0x2d, 0xa8, 0x8d, 0xc9, 0x89, 0x28, 0xd1, 0x4d, 0x93, 0x7f, 0xa2, 0x65, 0x98, 0x39, + 0xc6, 0x4e, 0x44, 0x44, 0x51, 0x6d, 0x98, 0x72, 0x70, 0xa7, 0xfa, 0x6d, 0xad, 0xfd, 0x6b, 0x0d, + 0x16, 0x0b, 0x86, 0x97, 0xac, 0xff, 0x49, 0x76, 0xfd, 0x39, 0x84, 0xf1, 0xe0, 0x29, 0x0e, 0x86, + 0x84, 0x65, 0x0c, 0x31, 0xfe, 0xa6, 0x81, 0x5e, 0xf0, 0xe8, 0x0f, 0x6d, 0x36, 0xba, 0x67, 0x3b, + 0x24, 0x44, 0xb7, 0x61, 0x2e, 0x90, 0x34, 0xd5, 0x78, 0xde, 0x3a, 0xe3, 0x20, 0x0e, 0x2a, 0x66, + 0xcc, 0x8d, 0x3e, 0x86, 0x86, 0x4b, 0x18, 0xee, 0x63, 0x86, 0x95, 0xed, 0x9b, 0x65, 0x2b, 0xb9, + 0x96, 0x43, 0xc5, 0x77, 0x50, 0x31, 0x93, 0x35, 0xe8, 0x7d, 0x98, 0xb1, 0x46, 0x91, 0x37, 0x16, + 0x2d, 0x67, 0x7e, 0xe7, 0xed, 0xd3, 0x16, 0xef, 0x71, 0xa6, 0x83, 0x8a, 0x29, 0xb9, 0x3f, 0x99, + 0x85, 0x3a, 0xc5, 0x01, 0x33, 0xee, 0xc1, 0x72, 0x99, 0x0a, 0xde, 0xe7, 0xac, 0x11, 0xb1, 0xc6, + 0x61, 0xe4, 0x2a, 0x37, 0x27, 0x63, 0x84, 0xa0, 0x1e, 0xda, 0x2f, 0xa4, 0xab, 0x6b, 0xa6, 0xf8, + 0x36, 0xbe, 0x05, 0x4b, 0x13, 0xda, 0xf8, 0xa1, 0x4a, 0xdb, 0xb8, 0x84, 0x4b, 0x4a, 0xb5, 0x11, + 0xc1, 0xca, 0x53, 0xe1, 0x8b, 0xa4, 0xd8, 0x5f, 0x44, 0xe7, 0x36, 0x0e, 0x60, 0xb5, 0xa8, 0x36, + 0xa4, 0xbe, 0x17, 0x12, 0x1e, 0xfa, 0xa2, 0x3a, 0xda, 0xa4, 0x9f, 0xce, 0x0a, 0x2b, 0x1a, 0x66, + 0xc9, 0x8c, 0xf1, 0x8b, 0x2a, 0xac, 0x9a, 0x24, 0xf4, 0x9d, 0x63, 0x12, 0x97, 0xae, 0x8b, 0x01, + 0x1f, 0x3f, 0x86, 0x1a, 0xa6, 0x54, 0x85, 0xc9, 0xfd, 0x73, 0x6b, 0xef, 0x26, 0x97, 0x8a, 0xde, + 0x85, 0x25, 0xec, 0xf6, 0xec, 0x61, 0xe4, 0x47, 0x61, 0xbc, 0x2d, 0x11, 0x54, 0x4d, 0x73, 0x72, + 0xc2, 0xb0, 0x60, 0x6d, 0xc2, 0x05, 0xca, 0x9d, 0x59, 0x88, 0xa4, 0x15, 0x20, 0x52, 0xa9, 0x92, + 0xea, 0x69, 0x4a, 0xfe, 0xac, 0x41, 0x2b, 0x4d, 0x1d, 0x25, 0xfe, 0x2a, 0x34, 0x5d, 0x45, 0x0b, + 0x75, 0x4d, 0xd4, 0xa7, 0x94, 0x90, 0x47, 0x4b, 0xd5, 0x22, 0x5a, 0x5a, 0x85, 0x59, 0x09, 0x66, + 0xd5, 0xc6, 0xd4, 0x28, 0x67, 0x72, 0xbd, 0x60, 0xf2, 0x06, 0x40, 0x98, 0xd4, 0x2f, 0x7d, 0x56, + 0xcc, 0x66, 0x28, 0xc8, 0x80, 0x4b, 0xb2, 0xb7, 0x9a, 0x24, 0x8c, 0x1c, 0xa6, 0xcf, 0x09, 0x8e, + 0x1c, 0xcd, 0xf0, 0x61, 0xf1, 0xa1, 0xcd, 0xf7, 0x30, 0x08, 0x2f, 0x26, 0xd8, 0x3f, 0x80, 0x3a, + 0x57, 0xc6, 0x37, 0xd6, 0x0b, 0xb0, 0x67, 0x8d, 0x48, 0xec, 0xab, 0x64, 0xcc, 0xd3, 0x98, 0xe1, + 0x61, 0xa8, 0x57, 0x05, 0x5d, 0x7c, 0x1b, 0x7f, 0xa8, 0x4a, 0x4b, 0x77, 0x29, 0x0d, 0xbf, 0x79, + 0x40, 0x5d, 0xde, 0xe2, 0x6b, 0x93, 0x2d, 0xbe, 0x60, 0xf2, 0xd7, 0x69, 0xf1, 0xe7, 0xd4, 0xa6, + 0x8c, 0x08, 0xe6, 0x76, 0x29, 0xe5, 0x86, 0xa0, 0x6d, 0xa8, 0x63, 0x4a, 0xa5, 0xc3, 0x0b, 0x15, + 0x59, 0xb1, 0xf0, 0xff, 0x95, 0x49, 0x82, 0xb5, 0x7d, 0x1b, 0x9a, 0x09, 0xe9, 0x55, 0x6a, 0x9b, + 0x59, 0xb5, 0x9b, 0x00, 0x12, 0xc3, 0xde, 0xf7, 0x06, 0x3e, 0x3f, 0x52, 0x1e, 0xec, 0x6a, 0xa9, + 0xf8, 0x36, 0xee, 0xc4, 0x1c, 0xc2, 0xb6, 0x77, 0x61, 0xc6, 0x66, 0xc4, 0x8d, 0x8d, 0x5b, 0xcd, + 0x1a, 0x97, 0x0a, 0x32, 0x25, 0x93, 0xf1, 0x97, 0x06, 0xac, 0xf3, 0x13, 0x7b, 0x22, 0xd2, 0x64, + 0x97, 0xd2, 0x4f, 0x09, 0xc3, 0xb6, 0x13, 0x7e, 0x2f, 0x22, 0xc1, 0xc9, 0x1b, 0x0e, 0x8c, 0x21, + 0xcc, 0xca, 0x2c, 0x53, 0xf5, 0xee, 0xdc, 0xaf, 0x33, 0x4a, 0x7c, 0x7a, 0x87, 0xa9, 0xbd, 0x99, + 0x3b, 0x4c, 0xd9, 0x9d, 0xa2, 0x7e, 0x41, 0x77, 0x8a, 0xd3, 0xaf, 0x95, 0x99, 0xcb, 0xea, 0x6c, + 0xfe, 0xb2, 0x5a, 0x02, 0xd5, 0xe7, 0x5e, 0x17, 0xaa, 0x37, 0x4a, 0xa1, 0xba, 0x5b, 0x9a, 0xc7, + 0x4d, 0xe1, 0xee, 0xef, 0x64, 0x23, 0xf0, 0xd4, 0x58, 0x9b, 0x06, 0xb4, 0xc3, 0x1b, 0x05, 0xed, + 0xdf, 0xcf, 0x81, 0x70, 0x79, 0x0d, 0x7e, 0xff, 0xf5, 0xf6, 0x74, 0x06, 0x1c, 0xff, 0x9f, 0x03, + 0xcf, 0xbf, 0x12, 0x98, 0x89, 0xfa, 0xa9, 0x0f, 0x92, 0x86, 0xce, 0xfb, 0x10, 0x6f, 0xad, 0xaa, + 0x68, 0xf1, 0x6f, 0x74, 0x13, 0xea, 0xdc, 0xc9, 0x0a, 0xd4, 0xae, 0x65, 0xfd, 0xc9, 0x4f, 0x62, + 0x97, 0xd2, 0x27, 0x94, 0x58, 0xa6, 0x60, 0x42, 0x77, 0xa0, 0x99, 0x04, 0xbe, 0xca, 0xac, 0xab, + 0xd9, 0x15, 0x49, 0x9e, 0xc4, 0xcb, 0x52, 0x76, 0xbe, 0xb6, 0x6f, 0x07, 0xc4, 0x12, 0x90, 0x6f, + 0x66, 0x72, 0xed, 0xa7, 0xf1, 0x64, 0xb2, 0x36, 0x61, 0x47, 0xdb, 0x30, 0x2b, 0xdf, 0x0d, 0x44, + 0x06, 0xcd, 0xef, 0xac, 0x4f, 0x16, 0xd3, 0x78, 0x95, 0x62, 0x34, 0xfe, 0xa4, 0xc1, 0x3b, 0x69, + 0x40, 0xc4, 0xd9, 0x14, 0xa3, 0xee, 0x6f, 0xbe, 0xe3, 0x5e, 0x87, 0x05, 0x01, 0xf3, 0xd3, 0xe7, + 0x03, 0xf9, 0x92, 0x55, 0xa0, 0x1a, 0xbf, 0xd7, 0xe0, 0xda, 0xe4, 0x3e, 0xf6, 0x46, 0x38, 0x60, + 0xc9, 0xf1, 0x5e, 0xc4, 0x5e, 0xe2, 0x86, 0x57, 0x4d, 0x1b, 0x5e, 0x6e, 0x7f, 0xb5, 0xfc, 0xfe, + 0x8c, 0x3f, 0x56, 0x61, 0x3e, 0x13, 0x40, 0x65, 0x0d, 0x93, 0x03, 0x3e, 0x11, 0xb7, 0xe2, 0x62, + 0x27, 0x9a, 0x42, 0xd3, 0xcc, 0x50, 0xd0, 0x18, 0x80, 0xe2, 0x00, 0xbb, 0x84, 0x91, 0x80, 0x57, + 0x72, 0x9e, 0xf1, 0x0f, 0xa6, 0xaf, 0x2e, 0x47, 0xb1, 0x4c, 0x33, 0x23, 0x9e, 0x23, 0x56, 0xa1, + 0x3a, 0x54, 0xf5, 0x5b, 0x8d, 0xd0, 0x97, 0xb0, 0x30, 0xb0, 0x1d, 0x72, 0x94, 0x1a, 0x32, 0x2b, + 0x0c, 0x79, 0x3c, 0xbd, 0x21, 0xf7, 0xb2, 0x72, 0xcd, 0x82, 0x1a, 0xe3, 0x06, 0xb4, 0x8a, 0xf9, + 0xc4, 0x8d, 0xb4, 0x5d, 0x3c, 0x4c, 0xbc, 0xa5, 0x46, 0x06, 0x82, 0x56, 0x31, 0x7f, 0x8c, 0xbf, + 0x57, 0x61, 0x25, 0x11, 0xb7, 0xeb, 0x79, 0x7e, 0xe4, 0x59, 0xe2, 0x29, 0xae, 0xf4, 0x2c, 0x96, + 0x61, 0x86, 0xd9, 0xcc, 0x49, 0x80, 0x8f, 0x18, 0xf0, 0xde, 0xc5, 0x7c, 0xdf, 0x61, 0x36, 0x55, + 0x07, 0x1c, 0x0f, 0xe5, 0xd9, 0x3f, 0x8f, 0xec, 0x80, 0xf4, 0x45, 0x25, 0x68, 0x98, 0xc9, 0x98, + 0xcf, 0x71, 0x54, 0x23, 0x60, 0xbc, 0x74, 0x66, 0x32, 0x16, 0x71, 0xef, 0x3b, 0x0e, 0xb1, 0xb8, + 0x3b, 0x32, 0x40, 0xbf, 0x40, 0x15, 0x17, 0x08, 0x16, 0xd8, 0xde, 0x50, 0xc1, 0x7c, 0x35, 0xe2, + 0x76, 0xe2, 0x20, 0xc0, 0x27, 0x7a, 0x43, 0x38, 0x40, 0x0e, 0xd0, 0x47, 0x50, 0x73, 0x31, 0x55, + 0x8d, 0xee, 0x46, 0xae, 0x3a, 0x94, 0x79, 0xa0, 0x73, 0x88, 0xa9, 0xec, 0x04, 0x7c, 0x59, 0xfb, + 0x03, 0x68, 0xc4, 0x84, 0xaf, 0x05, 0x09, 0xbf, 0x80, 0xcb, 0xb9, 0xe2, 0x83, 0x3e, 0x87, 0xd5, + 0x34, 0xa2, 0xb2, 0x0a, 0x15, 0x08, 0x7c, 0xe7, 0x95, 0x96, 0x99, 0xa7, 0x08, 0x30, 0x9e, 0xc3, + 0x12, 0x0f, 0x19, 0x91, 0xf8, 0x17, 0x74, 0xb5, 0xf9, 0x10, 0x9a, 0x89, 0xca, 0xd2, 0x98, 0x69, + 0x43, 0xe3, 0x38, 0x7e, 0x22, 0x95, 0x77, 0x9b, 0x64, 0x6c, 0xec, 0x02, 0xca, 0xda, 0xab, 0x3a, + 0xd0, 0xcd, 0x3c, 0x28, 0x5e, 0x29, 0xb6, 0x1b, 0xc1, 0x1e, 0x63, 0xe2, 0xdf, 0x55, 0x61, 0x71, + 0xdf, 0x16, 0xaf, 0x1c, 0x17, 0x54, 0xe4, 0x6e, 0x40, 0x2b, 0x8c, 0x7a, 0xae, 0xdf, 0x8f, 0x1c, + 0xa2, 0x40, 0x81, 0xea, 0xf4, 0x13, 0xf4, 0xb3, 0x8a, 0x1f, 0x77, 0x16, 0xc5, 0x6c, 0xa4, 0x6e, + 0xb8, 0xe2, 0x1b, 0x7d, 0x04, 0xeb, 0x8f, 0xc8, 0x97, 0x6a, 0x3f, 0xfb, 0x8e, 0xdf, 0xeb, 0xd9, + 0xde, 0x30, 0x56, 0x32, 0x23, 0x94, 0x9c, 0xce, 0x50, 0x06, 0x15, 0x67, 0x4b, 0xa1, 0xa2, 0xf1, + 0x4b, 0x0d, 0x5a, 0xa9, 0xd7, 0x94, 0xdf, 0x6f, 0xcb, 0xfc, 0x90, 0x5e, 0xbf, 0x96, 0xf5, 0x7a, + 0x91, 0xf5, 0x3f, 0x4f, 0x8d, 0x4b, 0xd9, 0xd4, 0xf8, 0xa7, 0x06, 0x2b, 0xfb, 0x36, 0x8b, 0x8b, + 0x92, 0xfd, 0xdf, 0x76, 0x82, 0x25, 0xfe, 0xae, 0x97, 0xfb, 0xbb, 0x03, 0xab, 0xc5, 0x8d, 0x2a, + 0xa7, 0x2f, 0xc3, 0x0c, 0x3f, 0xf9, 0xf8, 0x3d, 0x40, 0x0e, 0x76, 0xbe, 0x6a, 0xc2, 0x52, 0xda, + 0xd0, 0xf9, 0xbf, 0xb6, 0x45, 0xd0, 0x63, 0x68, 0xed, 0xab, 0xdf, 0xe3, 0xe2, 0x77, 0x18, 0x74, + 0xd6, 0xc3, 0x66, 0xfb, 0x6a, 0xf9, 0xa4, 0x54, 0x6d, 0x54, 0x90, 0x05, 0xeb, 0x45, 0x81, 0xe9, + 0x1b, 0xea, 0xff, 0x9f, 0x21, 0x39, 0xe1, 0x7a, 0x95, 0x8a, 0x2d, 0x0d, 0x7d, 0x0e, 0x0b, 0xf9, + 0x97, 0x3e, 0x94, 0xab, 0x70, 0xa5, 0x8f, 0x8f, 0x6d, 0xe3, 0x2c, 0x96, 0xc4, 0xfe, 0x67, 0x1c, + 0x4e, 0xe7, 0x9e, 0xbd, 0x90, 0x91, 0x07, 0xfb, 0x65, 0xcf, 0x82, 0xed, 0xff, 0x3b, 0x93, 0x27, + 0x91, 0xfe, 0x21, 0x34, 0xe2, 0x67, 0xa2, 0xbc, 0x9b, 0x0b, 0x8f, 0x47, 0xed, 0x56, 0x5e, 0xde, + 0x20, 0x34, 0x2a, 0xe8, 0x63, 0xb9, 0x78, 0x97, 0xd2, 0x92, 0xc5, 0x99, 0xc7, 0x91, 0xf6, 0x95, + 0x92, 0x07, 0x09, 0xa3, 0x82, 0xbe, 0x0b, 0xf3, 0xfc, 0xeb, 0x48, 0xfd, 0x12, 0xb6, 0xda, 0x91, + 0x3f, 0xbc, 0x76, 0xe2, 0x1f, 0x5e, 0x3b, 0x77, 0x5d, 0xca, 0x4e, 0xda, 0x25, 0x2f, 0x06, 0x4a, + 0xc0, 0x33, 0xb8, 0xbc, 0x4f, 0x58, 0x0a, 0xf0, 0xd1, 0xb5, 0xd7, 0xba, 0x06, 0xb5, 0x8d, 0x22, + 0xdb, 0xe4, 0x1d, 0xc1, 0xa8, 0xa0, 0xdf, 0x68, 0x70, 0x65, 0x9f, 0xb0, 0x22, 0x64, 0x46, 0xef, + 0x95, 0x2b, 0x39, 0x05, 0x5a, 0xb7, 0x1f, 0x4d, 0x9b, 0xd9, 0x79, 0xb1, 0x46, 0x05, 0xfd, 0x56, + 0x83, 0xb5, 0x8c, 0x61, 0x59, 0x0c, 0x8c, 0xb6, 0xcf, 0x36, 0xae, 0x04, 0x2f, 0xb7, 0x3f, 0x9b, + 0xf2, 0x07, 0xce, 0x8c, 0x48, 0xa3, 0x82, 0x8e, 0xc4, 0x99, 0xa4, 0x2d, 0x0f, 0xbd, 0x5d, 0xda, + 0xdb, 0x12, 0xed, 0x1b, 0xa7, 0x4d, 0x27, 0xe7, 0xf0, 0x19, 0xcc, 0xef, 0x13, 0x16, 0xd7, 0xe7, + 0x7c, 0xa4, 0x15, 0xda, 0x62, 0x3e, 0x55, 0x8b, 0x25, 0x5d, 0x44, 0xcc, 0x92, 0x94, 0x95, 0xa9, + 0x53, 0xf9, 0x5c, 0x2d, 0x2d, 0xd6, 0xf9, 0x88, 0x29, 0x2f, 0x73, 0x46, 0xe5, 0x93, 0xdd, 0xbf, + 0xbe, 0xdc, 0xd0, 0xbe, 0x7a, 0xb9, 0xa1, 0xfd, 0xe3, 0xe5, 0x86, 0xf6, 0xa3, 0x5b, 0xaf, 0xf8, + 0xab, 0x84, 0xcc, 0x1f, 0x3a, 0x60, 0x6a, 0x5b, 0x8e, 0x4d, 0x3c, 0xd6, 0x9b, 0x15, 0xc1, 0x7f, + 0xeb, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf2, 0x91, 0xe2, 0xd9, 0x07, 0x21, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -4679,6 +4695,16 @@ func (m *GitFilesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.NoRevisionCache { + i-- + if m.NoRevisionCache { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } if m.NewGitFileGlobbingEnabled { i-- if m.NewGitFileGlobbingEnabled { @@ -4800,6 +4826,16 @@ func (m *GitDirectoriesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.NoRevisionCache { + i-- + if m.NoRevisionCache { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } if len(m.Revision) > 0 { i -= len(m.Revision) copy(dAtA[i:], m.Revision) @@ -5686,6 +5722,9 @@ func (m *GitFilesRequest) Size() (n int) { if m.NewGitFileGlobbingEnabled { n += 2 } + if m.NoRevisionCache { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -5733,6 +5772,9 @@ func (m *GitDirectoriesRequest) Size() (n int) { if l > 0 { n += 1 + l + sovRepository(uint64(l)) } + if m.NoRevisionCache { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -10874,6 +10916,26 @@ func (m *GitFilesRequest) Unmarshal(dAtA []byte) error { } } m.NewGitFileGlobbingEnabled = bool(v != 0) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NoRevisionCache", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NoRevisionCache = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) @@ -11192,6 +11254,26 @@ func (m *GitDirectoriesRequest) Unmarshal(dAtA []byte) error { } m.Revision = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NoRevisionCache", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NoRevisionCache = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) diff --git a/reposerver/cache/mocks/reposervercache.go b/reposerver/cache/mocks/reposervercache.go new file mode 100644 index 0000000000000..0e49b5816178e --- /dev/null +++ b/reposerver/cache/mocks/reposervercache.go @@ -0,0 +1,71 @@ +package mocks + +import ( + "testing" + "time" + + "github.com/alicebob/miniredis/v2" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + cacheutilmocks "github.com/argoproj/argo-cd/v2/util/cache/mocks" + "github.com/redis/go-redis/v9" + "github.com/stretchr/testify/mock" +) + +type MockCacheType int + +const ( + MockCacheTypeRedis MockCacheType = iota + MockCacheTypeInMem +) + +type MockRepoCache struct { + mock.Mock + RedisClient *cacheutilmocks.MockCacheClient + StopRedisCallback func() +} + +type MockCacheOptions struct { + RepoCacheExpiration time.Duration + RevisionCacheExpiration time.Duration + ReadDelay time.Duration + WriteDelay time.Duration +} + +type CacheCallCounts struct { + ExternalSets int + ExternalGets int + ExternalDeletes int +} + +// Checks that the cache was called the expected number of times +func (mockCache *MockRepoCache) AssertCacheCalledTimes(t *testing.T, calls *CacheCallCounts) { + mockCache.RedisClient.AssertNumberOfCalls(t, "Get", calls.ExternalGets) + mockCache.RedisClient.AssertNumberOfCalls(t, "Set", calls.ExternalSets) + mockCache.RedisClient.AssertNumberOfCalls(t, "Delete", calls.ExternalDeletes) +} + +func (mockCache *MockRepoCache) ConfigureDefaultCallbacks() { + mockCache.RedisClient.On("Get", mock.Anything, mock.Anything).Return(nil) + mockCache.RedisClient.On("Set", mock.Anything).Return(nil) + mockCache.RedisClient.On("Delete", mock.Anything).Return(nil) +} + +func NewInMemoryRedis() (*redis.Client, func()) { + cacheutil.NewInMemoryCache(5 * time.Second) + mr, err := miniredis.Run() + if err != nil { + panic(err) + } + return redis.NewClient(&redis.Options{Addr: mr.Addr()}), mr.Close +} + +func NewMockRepoCache(cacheOpts *MockCacheOptions) *MockRepoCache { + redisClient, stopRedis := NewInMemoryRedis() + redisCacheClient := &cacheutilmocks.MockCacheClient{ + ReadDelay: cacheOpts.ReadDelay, + WriteDelay: cacheOpts.WriteDelay, + BaseCache: cacheutil.NewRedisCache(redisClient, cacheOpts.RepoCacheExpiration, cacheutil.RedisCompressionNone)} + newMockCache := &MockRepoCache{RedisClient: redisCacheClient, StopRedisCallback: stopRedis} + newMockCache.ConfigureDefaultCallbacks() + return newMockCache +} diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index f66bc71ac4621..41f26b1f434b8 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -300,6 +300,7 @@ func (s *Service) runRepoOperation( var gitClient git.Client var helmClient helm.Client var err error + gitClientOpts := git.WithCache(s.cache, !settings.noRevisionCache && !settings.noCache) revision = textutils.FirstNonEmpty(revision, source.TargetRevision) unresolvedRevision := revision if source.IsHelm() { @@ -308,13 +309,13 @@ func (s *Service) runRepoOperation( return err } } else { - gitClient, revision, err = s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, !settings.noRevisionCache && !settings.noCache)) + gitClient, revision, err = s.newClientResolveRevision(repo, revision, gitClientOpts) if err != nil { return err } } - repoRefs, err := resolveReferencedSources(hasMultipleSources, source.Helm, refSources, s.newClientResolveRevision) + repoRefs, err := resolveReferencedSources(hasMultipleSources, source.Helm, refSources, s.newClientResolveRevision, gitClientOpts) if err != nil { return err } @@ -463,7 +464,7 @@ type gitClientGetter func(repo *v1alpha1.Repository, revision string, opts ...gi // // Much of this logic is duplicated in runManifestGenAsync. If making changes here, check whether runManifestGenAsync // should be updated. -func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.ApplicationSourceHelm, refSources map[string]*v1alpha1.RefTarget, newClientResolveRevision gitClientGetter) (map[string]string, error) { +func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.ApplicationSourceHelm, refSources map[string]*v1alpha1.RefTarget, newClientResolveRevision gitClientGetter, gitClientOpts git.ClientOpts) (map[string]string, error) { repoRefs := make(map[string]string) if !hasMultipleSources || source == nil { return repoRefs, nil @@ -490,7 +491,7 @@ func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.Applicat normalizedRepoURL := git.NormalizeGitURL(refSourceMapping.Repo.Repo) _, ok = repoRefs[normalizedRepoURL] if !ok { - _, referencedCommitSHA, err := newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision) + _, referencedCommitSHA, err := newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision, gitClientOpts) if err != nil { log.Errorf("Failed to get git client for repo %s: %v", refSourceMapping.Repo.Repo, err) return nil, fmt.Errorf("failed to get git client for repo %s", refSourceMapping.Repo.Repo) @@ -506,6 +507,17 @@ func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.Applicat func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestRequest) (*apiclient.ManifestResponse, error) { var res *apiclient.ManifestResponse var err error + + // Skip this path for ref only sources + if q.HasMultipleSources && q.ApplicationSource.Path == "" && q.ApplicationSource.Chart == "" && q.ApplicationSource.Ref != "" { + log.Debugf("Skipping manifest generation for ref only source for application: %s and ref %s", q.AppName, q.ApplicationSource.Ref) + _, revision, err := s.newClientResolveRevision(q.Repo, q.Revision, git.WithCache(s.cache, !q.NoRevisionCache && !q.NoCache)) + res = &apiclient.ManifestResponse{ + Revision: revision, + } + return res, err + } + cacheFn := func(cacheKey string, refSourceCommitSHAs cache.ResolvedRevisions, firstInvocation bool) (bool, error) { ok, resp, err := s.getManifestCacheEntry(cacheKey, q, refSourceCommitSHAs, firstInvocation) res = resp @@ -728,7 +740,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, return } } else { - gitClient, referencedCommitSHA, err := s.newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision) + gitClient, referencedCommitSHA, err := s.newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision, git.WithCache(s.cache, !q.NoRevisionCache && !q.NoCache)) if err != nil { log.Errorf("Failed to get git client for repo %s: %v", refSourceMapping.Repo.Repo, err) ch.errCh <- fmt.Errorf("failed to get git client for repo %s", refSourceMapping.Repo.Repo) @@ -1021,6 +1033,10 @@ func getHelmDependencyRepos(appPath string) ([]*v1alpha1.Repository, error) { repos = append(repos, &v1alpha1.Repository{ Name: r.Repository[1:], }) + } else if strings.HasPrefix(r.Repository, "alias:") { + repos = append(repos, &v1alpha1.Repository{ + Name: strings.TrimPrefix(r.Repository, "alias:"), + }) } else if u, err := url.Parse(r.Repository); err == nil && (u.Scheme == "https" || u.Scheme == "oci") { repo := &v1alpha1.Repository{ // trimming oci:// prefix since it is currently not supported by Argo CD (OCI repos just have no scheme) @@ -2505,6 +2521,7 @@ func (s *Service) GetGitFiles(_ context.Context, request *apiclient.GitFilesRequ repo := request.GetRepo() revision := request.GetRevision() gitPath := request.GetPath() + noRevisionCache := request.GetNoRevisionCache() enableNewGitFileGlobbing := request.GetNewGitFileGlobbingEnabled() if gitPath == "" { gitPath = "." @@ -2514,7 +2531,7 @@ func (s *Service) GetGitFiles(_ context.Context, request *apiclient.GitFilesRequ return nil, status.Error(codes.InvalidArgument, "must pass a valid repo") } - gitClient, revision, err := s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, true)) + gitClient, revision, err := s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, !noRevisionCache)) if err != nil { return nil, status.Errorf(codes.Internal, "unable to resolve git revision %s: %v", revision, err) } @@ -2567,12 +2584,12 @@ func (s *Service) GetGitFiles(_ context.Context, request *apiclient.GitFilesRequ func (s *Service) GetGitDirectories(_ context.Context, request *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) { repo := request.GetRepo() revision := request.GetRevision() - + noRevisionCache := request.GetNoRevisionCache() if repo == nil { return nil, status.Error(codes.InvalidArgument, "must pass a valid repo") } - gitClient, revision, err := s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, true)) + gitClient, revision, err := s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, !noRevisionCache)) if err != nil { return nil, status.Errorf(codes.Internal, "unable to resolve git revision %s: %v", revision, err) } diff --git a/reposerver/repository/repository.proto b/reposerver/repository/repository.proto index 8e4b69000f7e1..de061122e2586 100644 --- a/reposerver/repository/repository.proto +++ b/reposerver/repository/repository.proto @@ -236,6 +236,7 @@ message GitFilesRequest { string revision = 3; string path = 4; bool NewGitFileGlobbingEnabled = 5; + bool noRevisionCache = 6; } message GitFilesResponse { @@ -247,6 +248,7 @@ message GitDirectoriesRequest { github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; bool submoduleEnabled = 2; string revision = 3; + bool noRevisionCache = 4; } message GitDirectoriesResponse { diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index a24eb5008c47b..3f2f74c4e5ae0 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -1,6 +1,7 @@ package repository import ( + "bytes" "context" "encoding/json" "errors" @@ -17,6 +18,7 @@ import ( "testing" "time" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/api/resource" @@ -28,13 +30,14 @@ import ( "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/yaml" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" "github.com/argoproj/argo-cd/v2/reposerver/cache" + repositorymocks "github.com/argoproj/argo-cd/v2/reposerver/cache/mocks" "github.com/argoproj/argo-cd/v2/reposerver/metrics" fileutil "github.com/argoproj/argo-cd/v2/test/fixture/path" "github.com/argoproj/argo-cd/v2/util/argo" - cacheutil "github.com/argoproj/argo-cd/v2/util/cache" dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" "github.com/argoproj/argo-cd/v2/util/git" gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks" @@ -51,12 +54,49 @@ gpg: Good signature from "GitHub (web-flow commit signing) " type clientFunc func(*gitmocks.Client, *helmmocks.Client, *iomocks.TempPaths) -func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) { +type repoCacheMocks struct { + mock.Mock + cacheutilCache *cacheutil.Cache + cache *cache.Cache + mockCache *repositorymocks.MockRepoCache +} + +type newGitRepoHelmChartOptions struct { + chartName string + chartVersion string + // valuesFiles is a map of the values file name to the key/value pairs to be written to the file + valuesFiles map[string]map[string]string +} + +type newGitRepoOptions struct { + path string + createPath bool + remote string + addEmptyCommit bool + helmChartOptions newGitRepoHelmChartOptions +} + +func newCacheMocks() *repoCacheMocks { + mockRepoCache := repositorymocks.NewMockRepoCache(&repositorymocks.MockCacheOptions{ + RepoCacheExpiration: 1 * time.Minute, + RevisionCacheExpiration: 1 * time.Minute, + ReadDelay: 0, + WriteDelay: 0, + }) + cacheutilCache := cacheutil.NewCache(mockRepoCache.RedisClient) + return &repoCacheMocks{ + cacheutilCache: cacheutilCache, + cache: cache.NewCache(cacheutilCache, 1*time.Minute, 1*time.Minute), + mockCache: mockRepoCache, + } +} + +func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *gitmocks.Client, *repoCacheMocks) { root, err := filepath.Abs(root) if err != nil { panic(err) } - return newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + return newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) @@ -73,7 +113,7 @@ func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) chart := "my-chart" oobChart := "out-of-bounds-chart" version := "1.1.0" - helmClient.On("GetIndex", true).Return(&helm.Index{Entries: map[string]helm.Entries{ + helmClient.On("GetIndex", mock.AnythingOfType("bool")).Return(&helm.Index{Entries: map[string]helm.Entries{ chart: {{Version: "1.0.0"}, {Version: version}}, oobChart: {{Version: "1.0.0"}, {Version: version}}, }}, nil) @@ -89,18 +129,16 @@ func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) }, root) } -func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client) { +func newServiceWithOpt(t *testing.T, cf clientFunc, root string) (*Service, *gitmocks.Client, *repoCacheMocks) { helmClient := &helmmocks.Client{} gitClient := &gitmocks.Client{} paths := &iomocks.TempPaths{} cf(gitClient, helmClient, paths) - service := NewService(metrics.NewMetricsServer(), cache.NewCache( - cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Minute)), - 1*time.Minute, - 1*time.Minute, - ), RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, root) + cacheMocks := newCacheMocks() + t.Cleanup(cacheMocks.mockCache.StopRedisCallback) + service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, root) - service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, prosy string, opts ...git.ClientOpts) (client git.Client, e error) { + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { return gitClient, nil } service.newHelmClient = func(repoURL string, creds helm.Creds, enableOci bool, proxy string, opts ...helm.ClientOpts) helm.Client { @@ -110,20 +148,20 @@ func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client) return io.NopCloser } service.gitRepoPaths = paths - return service, gitClient + return service, gitClient, cacheMocks } -func newService(root string) *Service { - service, _ := newServiceWithMocks(root, false) +func newService(t *testing.T, root string) *Service { + service, _, _ := newServiceWithMocks(t, root, false) return service } -func newServiceWithSignature(root string) *Service { - service, _ := newServiceWithMocks(root, true) +func newServiceWithSignature(t *testing.T, root string) *Service { + service, _, _ := newServiceWithMocks(t, root, true) return service } -func newServiceWithCommitSHA(root, revision string) *Service { +func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { var revisionErr error commitSHARegex := regexp.MustCompile("^[0-9A-Fa-f]{40}$") @@ -131,7 +169,7 @@ func newServiceWithCommitSHA(root, revision string) *Service { revisionErr = errors.New("not a commit SHA") } - service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + service, gitClient, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) @@ -150,7 +188,7 @@ func newServiceWithCommitSHA(root, revision string) *Service { } func TestGenerateYamlManifestInDir(t *testing.T) { - service := newService("../../manifests/base") + service := newService(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -247,7 +285,7 @@ func TestGenerateManifests_MissingSymlinkDestination(t *testing.T) { } func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { - service := newService("../../manifests/base") + service := newService(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -275,7 +313,7 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { } func TestGenerateManifests_EmptyCache(t *testing.T) { - service := newService("../../manifests/base") + service, gitMocks, mockCache := newServiceWithMocks(t, "../../manifests/base", false) src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -291,11 +329,141 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { res, err := service.GenerateManifest(context.Background(), &q) assert.NoError(t, err) assert.True(t, len(res.Manifests) > 0) + mockCache.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 2, + ExternalGets: 2, + ExternalDeletes: 1}) + gitMocks.AssertCalled(t, "LsRemote", mock.Anything) + gitMocks.AssertCalled(t, "Fetch", mock.Anything) +} + +// Test that when Generate manifest is called with a source that is ref only it does not try to generate manifests or hit the manifest cache +// but it does resolve and cache the revision +func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { + lsremoteCalled := false + dir := t.TempDir() + repopath := fmt.Sprintf("%s/tmprepo", dir) + repoRemote := fmt.Sprintf("file://%s", repopath) + cacheMocks := newCacheMocks() + t.Cleanup(cacheMocks.mockCache.StopRedisCallback) + service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, repopath) + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { + opts = append(opts, git.WithEventHandlers(git.EventHandlers{ + // Primary check, we want to make sure ls-remote is not called when the item is in cache + OnLsRemote: func(repo string) func() { + return func() { + lsremoteCalled = true + } + }, + OnFetch: func(repo string) func() { + return func() { + assert.Fail(t, "Fetch should not be called from GenerateManifest when the source is ref only") + } + }, + })) + gitClient, err := git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, opts...) + return gitClient, err + } + revision := initGitRepo(t, newGitRepoOptions{ + path: repopath, + createPath: true, + remote: repoRemote, + addEmptyCommit: true, + }) + src := argoappv1.ApplicationSource{RepoURL: repoRemote, TargetRevision: "HEAD", Ref: "test-ref"} + repo := &argoappv1.Repository{ + Repo: repoRemote, + } + q := apiclient.ManifestRequest{ + Repo: repo, + Revision: "HEAD", + HasMultipleSources: true, + ApplicationSource: &src, + ProjectName: "default", + ProjectSourceRepos: []string{"*"}, + } + _, err := service.GenerateManifest(context.Background(), &q) + assert.NoError(t, err) + cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 1, + ExternalGets: 1}) + assert.True(t, lsremoteCalled, "ls-remote should be called when the source is ref only") + var revisions [][2]string + assert.NoError(t, cacheMocks.cacheutilCache.GetItem(fmt.Sprintf("git-refs|%s", repoRemote), &revisions)) + assert.ElementsMatch(t, [][2]string{{"refs/heads/main", revision}, {"HEAD", "ref: refs/heads/main"}}, revisions) +} + +// Test that calling manifest generation on source helm reference helm files that when the revision is cached it does not call ls-remote +func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { + dir := t.TempDir() + repopath := fmt.Sprintf("%s/tmprepo", dir) + cacheMocks := newCacheMocks() + t.Cleanup(func() { + cacheMocks.mockCache.StopRedisCallback() + err := filepath.WalkDir(dir, + func(path string, di fs.DirEntry, err error) error { + if err == nil { + return os.Chmod(path, 0777) + } + return err + }) + if err != nil { + t.Fatal(err) + } + }) + service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, repopath) + var gitClient git.Client + var err error + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { + opts = append(opts, git.WithEventHandlers(git.EventHandlers{ + // Primary check, we want to make sure ls-remote is not called when the item is in cache + OnLsRemote: func(repo string) func() { + return func() { + assert.Fail(t, "LsRemote should not be called when the item is in cache") + } + }, + })) + gitClient, err = git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, opts...) + return gitClient, err + } + repoRemote := fmt.Sprintf("file://%s", repopath) + revision := initGitRepo(t, newGitRepoOptions{ + path: repopath, + createPath: true, + remote: repoRemote, + helmChartOptions: newGitRepoHelmChartOptions{ + chartName: "my-chart", + chartVersion: "v1.0.0", + valuesFiles: map[string]map[string]string{"test.yaml": {"testval": "test"}}}, + }) + src := argoappv1.ApplicationSource{RepoURL: repoRemote, Path: ".", TargetRevision: "HEAD", Helm: &argoappv1.ApplicationSourceHelm{ + ValueFiles: []string{"$ref/test.yaml"}, + }} + repo := &argoappv1.Repository{ + Repo: repoRemote, + } + q := apiclient.ManifestRequest{ + Repo: repo, + Revision: "HEAD", + HasMultipleSources: true, + ApplicationSource: &src, + ProjectName: "default", + ProjectSourceRepos: []string{"*"}, + RefSources: map[string]*argoappv1.RefTarget{"$ref": {TargetRevision: "HEAD", Repo: *repo}}, + } + err = cacheMocks.cacheutilCache.SetItem(fmt.Sprintf("git-refs|%s", repoRemote), [][2]string{{"HEAD", revision}}, 30*time.Second, false) + assert.NoError(t, err) + _, err = service.GenerateManifest(context.Background(), &q) + assert.NoError(t, err) + cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 2, + ExternalGets: 5}) } // ensure we can use a semver constraint range (>= 1.0.0) and get back the correct chart (1.0.0) func TestHelmManifestFromChartRepo(t *testing.T) { - service := newService(".") + root := t.TempDir() + service, gitMocks, mockCache := newServiceWithMocks(t, root, false) source := &argoappv1.ApplicationSource{Chart: "my-chart", TargetRevision: ">= 1.0.0"} request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}} @@ -309,10 +477,14 @@ func TestHelmManifestFromChartRepo(t *testing.T) { Revision: "1.1.0", SourceType: "Helm", }, response) + mockCache.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 1, + ExternalGets: 0}) + gitMocks.AssertNotCalled(t, "LsRemote", mock.Anything) } func TestHelmChartReferencingExternalValues(t *testing.T) { - service := newService(".") + service := newService(t, ".") spec := argoappv1.ApplicationSpec{ Sources: []argoappv1.ApplicationSource{ {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &argoappv1.ApplicationSourceHelm{ @@ -342,7 +514,7 @@ func TestHelmChartReferencingExternalValues(t *testing.T) { } func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { - service := newService(".") + service := newService(t, ".") err := os.Mkdir("testdata/oob-symlink", 0755) require.NoError(t, err) t.Cleanup(func() { @@ -376,7 +548,7 @@ func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { } func TestGenerateManifestsUseExactRevision(t *testing.T) { - service, gitClient := newServiceWithMocks(".", false) + service, gitClient, _ := newServiceWithMocks(t, ".", false) src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -390,7 +562,7 @@ func TestGenerateManifestsUseExactRevision(t *testing.T) { } func TestRecurseManifestsInDir(t *testing.T) { - service := newService(".") + service := newService(t, ".") src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -403,7 +575,7 @@ func TestRecurseManifestsInDir(t *testing.T) { } func TestInvalidManifestsInDir(t *testing.T) { - service := newService(".") + service := newService(t, ".") src := argoappv1.ApplicationSource{Path: "./testdata/invalid-manifests", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -414,7 +586,7 @@ func TestInvalidManifestsInDir(t *testing.T) { } func TestInvalidMetadata(t *testing.T) { - service := newService(".") + service := newService(t, ".") src := argoappv1.ApplicationSource{Path: "./testdata/invalid-metadata", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, AppLabelKey: "test", AppName: "invalid-metadata", TrackingMethod: "annotation+label"} @@ -424,7 +596,7 @@ func TestInvalidMetadata(t *testing.T) { } func TestNilMetadataAccessors(t *testing.T) { - service := newService(".") + service := newService(t, ".") expected := "{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{\"argocd.argoproj.io/tracking-id\":\"nil-metadata-accessors:/ConfigMap:/my-map\"},\"labels\":{\"test\":\"nil-metadata-accessors\"},\"name\":\"my-map\"},\"stringData\":{\"foo\":\"bar\"}}" src := argoappv1.ApplicationSource{Path: "./testdata/nil-metadata-accessors", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -436,7 +608,7 @@ func TestNilMetadataAccessors(t *testing.T) { } func TestGenerateJsonnetManifestInDir(t *testing.T) { - service := newService(".") + service := newService(t, ".") q := apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -459,7 +631,7 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) { } func TestGenerateJsonnetManifestInRootDir(t *testing.T) { - service := newService("testdata/jsonnet-1") + service := newService(t, "testdata/jsonnet-1") q := apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -482,7 +654,7 @@ func TestGenerateJsonnetManifestInRootDir(t *testing.T) { } func TestGenerateJsonnetLibOutside(t *testing.T) { - service := newService(".") + service := newService(t, ".") q := apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -553,7 +725,7 @@ func TestManifestGenErrorCacheByNumRequests(t *testing.T) { for _, tt := range tests { testName := fmt.Sprintf("gen-attempts-%d-pause-%d-total-%d", tt.PauseGenerationAfterFailedGenerationAttempts, tt.PauseGenerationOnFailureForRequests, tt.TotalCacheInvocations) t.Run(testName, func(t *testing.T) { - service := newService(".") + service := newService(t, ".") service.initConstants = RepoServerInitConstants{ ParallelismLimit: 1, @@ -631,7 +803,7 @@ func TestManifestGenErrorCacheFileContentsChange(t *testing.T) { tmpDir := t.TempDir() - service := newService(tmpDir) + service := newService(t, tmpDir) service.initConstants = RepoServerInitConstants{ ParallelismLimit: 1, @@ -701,7 +873,7 @@ func TestManifestGenErrorCacheByMinutesElapsed(t *testing.T) { for _, tt := range tests { testName := fmt.Sprintf("pause-time-%d", tt.PauseGenerationOnFailureForMinutes) t.Run(testName, func(t *testing.T) { - service := newService(".") + service := newService(t, ".") // Here we simulate the passage of time by overriding the now() function of Service currentTime := time.Now() @@ -771,7 +943,7 @@ func TestManifestGenErrorCacheByMinutesElapsed(t *testing.T) { func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) { - service := newService(".") + service := newService(t, ".") service.initConstants = RepoServerInitConstants{ ParallelismLimit: 1, @@ -828,7 +1000,7 @@ func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) { } func TestGenerateHelmWithValues(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -865,7 +1037,7 @@ func TestGenerateHelmWithValues(t *testing.T) { } func TestHelmWithMissingValueFiles(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") missingValuesFile := "values-prod-overrides.yaml" req := &apiclient.ManifestRequest{ @@ -893,7 +1065,7 @@ func TestHelmWithMissingValueFiles(t *testing.T) { } func TestGenerateHelmWithEnvVars(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -930,7 +1102,7 @@ func TestGenerateHelmWithEnvVars(t *testing.T) { // The requested value file (`../minio/values.yaml`) is outside the app path (`./util/helm/testdata/redis`), however // since the requested value is still under the repo directory (`~/go/src/github.com/argoproj/argo-cd`), it is allowed func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { - service := newService("../../util/helm/testdata") + service := newService(t, "../../util/helm/testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -947,7 +1119,7 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { assert.NoError(t, err) // Test the case where the path is "." - service = newService("./testdata") + service = newService(t, "./testdata") _, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -961,7 +1133,7 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { } func TestChartRepoWithOutOfBoundsSymlink(t *testing.T) { - service := newService(".") + service := newService(t, ".") source := &argoappv1.ApplicationSource{Chart: "out-of-bounds-chart", TargetRevision: ">= 1.0.0"} request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true} _, err := service.GenerateManifest(context.Background(), request) @@ -971,7 +1143,7 @@ func TestChartRepoWithOutOfBoundsSymlink(t *testing.T) { // This is a Helm first-class app with a values file inside the repo directory // (`~/go/src/github.com/argoproj/argo-cd/reposerver/repository`), so it is allowed func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { - service := newService(".") + service := newService(t, ".") source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", @@ -1000,7 +1172,7 @@ func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { // This is a Helm first-class app with a values file outside the repo directory // (`~/go/src/github.com/argoproj/argo-cd/reposerver/repository`), so it is not allowed func TestHelmManifestFromChartRepoWithValueFileOutsideRepo(t *testing.T) { - service := newService(".") + service := newService(t, ".") source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", @@ -1015,7 +1187,7 @@ func TestHelmManifestFromChartRepoWithValueFileOutsideRepo(t *testing.T) { func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { t.Run("Valid symlink", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", @@ -1031,7 +1203,7 @@ func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { } func TestGenerateHelmWithURL(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1054,7 +1226,7 @@ func TestGenerateHelmWithURL(t *testing.T) { // (`~/go/src/github.com/argoproj/argo-cd/util/helm/testdata/redis`), so it is blocked func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { t.Run("Values file with relative path pointing outside repo root", func(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1073,7 +1245,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Values file with relative path pointing inside repo root", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1091,7 +1263,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Values file with absolute path stays within repo root", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1109,7 +1281,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Values file with absolute path using back-references outside repo root", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1128,7 +1300,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Remote values file from forbidden protocol", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1147,7 +1319,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Remote values file from custom allowed protocol", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1168,7 +1340,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { // File parameter should not allow traversal outside of the repository root func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { - service := newService("../..") + service := newService(t, "../..") file, err := os.CreateTemp("", "external-secret.txt") assert.NoError(t, err) @@ -1209,7 +1381,7 @@ func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { // directory (`~/go/src/github.com/argoproj/argo-cd`), it is allowed. It is used as a means of // providing direct content to a helm chart via a specific key. func TestGenerateHelmWithFileParameter(t *testing.T) { - service := newService("../../util/helm/testdata") + service := newService(t, "../../util/helm/testdata") res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1234,7 +1406,7 @@ func TestGenerateHelmWithFileParameter(t *testing.T) { } func TestGenerateNullList(t *testing.T) { - service := newService(".") + service := newService(t, ".") t.Run("null list", func(t *testing.T) { res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ @@ -1302,7 +1474,7 @@ func TestGenerateFromUTF16(t *testing.T) { } func TestListApps(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") res, err := service.ListApps(context.Background(), &apiclient.ListAppsRequest{Repo: &argoappv1.Repository{}}) assert.NoError(t, err) @@ -1324,12 +1496,30 @@ func TestListApps(t *testing.T) { "out-of-bounds-values-file-link": "Helm", "values-files": "Helm", "helm-with-dependencies": "Helm", + "helm-with-dependencies-alias": "Helm", } assert.Equal(t, expectedApps, res.Apps) } func TestGetAppDetailsHelm(t *testing.T) { - service := newService("../../util/helm/testdata/dependency") + service := newService(t, "../../util/helm/testdata/dependency") + + res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ + Path: ".", + }, + }) + + assert.NoError(t, err) + assert.NotNil(t, res.Helm) + + assert.Equal(t, "Helm", res.Type) + assert.EqualValues(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles) +} + +func TestGetAppDetailsHelmUsesCache(t *testing.T) { + service := newService(t, "../../util/helm/testdata/dependency") res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1344,8 +1534,9 @@ func TestGetAppDetailsHelm(t *testing.T) { assert.Equal(t, "Helm", res.Type) assert.EqualValues(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles) } + func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) { - service := newService("../../util/helm/testdata/api-versions") + service := newService(t, "../../util/helm/testdata/api-versions") res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1363,7 +1554,7 @@ func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) { } func TestGetAppDetailsKustomize(t *testing.T) { - service := newService("../../util/kustomize/testdata/kustomization_yaml") + service := newService(t, "../../util/kustomize/testdata/kustomization_yaml") res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1380,7 +1571,7 @@ func TestGetAppDetailsKustomize(t *testing.T) { } func TestGetHelmCharts(t *testing.T) { - service := newService("../..") + service := newService(t, "../..") res, err := service.GetHelmCharts(context.Background(), &apiclient.HelmChartsRequest{Repo: &argoappv1.Repository{}}) // fix flakiness @@ -1401,7 +1592,7 @@ func TestGetHelmCharts(t *testing.T) { } func TestGetRevisionMetadata(t *testing.T) { - service, gitClient := newServiceWithMocks("../..", false) + service, gitClient, _ := newServiceWithMocks(t, "../..", false) now := time.Now() gitClient.On("RevisionMetadata", mock.Anything).Return(&git.RevisionMetadata{ @@ -1469,7 +1660,7 @@ func TestGetRevisionMetadata(t *testing.T) { func TestGetSignatureVerificationResult(t *testing.T) { // Commit with signature and verification requested { - service := newServiceWithSignature("../../manifests/base") + service := newServiceWithSignature(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -1486,7 +1677,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } // Commit with signature and verification not requested { - service := newServiceWithSignature("../../manifests/base") + service := newServiceWithSignature(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", @@ -1498,7 +1689,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } // Commit without signature and verification requested { - service := newService("../../manifests/base") + service := newService(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", @@ -1510,7 +1701,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } // Commit without signature and verification not requested { - service := newService("../../manifests/base") + service := newService(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", @@ -1543,7 +1734,7 @@ func Test_newEnv(t *testing.T) { } func TestService_newHelmClientResolveRevision(t *testing.T) { - service := newService(".") + service := newService(t, ".") t.Run("EmptyRevision", func(t *testing.T) { _, _, err := service.newHelmClientResolveRevision(&argoappv1.Repository{}, "", "", true) @@ -1557,7 +1748,7 @@ func TestService_newHelmClientResolveRevision(t *testing.T) { func TestGetAppDetailsWithAppParameterFile(t *testing.T) { t.Run("No app name set and app specific file exists", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1570,7 +1761,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("No app specific override", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1584,7 +1775,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("Only app specific override", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1598,7 +1789,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("App specific override", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1612,7 +1803,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("App specific overrides containing non-mergeable field", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1626,7 +1817,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("Broken app-specific overrides", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { _, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1668,7 +1859,7 @@ func runWithTempTestdata(t *testing.T, path string, runner func(t *testing.T, pa func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Single global override", func(t *testing.T) { runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { - service := newService(".") + service := newService(t, ".") manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{ @@ -1699,7 +1890,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Single global override Helm", func(t *testing.T) { runWithTempTestdata(t, "single-global-helm", func(t *testing.T, path string) { - service := newService(".") + service := newService(t, ".") manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{ @@ -1729,7 +1920,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { }) t.Run("Application specific override", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1760,8 +1951,29 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { }) }) + t.Run("Multi-source with source as ref only does not generate manifests", func(t *testing.T) { + service := newService(t, ".") + runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { + manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ + Path: "", + Chart: "", + Ref: "test", + }, + AppName: "testapp-multi-ref-only", + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, + HasMultipleSources: true, + }) + assert.NoError(t, err) + assert.Empty(t, manifests.Manifests) + assert.NotEmpty(t, manifests.Revision) + }) + }) + t.Run("Application specific override for other app", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1793,7 +2005,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { }) t.Run("Override info does not appear in cache key", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { source := &argoappv1.ApplicationSource{ Path: path, @@ -1843,7 +2055,7 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ProjectSourceRepos: []string{"*"}, }, wantError: false, - service: newServiceWithCommitSHA(".", regularGitTagHash), + service: newServiceWithCommitSHA(t, ".", regularGitTagHash), }, { @@ -1859,7 +2071,7 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ProjectSourceRepos: []string{"*"}, }, wantError: false, - service: newServiceWithCommitSHA(".", annotatedGitTaghash), + service: newServiceWithCommitSHA(t, ".", annotatedGitTaghash), }, { @@ -1875,7 +2087,7 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ProjectSourceRepos: []string{"*"}, }, wantError: true, - service: newServiceWithCommitSHA(".", invalidGitTaghash), + service: newServiceWithCommitSHA(t, ".", invalidGitTaghash), }, } for _, tt := range tests { @@ -1900,7 +2112,7 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { func TestGenerateManifestWithAnnotatedTagsAndMultiSourceApp(t *testing.T) { annotatedGitTaghash := "95249be61b028d566c29d47b19e65c5603388a41" - service := newServiceWithCommitSHA(".", annotatedGitTaghash) + service := newServiceWithCommitSHA(t, ".", annotatedGitTaghash) refSources := map[string]*argoappv1.RefTarget{} @@ -2485,7 +2697,7 @@ func Test_findManifests(t *testing.T) { } func TestTestRepoOCI(t *testing.T) { - service := newService(".") + service := newService(t, ".") _, err := service.TestRepository(context.Background(), &apiclient.TestRepositoryRequest{ Repo: &argoappv1.Repository{ Repo: "https://demo.goharbor.io", @@ -2510,7 +2722,7 @@ func Test_getHelmDependencyRepos(t *testing.T) { func TestResolveRevision(t *testing.T) { - service := newService(".") + service := newService(t, ".") repo := &argoappv1.Repository{Repo: "https://github.com/argoproj/argo-cd"} app := &argoappv1.Application{Spec: argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{}}} resolveRevisionResponse, err := service.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ @@ -2532,7 +2744,7 @@ func TestResolveRevision(t *testing.T) { func TestResolveRevisionNegativeScenarios(t *testing.T) { - service := newService(".") + service := newService(t, ".") repo := &argoappv1.Repository{Repo: "https://github.com/argoproj/argo-cd"} app := &argoappv1.Application{Spec: argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{}}} resolveRevisionResponse, err := service.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ @@ -2579,19 +2791,57 @@ func TestDirectoryPermissionInitializer(t *testing.T) { require.Error(t, err) } -func initGitRepo(repoPath string, remote string) error { - if err := os.Mkdir(repoPath, 0755); err != nil { - return err +func addHelmToGitRepo(t *testing.T, options newGitRepoOptions) { + err := os.WriteFile(filepath.Join(options.path, "Chart.yaml"), []byte("name: test\nversion: v1.0.0"), 0777) + assert.NoError(t, err) + for valuesFileName, values := range options.helmChartOptions.valuesFiles { + valuesFileContents, err := yaml.Marshal(values) + assert.NoError(t, err) + err = os.WriteFile(filepath.Join(options.path, valuesFileName), valuesFileContents, 0777) + assert.NoError(t, err) + } + assert.NoError(t, err) + cmd := exec.Command("git", "add", "-A") + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) + cmd = exec.Command("git", "commit", "-m", "Initial commit") + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) +} + +func initGitRepo(t *testing.T, options newGitRepoOptions) (revision string) { + if options.createPath { + assert.NoError(t, os.Mkdir(options.path, 0755)) + } + + cmd := exec.Command("git", "init", "-b", "main", options.path) + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) + + if options.remote != "" { + cmd = exec.Command("git", "remote", "add", "origin", options.path) + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) + } + + commitAdded := options.addEmptyCommit || options.helmChartOptions.chartName != "" + if options.addEmptyCommit { + cmd = exec.Command("git", "commit", "-m", "Initial commit", "--allow-empty") + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) + } else if options.helmChartOptions.chartName != "" { + addHelmToGitRepo(t, options) } - cmd := exec.Command("git", "init", repoPath) - cmd.Dir = repoPath - if err := cmd.Run(); err != nil { - return err + if commitAdded { + var revB bytes.Buffer + cmd = exec.Command("git", "rev-parse", "HEAD", options.path) + cmd.Dir = options.path + cmd.Stdout = &revB + assert.NoError(t, cmd.Run()) + revision = strings.Split(revB.String(), "\n")[0] } - cmd = exec.Command("git", "remote", "add", "origin", remote) - cmd.Dir = repoPath - return cmd.Run() + return revision } func TestInit(t *testing.T) { @@ -2604,16 +2854,16 @@ func TestInit(t *testing.T) { }) repoPath := path.Join(dir, "repo1") - require.NoError(t, initGitRepo(repoPath, "https://github.com/argo-cd/test-repo1")) + initGitRepo(t, newGitRepoOptions{path: repoPath, remote: "https://github.com/argo-cd/test-repo1", createPath: true, addEmptyCommit: false}) - service := newService(".") + service := newService(t, ".") service.rootDir = dir require.NoError(t, service.Init()) _, err := os.ReadDir(dir) require.Error(t, err) - require.NoError(t, initGitRepo(path.Join(dir, "repo2"), "https://github.com/argo-cd/test-repo2")) + initGitRepo(t, newGitRepoOptions{path: path.Join(dir, "repo2"), remote: "https://github.com/argo-cd/test-repo2", createPath: true, addEmptyCommit: false}) } // TestCheckoutRevisionCanGetNonstandardRefs shows that we can fetch a revision that points to a non-standard ref. In @@ -2756,6 +3006,22 @@ func TestGetHelmRepo_NamedRepos(t *testing.T) { assert.Equal(t, helmRepos[0].Repo, "https://example.com") } +func TestGetHelmRepo_NamedReposAlias(t *testing.T) { + src := argoappv1.ApplicationSource{Path: "."} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, Repos: []*argoappv1.Repository{{ + Name: "custom-repo-alias", + Repo: "https://example.com", + Username: "test-alias", + }}} + + helmRepos, err := getHelmRepos("./testdata/helm-with-dependencies-alias", q.Repos, q.HelmRepoCreds) + assert.Nil(t, err) + + assert.Equal(t, len(helmRepos), 1) + assert.Equal(t, helmRepos[0].Username, "test-alias") + assert.Equal(t, helmRepos[0].Repo, "https://example.com") +} + func Test_getResolvedValueFiles(t *testing.T) { tempDir := t.TempDir() paths := io.NewRandomizedTempPaths(tempDir) @@ -2926,7 +3192,7 @@ func TestErrorGetGitDirectories(t *testing.T) { want *apiclient.GitDirectoriesResponse wantErr assert.ErrorAssertionFunc }{ - {name: "InvalidRepo", fields: fields{service: newService(".")}, args: args{ + {name: "InvalidRepo", fields: fields{service: newService(t, ".")}, args: args{ ctx: context.TODO(), request: &apiclient.GitDirectoriesRequest{ Repo: nil, @@ -2935,7 +3201,7 @@ func TestErrorGetGitDirectories(t *testing.T) { }, }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { - s, _ := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -2966,7 +3232,7 @@ func TestErrorGetGitDirectories(t *testing.T) { func TestGetGitDirectories(t *testing.T) { // test not using the cache root := "./testdata/git-files-dirs" - s, _ := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return(nil) @@ -2989,6 +3255,10 @@ func TestGetGitDirectories(t *testing.T) { directories, err = s.GetGitDirectories(context.TODO(), dirRequest) assert.Nil(t, err) assert.ElementsMatch(t, []string{"app", "app/bar", "app/foo/bar", "somedir", "app/foo"}, directories.GetPaths()) + cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 1, + ExternalGets: 2, + }) } func TestErrorGetGitFiles(t *testing.T) { @@ -3006,7 +3276,7 @@ func TestErrorGetGitFiles(t *testing.T) { want *apiclient.GitFilesResponse wantErr assert.ErrorAssertionFunc }{ - {name: "InvalidRepo", fields: fields{service: newService(".")}, args: args{ + {name: "InvalidRepo", fields: fields{service: newService(t, ".")}, args: args{ ctx: context.TODO(), request: &apiclient.GitFilesRequest{ Repo: nil, @@ -3015,7 +3285,7 @@ func TestErrorGetGitFiles(t *testing.T) { }, }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { - s, _ := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3048,7 +3318,7 @@ func TestGetGitFiles(t *testing.T) { files := []string{"./testdata/git-files-dirs/somedir/config.yaml", "./testdata/git-files-dirs/config.yaml", "./testdata/git-files-dirs/config.yaml", "./testdata/git-files-dirs/app/foo/bar/config.yaml"} root := "" - s, _ := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return(nil) @@ -3081,6 +3351,10 @@ func TestGetGitFiles(t *testing.T) { fileResponse, err = s.GetGitFiles(context.TODO(), filesRequest) assert.Nil(t, err) assert.Equal(t, expected, fileResponse.GetMap()) + cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 1, + ExternalGets: 2, + }) } func Test_getRepoSanitizerRegex(t *testing.T) { @@ -3090,3 +3364,45 @@ func Test_getRepoSanitizerRegex(t *testing.T) { msg = r.ReplaceAllString("error message containing /tmp/_argocd-repo/SENSITIVE/with/trailing/path and other stuff", "") assert.Equal(t, "error message containing /with/trailing/path and other stuff", msg) } + +func TestGetRevisionChartDetails(t *testing.T) { + t.Run("Test revision semvar", func(t *testing.T) { + root := t.TempDir() + service := newService(t, root) + _, err := service.GetRevisionChartDetails(context.Background(), &apiclient.RepoServerRevisionChartDetailsRequest{ + Repo: &v1alpha1.Repository{ + Repo: fmt.Sprintf("file://%s", root), + Name: "test-repo-name", + Type: "helm", + }, + Name: "test-name", + Revision: "test-revision", + }) + assert.ErrorContains(t, err, "invalid revision") + }) + + t.Run("Test GetRevisionChartDetails", func(t *testing.T) { + root := t.TempDir() + service := newService(t, root) + repoUrl := fmt.Sprintf("file://%s", root) + err := service.cache.SetRevisionChartDetails(repoUrl, "my-chart", "1.1.0", &argoappv1.ChartDetails{ + Description: "test-description", + Home: "test-home", + Maintainers: []string{"test-maintainer"}, + }) + assert.NoError(t, err) + chartDetails, err := service.GetRevisionChartDetails(context.Background(), &apiclient.RepoServerRevisionChartDetailsRequest{ + Repo: &v1alpha1.Repository{ + Repo: fmt.Sprintf("file://%s", root), + Name: "test-repo-name", + Type: "helm", + }, + Name: "my-chart", + Revision: "1.1.0", + }) + assert.NoError(t, err) + assert.Equal(t, "test-description", chartDetails.Description) + assert.Equal(t, "test-home", chartDetails.Home) + assert.Equal(t, []string{"test-maintainer"}, chartDetails.Maintainers) + }) +} diff --git a/reposerver/repository/testdata/helm-with-dependencies-alias/Chart.yaml b/reposerver/repository/testdata/helm-with-dependencies-alias/Chart.yaml new file mode 100644 index 0000000000000..8a38d551070c7 --- /dev/null +++ b/reposerver/repository/testdata/helm-with-dependencies-alias/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: helm-with-dependencies-alias +version: v1.0.0 +dependencies: + - name: helm + repository: "alias:custom-repo-alias" + version: v1.0.0 diff --git a/resource_customizations/cert-manager.io/Certificate/health.lua b/resource_customizations/cert-manager.io/Certificate/health.lua index ddecb2631b39a..fce5bcbe3d1d0 100644 --- a/resource_customizations/cert-manager.io/Certificate/health.lua +++ b/resource_customizations/cert-manager.io/Certificate/health.lua @@ -1,12 +1,17 @@ local hs = {} if obj.status ~= nil then if obj.status.conditions ~= nil then + + -- Always Handle Issuing First to ensure consistent behaviour for i, condition in ipairs(obj.status.conditions) do if condition.type == "Issuing" and condition.status == "True" then hs.status = "Progressing" hs.message = condition.message return hs end + end + + for i, condition in ipairs(obj.status.conditions) do if condition.type == "Ready" and condition.status == "False" then hs.status = "Degraded" hs.message = condition.message diff --git a/resource_customizations/cert-manager.io/Certificate/health_test.yaml b/resource_customizations/cert-manager.io/Certificate/health_test.yaml index ebf8e75e89064..1af7b1a759a60 100644 --- a/resource_customizations/cert-manager.io/Certificate/health_test.yaml +++ b/resource_customizations/cert-manager.io/Certificate/health_test.yaml @@ -7,6 +7,10 @@ tests: status: Progressing message: Issuing certificate as Secret does not exist inputPath: testdata/progressing_issuing.yaml +- healthStatus: + status: Progressing + message: Issuing certificate as Secret does not exist + inputPath: testdata/progressing_issuing_last.yaml - healthStatus: status: Degraded message: 'Resource validation failed: spec.acme.config: Required value: no ACME diff --git a/resource_customizations/cert-manager.io/Certificate/testdata/progressing_issuing_last.yaml b/resource_customizations/cert-manager.io/Certificate/testdata/progressing_issuing_last.yaml new file mode 100644 index 0000000000000..4d21a9b3610f1 --- /dev/null +++ b/resource_customizations/cert-manager.io/Certificate/testdata/progressing_issuing_last.yaml @@ -0,0 +1,36 @@ +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + creationTimestamp: '2018-11-07T00:06:12Z' + generation: 1 + name: test-cert + namespace: argocd + resourceVersion: '64763033' + selfLink: /apis/cert-manager.io/v1alpha2/namespaces/argocd/certificates/test-cert + uid: e6cfba50-314d-11e9-be3f-42010a800011 +spec: + acme: + config: + - domains: + - cd.apps.argoproj.io + http01: + ingress: http01 + commonName: cd.apps.argoproj.io + dnsNames: + - cd.apps.argoproj.io + issuerRef: + kind: Issuer + name: argo-cd-issuer + secretName: test-secret +status: + conditions: + - lastTransitionTime: '2021-09-15T02:10:00Z' + message: Issuing certificate as Secret does not exist + reason: DoesNotExist + status: 'False' + type: Ready + - lastTransitionTime: '2021-09-15T02:10:00Z' + message: Issuing certificate as Secret does not exist + reason: DoesNotExist + status: 'True' + type: Issuing diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/health.lua b/resource_customizations/db.atlasgo.io/AtlasMigration/health.lua new file mode 100644 index 0000000000000..332b43ec21314 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/health.lua @@ -0,0 +1,37 @@ +hs = {} + +local function readyCond(obj) + if obj.status ~= nil and obj.status.conditions ~= nil then + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + return condition + end + end + end + return nil +end + +local ready = readyCond(obj) + +if ready == nil then + hs.status = "Progressing" + hs.message = "Waiting for Atlas Operator" + return hs +end + +if ready.status == "True" then + hs.status = "Healthy" + hs.message = ready.reason + return hs +end + +if ready.reason == "Reconciling" then + hs.status = "Progressing" +else + hs.status = "Degraded" +end + +hs.message = ready.reason + +return hs + diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/health_test.yaml b/resource_customizations/db.atlasgo.io/AtlasMigration/health_test.yaml new file mode 100644 index 0000000000000..b827f89c0bdf2 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: "Reconciling" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Degraded + message: "Migrating" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Healthy + message: "Applied" + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/degraded.yaml b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/degraded.yaml new file mode 100644 index 0000000000000..ee51f15e48241 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/degraded.yaml @@ -0,0 +1,29 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasMigration +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasMigration","metadata":{"annotations":{},"name":"atlasmigration-sample","namespace":"default"},"spec":{"dir":{"configMapRef":{"name":"migration-dir"}},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-16T08:37:23Z" + generation: 1 + name: atlasmigration-sample + namespace: default + resourceVersion: "49923" + uid: 0d5bc3d6-750e-4f5a-82a3-8b9173106ef4 +spec: + dir: + configMapRef: + name: migration-dir + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-16T08:37:23Z" + message: 'Error: checksum mismatch' + reason: Migrating + status: "False" + type: Ready + lastApplied: 0 + observed_hash: "" diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/healthy.yaml b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/healthy.yaml new file mode 100644 index 0000000000000..4a7a91324d196 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/healthy.yaml @@ -0,0 +1,30 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasMigration +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasMigration","metadata":{"annotations":{},"name":"atlasmigration-sample","namespace":"default"},"spec":{"dir":{"configMapRef":{"name":"migration-dir"}},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-16T08:37:23Z" + generation: 1 + name: atlasmigration-sample + namespace: default + resourceVersion: "50387" + uid: 0d5bc3d6-750e-4f5a-82a3-8b9173106ef4 +spec: + dir: + configMapRef: + name: migration-dir + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-16T08:46:27Z" + message: "" + reason: Applied + status: "True" + type: Ready + lastApplied: 1700124387 + lastAppliedVersion: "20230316085611" + observed_hash: 4969b3c84c097ff61a9f9722b595a66c1a4473bd85fdd282107b98a92db8a43b diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/progressing.yaml b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/progressing.yaml new file mode 100644 index 0000000000000..024f9f7558d78 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/progressing.yaml @@ -0,0 +1,30 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasMigration +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasMigration","metadata":{"annotations":{},"name":"atlasmigration-sample","namespace":"default"},"spec":{"dir":{"configMapRef":{"name":"migration-dir"}},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-16T08:37:23Z" + generation: 1 + name: atlasmigration-sample + namespace: default + resourceVersion: "50387" + uid: 0d5bc3d6-750e-4f5a-82a3-8b9173106ef4 +spec: + dir: + configMapRef: + name: migration-dir + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-16T08:46:27Z" + message: "Current migration data has changed" + reason: "Reconciling" + status: "False" + type: Ready + lastApplied: 1700124387 + lastAppliedVersion: "20230316085611" + observed_hash: 4969b3c84c097ff61a9f9722b595a66c1a4473bd85fdd282107b98a92db8a43b diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/health.lua b/resource_customizations/db.atlasgo.io/AtlasSchema/health.lua new file mode 100644 index 0000000000000..c66d66d15b5a8 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/health.lua @@ -0,0 +1,37 @@ +hs = {} + +local function readyCond(obj) + if obj.status ~= nil and obj.status.conditions ~= nil then + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + return condition + end + end + end + return nil +end + +local ready = readyCond(obj) + +if ready == nil then + hs.status = "Progressing" + hs.message = "Waiting for Atlas Operator" + return hs +end + +if ready.status == "True" then + hs.status = "Healthy" + hs.message = ready.reason + return hs +end + +if ready.message == "Reconciling" or ready.message == "GettingDevDB" then + hs.status = "Progressing" +else + hs.status = "Degraded" +end + +hs.message = ready.reason + +return hs + diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/health_test.yaml b/resource_customizations/db.atlasgo.io/AtlasSchema/health_test.yaml new file mode 100644 index 0000000000000..0fe102f299138 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: "Reconciling" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Degraded + message: "ApplyingSchema" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Healthy + message: "Applied" + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/degraded.yaml b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/degraded.yaml new file mode 100644 index 0000000000000..08383988e996a --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/degraded.yaml @@ -0,0 +1,38 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasSchema +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasSchema","metadata":{"annotations":{},"name":"atlasschema-mysql","namespace":"default"},"spec":{"schema":{"sql":"create table users (\n id int not null auto_increment,\n name varchar(255) not null,\n email varchar(255) unique not null,\n short_bio varchar(255) not null,\n primary key (id)\n);\n"},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-15T14:33:18Z" + generation: 2 + name: atlasschema-mysql + namespace: default + resourceVersion: "46659" + uid: 54a4cdfc-e4f9-4c3d-934c-e08b6122e38a +spec: + schema: + sql: | + xcreate table users ( + id int not null auto_increment, + name varchar(255) not null, + email varchar(255) unique not null, + short_bio varchar(255) not null, + primary key (id) + ); + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-15T14:38:41Z" + message: |- + Error: sql/migrate: read migration directory state: sql/migrate: execute: executing statement "xcreate table users (\n id int not null auto_increment,\n name varchar(255) not null,\n email varchar(255) unique not null,\n short_bio varchar(255) not null,\n primary key (id)\n);" from version "schema": Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xcreate table users ( + id int not null auto_increment, + name varchar(255) not ' at line 1 + reason: ApplyingSchema + status: "False" + type: Ready + last_applied: 1700058814 + observed_hash: ddfe666707ddf5c2cc7625c2a0de89da51e54fc7caa6403db307146430d20d85 diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/healthy.yaml b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/healthy.yaml new file mode 100644 index 0000000000000..eca8ec497f09a --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/healthy.yaml @@ -0,0 +1,39 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasSchema +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasSchema","metadata":{"annotations":{},"name":"atlasschema-mysql","namespace":"default"},"spec":{"schema":{"sql":"create table users (\n id int not null auto_increment,\n name varchar(255) not null,\n email varchar(255) unique not null,\n short_bio varchar(255) not null,\n primary key (id)\n);\n"},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-15T14:33:18Z" + generation: 1 + name: atlasschema-mysql + namespace: default + resourceVersion: "46390" + uid: 54a4cdfc-e4f9-4c3d-934c-e08b6122e38a +spec: + schema: + sql: | + create table users ( + id int not null auto_increment, + name varchar(255) not null, + email varchar(255) unique not null, + short_bio varchar(255) not null, + primary key (id) + ); + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-15T14:33:34Z" + message: 'The schema has been applied successfully. Apply response: {"Driver":"mysql","URL":{"Scheme":"mysql","Opaque":"","User":{},"Host":"mysql.default:3306","Path":"/myapp","RawPath":"","OmitHost":false,"ForceQuery":false,"RawQuery":"parseTime=true","Fragment":"","RawFragment":"","Schema":"myapp"},"Changes":{"Applied":["CREATE + TABLE `users` (\n `id` int NOT NULL AUTO_INCREMENT,\n `name` varchar(255) + NOT NULL,\n `email` varchar(255) NOT NULL,\n `short_bio` varchar(255) NOT + NULL,\n PRIMARY KEY (`id`),\n UNIQUE INDEX `email` (`email`)\n) CHARSET utf8mb4 + COLLATE utf8mb4_0900_ai_ci"]}}' + reason: Applied + status: "True" + type: Ready + last_applied: 1700058814 + observed_hash: ddfe666707ddf5c2cc7625c2a0de89da51e54fc7caa6403db307146430d20d85 diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/progressing.yaml b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/progressing.yaml new file mode 100644 index 0000000000000..79d59ca768141 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/progressing.yaml @@ -0,0 +1,35 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasSchema +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasSchema","metadata":{"annotations":{},"name":"atlasschema-mysql","namespace":"default"},"spec":{"schema":{"sql":"create table users (\n id int not null auto_increment,\n name varchar(255) not null,\n email varchar(255) unique not null,\n short_bio varchar(255) not null,\n primary key (id)\n);\n"},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-15T14:33:18Z" + generation: 1 + name: atlasschema-mysql + namespace: default + resourceVersion: "46390" + uid: 54a4cdfc-e4f9-4c3d-934c-e08b6122e38a +spec: + schema: + sql: | + create table users ( + id int not null auto_increment, + name varchar(255) not null, + email varchar(255) unique not null, + short_bio varchar(255) not null, + primary key (id) + ); + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-15T14:33:34Z" + message: 'Reconciling' + reason: Reconciling + status: "False" + type: Ready + last_applied: 1700058814 + observed_hash: ddfe666707ddf5c2cc7625c2a0de89da51e54fc7caa6403db307146430d20d85 diff --git a/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/health.lua b/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/health.lua index 9de2180197571..d614828d461f2 100644 --- a/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/health.lua +++ b/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/health.lua @@ -27,7 +27,7 @@ if obj.status ~= nil then if obj.status.state == "error" then hs.status = "Degraded" - hs.message = "Cluster is on error: " .. table.concat(obj.status.messages, ", ") + hs.message = "Cluster is on error: " .. table.concat(obj.status.message, ", ") return hs end diff --git a/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/testdata/error.yaml b/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/testdata/error.yaml index b6f1884be0819..4a373358dcd8c 100644 --- a/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/testdata/error.yaml +++ b/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/testdata/error.yaml @@ -12,7 +12,7 @@ status: pmm: {} proxysql: {} pxc: - image: '' + image: "" ready: 1 size: 2 status: error @@ -20,5 +20,5 @@ status: ready: 1 size: 2 state: error - messages: - - we lost node + message: + - we lost node diff --git a/server/notification/notification_test.go b/server/notification/notification_test.go index c1141e7ad6753..ee913926bc010 100644 --- a/server/notification/notification_test.go +++ b/server/notification/notification_test.go @@ -70,7 +70,7 @@ func TestNotificationServer(t *testing.T) { argocdService, err := service.NewArgoCDService(kubeclientset, testNamespace, mockRepoClient) require.NoError(t, err) defer argocdService.Close() - apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), testNamespace, secretInformer, configMapInformer) + apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), testNamespace, secretInformer, configMapInformer) t.Run("TestListServices", func(t *testing.T) { server := NewServer(apiFactory) diff --git a/server/server.go b/server/server.go index d9f1638024c51..0f9b0ddadd800 100644 --- a/server/server.go +++ b/server/server.go @@ -288,7 +288,7 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer { secretInformer := k8s.NewSecretInformer(opts.KubeClientset, opts.Namespace, "argocd-notifications-secret") configMapInformer := k8s.NewConfigMapInformer(opts.KubeClientset, opts.Namespace, "argocd-notifications-cm") - apiFactory := api.NewFactory(settings_notif.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), opts.Namespace, secretInformer, configMapInformer) + apiFactory := api.NewFactory(settings_notif.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), opts.Namespace, secretInformer, configMapInformer) dbInstance := db.NewDB(opts.Namespace, settingsMgr, opts.KubeClientset) logger := log.NewEntry(log.StandardLogger()) diff --git a/test/e2e/applicationset_test.go b/test/e2e/applicationset_test.go index 2fef0ace55583..5b9b8190c5437 100644 --- a/test/e2e/applicationset_test.go +++ b/test/e2e/applicationset_test.go @@ -599,6 +599,134 @@ func TestRenderHelmValuesObject(t *testing.T) { } +func TestTemplatePatch(t *testing.T) { + + expectedApp := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + Annotations: map[string]string{ + "annotation-some-key": "annotation-some-value", + }, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + SyncPolicy: &argov1alpha1.SyncPolicy{ + SyncOptions: argov1alpha1.SyncOptions{"CreateNamespace=true"}, + }, + }, + } + + templatePatch := `{ + "metadata": { + "annotations": { + {{- range $k, $v := .annotations }} + "{{ $k }}": "{{ $v }}" + {{- end }} + } + }, + {{- if .createNamespace }} + "spec": { + "syncPolicy": { + "syncOptions": [ + "CreateNamespace=true" + ] + } + } + {{- end }} + } + ` + + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application + + Given(t). + // Create a ListGenerator-based ApplicationSet + When().Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ + Name: "patch-template", + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "{{.url}}", + Namespace: "guestbook", + }, + }, + }, + TemplatePatch: &templatePatch, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{ + "cluster": "my-cluster", + "url": "https://kubernetes.default.svc", + "createNamespace": true, + "annotations": { + "annotation-some-key": "annotation-some-value" + } + }`), + }}, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). + + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + And(func() { + expectedAppNewNamespace = expectedApp.DeepCopy() + expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2" + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). + + // Update the metadata fields in the appset template, and make sure it propagates to the apps + When(). + And(func() { + expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy() + expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{ + "label-key": "label-value", + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). + + // verify the ApplicationSet status conditions were set correctly + Expect(ApplicationSetHasConditions("patch-template", ExpectedConditions)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})) + +} + func TestSyncPolicyCreateUpdate(t *testing.T) { expectedApp := argov1alpha1.Application{ diff --git a/ui/src/app/applications/components/application-details/application-resource-list.tsx b/ui/src/app/applications/components/application-details/application-resource-list.tsx index e5cad1bc0a93b..c5519fc4b6ff9 100644 --- a/ui/src/app/applications/components/application-details/application-resource-list.tsx +++ b/ui/src/app/applications/components/application-details/application-resource-list.tsx @@ -31,35 +31,45 @@ export const ApplicationResourceList = ({ return null; } const parentNode = ((resources || []).length > 0 && (getResNode(tree.nodes, nodeKey(resources[0])) as ResourceNode)?.parentRefs?.[0]) || ({} as ResourceRef); + const searchParams = new URLSearchParams(window.location.search); + const view = searchParams.get('view'); + const ParentRefDetails = () => { + return Object.keys(parentNode).length > 0 ? ( +
+
Parent Node Info
+
+
Name:
+
{parentNode?.name}
+
+
+
Kind:
+
{parentNode?.kind}
+
+
+ ) : ( +
+ ); + }; return (
-
- {Object.keys(parentNode).length > 0 && ( -
-
Parent Node Info
-
-
Name:
-
{parentNode?.name}
-
-
-
Kind:
-
{parentNode?.kind}
-
-
- )} -
+ {/* Display only when the view is set to or network */} + {(view === 'tree' || view === 'network') && ( +
+ +
+ )}
-
NAME
+
NAME
GROUP/KIND
SYNC ORDER
-
NAMESPACE
+
NAMESPACE
{(parentNode.kind === 'Rollout' || parentNode.kind === 'Deployment') &&
REVISION
} -
CREATED AT
-
STATUS
+
CREATED AT
+
STATUS
{resources @@ -79,7 +89,7 @@ export const ApplicationResourceList = ({
{ResourceLabel({kind: res.kind})}
-
+
{res.name} {res.kind === 'Application' && ( @@ -98,7 +108,7 @@ export const ApplicationResourceList = ({
{[res.group, res.kind].filter(item => !!item).join('/')}
{res.syncWave || '-'}
-
{res.namespace}
+
{res.namespace}
{res.kind === 'ReplicaSet' && ((getResNode(tree.nodes, nodeKey(res)) as ResourceNode).info || []) .filter(tag => !tag.name.includes('Node')) @@ -111,7 +121,7 @@ export const ApplicationResourceList = ({ ); })} -
+
{res.createdAt && ( @@ -121,7 +131,7 @@ export const ApplicationResourceList = ({ )}
-
+
{res.health && ( {res.health.status}   diff --git a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx index 6f28a40ea5046..3d5b1782a0e0c 100644 --- a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx +++ b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx @@ -564,11 +564,13 @@ function renderPodGroup(props: ApplicationResourceTreeProps, id: string, node: R
{[podGroupHealthy, podGroupDegraded, podGroupInProgress].map((pods, index) => { - return ( -
- {renderPodGroupByStatus(props, node, pods, showPodGroupByStatus)} -
- ); + if (pods.length > 0) { + return ( +
+ {renderPodGroupByStatus(props, node, pods, showPodGroupByStatus)} +
+ ); + } })}
diff --git a/ui/src/app/applications/components/resource-details/resource-details.tsx b/ui/src/app/applications/components/resource-details/resource-details.tsx index 6477509370905..52d2fef184703 100644 --- a/ui/src/app/applications/components/resource-details/resource-details.tsx +++ b/ui/src/app/applications/components/resource-details/resource-details.tsx @@ -280,7 +280,7 @@ export const ResourceDetails = (props: ResourceDetailsProps) => { const settings = await services.authService.settings(); const execEnabled = settings.execEnabled; const logsAllowed = await services.accounts.canI('logs', 'get', application.spec.project + '/' + application.metadata.name); - const execAllowed = await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name); + const execAllowed = execEnabled && (await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name)); const links = await services.applications.getResourceLinks(application.metadata.name, application.metadata.namespace, selectedNode).catch(() => null); return {controlledState, liveState, events, podState, execEnabled, execAllowed, logsAllowed, links}; }}> diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx index 674ffc6728db4..cd39470bfb25b 100644 --- a/ui/src/app/applications/components/utils.tsx +++ b/ui/src/app/applications/components/utils.tsx @@ -361,7 +361,7 @@ export const deletePopup = async (ctx: ContextApis, resource: ResourceTreeNode, handleStateChange('force')} style={{marginRight: '5px'}} id='force-delete-radio' /> handleStateChange('orphan')} style={{marginRight: '5px'}} id='cascade-delete-radio' /> @@ -473,8 +473,8 @@ function getActionItems( const execAction = services.authService .settings() .then(async settings => { - const execAllowed = await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name); - if (resource.kind === 'Pod' && settings.execEnabled && execAllowed) { + const execAllowed = settings.execEnabled && (await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name)); + if (resource.kind === 'Pod' && execAllowed) { return [ { title: 'Exec', diff --git a/ui/src/app/settings/components/project-details/project-details.tsx b/ui/src/app/settings/components/project-details/project-details.tsx index 224c2e1e45e12..8b00c8590edb7 100644 --- a/ui/src/app/settings/components/project-details/project-details.tsx +++ b/ui/src/app/settings/components/project-details/project-details.tsx @@ -6,7 +6,7 @@ import {FormApi, Text} from 'react-form'; import {RouteComponentProps} from 'react-router'; import {BadgePanel, CheckboxField, DataLoader, EditablePanel, ErrorNotification, MapInputField, Page, Query} from '../../../shared/components'; -import {AppContext, Consumer} from '../../../shared/context'; +import {AppContext, Consumer, AuthSettingsCtx} from '../../../shared/context'; import {GroupKind, Groups, Project, DetailedProjectsResponse, ProjectSpec, ResourceKinds} from '../../../shared/models'; import {CreateJWTTokenParams, DeleteJWTTokenParams, ProjectRoleParams, services} from '../../../shared/services'; @@ -52,6 +52,7 @@ function reduceGlobal(projs: Project[]): ProjectSpec & {count: number} { merged.namespaceResourceWhitelist = merged.namespaceResourceWhitelist.concat(proj.spec.namespaceResourceWhitelist || []); merged.sourceRepos = merged.sourceRepos.concat(proj.spec.sourceRepos || []); merged.destinations = merged.destinations.concat(proj.spec.destinations || []); + merged.sourceNamespaces = merged.sourceNamespaces.concat(proj.spec.sourceNamespaces || []); merged.sourceRepos = merged.sourceRepos.filter((item, index) => { return ( @@ -106,6 +107,15 @@ function reduceGlobal(projs: Project[]): ProjectSpec & {count: number} { }) ); }); + + merged.sourceNamespaces = merged.sourceNamespaces.filter((item, index) => { + return ( + index === + merged.sourceNamespaces.findIndex(obj => { + return obj === item; + }) + ); + }); merged.count += 1; return merged; @@ -116,6 +126,7 @@ function reduceGlobal(projs: Project[]): ProjectSpec & {count: number} { namespaceResourceWhitelist: new Array(), clusterResourceWhitelist: new Array(), sourceRepos: [], + sourceNamespaces: [], signatureKeys: [], destinations: [], description: '', @@ -648,7 +659,51 @@ export class ProjectDetails extends React.Component - + + {authCtx => + authCtx.appsInAnyNamespaceEnabled && ( + this.saveProject(item)} + values={proj} + title={ + SOURCE NAMESPACES {helpTip('Kubernetes namespaces where application resources are allowed to be created in')} + } + view={ + + {proj.spec.sourceNamespaces + ? proj.spec.sourceNamespaces.map((namespace, i) => ( +
+
{namespace}
+
+ )) + : emptyMessage('source namespaces')} +
+ } + edit={formApi => ( + + {(formApi.values.spec.sourceNamespaces || []).map((_: Project, i: number) => ( +
+
+ + formApi.setValue('spec.sourceNamespaces', removeEl(formApi.values.spec.sourceNamespaces, i))} + /> +
+
+ ))} + +
+ )} + items={[]} + /> + ) + } +
this.saveProject(item)} values={proj} diff --git a/ui/src/app/settings/components/project-details/resource-lists-panel.tsx b/ui/src/app/settings/components/project-details/resource-lists-panel.tsx index 2e5c1d1fedd72..ec9e617ac9122 100644 --- a/ui/src/app/settings/components/project-details/resource-lists-panel.tsx +++ b/ui/src/app/settings/components/project-details/resource-lists-panel.tsx @@ -99,6 +99,36 @@ function viewSourceReposInfoList(type: field, proj: Project) { ); } +const sourceNamespacesInfoByField: {[type: string]: {title: string; helpText: string}} = { + sourceNamespaces: { + title: 'source namespaces', + helpText: 'Kubernetes namespaces where application resources are allowed to be created in' + } +}; + +function viewSourceNamespacesInfoList(type: field, proj: Project) { + const info = sourceNamespacesInfoByField[type]; + const list = proj.spec[type] as Array; + return ( + +

+ {info.title} {helpTip(info.helpText)} +

+ {(list || []).length > 0 ? ( + + {list.map((namespace, i) => ( +
+
{namespace}
+
+ ))} +
+ ) : ( +

The {info.title} is empty

+ )} +
+ ); +} + const destinationsInfoByField: {[type: string]: {title: string; helpText: string}} = { destinations: { title: 'destinations', @@ -180,6 +210,8 @@ export const ResourceListsPanel = ({proj, saveProject, title}: {proj: Project; t {viewList(key as field, proj)} ))} {!proj.metadata && Object.keys(sourceReposInfoByField).map(key => {viewSourceReposInfoList(key as field, proj)})} + {!proj.metadata && + Object.keys(sourceNamespacesInfoByField).map(key => {viewSourceNamespacesInfoList(key as field, proj)})} {!proj.metadata && Object.keys(destinationsInfoByField).map(key => {viewDestinationsInfoList(key as field, proj)})} } diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts index b3f4c284dcfc4..861513523c7a3 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -714,6 +714,7 @@ export interface ProjectSignatureKey { export interface ProjectSpec { sourceRepos: string[]; + sourceNamespaces: string[]; destinations: ApplicationDestination[]; description: string; roles: ProjectRole[]; diff --git a/ui/src/app/sidebar/sidebar.scss b/ui/src/app/sidebar/sidebar.scss index a3ff7a0355c28..d41cbeed3f7cf 100644 --- a/ui/src/app/sidebar/sidebar.scss +++ b/ui/src/app/sidebar/sidebar.scss @@ -58,6 +58,13 @@ $deselected-text: #818d94; text-overflow: ellipsis; } + &__tooltip { + max-width: 300px; + @media screen and (max-width: 590px) { + max-width: 250px; + } + } + &__nav-item { cursor: pointer; display: flex; @@ -81,6 +88,7 @@ $deselected-text: #818d94; margin-left: 2px; margin-right: -2px; margin-top: 12px; + width: 32px; } &--active { diff --git a/ui/src/app/sidebar/sidebar.tsx b/ui/src/app/sidebar/sidebar.tsx index c690565d01cb5..1aeb77c9112ee 100644 --- a/ui/src/app/sidebar/sidebar.tsx +++ b/ui/src/app/sidebar/sidebar.tsx @@ -64,7 +64,7 @@ export const Sidebar = (props: SidebarProps) => {
{(props.navItems || []).map(item => ( - + {item?.tooltip || item.title}
} {...tooltipProps}>
0 && args.Get(0) != nil { + return args.Get(0).(error) + } + if c.WriteDelay > 0 { + time.Sleep(c.WriteDelay) + } + return c.BaseCache.Set(item) +} + +func (c *MockCacheClient) Get(key string, obj interface{}) error { + args := c.Called(key, obj) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + if c.ReadDelay > 0 { + time.Sleep(c.ReadDelay) + } + return c.BaseCache.Get(key, obj) +} + +func (c *MockCacheClient) Delete(key string) error { + args := c.Called(key) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + if c.WriteDelay > 0 { + time.Sleep(c.WriteDelay) + } + return c.BaseCache.Delete(key) +} + +func (c *MockCacheClient) OnUpdated(ctx context.Context, key string, callback func() error) error { + args := c.Called(ctx, key, callback) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + return c.BaseCache.OnUpdated(ctx, key, callback) +} + +func (c *MockCacheClient) NotifyUpdated(key string) error { + args := c.Called(key) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + return c.BaseCache.NotifyUpdated(key) +} diff --git a/util/env/env.go b/util/env/env.go index 221db7b0efaab..985484c1ae80b 100644 --- a/util/env/env.go +++ b/util/env/env.go @@ -186,3 +186,30 @@ func ParseBoolFromEnv(envVar string, defaultValue bool) bool { } return defaultValue } + +// ParseStringToStringVar parses given value from the environment as a map of string. +// Returns default value if envVar is not set. +func ParseStringToStringFromEnv(envVar string, defaultValue map[string]string, seperator string) map[string]string { + str := os.Getenv(envVar) + str = strings.TrimSpace(str) + if str == "" { + return defaultValue + } + + parsed := make(map[string]string) + for _, pair := range strings.Split(str, seperator) { + keyvalue := strings.Split(pair, "=") + if len(keyvalue) != 2 { + log.Warnf("Invalid key-value pair when parsing environment '%s' as a string map", str) + return defaultValue + } + key := strings.TrimSpace(keyvalue[0]) + value := strings.TrimSpace(keyvalue[1]) + if _, ok := parsed[key]; ok { + log.Warnf("Duplicate key '%s' when parsing environment '%s' as a string map", key, str) + return defaultValue + } + parsed[key] = value + } + return parsed +} diff --git a/util/env/env_test.go b/util/env/env_test.go index 691d235805b23..9178592ed3552 100644 --- a/util/env/env_test.go +++ b/util/env/env_test.go @@ -210,3 +210,41 @@ func TestStringsFromEnv(t *testing.T) { }) } } + +func TestParseStringToStringFromEnv(t *testing.T) { + envKey := "SOMEKEY" + def := map[string]string{} + + testCases := []struct { + name string + env string + expected map[string]string + def map[string]string + sep string + }{ + {"success, no key-value", "", map[string]string{}, def, ","}, + {"success, one key, no value", "key1=", map[string]string{"key1": ""}, def, ","}, + {"success, one key, no value, with spaces", "key1 = ", map[string]string{"key1": ""}, def, ","}, + {"success, one pair", "key1=value1", map[string]string{"key1": "value1"}, def, ","}, + {"success, one pair with spaces", "key1 = value1", map[string]string{"key1": "value1"}, def, ","}, + {"success, one pair with spaces and no value", "key1 = ", map[string]string{"key1": ""}, def, ","}, + {"success, two keys, no value", "key1=,key2=", map[string]string{"key1": "", "key2": ""}, def, ","}, + {"success, two keys, no value, with spaces", "key1 = , key2 = ", map[string]string{"key1": "", "key2": ""}, def, ","}, + {"success, two pairs", "key1=value1,key2=value2", map[string]string{"key1": "value1", "key2": "value2"}, def, ","}, + {"success, two pairs with semicolon as seperator", "key1=value1;key2=value2", map[string]string{"key1": "value1", "key2": "value2"}, def, ";"}, + {"success, two pairs with spaces", "key1 = value1, key2 = value2", map[string]string{"key1": "value1", "key2": "value2"}, def, ","}, + {"failure, one key", "key1", map[string]string{}, def, ","}, + {"failure, duplicate keys", "key1=value1,key1=value2", map[string]string{}, def, ","}, + {"failure, one key ending with two successive equals to", "key1==", map[string]string{}, def, ","}, + {"failure, one valid pair and invalid one key", "key1=value1,key2", map[string]string{}, def, ","}, + {"failure, two valid pairs and invalid two keys", "key1=value1,key2=value2,key3,key4", map[string]string{}, def, ","}, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + t.Setenv(envKey, tt.env) + got := ParseStringToStringFromEnv(envKey, tt.def, tt.sep) + assert.Equal(t, tt.expected, got) + }) + } +} diff --git a/util/notification/settings/settings.go b/util/notification/settings/settings.go index ed6a44b60f365..79d70499aaea6 100644 --- a/util/notification/settings/settings.go +++ b/util/notification/settings/settings.go @@ -12,17 +12,20 @@ import ( service "github.com/argoproj/argo-cd/v2/util/notification/argocd" ) -func GetFactorySettings(argocdService service.Service, secretName, configMapName string) api.Settings { +func GetFactorySettings(argocdService service.Service, secretName, configMapName string, selfServiceNotificationEnabled bool) api.Settings { return api.Settings{ SecretName: secretName, ConfigMapName: configMapName, InitGetVars: func(cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { + if selfServiceNotificationEnabled { + return initGetVarsWithoutSecret(argocdService, cfg, configMap, secret) + } return initGetVars(argocdService, cfg, configMap, secret) }, } } -func initGetVars(argocdService service.Service, cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { +func getContext(cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (map[string]string, error) { context := map[string]string{} if contextYaml, ok := configMap.Data["context"]; ok { if err := yaml.Unmarshal([]byte(contextYaml), &context); err != nil { @@ -32,6 +35,28 @@ func initGetVars(argocdService service.Service, cfg *api.Config, configMap *v1.C if err := ApplyLegacyConfig(cfg, context, configMap, secret); err != nil { return nil, err } + return context, nil +} + +func initGetVarsWithoutSecret(argocdService service.Service, cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { + context, err := getContext(cfg, configMap, secret) + if err != nil { + return nil, err + } + + return func(obj map[string]interface{}, dest services.Destination) map[string]interface{} { + return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]interface{}{ + "app": obj, + "context": injectLegacyVar(context, dest.Service), + }) + }, nil +} + +func initGetVars(argocdService service.Service, cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { + context, err := getContext(cfg, configMap, secret) + if err != nil { + return nil, err + } return func(obj map[string]interface{}, dest services.Destination) map[string]interface{} { return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]interface{}{ diff --git a/util/trace/trace.go b/util/trace/trace.go index 64a0361dfa3d5..9d281bf0d4c76 100644 --- a/util/trace/trace.go +++ b/util/trace/trace.go @@ -13,10 +13,11 @@ import ( "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.6.1" + "google.golang.org/grpc/credentials" ) // InitTracer initializes the trace provider and the otel grpc exporter. -func InitTracer(ctx context.Context, serviceName, otlpAddress string, otlpAttrs []string) (func(), error) { +func InitTracer(ctx context.Context, serviceName, otlpAddress string, otlpInsecure bool, otlpHeaders map[string]string, otlpAttrs []string) (func(), error) { attrs := make([]attribute.KeyValue, 0, len(otlpAttrs)) for i := range otlpAttrs { attr := otlpAttrs[i] @@ -38,10 +39,19 @@ func InitTracer(ctx context.Context, serviceName, otlpAddress string, otlpAttrs return nil, fmt.Errorf("failed to create resource: %w", err) } - // Set up a trace exporter + // set up grpc options based on secure/insecure connection + var secureOption otlptracegrpc.Option + if otlpInsecure { + secureOption = otlptracegrpc.WithInsecure() + } else { + secureOption = otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")) + } + + // set up a trace exporter exporter, err := otlptracegrpc.New(ctx, - otlptracegrpc.WithInsecure(), + secureOption, otlptracegrpc.WithEndpoint(otlpAddress), + otlptracegrpc.WithHeaders(otlpHeaders), ) if err != nil { return nil, fmt.Errorf("failed to create trace exporter: %w", err)