From cab9e0619f69b7e88e1ab49c2f50a3e79fbeb3ca Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Wed, 17 Sep 2025 16:22:18 +0200 Subject: [PATCH 01/29] Create content_loader.md md formatting of content loader docs --- docs/content-loader-docs/content_loader.md | 212 +++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 docs/content-loader-docs/content_loader.md diff --git a/docs/content-loader-docs/content_loader.md b/docs/content-loader-docs/content_loader.md new file mode 100644 index 000000000..faa099c26 --- /dev/null +++ b/docs/content-loader-docs/content_loader.md @@ -0,0 +1,212 @@ +# Content Loader Documentation + +This documentation shows the Content Loader feature and its usage. The Content Loader offers the ability of hooking into the GOP installation to deliver your own content. + +Example for a GOP (GitOps Playground) content repository: + +- Sample [configuration file](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/gop-config.yaml/). +- [Directory structure](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources) as an example of a folder-based content repository. + +# Purpose of the Content Loader + +The content loader feature makes your application cloud ready. It gives you the ability to deploy and operate your own application in cloud environments with the GOP. \ +It provides the flexibility to deliver more applications using GOP. This customization applies to the Internal Developer Platform (IDP), for example, other ops tools such as monitoring. \ +It also applies to end-user applications, for example, replacing the example Petclinic content with real-world applications. + +# What does the term “content” mean? + +- Currently, the GOP (version > 0.11.0) consists of sample applications and exercises and their dependencies, in addition to the actual IDP (ArgoCD, Prometheus, etc.). + - ➡️ “Ready-to-use” provision of GitOps pipelines +- We refer to this as “content”. +- When rolling out GOP the `--content-examples` parameter leads to sample applications being pushed to Git. +- These applications include: + - Code (e.g., repo `argocd/petclinic-helm`) + - Configuration (Argo CD `Application` and YAML resources in the GitOps repo `argocd/example-tenant`) + - Basic configuration of the tenant (Argo CD `AppProject` and `Application` of Applications in the repo `argocd/argocd`) + - Some of them contain Jenkins files that describe how to build and push images and start the GitOps process. + - Dependencies, e.g., `3rd-party-dependencies/gitops-build-lib` and `3rd-party-dependencies/spring-boot-helm-chart` + - Jenkins job that clones the repos, builds images, and triggers the GitOps process +- After installing the GOP, the sample applications are built by Jenkins and deployed by ArgoCD via GitOps. +- The content loader feature provides the possibility to deliver your own custom content, i.e. real-world applications instead of demos. + +# Content Loader Concepts + +- The content deployed by GOP can be completely defined via configuration. +- The content is defined in Git repositories, known as content repos. +- There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` ([see below](# Different Types of Content Repos)). +- For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET` ([see below](# The overrideMode)) +- Templating with [Freemarker](https://freemarker.apache.org/) is available in the content files ([see below](# Templating)). +- Multiple content repos can be specified in the `content.repos` field. + - See the [sample configuration file](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/gop-config.yaml). +- These are merged by the GOP in the defined order in a directory structure. +- This allows you to overwrite files from all repos created by GOP. + - One use case for this is, for example, a base repository that specifies the basic structure of all GOP instances in a cloud environment and more specialized repositories that contain specific applications. + - Another use case is to keep the configuration (YAML) in one repo and the code in another in order to deploy multiple examples with the same code. \ + Current examples are `petclinic-plain` and `petclinic-helm`. +- This also allows you to control the configuration of Argo CD and, for example, define different tenants. +- Different content repositories can be created for end-user applications (including their dependencies such as Helm charts or build libraries) as well as IDP applications, such as monitoring tools. +- To accommodate these different tasks, each repository can be parameterized differently. +- ArgoCD `AppProjects` and `Applications` can be defined in the content. +- Existing repositories, e.g., `argocd/argocd`, can be extended by content (“merge” or git clone + push). +- Jenkins: Automatic generation of Jenkins jobs based on the content. + - For each SCM Manager namespace found in the content and + - that contains a `Jenkinsfile`. +- The example content can be activated via the `content.examples` field. +- You have the option to change this via `content.repos`. +- Kubernetes namespaces, e.g., for sample applications (currently `example-tenant-staging`), can be specified via a separate `content.namespaces` field. + - The namespaces listed therein are deployed by the GOP via GitOps. + - In each namespace, the configured ImagePullSecrets are automatically generated and RBAC resources and `NetworkPolicies` are set up, which enable Prometheus to access the metrics. + - This also allows the GOP to create `ProjectRequests` instead of `Namespaces` under OpenShift. + - The list may contain more namespaces than are used in the content. + - The namespaces allow templating, e.g., `‘${config.application.namePrefix}example-tenant-staging’, ‘${config.application.namePrefix}example-tenant-production’` + +## Different Types of Content Repos + +There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED`. +- `MIRROR` (default): The entire content repo is mirrored to the target repo if it does not yet exist (see overrideMode). +- `COPY`: Only the files (no Git history) are copied to the target repository and committed. +- `FOLDER_BASED`: Using the folder structure in the content repository, multiple repositories can be created and initialized or expanded in the target. + +**Global Properties** + +- `url` (required field) +- `ref` - Git Reference, that is cloned in Content Repo (branch, tag, commit). \ + Default: + - `COPY` / `FOLDER_BASED`: Default branch of Repo. + - `MIRROR`: All branches und tags of Repo +- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle pre-existing files in the repository ([see below](# The overrideMode). +- `username` +- `password` +- `createJenkinsJob` - If `true` and Jenkins is active in GOP, and there is a `Jenkinsfile` in one of the content repositories or the specified `refs`, a Jenkins job is created for the associated SCM Manager namespace. + +### Different Types of Content Repos in Detail + +#### `MIRROR` + +A content repo is mirrored completely (or only a `ref`) to the target repo (including Git history). Caution: Force push is used here! By default, however, only on new repos. If existing repos are also to be written, `overrideMode: RESET` must be set. +Note: The default branch of the source repo is not explicitly set. +If the source repo has a default branch != `main`, it is not applied. + +**Properties** + +- `target` (required field) target repo, e.g. `namespace/name` +- `targetRef` - Git reference in `target` to which it is pushed(branch or tag). + - If `ref `is a tag,` targetRef` is also treated as a tag. + - Exception:` targetRef` is a full ref such as` refs/heads/my-branch` or `refs/tags/my-tag`. + - If `targetRef` is empty, the source ref is used by default. + + +#### COPY + +Only the files (no Git history) are copied and committed to the target repo. + +``` +**Properties** + +- `target` (required) Target repo, e.g. `namespace/name` + +- `targetRef` - Git reference in `target` to which is pushed (branch or tag). \ +If ref is a tag, targetRef is also treated as a tag. \ +Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. \ +If` targetRef` is empty, the source `ref `is used by default. + +- `path `- Folder within the content repo from which to copy + +- `templating `- If `true`, all` .ftl` files are rendered by Freemarker before being pushed to the target ([see below](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#templating)). + + +#### ``` +[FOLDER_BASED](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#folder_based) + +Using the folder structure in the content repository, multiple repositories can be created in the target and initialized or expanded using `COPY`. + +``` +Specifically: The top two directory levels of the repository determine the target repositories in the GOP. + +Example: The contents of the `example-tenant/petclinic-plain` folder are pushed to the `gitops` repository in the `example-tenant` namespace. + +![Enter image alt description](Images/8Mc_Image_1.png) + +This allows, for example, additional Argo CD applications to be added and even your own tenants to be deployed. + +**Properties** + +- `target` (required) + +- `path` - source folder in the content repository used for copying + +- `templating` - If `true`, all `.ftl` files are rendered by Freemarker before being pushed to the target ([see below](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#templating)). + +# The overrideMode + +For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET`. + +- `INIT` (default): Only push if the repository does not exist + +- `UPGRADE`: Delete all files after cloning the source – files that are not in the content will be deleted. + +- `RESET`: Clone and copy – existing files are overwritten, files that are not in the content are retained. + +Note: With `MIRROR`, `RESET` does not reset the entire repository. Specific effect: Branches that exist in the target but not in the source are retained. + +Important: If existing repositories of the GOP are to be extended, e.g., `cluster-resources`, the `overrideMode` must be set to `UPGRADE`. + +# Templating + +When `templating `is enabled, all files ending in `.ftl` are rendered using Freemarker during GOP installation and the result is created under the same name without the `.ftl` extension. + +The entire configuration of the GOP is available as` config` in the templates. + +In addition, the people who write the content have the option of defining their own variables (`content.variables`). + +This makes it possible to write parameterizable content that can be used for many instances. + +In Freemarker, you can use static methods from GOP and JDK. An [example from the GOP code](https://github.com/cloudogu/gitops-playground/blob/0.11.0/applications/cluster-resources/monitoring/prometheus-stack-helm-values.ftl.yaml#L111): + +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO`<#assign`` ``DockerImageParser=statics['com.cloudogu.gitops.utils.DockerImageParser']>` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO...BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``<#if`` ``config.features.monitoring.helm.prometheusOperatorImage?has_content>` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``<#assign`` ``operatorImageObject`` ``=`` ``DockerImageParser.parse(config.features.monitoring.helm.prometheusOperatorImage)>` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO``` +image:` ``registry`` ``:`` ``${operatorImageObject.registry}` +` ``repository:`` ``${operatorImageObject.repository}` +` ``tag`` ``:`` ``${operatorImageObject.tag}` +` ``` + + + +# Example-Use Cases + +``` +## [Mirror the entire repository on every call](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#komplettes-repo-bei-jedem-aufruf-spiegeln) + +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``-`` ``url:`` ``'``https://github.com/cloudogu/spring-boot-helm-chart``'` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``target:`` ``'``3rd-party``/spring-boot-helm``'` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``overrideMode:`` ``RESET` + +## Create additional tenant in Argo CD + +## BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``-`` ``url:`` ``'https://example.com/scm/repo/gop/content'` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``username:`` ``'abc'` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``password:`` ``'ey...'`` ``#`` ``zB`` ``API`` ``Token`` ``von`` ``SCM-Manager` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``templating:`` ``true` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``type:`` ``FOLDER_BASED` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``overrideMode:`` ``UPGRADE` + +In this repo, the folder structure is as follows: [argocd/argocd.](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/argocd/argocd) + +## Mirror/copy repo and add specific files + +For example, to create a `Dockerfile` and `Jenkinsfile` and then create a Jenkins job. This example shows the `MIRROR` use case. As an alternative you can add type `COPY` in the first repo (petclinic). Reminder: no type means MIRROR (default). + +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``-`` ``url:`` ``https://github.com/cloudogu/spring-petclinic` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``target:`` ``argocd/petclinic-plain` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``ref:`` ``feature/gitops_ready` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``targetRef:`` ``main` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``overrideMode:`` ``UPGRADE` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``createJenkinsJob:`` ``true` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``-`` ``url:`` ``'https://github.com/cloudogu/gitops-playground'` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``templating:`` ``true` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``type:`` ``FOLDER_BASED` +BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``overrideMode:`` ``UPGRADE` + +# From fb6cf7000ac4887fd6ba8bfabdc6406fff16dc01 Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 08:28:07 +0200 Subject: [PATCH 02/29] Update and rename content_loader.md to content-loader.md --- .../{content_loader.md => content-loader.md} | 55 +++++++------------ 1 file changed, 19 insertions(+), 36 deletions(-) rename docs/content-loader-docs/{content_loader.md => content-loader.md} (85%) diff --git a/docs/content-loader-docs/content_loader.md b/docs/content-loader-docs/content-loader.md similarity index 85% rename from docs/content-loader-docs/content_loader.md rename to docs/content-loader-docs/content-loader.md index faa099c26..a8b7c06a2 100644 --- a/docs/content-loader-docs/content_loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -96,72 +96,55 @@ If the source repo has a default branch != `main`, it is not applied. - If `targetRef` is empty, the source ref is used by default. -#### COPY +#### `COPY` Only the files (no Git history) are copied and committed to the target repo. -``` **Properties** - `target` (required) Target repo, e.g. `namespace/name` - - `targetRef` - Git reference in `target` to which is pushed (branch or tag). \ -If ref is a tag, targetRef is also treated as a tag. \ -Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. \ -If` targetRef` is empty, the source `ref `is used by default. - + - If ref is a tag, targetRef is also treated as a tag. \ + - Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. \ + - If` targetRef` is empty, the source `ref `is used by default. - `path `- Folder within the content repo from which to copy +- `templating `- If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see below](# Templating)). -- `templating `- If `true`, all` .ftl` files are rendered by Freemarker before being pushed to the target ([see below](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#templating)). +#### `FOLDER_BASED` +- Using the folder structure in the content repository, multiple repositories can be created in the target and initialized or expanded using `COPY`. +- Specifically: The top two directory levels of the repository determine the target repositories in the GOP. +- Example: The contents of the `example-tenant/petclinic-plain` folder are pushed to the `gitops` repository in the `example-tenant` namespace. -#### ``` -[FOLDER_BASED](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#folder_based) - -Using the folder structure in the content repository, multiple repositories can be created in the target and initialized or expanded using `COPY`. - -``` -Specifically: The top two directory levels of the repository determine the target repositories in the GOP. - -Example: The contents of the `example-tenant/petclinic-plain` folder are pushed to the `gitops` repository in the `example-tenant` namespace. - -![Enter image alt description](Images/8Mc_Image_1.png) +![content-hook-folderbased.png](Images/8Mc_Image_1.png) This allows, for example, additional Argo CD applications to be added and even your own tenants to be deployed. **Properties** - `target` (required) - -- `path` - source folder in the content repository used for copying - -- `templating` - If `true`, all `.ftl` files are rendered by Freemarker before being pushed to the target ([see below](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#templating)). +- `path` - source folder in the content repository used for copying< +- `templating` - If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see below](# Templating)). # The overrideMode For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET`. - - `INIT` (default): Only push if the repository does not exist - - `UPGRADE`: Delete all files after cloning the source – files that are not in the content will be deleted. +- `RESET`: Clone and copy – existing files are overwritten, files that are not in the content are retained. \ -- `RESET`: Clone and copy – existing files are overwritten, files that are not in the content are retained. +**Note** \ +With `MIRROR`, `RESET` does not reset the entire repository. Specific effect: Branches that exist in the target but not in the source are retained. -Note: With `MIRROR`, `RESET` does not reset the entire repository. Specific effect: Branches that exist in the target but not in the source are retained. - -Important: If existing repositories of the GOP are to be extended, e.g., `cluster-resources`, the `overrideMode` must be set to `UPGRADE`. +**Important** \ +If existing repositories of the GOP are to be extended, e.g., `cluster-resources`, the `overrideMode` must be set to `UPGRADE`. # Templating - -When `templating `is enabled, all files ending in `.ftl` are rendered using Freemarker during GOP installation and the result is created under the same name without the `.ftl` extension. - +When `templating `is enabled, all files ending in `.ftl` are rendered using [Freemarker](https://freemarker.apache.org/) during GOP installation and the result is created under the same name without the `.ftl` extension. The entire configuration of the GOP is available as` config` in the templates. - In addition, the people who write the content have the option of defining their own variables (`content.variables`). - This makes it possible to write parameterizable content that can be used for many instances. - -In Freemarker, you can use static methods from GOP and JDK. An [example from the GOP code](https://github.com/cloudogu/gitops-playground/blob/0.11.0/applications/cluster-resources/monitoring/prometheus-stack-helm-values.ftl.yaml#L111): +In [Freemarker](https://freemarker.apache.org/), you can use static methods from GOP and JDK. An [example from the GOP code](https://github.com/cloudogu/gitops-playground/blob/0.11.0/applications/cluster-resources/monitoring/prometheus-stack-helm-values.ftl.yaml#L111): BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO`<#assign`` ``DockerImageParser=statics['com.cloudogu.gitops.utils.DockerImageParser']>` BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO...BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``<#if`` ``config.features.monitoring.helm.prometheusOperatorImage?has_content>` From a70476d9893ed2b75f5ff4bc044a1884ab8c3b4f Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:06:22 +0200 Subject: [PATCH 03/29] Update content-loader.md --- docs/content-loader-docs/content-loader.md | 72 ++++++++++++---------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index a8b7c06a2..319746f23 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -146,50 +146,54 @@ In addition, the people who write the content have the option of defining their This makes it possible to write parameterizable content that can be used for many instances. In [Freemarker](https://freemarker.apache.org/), you can use static methods from GOP and JDK. An [example from the GOP code](https://github.com/cloudogu/gitops-playground/blob/0.11.0/applications/cluster-resources/monitoring/prometheus-stack-helm-values.ftl.yaml#L111): -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO`<#assign`` ``DockerImageParser=statics['com.cloudogu.gitops.utils.DockerImageParser']>` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO...BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``<#if`` ``config.features.monitoring.helm.prometheusOperatorImage?has_content>` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``<#assign`` ``operatorImageObject`` ``=`` ``DockerImageParser.parse(config.features.monitoring.helm.prometheusOperatorImage)>` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO``` -image:` ``registry`` ``:`` ``${operatorImageObject.registry}` -` ``repository:`` ``${operatorImageObject.repository}` -` ``tag`` ``:`` ``${operatorImageObject.tag}` -` ``` - - +```yaml +<#assign DockerImageParser=statics['com.cloudogu.gitops.utils.DockerImageParser']> +# ... + <#if config.features.monitoring.helm.prometheusOperatorImage?has_content> + <#assign operatorImageObject = DockerImageParser.parse(config.features.monitoring.helm.prometheusOperatorImage)> +image: + registry : ${operatorImageObject.registry} + repository: ${operatorImageObject.repository} + tag : ${operatorImageObject.tag} + +``` # Example-Use Cases -``` ## [Mirror the entire repository on every call](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#komplettes-repo-bei-jedem-aufruf-spiegeln) +```yaml + - url: 'https://github.com/cloudogu/spring-boot-helm-chart' + target: '3rd-party/spring-boot-helm' + overrideMode: RESET +``` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``-`` ``url:`` ``'``https://github.com/cloudogu/spring-boot-helm-chart``'` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``target:`` ``'``3rd-party``/spring-boot-helm``'` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``overrideMode:`` ``RESET` ## Create additional tenant in Argo CD - -## BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``-`` ``url:`` ``'https://example.com/scm/repo/gop/content'` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``username:`` ``'abc'` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``password:`` ``'ey...'`` ``#`` ``zB`` ``API`` ``Token`` ``von`` ``SCM-Manager` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``templating:`` ``true` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``type:`` ``FOLDER_BASED` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``overrideMode:`` ``UPGRADE` +```yaml + - url: 'https://example.com/scm/repo/gop/content' + username: 'abc' + password: 'ey...' # zB API Token von SCM-Manager + templating: true + type: FOLDER_BASED + overrideMode: UPGRADE +``` In this repo, the folder structure is as follows: [argocd/argocd.](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/argocd/argocd) ## Mirror/copy repo and add specific files - For example, to create a `Dockerfile` and `Jenkinsfile` and then create a Jenkins job. This example shows the `MIRROR` use case. As an alternative you can add type `COPY` in the first repo (petclinic). Reminder: no type means MIRROR (default). +```yaml + - url: https://github.com/cloudogu/spring-petclinic + target: argocd/petclinic-plain + ref: feature/gitops_ready + targetRef: main + overrideMode: UPGRADE + createJenkinsJob: true + - url: 'https://example.com/scm/repo/gop/content' + username: 'abc' + password: 'ey...' # zB API Token von SCM-Manager + templating: true + type: FOLDER_BASED + overrideMode: UPGRADE +``` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``-`` ``url:`` ``https://github.com/cloudogu/spring-petclinic` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``target:`` ``argocd/petclinic-plain` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``ref:`` ``feature/gitops_ready` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``targetRef:`` ``main` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``overrideMode:`` ``UPGRADE` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``createJenkinsJob:`` ``true` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``-`` ``url:`` ``'https://github.com/cloudogu/gitops-playground'` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``templating:`` ``true` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``type:`` ``FOLDER_BASED` -BLANK_LINE_FOUND_IN_GOOGLE_DOCS_2MD_PRO` ``overrideMode:`` ``UPGRADE` - -# From a6027eab4b8e0b0de71615a16034337f17c715ef Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:21:59 +0200 Subject: [PATCH 04/29] Update content-loader.md --- docs/content-loader-docs/content-loader.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index 319746f23..91d9a581e 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -191,7 +191,7 @@ For example, to create a `Dockerfile` and `Jenkinsfile` and then create a Jenkin createJenkinsJob: true - url: 'https://example.com/scm/repo/gop/content' username: 'abc' - password: 'ey...' # zB API Token von SCM-Manager + password: 'ey...' # e.g., API token from SCM-Manager templating: true type: FOLDER_BASED overrideMode: UPGRADE From 5f22544fbee97fbb7238ac57bd7ccdfc362d9394 Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:24:21 +0200 Subject: [PATCH 05/29] Create content-loader-config.yaml --- .../content-loader-config.yaml | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 docs/content-loader-docs/content-loader-config.yaml diff --git a/docs/content-loader-docs/content-loader-config.yaml b/docs/content-loader-docs/content-loader-config.yaml new file mode 100644 index 000000000..078849db9 --- /dev/null +++ b/docs/content-loader-docs/content-loader-config.yaml @@ -0,0 +1,54 @@ +# $schema: https://raw.githubusercontent.com/cloudogu/gitops-playground/main/docs/configuration.schema.json +content: + repos: + - url: https://github.com/cloudogu/gitops-build-lib + target: 3rd-party-dependencies/gitops-build-lib + overwriteMode: RESET + - url: https://github.com/cloudogu/ces-build-lib + target: 3rd-party-dependencies/ces-build-lib + overwriteMode: RESET + - url: https://github.com/cloudogu/spring-boot-helm-chart + target: 3rd-party-dependencies/spring-boot-helm-chart + overwriteMode: RESET + - url: https://github.com/cloudogu/spring-petclinic + target: example-tenant/petclinic-plain + ref: feature/gitops_ready + targetRef: main + # ref: b0738b2 + overwriteMode: UPGRADE + createJenkinsJob: true + - url: https://github.com/cloudogu/spring-petclinic + target: example-tenant/petclinic-helm + ref: feature/gitops_ready + targetRef: main + overwriteMode: UPGRADE + createJenkinsJob: true + - url: 'https://ecosystem.cloudogu.com/scm/repo/gop/content' + ref: main + username: '' + password: '' + templating: true + type: FOLDER_BASED + overwriteMode: UPGRADE + + namespaces: + - ${config.application.namePrefix}example-tenant-production + - ${config.application.namePrefix}example-tenant-staging + variables: + umbrella: + nginxAnnotation: 'my value' + some: other + +application: + yes: true + baseUrl: http://localhost + namePrefix: customer-1 +jenkins: + active: true +registry: + active: true +features: + argocd: + active: true + ingressNginx: + active: true From 29a1a3e3080066e5d2a1d57ea43ebd14a0eee08d Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:25:59 +0200 Subject: [PATCH 06/29] Add files via upload --- .../content-hooks-folder-based.png | Bin 0 -> 469121 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/content-loader-docs/content-hooks-folder-based.png diff --git a/docs/content-loader-docs/content-hooks-folder-based.png b/docs/content-loader-docs/content-hooks-folder-based.png new file mode 100644 index 0000000000000000000000000000000000000000..04c06904a222f9ef362cf1aec4e3c20870eb778c GIT binary patch literal 469121 zcmbrm$NbbJ#5`@s>z3>j zZ-1{xXpRzpzy19Nr`YN<_RvVU-O;}ze<#R0_ILDlJ^Nn=DZsh=-|ukFiHrDC|HI?1 z@qhErT*G93ruJvY*M&KayZqN_c+_&&$;}J9Gb0lme0R#{@rjH$8M?L|9mnXhXMBc zpBl!W&$#__vtsOiPw#hUZBIHE=YM@R)0Pk#eZMv z<3C&fJ~3BuHg3N<_&N2D`|@ig|6I?{I6{B_uxP?y8BAxHcI%^R}D3NZ~VVh|C0VGVBfe~f3Nv3QJ9zGPZ5SSdSBP-{%2np z5c{Qu-B9Bs@62(omtRVdjLS0iptap~fr-<${EX|6v12!0qMzkOymqjLfAv6jb$O}J zGQQz#JimWQOHuDRNCflqK>E+KpeMi1TwTRW{KuXCH6m1a4<+b*{bCGzL!M$e((s?| zcopxJ@T)@LkLStKA^gn}*@wd62hB)2>%1(PrAxV>tG50**&+6;LOhh}GbyXm-lHQF z|0ce-q^N#G{%cLq>YEuP_dT)ejw$0`Va8wA1SIyURTk_ww5RPsF13>`U0-<1oV;m` zS88rbXs!kShoyzQ+?RSx375jKXxi~?<|WnXL%QLG5(sNS-S6*xZe@p8tu~ZJ{?+j} zh7IQ@J1IfTOWw1KtoY$gME80;A3@+x%SaHn99@?i~x-i;HW!-$|oWC+#dgW?lTc<1v8w#xmt(c6M2Ja6$B;9(z2b`)pA?~ z)K3t}+?0w3hmO~Td8@icT8_!d4;G?xcDavRBy#r1i;33D!Y~Z2c*1{;B!0(Osy=EI z1;U}VjxLQ;+%q!?kA>qn@}h{MPRRod9`yNqkSy}EE=uxMszxNyQ8oB<_d&!^8B3A- zopjMhw(6G~`=XE3DBuSi=Rjhv{XLVbV=aX<`x~Qj5?6dM^YEyvksJEz>y5a}L?D`= zo-^6q^u))$FkmDT?DU0iB(I*Id<}@|>M54Wiiqyl&qRO2pVxB6{qi}{yA@_LiqB|L z9RgSNT)c=qOyZgr@tA{T@t6HL4iv+qD48YrcYDD0wcoEvvsH;C)ps~?(m)@H=};>L z_fhA9JeDnbJbn$>oMThE7G}rDtijT!5bG$R$C2LOBOh(5V3vw+@ZPZ0QRY55NK>Pt z@y6YYqa2^d!lePfuS4-omb3T{$V2_y5o9pLo$AGMOU?1)Ae3}8m^G+fedDqqxEcQN z!7!M!u&=PzB&GO!dQ^&frd#{CR08LJ<|!mg8$F$Lfn}4gW%~|&eckt#QGGWaBx1Vj zJ^9`j@m`#7 zm7OUs?s@DSQV3QcYWN3`VT{dU8}q{qI`qa80HF*)u{1^z-^l3#D2>l53*%lJLT zZK(HKn172kiER9lfKZyjvRn-fu0n`he|&Gx*1b(P(7s!;Of30jjx>GP>)oF4HR(hN zJ(H!p6@|$Q&w89%r4DOe2Yc zbdS|h59s|=yMvO7;ZpIiS8C*`OB}YvdOC$nWFp<$e}UVo=vP)0uD5=n-~FI9wz9DN zM`{Gd@?;iTB)11eCZM#M&F>nwDP87&qFD^5XAM_HY%vD+U2UVKTszOiAgB$q-nr)G zww=Oeu&LXfBmk~}?Dj%6=GlX9K!h&iBWiQ-z*3rH+Jm7r@eDQEFTb)o$NU_D>%I6Ihyi^1h+! z`}PDSGU=9fc*?XQ{ew?q3pw-xO1?Pbj(bWoVXiK2dr zrMb)#>-U4iiU7f^0A9mhK(6o?JPuIfXV9Fx`p#c3U+A1A2ru&tM-kV{$Ma7R39F4n z=Ev7lf=d(_29~m(ws7{I*AA6;!?-+9NI9eDPxuHrEy;7BB9Y=)p!oe{fl|wAhZ30n z1|0HoyiN(fquapJGFy-?t7!e21Iy&*OQ97S?o+y=`l3+`hg_c$sd}?UCY5( z1C3<<>v_v+oFp>R{8B&rhTL>6gS|m>kM;6Ed}J49L>}4rniFw9w6E$R@vLPK#xsSx z)FEncgB}a)1SftSHJDp;;ml74P8y_c_Q4VuKWovu`XH8SCTNXu&e7|2LxoDV_=k=@ zE_H?7Loy=&jC+5-CJIN9H&MF!_IJstO&C52BQ-l19kAx2XoBe!zTfZcy9&R!{;gN( zlIF3zklPC#JAU?Mk8XWAo-ox(lkJnWZ&&HsiqoTE++@wk(51>`6qdp zJ;wvzA{5{I{-}2B#=Ksk-#K_uj~A9p5veo;-KST~}ytl|A{7 z(4U(4@t!(t*zW~G$LZP7)&Aq9WKR`{k;aNUSb%~qEq$k`+kFEM*Igdjy%2;d92lZ; z_=RmQnJ@cSBwvunO*Ku|3F!D*D>xqF*8;!SbMCuEF)E9aHj4df0aZm!u>U?rQTPJ^ zyeHo5*DD9lKRJlKKj&h+x) zaK=8|pK@bQ&(0JE^c<7iRwSvdc3nx898={uVERd;$RWVO%6> zML%8}#QgHqT#Nh3OUGTX$|XmarKkR2qX_yVaW)%o@%XxsMaO9r7}Ihcz!nVlHJ0LY z>$&VJ^#n$>1vv%K7)tD%z3^^S z+UQN_gD;2ka149cjh-Y8CEfKeFvh>0^!f-Bpkqr_=Z;BXN+BwgBsrH&Ew8F|6Kvjn zkR)$_NwdZxeDgTQltEEEpogg3!wsP1NBL_N<)eMGm;Ec61h_x}6TcK`4wo89@c;Ks zoXUptIG7qT=C~7+X`zNy1=IFE6ln41AxL*&Pvd%;e)g%@4%RS7(6VTPh10lUfbJRN z7X}os==0}bQc^eIg4;Xih3*sTz4$%g=u|<+e6}RgaEKb4b|d7<{-JoWh>|U z_{i0g5Ds}c&yMUlrDIpM!N5ZY@`hg`7?z3?2%{#ckN0MLE${=a-9=8YeoftYKb=+v zK*>EWK~}TuQhmJvIs?!gNS0Y%Juf?s-|k}z2(78m2LpV}HSM)-ltt?H6;0Kcx^^o! zgLk=OSjH!C{Va+Fr2rUj2un^0Q}5RJ0z?O1;x^t0uhuiK_91`eCnWfo6N0wMtO*7l0cG>6X-3mt_lq zCIW2yWN&)}vT(?!wrc<_Et(cVYfBH}jD(*>iQ}0$sVTT$-crMs0aER>%+NHx1A_Rr zojoFP730}@fVwhf^-y4>&*u1RK#X$D3f4UVn3HAIx50ANej{7xD(y*sI`rXzsBsz{ z6~OB#n6_8%IuunOxjlr&K7pw)IJtGS=NHo??vNkG`JHn@qL&_dN$P7s_jm`tiQ$T( zwu<3~WJ!hF2_xw@m0n>knfRax>WX>G@zA(yT?cnWXfZSHup;?+Z!UEqX%dCFz%1Z5 z9QYkK-1f33VsIxYlfNJ;c#S(M*&sh5+`H!AWUeE}6Z9SI9~$an>s-bc?!Tle;Sf)+ ziOhk;eNDpU6}SgP5y;OLi`-7Fr)&$z5`(nO+l8{D`BdinPb(}jam0Wd0VOH4r8)S@ z(iWSW4;<{iaK)MMSGiZq*S<6=yA-JiAh`DdkUTG|94YOQRQPWVH6T9l7WRw~xDTAr z9MpTbSRI}Z(>Q?oDC%oPZP*Wq2L@xjG36Fl$*&z`2)*9r9b%;~XIUHhgBy)|vFiFX z0G>5mY*On7M4vkjUYceu9QtF&U{qiOLWBgbrS~azx0;cO~^)3?Yis49VhW~4Lv z-XZ3>;uQ%y&q3;&*GH28Jd5@a9U83412EIYMG0SUnJGj~dwC}6)9icY(Ua=q(tclw zh0CUKus5=y@Q*mL{F~yGph;OTu@&8o2odVoYBp)sbsZsqnZUytgp+2|&dQ(Z@Ft84 z5k_J*j3}6e7VR&rsi0>c67-V+h)9SSXNeaFVEx|z;xfVG8F%g*Rog=muxpGP4lG%3 zDZ}s};&2PK{E48)I6gJTbx-jAj|ahy0EyEl5@))%vvma|8`^WA2Yr9%EugX%Wg`~n zJ>T9#ci@>P+_ENl0tmA&?dF)v!-Q`anG+)V74PvvcMvZT`jcsjRpOic>yBl5YOVpuoLRCguMb%7#w8%4 zfsy6Sg~zNyO>b%fE#OFDdxUX-OUsUH_2bOn)5SUG!%p`Z^(5^Uf zaSplyQn3eu!RFc0Vt__?y|4$qKmyg3ZjjhmSTuRfsTqu(Xtxoc_vtSGfZ8|T*fm-x>JnJ_A%QlLh)I~5@S4?^F5Muk41opXq z1Vy03>|bY_CPT zDm28Zj3J)V`a>uYA;dBRi<9K@R*Xmi&h%PwI1EEWfx8>S!Wvso{hD_ay*Ct<75mNr zgP=nne&$7lUHW!H77a;Pf;*+!XJzuo?FW`|6`@1y^T6=;@+Geb7L_p4ki-{52p5Af z-tuqI#)~^&RcNqM{4JHsZ1od5)T#+p`$wnkKFRc!*rv3SlS-$ly3M&RWy*X%<~1VNCJ_C#SjU&Dm&i5$QVf?wUy%PYL|x1Jq6TU6nx9P{5j(D z_f1|=tfNoHZpOI^(YFjM>{#N7o_b*j?ays{{D4UE{^(x*3%uc5v*m1@%!UMV={V!v?CL&#Au2&@nFKgu(-#|xif%n`B6T5;LhNp^dyJSpX%7+s@H6*=5V*j= z1*EK0HooYldGnN!ZXqnIR0p}BW-&Zu{St=9gHvbp<9!}dOgZ`oNO4WNEMsH0ypG!7 zY*kozy&?&13?$dKuRd<3yLC9WCWRpEp&!n;m;(o5Jc2%ZLV$5k_c!u}5EonfVL%@+F&CKJCrRnb zWx-7U3p52I1(wV8jzgFqz#_i$G}07$W(xC?6<{FWA>re!-GGk=}p)vngKsE)3^=&X%^&%lqqJ$ z3;Sfv#fn=N1}=4u078Le8ITK*-w@lg;dWfvgmCf4*X5(jXaaxbzHXtX_3TqvKO@A# z80A9(@|rUc)yPY*gJ#>TY{xX3c?sajGT>Tno>YEbz-TETJ(xgq0JQaGSx^ZwoWEG6 zU;JeiwI`4aj2e7lA_Q=+<_zEud-&H%O!x35FrhEb0Jk7ZyIoU01)$`vjHOTn!NuTj z1rTo=LN$}KT;Z=}-?n1j!~E>J8}Ynw4<-ZO(=xz^_7iaU99cEM zW@~yD#wGxNrr>_K=@2q_RRcl*Pm`vXF}wr_3VD*EZ2KqvhfD*>@1R*(4SqQLkp%>8 z7)S|>J9BSi`L zki40uajMm{g9u(eNlHq5WN`pO&yY8uuV{?t@e!#I_3f-+BLfTvThj`7N*8lnB5@(0;A2~M!6M6vaGKH7GPF>m>b3+6Y&_nGBG4ckQo()p}@OA%@1tY z+W+`EvwedN`;lSL!>qX^J6^K%Le9Vu4lW7Q`j)}A62e8AP=P+)Yh#3W@GW3a<nSQC8RxJZWPH+3AM|@XWf{-h8<4*zEnV`BzK>SRIN* zt|+Xg+pR`&6Uq=2|5du82w4Z@E~%<&vA{~i^;oOkZ3%15m2C1($Guk}S5yG|ApqXq zfAOps1$#;Qn&_II{<&8hmVX`>Q3Tnjw7w#;=PjNs$Y6@L?DCX&Pp&~e@de>Q7=hyyQd&VT??dIE7X*N_4WY3mzQH%fy4ZWIbpuu=4xq+j{_>3Gj*rC9 zizEm1&3RB}QeC;a;|eIv3TiB_9Tg9SZ#3VPd6>@S{tVztA2bG`HE*ZD_W^gnAE{xA zNOu&VYLIXfoOTd?V)QLrZ?S0(?S*8T;(Nv1(B@;ky*W6QOUb1x8#Q|c{Dh;DpiF}h z02PaNd5bI1La=@B9~wvmhs52A#8=X9fa2|T#WsNCmnWE7#`f<3{yWVEhc}f^3YOI|DhblljHQ&RAVBCM97s#-DxhtoyL2RR& zE|B_g2`UsI5%=s|%@3Z!)9K&q)3~-DJm|j$b(A@ATVLVa;a$A#Cn@s!qD`Qk30xla z^7s1tEs_{H@j!OSuZosxa@N-4ic1S~ry!(zjrY%nU)2)cWE3H))H84nVrBWlG%gR$ zk;YTZSR(jbLBwhRSbJPt-UO`c_^IVyu{_9vl{97SX&_*rR!7$C;rN2&DDsnux+c^f zX>y3Zrmc5KF3r>HNl6wWvj9$Zt#53Fv)(M}c-N8waVF6<;NRRdzoQIklFs38`kuWY zzP}xBq#RlC)m;3UK!rQ^{NXmCa;G5+ND_Vbv-y4}7KOx8X6VxM*rC3r0xJ%|-?i$D zd{r6HdC=kohZR>wI?ft%U#kNnV?RO0i&5}Al%7oDhS*Tn8l%E$ijAiOAvQsc1@yJD zSL#4>epulzI4s6o19KQUL0mB#B;kF5U+~V2`+L?vs8?2xe1|c%km1@R4sZm6TWRHtwPU3Vji}G1`CTh2E`#^+A45NdVF65HWWt0%}iwB z81Sao!d+1kmQO&~#NSJ?Z`bmem-+gd9Lw%N7_iJw78||IyRy+Tw)>Aa631rO)xf{5 z&04V~!hM!Iq>NxMQI?Yg_w3W3G%9y3A<%-tCtB|zfZtYaT9v+HL5bTQkWL$Wkd^h5 zmcN4tXn$#h+=K{qH9MZ^hE}+_Lv{5ZCQOnlW@Jz9k_kBM3Bo$*&)E^ z6dRqa)rI3-6m^ZY#&FwKlw=r`)~Eoz58rQ?Khib0cz!tYtn%$Rzg7Upe{pc|bK0Jm zaiJeL?pN{H_2WEqBhNDO=@V2B)ih8Q5&GwCy+GuvVB+IIz=|t)?)D%@3xwF*QGJR$ zFJ~~>AnC(MB(TZ?l?^`aRW>}{H=E{{j4|@-aumQG@t{3Rs$RLb9ZpTxAy7j0 zBR2=@`Yhax^r^l9=*WWb2L2@hNoQb5XYrN{p8e3@=3Bji?YtyeU^Y3^682M^^JjDZ zv8E5Mf({5w<)#IX{i-4SsqHhdP6pI$LrvjdwTFSmA~F3>wSxnr{nQk0@}tjwSL^+% zM+~e~kJ)B52D7;(FVFj_+sO_>pMpMgxe<_8E(hjXFj&|cR1FF-aA1AeKtSm&X=Hk=0HRUExjLJ`m3Y|I%}=VS z2_nDEBuJ^yIB;qlZ)oxyWgIP*;yO3n$ao=i$9Gu!)hBL>zHe$Tq3B|54os)so*rP{ z?OWnD%`#Pjyc!zvOykQ0TCWF%VdR#EGNU6Q$NY9wFA|HNTjsXb&p;p9G&NnB^^ zcr~y)js)j=W|c>)dM_BaPyUL-_<@vj=MS%(hmkyM2&xH9i@m-dlGAOtn`}^rS7+=^ zZ)Kj7$~&WuX}}qftCH{NLHir6mYinn@6H!56E#7d7L_~6rmulh-|;RCtu?J*(o_;O z6hBUbbr;pAhGMr5;vkinzMzoSFg6-Eph#NTuI3``!3?t|F}twRPc6HYz&n&yv6H=N zF;y2>U{Yziryqr*Omk@!U9>X=M4pXa7A+p+jHF>YS7nfES=6EW7>Szdky- zr7O2HaaQU?aa!6-_Y3u)(yi^<`ynoxcdvI~8=>*mnY2$nV%>pAT%d*0aeMn=ef%nu zbt)#L=H{Z1d)=TM?7QV{!|ri7Dci}-1VFfsKdSD05~^dQL^nVOy!keWk2XJv^Gjiy z&Pu?z@JmTcCvz|RNh5r+A3pqHW+lES-r8KjwgH5vS)t87298L-*#;`7Hk#pj=Kk3D zjp>r=B$65d5s%m^JW6`Bwbb&=zk zt-C>fi$Tl%?#k|KXg<4=BhODLj}4{Z>j1n$eKmWU@#itT-iud>Zn~mJ2L;1u6ZYjm zuU{o_nErvXxxSUP_n_rj=2bt^%iBQ12?0Xyf$&+@y+O`1_us0y1Ub;Ii3QmBruE9W zpFmU27yKDZjhBtey{HWZ5SoxXZtz{Tp_G?1=STAl(1kf9jhL)@1^%UY(ZSs~OHvFq z1g0%&`LIX9b+w2*C~T>548YT-Ye|o{vcP(iLvyI z4B{akK9`nd$q6#l43oC-e12!W4>djFCH&l>l2KY( z{3zuE>z{Sf^CuXlT|I+`#Y<;kzEozy z_$XOyCmV!Oh}%PG20o^_uqL5=wi9=i?AiwkW${6gb5HzbP8KF|%HhFqm$b*ZH)g+~ z-$>u<&zoVYyOGdCx9$Yq-zytlOBmlcyiw%Oxvf}B^ZZ(`)QA9t#L}n~Wb+7`777N9 z*SXR0eF|=s(~_6~#Se$vHPK;Z+*|iHQToW5+BaYIi7MI~s#sI%xc8?lg|wQdRH?GE zE3VPmN5gZd1KK)}*${3$e+yClZ6Cn3-daBq@ejUV<9%wj3q1RV$+FbFLxGtphJyk= zh{^%I4ZKydgrBNXj>aMWz{GM!}7UF8e_BUVg;`Z)-fcrSvxgp;y*V zztwFkWCrVSVeb{SQ%fwV?82DNx zXlGGt{ULhF&wO!Jpp3`&x>f8mHgRZf32w3Tf6-;V49|cB0u*8>ki_D#6fj~U5+^N%!s=ru%Ox_iLbM}LUm~2+g%CAGFGx@@2D!6iQm~>fnZm=(CySHxxkBoJ zSD!(%w;zq!A+;xNZa_3c}CaeZ}_~k6nB4xGGCb*m~yCC zA3K!mC_(19jkIi;;+uFNdoSK7`Y~=x-=>@#@-{s;;fmU)+{m7(=KL$Mwv-b&8J*}C zMb*+VUJz);7DjkU)4-pQQPxgm#ShY=Gy48q@)5sZe02$ttMUb$xdiv#7J_*xt{B9p>&W5+AoMUa(>3V_1m%OGIJ`ONE zdhNz(Zhhuw*+%b+&>N>xOE(W{Qp#lBX0RQ&z#h$l4S+Tf5g|pW1MQqX{aR`Kc((RG-gk8qt8$EK0`4C?9rW1C$J@$cGuT5aI;k%_#NhXA99n4fCDyevPoM&oF65(vE;Vy5GVlez**Vtsm+Ajlc)8Z|o4y#tYq}R^AM~OR4f+p66Q* z0%h$n!g?2&l`(rHZ=xb@MI>yOeZmJbTC`2aX!(5)%oy6A^sH7|;IymONI441 z@@T%&&|T#~G~T5tDKXdYUNb@Fiachrd?9UZl_tscD8;&-7Bk%z3v-UQWL zoM=I-SCaE2qnA)&3wtxrIfC6{hS|5lEg|r_Jhh@tm8Oc4Q@k~Cm*zQszH{*=8oU@u z)Hr9@TcDj3;ygx1WI_oci??xQxid$*t+j_*gO6f8KS>QIGN1xJ&BIGe?dvcE70S=J zE0D@UTi23?)l%?Pg>~{f)SW7cJcwYz!p3O*o4ljr?t<4C#>1PBGaEjKAuHNLF$g+q zVxH+LpX6>(!kvg2@|ZCE^ga=;%8|ob3YJvk#W*S?#;Bi@H3F_NlGa#nHyYC-#SjsP zC9}Qlb5Gq8gYJPB5GD?D+%_bF-Fzcz8BrX(kVV+k>ArigYymh?Am9?T8`T`q{MbHh zXFQ4bi&96_dOf-e9^`yqzT=L0Z(-I+UeCQs#Dq#`soM^(u^xc3S=$oiD?-(Z=O^+? z+@a&a-2+=B2m@O+L70h2B+3L?Uh8*dH8&dX#)=#il=>@`uMeeYd@DgeyVl@`!jd)t zVqGQ*H(IGxHl?FRu=p4X1*%tuOp%hKF;2>tkj^Me9-F1U0z#Yg4-zESSCWgS(LNp5 z#5ROUt)IzX6S=}lHo&*TUF7Ik{h);~rqbR<^vuIfv$_R%R5gAfj z9d3FL`)4&miBr=ue0A&gz^(~IYB6%`koRSm2FbCB!P_{cMq4Y7gPlKP#&rpeJx!dKxW5;zs)S+9U6W#^!8v=h>0~fSd2F4 zvh_io`bBDGx%O;Kqif>G8t>8dl+Qh4t+=KkO~vr(ZhcwC*;pSMPyXhhg~&olWG3~S z@~#yPhu6N+F6e_g>yEm+II9zLeZOj4{HSpiVkYLuHF)_nBaC8%7tLMT4P2&jRx9xL z%k?*C`yJkX`jmZ&x4#zTB-r-(7WMYEHCt`JxOaW@Dqc zb6tkNdDotqR&>WT$fIe;XtsHb5Kc%KGl;b{liP0?Ml$&{@?-LF)qpE?=s==Ip_oE^;7 zMF%r)!ML^$o?=wh%i8ECSX<%E2o}83`5s8^XSFh8JUzy<+cG z!yDNR_gsc*rLA}mT9MjZa`kj|5ReL9roE}U5MvftGlJKcKQ=0MSB3@mDS$4v{~YKmC0l|eI#ZHqn( z4W(194uF3*Y?$xs)7|WN80+zSIicKT)fj>}Nz(kylPEsrr4RooLuME(FC#)zc5;1h@4+wNXaZ0Wwvj8f-pi+c8j(-rY37R-#v=4k^5GnCU6}(HNIFvC9>_qU`d|*!W+Hqc@(VnrsHF|OXz)M%z zc}K}_Hp;4hA^BBFkAl~JsizLAc6 zAC*ya+kqZ?a#lX)FmN9N1?~@u_!5jehL3E@kX7sUwj_MC9`@$_S>!|po60zA0<1%B z)mlT&8^i>r@k$v6z6rr5X>ns41qxqfNDxvd4$ZeX%VSl19wQqZ-F>TkEM`8@KnyDJ zR%oafMZ%}+9_o%POCaWAfHf~D&W8Hy0jCZ3UV}bR_J=-sdgC5-owUVF-=rxspOUC2 z^0u|oy?N0hvU{_^sp6J8vH32R=jc1=xkYgpF&{K1h#$+{-hn7At>OCWdx7DPUNN|Xkya|!ye2*dn2Xa1f(bh=g;zPN`PydP^z%T$BqflVGs)lT=jG1-J) zBPlNQRz)vnoIbNptr8+LJjB~zEys|JQ1i`=$7Ct*3dvIAJC;K%k>EAe@xh}U-a*EA zzaM-Z4PUP!?nP^FqrqTlcdpTfc2OE0&WO?cmKFrdgiIp9H!dKoWN2=_pJl+tEj@?0 zvncMe6WH1 zvNFpeW^WbA3QF4}&p>$s@(L5)Eg#Xv5#9j%%*rJ6;?cc+Aa}@}G`R;~{jh5csp&erQ5$!1_03`4!fr6QFtd}xOWTy(Jy+|khTDAkc%dDaRi zb5MB8qu?pp{BhuI0k`lpaY+1&>O4M^j>#J2t6FbEOHwZ;{rkWOl4%tKukm1^lM*>vs8!KwCJ zK2f5oxzKk*2q|Rw;UG-6P!Up-J^gVg2xoKy9keO15-4I)Zfgs##`+E+)}j-M3J-;| zvuXqS*ac-RPmdnxfc9;Ko*nP5RME7in_~(Ykn`=DWdeM3VDIi&;;#i09fn zmaNS6%9k1D$YB&q2vox=XeD)&e1r>>P~ecw z#d$A6)8gMRgcsow-c z+8T39*~I=y_cv&I#k;}b`mK)9Y+4$~42dA}8`A0EV{FYIBG8neY z&CRFsCw>yEjNz1dw!Vz}#JQe~pH{p24giXWgNE}qT~K74@C z%T(1AkF3mOX#sqLhA)v<+Yxt#AI_$o=lmX9FX=dU73W_U^(exph~R|@nocOrLbiF6 zcJ|zB_)1qO)$_1C&M>IM#ewoz^wCBZKoMs1MGsykfnP=h1RUe#0uQzSZ!$$16pt!r z)b@z_Jd#Em1UbOjndfF(p-CsYef&kD9C~nM6tWSX?!viS6mCly^R zDu1d-xEpn*ZjVf7P?vzR+FOv`@g)?_NpfXmr*3YWy9Qgq5|Lw((=EhR2tO^2igrR+ z8G;wasZ^ssq#ya5P6yKR-8iKyloEz}(tIFDH*m0n0u(;K1?Joc7OPmylYE@R11x{K zB!3PvRMBG;yZe0g9KSE7f8P{)jmqWm3~lk57{G$k=@>62y{K3vj(4x?Y!+S+l*~+R z-0}9%EoN%hmALU@WtXq1s`AatToTISoeZ6dvgRx(f4RV(2RsY>)!*XF^>-tNy=2;* zUOO&U>XieF>FA0CGKe?$dlq8w^(v?nh#(i}Gnf0XY;3opgC*ein9g6MOh#o(kYEPP zB)Hi|MT|+KfZE8s3FQiWe#x9)-}&$u3SV?`smqc%dfvgeOZtY$IAPE07jT~Va%J?b z(=~1*7A4)s;J1})XO}tRvT>iabV~gZ?d+BfBEpf}Y-l&y9CbVzKSE72p{hrAHx1&8 zCgu6@eRnK-Ng}0>S)rDq4_{jXMCEdo`i9r_ky(qia`>2uobH$Od3Y?e16c)z`|0nY ze&w5mgO zchYbQ0MzpBmuF!c5EpaFSo``?0#IbX4-c{x_m-F9RJZfKqZt9-6g$7DOKYYRT8J@^ zRvSb9Jk@U-s6*y0Ta(fxe8LB);~4UC5g=X=9eePR0ByN( zfQsOoY0T_-@@NA8`qBXmk|53JV|!D=PA1NQWmak*J-vM$C=sNM3Is(kYbHpkcC#&i z?jt@>aI0-&@9}+676u>ggZhN``iQ`v<=FiO^*P5#u|S73uh+q|7jS;1g;T)G2^H~1 zJ8@YhHEkX9o{ZNvP(Tt6?K^@`3N1GlSZ85xX`dQTAw1Ok!>AyqN7*}kcLkZ9UF^AM zqNyp%S=Tqod`>b{ARg%B!2chXu4`LWB#8bJ$-pBSB%>hsCOL?JfCyhdn{#I^XU;uG zMTG9^>Z%L=Nb#OlSuj{)Wg=Y>-sqEL%)%jp~7A@vCq#AG_9vKFyqN~5}LU8 zuU~t1H=TEBUkc1)cr%|%-t=0&BQW`l8SM?zk#YztH8-R;yqvz%Nc^?8Vu>yh%3ZVV zLIgnw1J`(^*57^)6%$%{^TNC>R)F`o&u8eEq{7tFrDOJUI^s4b>?V8ntt3QEO>cy8 z-uPQ{#kFV3>uK7fsT4Xu5vLV>Q=r$cF01$*psrq4=&e?GWa#+*7XHvAT8i z{fW03c?*`I>^YyqSHeoKy4fEJ{J8J7i<~j#$K_-P)Pb*X%|pcu|G<7aIy!IdW*?|7 zcw^mYTk4pDjif-kD!cCAy^9WtbvRb)>kCLia*|^%V$^1v3!As%OL1S{#_g?n*82iw zHlz+B&Fpd3^!^$qDna7&t|yuMZgRn2+SF8RWQ+ zW6CPNtI=7CUSnbwR%3A}Q>3Fykbo9tZ`nC%&vNR^%RLhB`$q9pX^$ZN>zV5@et$8) zI0#Qgn%>^(_dM_~(fZn}%Q$xbonM_)w4vA+ub<6`xFQAlt|D13xij~;e@Xc@b@#e` z;6M+4$_m4?ZxF27oDUN&YZh{Efe;_gIS!J310eJ-`FuG1@ov7c7!J_kyVc5g+LCr` zPMxx-et!LaME*x9#Pawl7|MeBsQTr8)!f64Es6eT`YA=J->;nfPN$ce>>>>EyM;DG zb?J2S=il6`c$rIAOEYw{m!EG1{65m+q}+4MJ|~aogl1^~A!dgTa-wR|s?0vl!%Kt@ zdK>@`T^J%yV4jzmar{%}2@)r#Cu1`5F^IrTF4ckirU_?M$5V?}2X4(+DZm_G#m z(Pv&}?bJ>gbcHfJ6HN8BU&B$cf{S;a%d$5eT^8sMQkNfI>(ezy`w6M)hfF|0 zPTX@Bd#>N5^6csJRuqu-xZrBb9aderzT6o9i)#JM9vpUGq2#-zWyR)^MClH$7RbvQ z_xnLSk$+ndG{S3yTPF)CIQN3&wdQIqijNn7_Jq<2-(vSm?ZG!8M4HcvgJf#9%X!iU zkgsiuXHGeD6J9uS^Kx8JayqFWE?zkia$oM@?2AO<_d@AEeD;}PYw}#YHTp~uz0%$D z6UWo>@(tYm6LBi%V^mu&bvpRx;jwg-O}9be9v=4cUFDxf7pqnzNz#082a&e(X3o7Y zKqs6TV~^ONI({4a1&J8n#SpyUP@|F(+w$cOS{Aj64I)p0)0J0?M3<~knGz>mSts*s zGnraOJw9&|uP&$L_jyhf81B%bNUuqj<%p5;n57yQEzQhY{k}Me3aI9`B1QxCx&Wc(@0y>xb(@@aw)O8|kJghZG%?(=R{ z=xE8}^bHk86PG2-J|Fg4u%kx2%{m$GCy@!)U0jj>5!eOS19L5M)jTb8|^H}>1MC%v17E;I2^KQIDCq-g9zD1bR}wpg&4?d``(-|S&7H-czJID zQsJfZH}TWm&El$!lr##PmS4}qp;_tLu%azZ^!9gn7$j3l-SM8*!oxDm`^9ddAbc@G zQ4xOI3}OkrCtm}1s+@PAaF&dwJFddKtjQ}r*W*B|T01JA-*>`5Be@f!d&lKX+-Dr$ zdK;W?hbZTjGLl^R(~H;^AYQ8rySd)(jar^%`rEpXbo%gV1koNuq1E)}VlWN#wD zF+n3VT%S?}8RoO0#=C{_*gJ8Fhxb-vdMs&oQIboN>lLZh^kXw{QF z@$)|Om{cOEhmSMah%sGkl<@p|_t!V1%@-1rx5+Av4zwg_Ndzqv(qsXI4 zPO?4D2`^!hSzp}`sS|f-drHK7L!v{_E_c^nwmMh`-gi6o;?rOt)c|;@d#F$*TA9JQ zq`b>A`Jiw3uG3QptI?v?(EG^&PWCyfINtTnkO^t4Icl>Ia6CFLG zN2Z=V&c$$!KY`Sq7d`CGuOrjChc_z-srHh&XP5;YBVXS1+#D!HdI7T?a=r59QnqHD z6$YJMSAOMuT!I;riD2 za_()Yrbmqfgza4F%&QK`>T<2O=2Pk4z`oy&(5Ui&q&2`T%R;x@TnwWC?ax=lxA&>L z{4U)^&^mU;&*!%nG;JWS@Kmc~X*JNv2}@yVk0q$@fY^Vk@@=NnPu~#igDfT*Z4e0uvBJ3;AisNs&VR_!{bva(Qfp`Ccag`E{TLvQN4Dd)%j`UOxF8r<7z^ zapY)o!>W3C?_+R?*DLnM%mpRO;w7rsf;QhHn4q&;-tzDG$<>1+o~}M*qUe>_>#P z)&0s3)v%aa9qa1N9Nt--NcZF^C9So|`sEk8f+?lB7HPjqQ(naKTW7PdA6(gCu7HNW z_FoFMu3y)cC+MJ;AfoFd|uKCO~ z@(*k%YKL{IjgAoLeJ-5@p+o8+K*6Pj$Pca zc`s)7q5vI1b3*zha8+d#p#ftr4tQt$sd|)=<)k`dH#Bh9yYafw&8y|_9`x~kJctz- z9J0MAh$g(r-+}5|WEL_6?h9l?$jQAVH*iI=6uDr(1(ZZ@+sfY=t&ef(<*&5Hm3#Qn z)W+0f_U!lj>b#X3KZ?JEP&$Sv?Uz4~_MQmVMEJfJx*3^V*QB68)Xj3=pd8U2UYoxy z${>1p*)gw879U1)ul_l-7B)-ry~x+@+NeFoL`E;u9PTTJtoAE%EPz$sv4*a~{<%qF zcMsYjTeW)HiX!<6bS+JhWRKDat_RX}p4%M*c+m8FGg9!?;wa{FAzdw9l~@(~J3$7R2> zf$y>OIpMNC?(!br%Gz_y;AP9@D)c@dd5|Hu6m7>{HwWtN_=e8f`ve`x_-6eOLU_I2J`as)lZOS>_}Y%j zg&^z(YlBXsx5eGqozXfmO8cAAo|MVM(N6X0<3_*Zl~_(^Yj*zx%fMq{NhnJi>Mp@i z$ri}hBdRA`Uai}{dm=C0IlWa1R8)Z}B5Wbj?nA?71pC_K?=xtI9_mhbWzWRjIHG{0 zxx;lVy$`=%pA;a0O=L0Q>gn{_4(iDqPFw~J!7{y(`@K}!-cQ}b(RjLk1M1TUju7}W z`88iuYxG~hB>dDAFI*^Bfj>$OdIc-CS8~NTk{*b$Url6dM*ItEGsT6g(YIU@G?WHx zetxsI)tTm)XzWvOgZH_eAC#8VHy1}n2EocW%k5btuq`MBQ;DQjwW8zEDGuCb^*+s9TW4Fzbv zbfN=<20eb)^DlTY)5f_#E+Wg1?Y>m(4(G*poa^~qpJdWQr2B{XygZOW9NBuBIknY7 zGw$6Y*#_skTc{s+M2Y$WX~83JJ#;C(y|IO~n}2O3Dw#ZKC`LxP%Dp)m zAfKPchoihczu}bssriK!0y4DGg)$9Krha;EC;pH8>37QoS^Y?HWD5I|qdg`<_%BM$ z8c37AfTFR+F>xO6gX7?R7fXf!@1#Ha^x>78^c|;UI@hZxa?p=B8LAKHKUN+gjg-!m z8fcir+;OpO*FK_f^vAD5R9Ngg6Mq9Qm+RLhv0C-qc>0kzJ<)xOpQcHa<%PnxP3l5) z=U6?w!p#hrH8>AeoJa>g{p0=hvZI|jgR!p}8-vHZ37t{DUrU|#Kom3g*HLQe&%U0B zt5V!@F4wYHoT_vcUT^nPCM+rGE3R8*G2sEFw21riJ|sz%d+dZ!{ixj#8fR}9cW4l$ z$lH+?UdxLC3zjnci*Af$sX;QyZdIN;hT-kQ_O$zYEVjY6!*cqK$JT5dRQlq>Oe@#Z zTXh&2+9DxQaa~xdN-y3%5;{7LeyARCzOA=KGQnZvL9Ozw-DLD{3SYF7}x#bJV(9uc_tYWc?Eu3y#s*9e_DYmFjR? zu@~#O0{X_I3QQ3Swx{F_iNPr)mpUI+6?b+J#hD1$HUc9z| za#uxmLtFFPSU+Ad?0{NXd)Pr6H-L4SU!id#mLohHC>M9ONmEi$I|g}hcG(jnY6dTR zsq;1-5f~!py;6t+1go=`)Ile}FAam@MnJBIv${`Bb*V-Aqb7ErEivl9_>=PXU$;Xg zSXwwjOKRrgE+M13f!q%%9Fi1}iSs9O?J5jVXX5u2{pDafHs`zEu;#Ps*`q&Lxmx7i1=jX_`Kxq$7{ErWsMpQON#r5&NLX-lDMY&v zROOi<>EI*rF@~KK0kr(`CvlnOrkTU@v64~=z^Q12b&3)=~j98Kv9{4_Wv>$3L@9u3ewC&K-v3vqrv zgdW%J#bVH@`89945A)*V<(EKj(;hzhOMax%8iE)vE>fO6TEo9S5RpP#3`B0|mBG4m z)%W(W7CmL<+(m+UDf5zO9&suvRA-4+Au^2>&;rD-yFEEnQYibyHgSOpV~dLo8cM?3 zRKTDFY!k~l17Z#HfWOt={pRpL1cOpsOf9CSjK1vpn~b07W7XJC z$;kU~Pb(reoU;{E&9Mj_jqLNAlqvLC{)`x==j0C2Wcm3O+2gzU6Yk-b`Ac{Cxb?Fa z)FDJva2QuA&r%aIY4qD?y|RzAlJ z+J8rPEHTGjsuAc%c`1Ky`tT95}HrORW<3|G|r=kwR@xN8%{=9BpT zTC3iNtuUNakBE6m4UgO%!qLBd&tcwG;xXbMc;QbwtH&G?)F*YxcezS=lC&WNv?=JQ zN23b*?Y>CS4<@F&^8Cp0h6GU*_H70W_(uaA;6-vbk&aD;<`aZ+^G@z}|EEbBL! zo5B}Op;NJsoc;c*nj%kU#rbultmf1yDzML711OO|>qugIc-54=aj=Q~W~blE30cbi z?!jz7`t5sv*)tEZsW|Lk)E?6JD&Du-13G=yc>Q+>LveiW$yAPZ0`}{EWiZF$97Lxt zG_fP2HR!t5Cq@IyHUb z)`c4^=Xc=+`-En=ik)@ode~gFRBIi|h7PoKX89KAi;5nnihdZkQ0)YSg>eADA8z-iwB*?)owG0lZ>DK-` zF|MBbUG~KV?-~eWGcMZy>>xZ<-Uoj$QAS$xekN|CU2ZJYXoG6IfwH z2Q8Z0KnCH>pytc*1Xb7Io|MbA)hI~b3`;g!h>*%hdqK0xTd`f@DNsU-p9Dc_w(hmF zFp-9lLPLr9O}_{VN>z6M9kyec9s9zKgNRO+gS+qjKn}y#?MX*N1$Ijkx?dw>ss4K&_SJw|E~m%=o+lfK%Ts|3C!AdCOi$ zHO1U5GDtc7j8rS1Ayu~%l;vrq%2*mgI@ImD4^yLHDfdSSS@$CJQV_b^4e11SD!>KC z`%UHbwTG~$EY|>T6Y(K19N?>8(oDDeP0u(3qB$plZvC90lC2)3_H%RQIV1@B^TBk- zhrDxU#z+@FmitIaP|}@#urT2h0IlV>sf8>nJo2_D$_=&vw+9 zK@Z+YZLfZqT600%0}PC621N~%Zr^1+6I3Vqfwsp`LZ2qDjnDC*vfuP`4)*YXH!S68 zzz@gE6W(>4*2q}(^S%<nRQzM)YezZODZ3RX{b@PkbeZWupJ zw0aW8gu4&qX6lEX|AjxB?u;uC3vA_ARCpHf_D{KodGoA#v$N7y%>I4uQw%~s+&|tp z4&%0_>^y0pg3IePzPC}diTC1iYdKjV;{ZTD2IaG8tz!zr*dI0kMl`kW-cPH zl1FXpcWHlLCEBer=(=myPn0&|Sj=)Ul`Oi%C_#8Mj$@8B)Jx}(aTG!M7B|SO{;I9> z*IuF(bl)IfhAucxp*B&J0()o&yZ}_ML5NAG4w{j~w~>6*$pLCAgmwmY3d;8al|dQm z9iKyQodzi?r@Hx`_QmZ2jonruKKSSO(=WQ7c2qjh2kBzcZwb2dYQY6@nBD4Un_|s@ zQ$u#Z7U8(^`5EYN8sbTJ1b;*i7*XhydQ?F|N7o#b3E?C^0e&T3zhcZoh{*Kez3XCG zJErkIDz|o?$KU53WoUKZh4t`uwOJ{J9M)6t8d4~G|?l-@k<)myJ#-5d0rcyW7z0tQ3qLkbl7E53MK+=-K!q&k_LUKyP$ zwFi(2EPn8u;2vn>>>NKc2{;K;e`{y@o;vlp?ExD4n%~WLeeTDc>SLT<$L!jNK;QZWdtQ!J z`?fjxu7+Qz2jU4lv@nC-S)cFc#v8DObI%#`!)lyazVv*jL}iUKei)C#@@$~f;Mw^5T! zhY_fHpn9kb$(j4!A-U!vl<83uKG4%f0X5GedZmUMzTt^ilL4im|$Lr_0RsPTc4LM^R4sNueqV&*!(X z9fMLwXV+cc*A=1L(iE;d_$SQ_*Ow7@uNNdF0v5?zCjW_g-Q~kQl~o0XKxdB!#}*>8 znblykkzP(sLC4%>3D!rzCy-OIpWQBArw*tmdfQA&PxW2g+NQxD3V*sOQ z2E$Zl=RqVV7JP=5S_V1*ZUdEkwjb6>#0SYFbvonxNjLTT0|Xv?w>GG zjZOAya$#&;ac6WB_-T9%FYI(pQi#LFd1WOep{&&=XsI%f5FEji_DV9)f9$=0+y<&~ z%9JCEv-e^)*w{KT9LAD;y^!N3BS$-pB=-cqeYt_z6|oaJcM1 z<)OMo4EN=_2hi+vcCLj$cteJsq9fvTLn`^wsP+E#ZNp5 zuMHJC2)ElrDW~vyNKqQw-{U?nWMJ<5|AHk{ko5S-x?HQ*;zJ%~*PoRcp~Ae756UCj z7u^~-aQvF=>yEP@dC!0pHTwa8c1Tr2Ob!|6w&@<9m3h;v~cW7@NIA>Kn1??K|0L@w?C~~WhI%uB79>nSXJ{MXnNbu`MIsnE)L22<=0{KLIcl5>h))mdGU(d}B z0U0B0mVarIRYwep;+ws7Rg+Vg*SGQ-@zmo7C?S7~bh#1k{v~|VPtD959o;E5fpYp@ zCQ^2@(0Wu++Tlb@%TSsqZc7x!;A>*&husl-^g*M6^59IZ=Zi7(^| zFKWCUU+kdlxnBySrlZDqRn9ZFKVe@XU?Ek^T=XqT>BytM3ML?WQZ>;W}53S7rs>lKaGMF6#E*6gOqT8JDcp+LAh7QQFU!zhU)!Ow7|hadx8ECE zJw)Qz-E*dJeE2eIk7z>CJHX`K4{8eVtPPU)q@0qyBKTsgmlMOeK!Mhd^*Jc8&G=0W ziIt3pc30bIR9$^K%c_E+fGxnMGOuXvfVuqq4Q31WuO7}L+yFl?f^OzEy*X4^Ue1I} zy_-3@kj^|3q(e1~-jtUA(xCnv9t+_~CnmHaGA1aDLG8L8dWay8pGWWaqev^Lms}@N zEXW>iaXltuXS_Z`N*P91+`G`(Q^09pACP+!!r3v0AGQth58iTLPx78t$_WLWCK9O8 zfHrQz{~BV*Wpst+83Y9YKl(Dxrrg4^ez?GJgVSe7g3}4fz8K@!j1ys(VjTEffy*XX zMS_^MfM3wQKU70pz!u7fv5sC3Vdq{?k{76jaJwxw z2?vPhYmX$Lab@qCF<64l>-=)>zco@E6s!>h&IX`1u)^xghKreTd0{(k>g-_xL{%Ca zNz$JEQ_56I`vA|h_)h}bX;Ye^+n-$4&vNd5k4zC!x+}i|E7Tbz0?T}=*FEsloPwqvqhBz`sFp@ zDh>Wpn5aPm(;uG1dDekCb_497fl9`6#>-+)`+^!f_fA}b6@Aq4s)&R2mAIq{uky4K zSBSqWvm}93Unh@!FfPOS{P!b(&>V~(eoSqcc5cDaV!uXvSUoXJ`6PIs|3%)x{WDyj zM)d`;A*i^YZjCBF>5h9JAXFB$30OxEXP;5Xcs+dyVpX31*bS;$W|1smtWNm@d{Vzw(HAl6zLDw)r! zoN5OU*-LSbO_w@I;qe81mgnU%@zxg6T-+Q4&gq2<11X$o$gxvu!bujIvMZ`rex#_2 zW6n1(AP|BNH(uz%+mk3 ztX_OlFqrE<2eW>jEjL>~e()No$Nlrc%51=t!TAh1oNetGGE*x7Rdnth>#sJpz~#$B z-J>_>O`#vSr!9H0e^N4*hwwJddQiNzvWfk^`usKw4-6m~$Y_e1VNi4Vpvbzv31srE zc)(Y}hZpj_<4UAKBWJ_29nc%&`EG6P1~d9va9&gWEN5T7-?yM9x8l!4`9MF8qH}iT zAANkjcMn!1;!L{-&m3?=|G0S9_>I+NocJ{aQuF~P8!u+1$5-;R?gZEUlkZl-K?5?r z2k#E}0B?Y0%C8f^2VhGUKtuM^HOO?{+yllv$6L~}*$qiFq~Y5qYcEF_QQ^DTD%w)= z9^m$bHa%<`FHTM`(hKUD^Pcy;vjcgk%e2p^1qys_empFfF0~9>PhymnjQCl8NWAb8 zTGYmGR53^R4gB0%JT-90C>9u^k{bU`a2f-tY>0=G&Biq(UE3&XT6q6dC;@p3x{`W0 zn!mCAJ#enyZ;vY3#-`D7%(x2=|0%t@WRC-cROjcE(#@;`t>$5S?G(EtzXg|gPvm&&;N+At_OCJI8;c{1*sBxW4 z7#eh~*i!&M+;0UKeG8oNjz;Sd+q zoC1+%r0Puo^1Y^lFPTdE5gjX>RL8)3T-k`Qx?_EUlhZR`AX|#ED4rx51srs5zXeuH z^MgqL8Cn&$gAWK6O-QwI5l7TimExoQnk$r_Vdw*_hpb-Mq$1}$!;%RDk>e+VWb_0L z#tM)*{Hf-ctB;>leMoG{&8Ww-xsduMG-&J!u)1$M=ofuc!MsHD9*mNu6! z_m(rmrP8b^boG=j9&J;jvb#-Zh~6mr2Vxd>seJBxN{%&3=8^)s#j~mWag;jzg$({Q zB&h~4TP@uk0f^7q?MrRW-@&J(-P1Uc)_9ETw8dZX4Hl3G=*EhIvF^nov)HZ#t6@Wz zUCmLd0fHGE9=AI62!hMaIw@~`k=nawxwh2S5IfmZOgsiwuf;bVgVCxP10AOpBuDD5 z&Q-BNuJvi|AR*y(DAQ0MJp!~Yy|KxO$7w+5(Jv)_AgIq?mVpGmzb2+vD9~2OKvcj^ z%((7BiRX-aPp@4W1W)#~=i_*MV;7z__Ht3#EQLF{#~MCwxvM3yEAs2kgY>P$OVC{V z8tqv|#Ik{WyFS_vmD31eX%(2(u*t`~+GmFLnWsmH=_o51+|(M;B6KYxN%pmZB5kZw z-%e5$^)A%ao&A|AegdOc9CCu2yi=Y3;1!3SH|ji)a9?_ndE{=SY5J@8V5@(z{9MFvwT zm9e?(25XkVcjUV6eRTg|1;K#k8~feqXsJGJ9=zg>ezJ$8@5IrmNi#;)F==gyEDTFb zo1SAIl40k|s#!Ot>q0-HIOhGroI(F(Dl7Sfi!nd63mm?|zP38_W9CoGW!s_C8}6U&rpL(0ZoT}_&g+P0s|inl_^abR%nS9YcI0;Cp5{sgI2Qs zT`TWOoaai5p{oK4v2;W->wt`1Ex&junh)LMgrJG>@H+=zz$-20KxfU_h)eBYfd#~$ za*y|3z%g$lyLXQ&Cs|HY{pjTneiP3#?vE@|F@D*TtsXZOKk%qN#vaG_>9Bw6uZz}k zlULu13{x=Zy;#9Bmtpg{GKT?v@TYKfiPHZ)WyU*r_aLCf#{*dU#79x=-Rit>BoF5t zCBwQywT6?dj?xt~f!=$(_pOY}0soJSSK#4ORdF6AP1dv^%nNbw;5-DKLSc|^5L$$7 zd_yITHH2?3DShZhUhH1I5?kefrHFko6>FF{8h(8}+#W>qRrWR3V1vv0=+DExIN4vA2u>7g zW9K3!A0KvxG{kBCcxvQp#Rpe`AK$3*4p^qC{hB~bADvMf;aEODhxk?`8vc3xtFQmw zV*mJ3+JY&AH)^)!1uw-xcZucW`~``=SoeOTy@Xgtnk3$e0HE6f$mAhwAVjQIz#QlA z&4((Q_?+7tYTYI5=8x+cpCMY#e2B5&nJB4v`vz}276@E;4Q(5ie&)pTLfBf}(NP_eaaol&M#UIWq;k9hO zs*qoKPK!OXT(>0Yf?@@qQk{3GmxFLJpOw8Ss~A#=&iu8$a`PuzYRG(YdRi44p@Ls| zo4u2|d1&|S3&MFltX-FbJozH1W7^igUG)!EMQg_TE0IG*m~L;GCFJ1;WFTZ+zRIT1 z4h0m*CxXGmMZ3nqH(yR9JON@+CQ+C?#P$;4_+g-EC!tn{#Zj1eHZn?#X(iusxrB`J zc8(6j()|XYw6EB~$|`oarGFZG8T(3T#h^El(_b|bpk@fwAAkDpI+Ukp*{_7$pH8O^ zpgsA~{)Qk5>gX_NMak{SDC#iVtfr&g*4N&pul$WvI?oVcD@j7!V$bHrq>hVqygCg` zz<0R)*_2}M+2)Jpg=))+> z!XKQFd>Qr_18>04$AF8HiQvZ}g^KB@yXlienK(L6+BVj63F zhNMExdOW!Ml>kp*`_^-FU1Ill4a8A18Uv;pJaWOr+;m{oiFqJ`c;s(j*8R7NiY@gnVs?7&sP(bnmaHa{TIhxOVP) zYL|f5{}hL;gj{7*~c6Z*0uROOagoSJ{y>K6gB!+=i)NEbfkjaMnK@l9BJlD z-%TtU4UwZ;|9(*y^@hrYJcpL828R@esWy1IP1Q~rUfnrG@>d5&ReNlW1iaSiw%T;Y z(c~8J6ByA-nkg)6+!-7t=GPe~7jqU|P7OcRVIlKgtw)*nAl1vf^ti?$>Ur-kGwUDJ z$?Mm0jm&qFI_<~)(FcSaee!;JvF#BVM=ZCOB^8R41u|U~p$I4Y8_Ff>_Y>0Wt1sE+ zc>Mx~u0`*bplPVi;mgrLpVM#$aMVMj)$y}!mb2VRQdwE1 z=3im^?eZp6yu(V=^NhV3z=V-ObpJRIN*X{?vW^;8`xBDtaR z{k&4ZK)mU*f0zhb+T1K)a>R<049`#pB^=^6JFPF#qVs(E-Szo|_*18!&X@%}f3p!$ z?Ma#)voUKU6QGOMA_h;cY=xSs!R^Tm9`6rxtkR6rXFHe2Tn};$nqKnDn~Y?4l$OaOT3O$i z6g4YelX^SyvB)eZR;-h}J;KfsuaQHP^;y^UfyRMCjB+co5o$))i9Fml!M%p})6eze zkO+e9Owo5Hnl$FE<}=#NQB%S zRGcM5ho^YWNB&vIVRv|#hm#C{ya@7BB5bXf=-lqf37Q-GhFGMkE1ahvrqNvU*q76= z+Wg!YotT2wfh?=Y)Vi3+a<_tK#`nT>55=Nu+mzb8@l{lh2H^6;Xh4kL@o4w1SJjkc+Yj6 z2O6)1_ykSnwR0wUGdm~mZ6Z1A_Z*uQ*A;qr(hkhpN9iqvYJ@L*>i3|a^a}Nt*EM?Y zL-;j}_mg=&pJLB;X+f5Vhe9AQLTBSipjF^B%0m!Yfbg`3g=-qAt=wN-*q_ezE&f$= zt8!yLHMMwdsmIF$!1)i(h9kfh;#GxJZfz-A93$85;2T3O0FqNb^gA>xy|W zY5BE^#^FbVEn}vwGC)Iazdm1o3adBSK~54iu3`O%X>`V&8gJs+ppE)0JWb!*cm0oe4 z`;`4;NyGYISmq25-gTkEBMwT`f!M$InQxm4-m-skeO@%Y)4OeNLBPGZ;wr^zwKmLt z?$?a|(8PWLcRYHBhd#BP3s-3Cq0la!;t#=^CgZ8aP&AJ+q`eKh#50UNM5_!$=| zIkF$~XHMr^Fg%@UdSX2D<9Ha6li&54IEq5IUfSgh+NY$E)vq) z=BY;C`7@hlf84rxR#In?=C>BNupll63?{yHU;3e* zdfhM5w)*YJEMC1>*Ai|rWb!e!>PVc=*WYa^1x;FaJgfXbqk~i6dQowt+upV7dq!;( z1@Z?Pu?z9~ez`@^vu{S1j*8-=erQydfluK=O*53imHm4p;4FjAoXmIG$WCdhWD&iUewxbCi z3^)>!KRhH&usg?Icx)uuQ}Qmh`mk@&{HwjyV9vNhLz~hBNM=1r&lHO5zr+2mBxCFM z=NELlIjWhbOr`S-*O&rs>hCy7#4&bFp~epf<66B;%8zOu`^i zhx2ijAMe4Q7vYRjam%x1(hJa)^DqVn>1}=`>5Ps7A+=$&U!vD&p1Od9l+SV=S~hyg zET7s~RE8Ry+XkL9SL1nP1!hkXAH>K!g)A|;tXTa+VQfL4XP?ND?vW-05=;Plj&P&~ zFhr3brv|2w{=;n_P3_*f=2qz3W~5ifzgrh-TNCOEnN%`p6@I-n!* zYmUs44hixADw$APPaH#Y`SkVy%fPl~9zb{V0hP;&=M<e=oe!9;9 zZ#^72hIFaj1YgHd^gZ_6pEWu*=G%cg&!m+XKjClbW6~$#k~W%llnd8Dw!<%nR~jEy z?fW`;@8Qm*Y5s=F-?z_)5rS9diyXPiB_AvUgr0=FS*FdOY)+qvdrZFl*-Om*{nVDV zJ(MiWyYt8AH*a5vrUtEZUbkbRJ(A*+c|H7#e1NFoKz65QtDAO8wldX|#*!KwpHUxL zJr#Y9;;XWbUR=CmMuqMP81|RHd~+%v+?=uxN9v-FKPI5=Ht=${VwKnsTC5jT%=dGt z09qjA%8?k@9{AI>_`sIg79N0fSw;vOv-*_D#J+#aGRwQrOxvU1XPE^lWb)?%{Ymcv zq)wDsL|5-omG^txC@yAu08m;U^9s@I>^)3$U=;37u6xwT|jEuR(ArkWTY^oC^4= zxyZfiUiZ%i2*?`YnfiGJ5Y#ublsqmH2L)_A=S;Ele!ws!CEu-hfBSdGQY*lCrkXyU z^b2d;Vs7(w*k8dtd1ZsdFk?yY#n1dBSP25-ILLjr^qbU{k9v3U+^%s2E*)+Xo-v#d=45iqQXY zAYNjQ`}W^})OqqbXplHJ{O}{kqm9h|*%VsMurG!eDAE<&O5~;P;OQ3B7d#_8Xmav$Qyn{)&s*fk z|FQQT+sbNdwCF1#AZQUJ2a&AQ2qGC2Nk0AQ%(d6vgNAuwCybj=W#M%5hXZObFcdMM`U2__lK?S9Ms$3%(+xzc%k5oI&F^w1YxyO`G736 z=k{&oeN0bcm7xnko~^?Bx05rhTZl$KgAVEV`w&Xtr+Br) zYn7YRuV3suTWFejTreu|8FT`BIlJofd4k0XuFiZ@ulKYan2vobBlis;y9AnANvem@ zZ3+qQntO*fru{e2T&-(ula~5zlX=^~e=bd=6xn9^sK0pG?MhM9bI~D-fIig9D*=Wh z&a50ZH-8dr3*7$5w-~=9$xAIygTLBP)x{COY*ftmTw?ha#LP>-N{bSY1m!m|Q7>|Y zGg6AEg5aLq-_KR>=1zTuqR48Gf^>YlY0yN|NxP3)SRCD^I&W`WBYw+5KvX#P{niAY z;SMcQXB|W0o?}sE@O(o4As)xqh{Oqzzr%hmWKKdKhrHIGk407q*TkECc)fkkVIZWn z9I|V5#HVk4yQ2Sj)!y|INatEBP@Z5uS^QYac|V*+%tW)pS0UoJBlNapl~bJbJB0&8 zk5fvlBV^5vkD`qe|uRPjQ@ z@+!7Qd1+T&2U<>J9Iw>_sQm^{b#mL%Y4%8eYP{%09DEpqq!^VOi^;f$()ekQX4a}S z&WwSAKh_ji+$F|&eqaw8G4|HK@0+Vd07Be@S4whwAq1EPzV*qsjRime4qbImQZDwO zu0{M#n?0rjf6;%@UF{m?mn1F#V6na@KJxV&8t8MFTl9q-!u9!myd+w9QoaF7pd&sU z!@WJYX^na{8den}3_^CWJ}aGTF%p*7&zS0ii|nRnoG-FBC8w$IP}XYqes=WGQ)vzj zR8pgUX3 z6Jw!PE#T`6u5`NB=^HE(GYmYQ*tI+zP6Y9|oh8Vf_fdG14~=zBo4Vm3!GZAum(b0} z^8s{%r`y&0jqaKs0H-Yb-Q%H^oW3XV3+BbgPo*~fa0PA;rgV4@jrK7nB7I$*p9IuQ zcf-ELKM2zIfoqL3R=KhOB?l{kCjBW@kWFKT<{f!EerdtwAKUZt)CCzSVcG8b->v5IKZv)XSHSiM>W*oVaFuJBT-W*s zvcvHE2(h=v2qf`Rt#&mt-15*+cMWc~&SNV;Z!vuKVOhJfdg!caOUY7<0JSayraRsD z`Cp9PD9#q}#9J}vWM{f^*YKi;BOC%&mDKkeK78HndeqQdFb*vM17CmF;jf`?yzY1U zK{4d>a0|_vVca|aPQ*6=*}d1lgLNoim6p_e=hFDH8U*S)H*v0lbs~hQ+ zC^hR&d6Gy^rQYD#XzxUg6mVU;2MBGJ=)HdLjMJb4O z5CL~Blf(4Nf6MM7Esyv4Mz==n9L*b-STI95)XAqhWQ+`K%t3l9+5olzz_&F7FYz(x zKVQ%7CQ3{IDQ!F=0_!vlMJJ*(=KH7===f-HD`d)#mO z!-_2t0jpiCb7^&z_F9E<+k0QUWxjiZU?zWjvn^vJ<{+)?J<Cp{CNqYlK;<61?c8@zh+cEMT* zen4sR@z(;Mz%=ET<~a{CbH`25dt!z_4ZHS>j^4&#Y>S1XVuXmlkwKNaT~ zLC!zTL58$#2p_bA{+iPLK@u#r@quG3u>I5f3`4Eco^`}8t4d<(-iASy$(~Ragg02L z<$|RtRr729RR)uGJsUZ8^vDC3f~350=JGon0iAw4PxG6#N_K**vfvdHZvW5dJgH$W zUKQHx$VT>p-pdR%cd8HTjd`g!C!gre?5h%yZbpQ9uPBEuQ@29cKPiF zd?>nU5GalAj&@;e@uEiEv-aJ-TzC)CYqI@r-?r>R+pW5}7jul$^>$?}-Ea?^^ZHGk zCUSlByvKdjArj=({m1j?dusyCK9WaF=MsPN9S7*Wo|hA->p$_eG7x~Im|?zn+&M`w z^s`!vQ+-8ojI>c#O=S{tk*qxu-ka6YZa${Z^L{9C-+X2D1#<8Uo+DBikNrI*uHcZK z-bqu?x%@;nW7nTCS3YRH6%Ay`(5l$4E{g76@ogru7fq!6ux*Mx1T?48t2S<*hr-1h zC@$~83xhP1TQBsg3KyAZk6(ia!2Q))(XqM$J(ol6$p z2FLMFsB(adyLR?9^O?8ytidv9X%{wtnS#2HY%F9V-+Pu_9NVdUz&7Ap37d6y$4pkw zz?-JY{O1i>)x&zx{=pM>L{-(eaP&t`} z!_j|lG>9nY=ETCD?nC;e0{FLrXFxy17WIh!ItM+wyC!SHkEgYdVgX}przbCrqtj-* z)bo9=F`=Ce_2+n!nSI2?QqzL87=pY6QC>Cf^{V6?yBAK$xx4?w;C&*J11cfBt5x#1 zpJ~^0A01$bF6x)3+yzWug-qVFX96tyfN1 zCG`s`|7TB`t@5X;@a|LXXiQxz@~<^94?JbUSQLvZsOH&{rm!$tj_rDh9D=1)ztGM< zj`>C%+_d-LU*jzcP#I#rUG7$X3;{+*6$DrWh>X~e=6fj8x~nzC!8L+-=3&|-*-w~H zX}#dCnLcQb5Ijz<#%Zs*-giK|)IzSzho@af*QNi-RIsuSPq$2Nj6`JQJf`qYZdt{g zxSN$lI^4fL%V;{m%A+pOK=EFG23sJA&zC~E?|*!h-p4Nfxvw~jTZp@&DILai{eJL% ze(3V_n0Q;`6DNr9pYEo7q`YP!Chra*6s}!BcXd900(>o+ERvcr0g8^?^D2V}i14qE z75k@sZ(jCk+Y;Qrc~VqQJ>fL+z`Axv$${nV`o8cd*zOZh(3`D+x0BY}3G^xNY%Mw7wgv!A!m1I`O)T_(($jlN$j z3e3ga6RR#hEy4mPP+E-CV)Y_%g*ev)fjOZf!{IZVc3aHTTUU;lw?jZAq)C}?}xU$VPs%yRiPP-Vh1GTZrh~m>bbiDJyxWK6L zsaMx(7Vl7MIIfXn0rIE91#|A8_$DxqycX*Upd%TR8AK@oxO#se{O*2&>%1N8dtAjy zcb1I(p}v${P@WrgQiV(`;<}4^N8JLDDjt5ID^N{G)&{Hqc7uIqUEwk{CQWa>*xw{7 zAL=CPSDmTCSFGHKRNr{Tqa+#&g0PrzoknuqR{N>}S;gCND}MVYy1oi`Ln%&CWgpd%MBEQVWm zp`XLa4Z`OeAo4woFD>|1J&Svs*$vd6zp--I$I)*|fOj34k^xyx@6Ni9>Tq$!xGuTl zB5{}VNc%VcOazPUmfKMJ0VjlV?t8dezYl$X@^9B~zq}=7Q&_6**U>Ao4?Wq4{ZGH= zlT0suY;J?=jGpt^qi^4PG@WphD3!V-XF>cDkOEBuaOzBT-xfy_sQxI{}aB1SgQ}ZC+eT>@_^N; zTP;O4cUmXoSp6(OVi^xf4lmtXrRSCp+*=xvKS+*nd=e8Ia9G1*81!0kj{06r_L1B{ zE5UfnB<#<~x_)rS%Iv@X+OO&9k?RTbAQK6CmlOHDf=5y6i61vDOKlGZ@a*#k0HqvY z<|{G>$zR<9zxnpFLYZoaTCq^NPbzNtkpw&9rujrtDgm%6ukeMaN^2a6nF!gPXcDc2 zK{22^wu#T?MN-=r_?FiK+cTBp(PozXbjPEqrz^kt{BO`k)oJ#?1L`mYZ|unfOL~U@ zzy#O$Omz&AU-dAT%Y*c!6bgheg#a(zdwS5z$6zV#1a}^tB3u=RGr*GHf)`K6T5C-T zvmeEt5${@!JY1T9Jd-I&JKSw?_+5^-siZmfA@~#V^F2w?r7K7sUzV+3uI*c4T>}&K z<-=$l^6l4-$M`tarAWOxD|N*Ungtmd*+H;^G987wenJeBX1nEcs$tcs`| zX0l3QxOWXMj#Pjt=@0uX+r)nuI>Sy{r+i1&*Q2iH7nE#M)T5FTSfCiN8g{+AkAZ$+ z(8jzH%Evw!R%d52YFb?{>$U*kp~w70f0j7w5CI=%uVv+mpr^#o`U@AT1{L;12EraD z3n+*e8r~|#XzJG-9p5i{>OYmX()(q-HP=!u8zPmWDgql@E8GX9IHQ|Z z=h@xt;xynel)c~ zl+B_Q;E3%wzCh9`9;awipo!Z~<9ClQeZXrexA_7SDah{|%V zq#8}S_ERX-$b=;5`K=fF?E2H`(40!DNmv554%iRvj536_UL|NFgKAlT#W?4vo}quC z3cwB|n&bEOizQUtQV+qg3x-Au^^mL11MX~*>-tJB*bx^qByyd@sr0>uXxir-+c5v+ z`%Q5IJ921=0=7tB`NaODP@}CTQP4zFhR^DPOhVWgU)I zy~rc9HE~lzJS{OG*%`caMrbSQ;cfu9#SrUf8{}S#YCT)v{Z(#umjT(k)fD35ulo5u zl*20uOy!}CPrGuNaWA5-Y#_k4raLa+r;hKpx6%Wgp+|DvXeSrZ!8)+k)ilY?f96)) zyf<(oT9|+Gp|%AJN?gPvx%io2`#Psv%nAm-sc2PmS{~7#r&tPjS>26F@l8vbMgAWL zUzicXvZZkMvE-c#Szo>0;MIdf4SUv!G`f}U~%wZ1F zg{IS?n)e!+D;K9ZIYmP6Q&5lRZvhI39A+=^7)WG?Ff{ea1%&C|C1N@b!6_Jf2976c zo}$(#j{}z~9q`xo(J!t^$t-V77Xw%DGWxzI=c>Hu+C}7oPy_oz`^AG_G%u$g5KpOm zg27AOKirXBn!pgwN9I{Sx2JJ)#mKqMpV#$3bP!yBwc&=r2Xuk%LDSFS0YocAH2he; zfV*}}!TnOV<>g4~EFWHTKZ!pfi@D=4+r@)X%%O^fo!}{LwT9ZgkVLP??dyNIM$?`4 zM%r)yMBy8*8a+3t?>Z)={_#(5Dt^48XW$Sf-}d05&JT&XePL%0b0UnSlk&?vShL=( zefWC*N?6Z3uqp;>cRCASNOb7|9tJuZ^f^8Yhb*EyjiM|_)P4v#Zz9wxl?6K{2YJ`4 zk_)1;u|K!dx)(Ae-N^ms{v^tzeebPldC>_^9>^&xb;+~6t$IOyP}7<9eQA-t-`>s< z<#>{GzR&A;^cS9LI55`_%5!ivzK-OE0{3XYJ-F9i{KgAPL!aNwd|%*Yr!5iwm9qYj4f;8Rr%x`YBF0m=5N(IUXLuGRgQ*MY>DfZ zN>`U?2Qo=Cy%dfa7~rL@5h*87(|PETIC?2R_jnD4j@T`0_~FA4YU^K2V97 z^)?922SaS*qeq!ezSK~wSajAq?VHRX7^(g~HOx@Rn-SiVVW5gT)NJKi{rb@@OTx$W zyFKXEfeyUhK-d0H-pH6>w|SW6WlqEZ25VqMBK|m2;AWj~b(i9nx_)ouC& z8_;*6la7A%`HF2*d}#EiC^@Kj7S;3 zuOvAn_OmIV*e4Actd08uqOWI@2cd&02=fjH($e!cxEv*hE;G@Z>#tQM{v-s}h$_-W zfrF;f16RxyUPL4Ahs?+K=%6;U0$nzk%mg!4__S`@W7AyO;UN1MSI>JmYn;rBx6Hld zUB!va=MTH_24Jpk4P{J}$MU?HN8?iJ6AK4KLh4$d{~0`AvhoxHi1$l)fmdD$JBjV3gM8CQ69;W;(SZ#y~ji-`uUtoG~zQ41mSx@p~V3hP!rHo-|fhscD*Xe&iAC1#3%x|}c zc)ez&mYu%{r|H`k^-+w%jr82^-qm$FQsdq;hso@D1m;Dwwp%b$6-u&{ZnW_2qUhY! z1S_vThgbM{vhRg>1#rAE&Pq!)0cyao+IdT{9PNprl=cW09Qk|tS@LImo^E^HusGNp zE6j&y2xe87BZTy;esy)NQ3kF(gHGF27GahEmzhGwP>?<>kJc96Gh&~w_hAFS3?1ym z)V#p?kJ3or_;k2Y$=fb|CK-NF&L*WKVFqvdPhi%LHX)dU)FTeUhMS31D1^NE>*oPw zM78MI`6VA{08cKX?+G=p_lMv-6vcLx!eN5u(-$hTAUugzwbv$U==4F~kClZ=^Gg^m zUDoQd)*KGg4b}RG?g+{1Z;@J#1-6dba>TPKk8`_`zh15x$qF!OQ_`E z7tXnWlLqe$B`}ujARR~3GQrx(Fda)i(x4_VGtzeszKm*$(i|kZ2w9+a`?!WpQnB`r z?ScX+>xVKVBkaIiO8wQ@b2ERAUi&tQ8gx48NDf0>wC|+PhWB6*VMwX)VL>WsAk0eb0AgsEpLwx2_or7@zWvQH?fan=r%J@ zRF#uv-!BVpw(%tjZT*)`$U$=Tt{nC~}C2fTM0 z0BnR$MzDtq^(Q->oxN{z#p#xq2iVignP7n#>)%;ll;y>(OZQothZc9fBpwn6j&EMq zAJyk-j(~;+xo7vfzt`iXL)oE+;4B1&jCbPmk&}37@Cuw7PdM+R91hzblu?1ilW|ymaYoe>w=sUflGzrnx)?7+Ipsc`$mv1g*o|;Qg~iSAyJABd{EU zT8q4OuS%~$*YsC6hNBXC3hVo6bCD(!xyt{VkMzCJ_IK#!OAr(Q!j1mov>{E4h5QmU zF{Fv1AE!I`z{l51Hmzr4D#h#c%%t!kxW~p(KqcS!!1z|CP1WCFeZS)9>;9o_SIl9! z2>kg_tn5bW-)*||kG5;8-A+IPi?aO1u9=fJdHKq3!*fuL6nuMN@F5$5D;&JFv7$q) z+v|8brjB)~qa*7ng*5@Cy$4XQ3;ejIPviFA2^iSh{dVuq>~p!i_!j&_Bs1swp&vCl zKIAofd}mwnJNkSLpa;GLnJOD6bIk?Zlrqined{v93#T+?WBMea9TKWEn^5~+5GUoP ziD!K3MHZ<07SM;5J4t&k&%g_f_;o(M4Y}3sgJ_AKS_unRz|LGi|FD23Y~9W8`>BKR zL(1aee}j5|ST-MVo|Tw7>~JIz!5zjfp8jp?A@gB;%-k3;B6E?J)lhNg8W@Wh?oz#~ z4)5nG9XgYXs5ot`W6r?+)tCID};ZIzPC$=V-KC z+b&SW=ckBL;g{RI`>?K*M}E6F=SI^|pY(f2xBGk_)14c7L0{9M_IcznI&OPX`mE91 z#T4(zoS_uGwlyNCrSR=*?9TLWkSz)&_jOH05aN>7S7H_)hCfO7;zo7Vl6}tf<0Osn ztfB;m8kzX)GN}h^@M`~PlaHpheUIB267%QZ=sUxBsMpjvonC`Oalf&DO_0wjV*iSa z@;SB4dE&07^DBe?32kG3nnC>M#~C1<030_g62{KN;N@myvz!)|~85 zyLpfY$!1wE%XJcN>oglCv+m7}+k>MIyHNuktn&(Yu5U{RO&K;q4R#{83AbTnCxU z)pRins^M9S$0mAvK|8shZ-08i%^7O5$+K~Cqt?%qo5yCO@?%N#)d6$^^(BgvziF8B zcytM>l9t`4`i3TP+lB(#!`$s_M^F9`O83$xp+tDuYvlf@J;IxD6ng_yrqkTJ`Hl_0 zXeIUa)UQLh;*S7KP8#w(0r61NTPpSEaq6TMPuJ^(?nwiZIENB?WY-g;sS|Kc5$E42 z)C+LBq*30WT#2q8{no@6)FkbPN?_#bm20uGsyw!i(DOw=2_&S^+C)&*P<&6PpIK^ zskS@B{24;yU@2YRUZFSB_6A)U5HX1@li;7o@BpNf`aZhw%*|6L!|om_(P?D0&q%yK zxo;<)W$!k0m=5mLz%rh>6nY(H-rZxJEki4%ja)7MAzM)kR2LpL0MV#Cmb40stt~g) z(Vnui&OwmJp4~&&z@?&l=I?LizR=iwUrxX}!w;%CJLAqrYVdwgyo)14UzNFzE7?{29@l;=5gXz2&v_g;v0E+ln&-kXDx=}-^M^7$(E zLD{x&y@W=tntC02DLjC*0Lq8^6r54pdR|Tt17i31g(Reu{Qd;>;XN(4gm0C3l=G*c z?gKpx*PDYb9ow@H!cn|OH|0SytcyjqmZVYe@PsW z7x8_+ZJhD>0@|BmK7{|ycQ70({AobeFhso}tC!RtDBAjBItmT@KmFW9(E#E?9quDz zpb9!aUP!k)6-7asZC|;Bpc^(%j1$+RB*vH*Zwr8F6N-0~!*>AYv5WydeNvUW@D7Pd zMZeX}=+3VLByBh?Ffk~iHlvFOeI1FuT6cSLO~H)v#%6T?;Jp$XA>;3+&#zj1j#BLd zUji)T0S8{}^f)Oo573EfdmpvH)#Z9(Nc(6v!??Bs@sVx#Y10bX>kdJ!UTr<>p=m|kp3uJ*l_*@OBZsOHr-WyVpnB#U>KW5+W% zbMDk9@+0wg3n7Ph2rOV9daJm67uJe8-%sh&MyY3F&d}k8NJvk&VLpc z$Be5_%zrn(FYNxikp5ek|NGqn7FO=RpQJOfIqBa279!|%A=m!TH)l$7x_H9tKYLD} zrk9&$|J|*IxOl(*zlVi|&;Knf_JzZL7g|^d73_b%7kYflVE((uR^{TLK==6X;^%$Q zOzYp>sy2q#R^s2?dfsjAX8rH%Vd3$A3zdCg_rFug!_j{F?>;+P{(sN&|If~Ii7_3f zw%UI8pvET+lBy{J!^F?(PXZYCRx2FO7T7#{hLuIqsS_5`ycKZGG$K^vTyeiqu^#oS zJ|6?3f)Lc_7XBTR-*wwa3a(-Mr0SVdgQsIXf?>tNB-hvWUXgUCQM#v2Ce1R)NBPqp zEy^9{*(2!dbfC%kpIWi!L9#C2PUr?DHJo*@*0O@kp}-wJ7f6Pi1Rgx;w)cv}1pBLm zIKl5`h;TS8atsL5rLKwNgt}%8J!f8G?Ysg*NKVgjb(k{;sg7F5wtmAW*nHGxc%9Y9HkUJHUg_T9D-yf^`Fl94Wen5gy8s@Tw6NVw;G*!VD&&aZVtEHy4|j(ra?OE z`6*~e0oRqDImJ-CKjmyGDHFggjNyYVYixA<;f(8>NnO{d>A+ayYDp`Zf9gx0^c%7X z8tXZPz%PCS38>_6B+Y?r;&kzS*;8+dewb7*7IQL}A$zGx8NQbP?rj8)7vp*d#_YO_*}b@q!F}1q#NC zA7+0{D=kNnfmemQxL zrMD3w^?^Sq6!-nu&);=)?+Rrv=Spopg?%MN{{2$hy1ppHe@$y4M8t>12 z=CyjKD2+Gx!8~XCGJo#bUVgp#WrQ6PK2Ej8J0A6S5Rc3Ub-?13cPJfU=Z4K(IX%Y+ zB8f_BCSaXU>#;e?l(C_Nx)<&!HcjPX4QhxBd_|AnZ{s5nacBxD=Y{^3((N?axb4{U zp3_t+CZ%w{)y}+1vfy#*=PDt_uF35BhWl}(jZ~|6k<2xl&Y2Z-eLHB%NNMWJNL0-&bRiV&Cq5+_75kTic;tZ ze$~AJ&oD-9_F@qfH1>gk%|Gi$b(az}Lo^_s`3>$Q*LLF_jCgT5enh8wz+)p0f-so$ z0k$q1&}!NA%bD|YQtaEvfl#~~wJ)%2v2Iei9m^kNRnk%D;;JYwyt|Xcm=h4zc}i8`sdUENVz{v(*AQYMoDnc=`dh274AX61kQ#+o|QZtFV3Bm zF@}I+sP5-7*RM2?HD_TT^7cas{L}^YNnU=Pj)tY_kA*_wQ~9Nu;h-9o!7a&6b2 zLvuq>jO&jQ0xnt?S9jh)t1uVrk5o|!gm(l|p>qKSA$L(s@A0eA(2j%`~g@GVhQ&|#(RnFKz}YVy) zAQcauFI`mX60<}@bQ_bed&f+Q#sXa))%z&(0{3CKFfE7QW4x>uw34wL-*ypJhY-<9 zIal`)1D3Q(Z3F{{#wkw1n>j;m{nHcf`%&#d>EBCw=k)%>CtmiG4|rntw<~p?o<&J1 zfR07{`*nuFT55g-jOUU<8BZc%kfp&)x|1H0!T~B;y|`>WolXZ;8%&ycmsKsk>XVAv z%zh_u@^G+@%J%{3)PJU_GfUO`q>riw|Cl;^U_V`_U__H{2z*y9<(_jGk}-Tb+N-O4 zwn-sx>|aL%Y;&6}Hon*X%yud$`T0NQPy=3YV%#Ud$X`Gf%FptJHQ?z2Lfvy6>^Dyd zQb((cGf@?UyP-j@C^t6QzcL@F#@`ss*8_K^!OYK~9(8ehfI)9P(?P@ADo^Cbr{ zc#s9+k!BAx)rZSxA?GW!mYsVe({Z;e!<7Ql&(iwBv)s1c!-YYeKznu9IQj3aswHn??O|G=XuF|Qa|bXI3=&| z_dD4KB=-FUrVuNF0t)-xD)z0~PUzSDT=fnZ#Fc|Y1w281a3TDN$)$WB1saIAFncF^ zs~NB20$tV^tI-h_<@XJH9pH(FbD@5u0$bIFIUvnbZ-hnGYpf`Q4 z6%+laLE2tt7Nbcp^1aRU`gquH0QEB7eA!T4b?L{;OVJBhJe)Vynjc)4eqsnDkf(XM zz*lrngTORrCJ*)_iJuHEwAYTu$HJl~pYKDe@a^|Hu8nT%X7iV7ye(Wa!DZQF_gxD^ zVIUxVgFo?NSR%9iF>3_jNBB59QfFnq;d(>RuROj`Ck$wkC#MmZusK**EMR0aV0%g1qd~&- zTH25>s=s#86rAj*3I)Im)F9M=H&+mbp=qVT+12qa!x!OQgpD2U={bXL5RxgrdSfcc zy1-lCSvr&3`WT`6qTKKIKP$8|E)aj)qsodWSgB6)-1DAK%esE9H~P416-#eun};OU zJ41^atss};4(9ovN*2r>eyE6`hA@NA_7%+@xsS6v4s;J1ZtMQ8_4!-I&>vhWoO*=GT#a3%efbRB#26M_|MlDtE9OEa#Z+h-On62HTxDGbok<}+eFriixFJ)mR4 zE-#c*)E#AjOu zZ~n(ge@}?}t)s18tFW`!%)dUL%c&_F2^Rzh5AwVz$X(vSbIp0FDw<55I*bVvA`Ms6 z1*~#%q5UfTCLq6+pM~2%Nia;K#2p(GEV=jvLLols9d#d%DRz-1%S7IK@7V71`==AB z8B$#sv>?2AWT`?VlQV4scMX|dZ2q6ua0cmjFE``XmPiHRHrmU{g_$9T*_UA?tL=%{ zdp@tV&RJPY@n}nC*ho(aWrONdv!l6aLQTL?s11|#%Ce84YF@9x`Q97j@Ot3;Z(sRr z8YMnCQXY~1IV1eqWQW`Gn}j*#HYQ+?0he#yF`Q3d>+uZQK#g9b{eW-5G+r zGy6X2hH>2keuyWP(Nc@X_gXO43IT^ee_YPq-WY5s?~9Ovx;=<9^Ln19!+ugcS#Ww$ z6?*4tpg1~Mx8yqz+vC$ch~!FPb5L?S-HOv=zea})0##tme{E(ukfg|YAGYT;Z+dsw z7Qmn87-qC;of_CU8L9^#5bgFjpS+hjCRzVbx~Lt0voO||DTht8E`_t$gM|6T{NgiW zZ?=zlA9dXDJ4CQXII!|2E`go|Z%Yauub37}KthzsG)CeK?BcavHNHD9XnLgVAYW>lB&aOj)FwbYOe@ODGu!D1*7YGw7{g=O)-2DBemSqLCa`gb{mly+5Qq->l zu|%*iOd!T)dFyxo1>JUQ>C=6M??>^tu2}R#Oty!l(nHp`ykar(@+siOAyj+z8^vTd zLrzW?dyB3hN@_`)05Sz9fGV4^s~H|6h}n&YU;+f}Rvh8tX^1AGh$Y$Lw*UxwdwGV20UkN?<&Lby7V7WR zpfcJWVgu?7$7L+Jhho{U_XPo6SU#{NypUr!Hzz_IiMEY|I3vHC--!e2My zVnO~Qib&wblzU$(*h>Qx2SW@ePIM-ZUiL@0m}rKUlhmmw&>sCODr^~Wm-OBdyq3o4 zc`&Lm>_K(Y2`H97&Lwn;Rcb$`Te44Yhi}DnI&&}9yh!BhPc-W-zK+*KBr7IbaQ6zJO?ICJod>Wq3yFiEFGn|`{K1aGh z1~vH9xj{j>kB#4fZe*kmU-=VkXG~XjxLMsSi&7r&5+5kytGn~%@S)&meLfr{G(cJo3ya>@i;&AFkyl>6Q{0zdK4T7)x|&=O z`r$8#;NKCEfk}&TMb)5lh&QYI>ABxHIkY>!O)T0rJ#AT-={*cLwX;EpJe^8srHsfb=`{-jp(0FL7cTa4G7Ae8!onp15eu`Iorkl^q3H4;kT|N-Qz@* z-wq|}7MtMpIqPEYEBs7lt+wxZ4dOodqy=A;TtC zy}KB4eJgq}!eBM{I>I{y@>dW7J8z3T?{_cjN`E%IKf*hI(oa4#mxQiSKlfgzahi61 z>mIj|ziECzglEz#dTR0fc98h;E ze6G|E2vKiG^WF8lGXIKOR3&889xvL(yVD+|PpXR=>@FjGf4zBKh&_w7MG~2yanTASMT)1~#vAi+QVdV0G<)yQ zEBTPUYMSPGWxDPj$65hYA%ZF_np)IO#_yLD^yUKhPMT&%rCJ}|KH?F&B;fn86yDQ$ z3@h1CJX6tMSOpbA^!zScR>=FAy&muBO}Zkg=GEE2*dqxLiUx!MZ@4yOcrHnh?6LYq zX!o5i&wFlvMqw>R|Id8{-=z4M9a7(d+MhV(y6?cE@llxV;yQfcZ^d(L_fK8x!+uoy z&?FQ4iqvjeu73h|r^lYxtqlLc)J~4g`}V2%evf$qgnDgU&{2uN-dC}422y@^dN?P z$f{l>`3<9ECjwMP^%h%n=(i#G=B}s7#aEp3I4s~HjCKEBypLZv`Q!I#wauPzI_q(o z!%qtR^!=f^-tivw4$zl+)b|)eroZPm|A__GeOQ}K!>KOR{1<5`R7X68)BW5DCV#_c z`)Ni+^p4XmbKb^mb^T~_583B zy?t+INvIXL&}dIer1nSd+_5Yx^oWVC{V$KU_^dI2qH-@AsAm{`Iz#zF6AKt?gXH+o zmJU=-j`5*pOW1)KU6cj2y!7r1gwpHnq7k+Tv?>duJ$&_cMG3tDFsm+Zdk}Zto#{*p zY>GjT(i4h2RpYHNP1#2Tt!`fyS2oVR&$4)NahFNoCE<*sy1X1Bi_tZP9dxNQ5YKY_ zy09FGj$XHT)c`ib%3Xn(QSqk3ImD%wpnn#hp&R~bmP2v2D*ViGGbK)+7hn{NpYqft z-{a(G?iW`Cm+@v?hr_Vfo!0IOst74uKKn`X;JqdZR+qnM=G&f4;C%NXB>7F&2I|^n zzCFI%Gq`6HfX68i*Z!xTX7(OW-N{N}yn|8kqL%9G(tq?{y+?rmyfB`l*@eFy`|k#! zob6H%Fkk*>v2{g3$JNa6CKHC%Y=lK>o7O3%IU446{Z-Wh7J9Y*ZXX)OA8bq@t9RYN z@nFO4nBMmSI-g$D)8yT{@tQs|i3@{r-Bn|F7{KR=cgFqAN79*Tb927w%=MgGNOwzb zKk#Ej?GeMZAnN>Mza_D9fLQecRJm-FM}(?4Q8t%Zb67?68B^cieoOb>6${N;+(KHf za9c&0)*&(e&g9!A8|tKQs|txr&uP0`RgUyEl=^2TD;-jMC@NLk&kB?aBnP!$daTd; z&=zS4lvLX)9K*zFyZTY9@3i{Do9;=^>ka>TZ~J>6b$#UyBQp4Vry23rdCL+bey8e+ zVj7iZoigHpaQ3AO$FC8lEy?iKK3VH*KPA*7+mg`(^XBmmZ+Z3j82gTtX)*j6IKGzC zUJ1#Y#AIO|g+B-Un2!s|G4B{^|HgK@4AU(?Vbt9ROe}4K4tk7r4mdJD!}OtG(M5cE z;BIZP^k{JPC1SQNcjEoQEmG>!5!~%ZoRKR?qxlR=ZA__~mI}ss7f^`j=r8(poZkGB_*i4bUf4odZweejC1_->!*=l!GW$}ws7 zD+8gT+7X@W3YFK+_&Xy;N#WM!b#vICA@G!Z%H7YDsyTMH|M9@!Q_%PWnt6aV?Jj1soPCDabbd6pXu{ z4~Pv=)dSr#sYFW}xqH0aiQ;8x%?vi9m|nCdp!6Y zlP+|kw)}Y9bb)0tiTBO}MJ==ajsI77VKV+EnP3g{vX9>b3eB@W-EhjSlo~4CnKmM+ z3;P7*LPC;CbY68=gb~#PcYs%_)&Jq{&zjcN-Yr4&)8u7F&^MQ&0yZ=%B6264fb>0l z`Wo|H|Gm#X8FeyuRAohGofWR%tB5p{**wj7#yEL$va2Q2VvVOAnv$!(exX|L?Q~|g zwpkzFa%05fw?x4ZpV;2jtQ#uN>if}0#Jg5?Wxg?==WA=VLq8-EGwCyks!}cG(lWBX zbZHxc4Gr#sj&B_ewa~kEhXJLu#w)T@#s>GJ1Wtml6YBw$@^!3ORV5x-%+Xgng`9?Mjc?&~&r;9`KxCIep^EM;klCu) zx5r%l{-KW#wO*l&^Fb8-86X3zZy^}P`Uqcm<|&Q`yXt0eo3Rg z!vNm_P|{sDp7fIbQ2Se(YrDk3?8n4NnxEiuz>ZOmeZ98d*@xKNjwVEbkpR){y^86#{W_63ltxX-IccTr09Qg1&Uz}z5n>AJa(OukM z1tFO-fi@?8N=JIm{?VcdBKLScRulo~sdi6C&&b}w0R^BzXb1DuJ5YQplNnTWOven} z-8(GA4AwXU3m7;$IBB;Ur=E|TpuVOWWmN-K7TSf25&>Y##Vp>cLAwA?1V`%NtJuBC1%mW)wenO2tJT?gU~ZWUOa-BqdN#Jwwi2%{7V8 z1_GGn%y%<+VL$bF_w|A6D|~aaJT#Cp_&I8)7-rXX(J~lz-d^|(dg^JUW&E0t;;?_r z8o3>w8z2qyRgxfwmekKU1aR(-TJkp3`*jb`p-P0rO1|? z?KtX^%CS%nJ5nq6d{LzDv8EGPq8fyD8zzb6lUSRFgEIv80Zt~ckS9v?k zNiPvA`<;2!)_eEMbvL4SXPt9pn)Bl zEDtOQKDu;Ob=7lU5nWr8pIL7~{8MNKDrT|;ev`ILyvn2d0EP2~KY?)T_-;-fp2Gs> zPWEmj0fS4CCWo16mIJYp4)qW{zsol50DNlftMlU#b+~drrq7^r&vh`HXP}S^Mo66F z`m_s}tFCWTlg5=jp$KfOLf@(0eqWz){t}T5=jxO0yH*L9Y8B~X0<}LgGe}>LC+h=` zBGeG9;vg;54ZIQ;Z^4q^lh4>?O_nPti<}LBU!a^KSN!`xKGs(+eg-mmNCI_!o4;6abU*%MEoLvqKLv- z9e-{VrzWxTfGNgvIN2@SQI^HTb2_jiT+5jr*t(7fnL2#W2oXT%oJ=x!GiB--8N!6`JeU zUMdHu+t?5VPj(yRj84CF*$LWo8`vqwxe{ys=i;Bw-Mfy&FLPaQ9e=es!M6;5X8DIF zcpY=ENZ<*(rl-IC6(@UiQkUu6q0vqzGQHSrYqiguf~7fU7ko6^{vroM-yN_PC*xa3Z{+U8fv${H*f zT_9Kd6Q!G3%1Nt90SOK|LVXYoaFc*cs*p9=@vKj}OR~Vd-+yP(`1KG}9L|*ng2T=& zTXP>fz=D>pa&x&MtiL}Y0YA~Rnd3q-=%vTf6!el zs5MBnCJezWNCtK2DsI(7j*#&{W4)1|+oR~(W)H0vVRXeeg z4VvZkayaiZ3+$%GenE+Cv!Ks_x6~g3qc_3E+?>Ch!#KL{x8xFWvSG)|DZ*dP^pmC+ z%lfy_PR%y|IImkl;)KfMnot~=P%fQzuvhQUs8Rgcm)msjq%dG@(tABo>$Hi;Y(uq} z9GW>~h%gv7FTd~J=e#2a;v@*G&ZbN{`uh|mb^;4<7CxH^@hB~f!Y9xjDD3qv)8te3 zlNlh}HLEx%O4J{uO=l_Kq{oj=>TWdsxTSnP3oZX$70ol2-07oLQT|XR%!I7&T8PEB zNeGGiakgEfN^WFbUsoZ8<{qyfw2oXA{jxsV9iS|H_x>jK7pNPOzEjf>`At`idt%r` znJC_C(EFP#c&&foFfXuY;88 z`I{^*RLS>GQ67N$Gd|cc`1}H&1QPKpwC*c=L~wPL}Judxa$?tDRm^w#7bO;Ce6qjewZ>W2fDC0iVnAG$0Nk=Vg zpH`vB=kE;^cI9vLWwk@WCM7J@1@Ld4fJ)S){jQIspSa{X`T}NBl|+Ve&=Zm`cX{>2 z$n#i`Gy1Fe0e^q`vIOQ{Of|=jr0;Xq@d_z3A>0e#lx1f2qyp0b;$k@v?)#G%ZPL%W zA_SyD&++wpw_N5Jm6dPu{>EALaA-15t_>8o>HTQ30kwqZJs9`b@+;VhM)B1KfjFe=` zaOrUH)NVi-k0bzXL5OixZ;2SS0FFf3@w1cLdbVmub3Krm8(DwX4quc!XxlZ@#)%^e z(2D-bU+XTa!aE0k1n$^)3V+QNdS!uxY(b*(tiBk$b4vdTm7>DhA5@?oHdawUnrpwXT<3Xth_aRH0_AKuHO|b2wjcunf zS=7%0Hu>@@==v0gH|A9zpZJQCxhX`BgqOac8^Q*tW)0oTvi{h6A>S)1h*i9EB0#5> z6Q}dBe@-?j-kpMi4!+ooYj1wy0DZ^wjj~rmo8L&bT#rTRCU!T%?^=zlJ}t&{{o2>h z=N4~-S?Ng0APQ+g3k;ZC0<7Zlm^M4aJF@Qe=mo9aC$!ZMJ@%VDLKG|$gjoj5%GI6y{GL@Wfo#t zM&GZ@Y_}B7#bqyF{jv})$ny@{dHY?xk}#M7=evS!2;tMtdo1acf7%Co^+(2#FW!$i z>}F}-eKxE8HM(0f=ibrlOU?Z@_6z|zc1|W~AWss0bTIR>?scu!;IkhNafXEW@>~MQ zA|+RmnNQl&yONBXK9O51wKFPEFBQz3T?RHm15B#0o7At-LZC8`2z!YNRgjAYB^b&& zrh#+-8FRWJojiEb1VUcypi25Z@|wL^ZejSsObL9uIfDHs137HvaOS(?xmbmRrdY=l zC;df(x8KxFEMi)d$fYPot~3eQ{l`F#hyOQoG>=41Ks zva1W8{)zm2JBs%oqp{Qo6u=!6TgCE-rm?Cy#FK|4Z2R#D7>_;(xybk?#E{<$^mw>1 ze}ZBaRn<82v9qhv>A;VPb6Nj77jF9UqM$GPf9LMmLoGzcsU~riv`6uaVAbs@|8kmw zIFyNyo6}~|0M0c;+qulh_qX5qc-#J({LAbZ)Gg|$0tbgPqJZB$3epf;yOE$B|9~pp zUr=;7&!ferh~eLlFOWR`PkVCzvwFb)_&ByY%b>qGAHH0PcHc|3GP|?Vmi7Xa3!Ebz8fY09SQr%# z=Cjr0f!0?@bT){#k=j9=2{fd57R@!d{~|6vA=NUyr}b)43< z@}9hLYfmH=tbn)fzl~x>b8AhGMVk5d4z9EOJXi-B1#F;Mui#N8mq@oO7K7I<>4C{s#aa9)s&Pp%(7n=jr2 zoM#up!>6>^&!b zW5A=d)_ue5zHXwgTsq-#D|Y)0`o_U|SCOSMG&5J(pb~!hjv?p8)NAx+|M);VAHjVL zH5yb_jz_iAwLM80B_L}4fo8Pj+2+D%e+<((C0Q*oA#N|kt2U{8&9}pOgF9^L_pSoX z#O+*LZ2kDH;^17r9y$=Tl6m@TFbQJDUMNL{m_WWS=ABQp1D8;8sAp-nb^|4kH#=PZzkrT8L4o64H36NShHdI{=OCt7M+5;p*u9H=p>I91a^PFo%x7hh7ob{!ect1pbA+vhY~zTBybhP3t3O49?K5ytP0G(GKS~G~c zrQGR?cAVDLFN8OVL@4%B1^b!8yeobom(aC}E-?NvO^Uo*>mLb9go4`3a?ZjFQQ04Q znPPYxx+3c6JGM|!ZOfkBa(Cm`L7=~EF;0>xJ`V6L2M}J$_!ZSZ{!rC?Dwn57HjrJ> zi{iEibat7=Y8k2{qLn>JA08VyBh5|+`7dXQ02zrQ$uQz6o!}@;ZT3-U;r1Y!#7BU2 zuAy84Z>vs|lR@IbXfgU!a%)M)j$G@B*9>chVx$-ekd^G4&Gy(*IV?6yqAaUfg?sos z7IWO>k_nwpLcd2o(ymDMks~QL;{JC>wkH1JE&tx$&h$Y79iLeD7m=%a(k99i&%5Gs zadvC6vuAmCX`9YONs)fEvs%pG$RE(Bk9N4p2nBbCtL{cjayYCa)NqQYd#yx0b;g;C z+*VbYQF|f^wWC^!%7G0+ip)qHaRPPR@s3*Md$e1v+5XVb8^QT^BWX5dOrC(e1Jos| z=DYqyG8^veGTy|Y|6Q_Ges17Ihtl@W$0VTof1Uit=9&4s*2Foa=?diHn>>4@ZTGwk zRS^gY_^`srAOaqY#PY8A7XoU*>wqz;inP|T@pQHUA}xLbS-~6w2n!O)X(2YbK)#J! z+=Dzv{=(h>9XaFebz^r6{!WNhx^fnCOwm?ORjMmrWbsRVU%nT5F}Z+};vgW;bS2AJ z0C34Q)+q+m`xY-ljsyir_>xFIBkj|$M_*WYC`jpSvhgb2wQTPSnbGY*-zD%|n`; zA~M=-;Wke`)GCj&XxzmoGVlpaF4Sj3q~n*9og9bn(;7N{vxwe0Rv31R4`FwCP(tbq z{0TIzlM7~YL$#dC&8+OfA68U#l;%_)VEq{eYAHmZ6 zorOu?g`3H-S=%&+bHNW*YWLuPp#xW~s84p+o!!#o?9n5vi5)}N%uKS009bLaBZ{v% zNsiG$l*FqTWNv>J&$1x44;4VYp^rukFR>7H&Wd_oD8`2g;VbiYyxJoNF0l17*in~J zT!H<3c65sK;j{+JJOp912oJ0Ws#{5TxX6~G^`QE!X|2(a)h5VNEHDfT@o`4;cRa~*7 zQIi#8x1mKb43rY!R%Sq8_JM&O#LF7VDOoB}N z1>|9W;`_odtald8%(;ViV?bmL=yoF>Z#vjoZ~{$^*ba=yX-$=6ITaxwmzfj9KseC9 zh1uA&&q|UF$at%>51Pnak>CBX^ZY*Q(QlMVM$l?rTB$~gLaJAYXt8VuBc zV#~0(@6{AexMS634rh>{KAwC)Za9Oc-mqg*T|d-cUI6P}^Pq+@3Blz%T$x^jh#_no z0lJpUjjvGPg&!plcXYmOXEI!V1ttWdd_T3Pg&*a)wo_Kbh{0}3B%PPwHXu;^QdN5< z_g9=+2$gKwNu$WbJ&$5aJcn<~r%?NGclCRMGQ##ET&Jpu)asX07*q}2Xf6Y)ws2tqkYMeAo~*NU!@(KrN4x@6myih;JkyOi@`MtuOVk$9PNU=v zWY)BX=^^b{zLGz$E&<^=jVBR5@_wP__M`L;<4*xyMO# zr&%?mV$pRSGqEbCkFh5+Q7GeVx6lMnEjafOE$xAv_eC;=+hpd^D>6OAH#*3%h@#r1 zz8L!J^@Pmj$8{fJl;EY%trF|80D?)ps#%M^1ZuFwJcRn#da^yRCbF}POjq=^G;@;3 zytSKVGV&XkO8C=1ASfM!i9>v+*Wf@4T!4eBT6u|*_nWk-BW}#nTRr2`SFrq3WE}E* zm4X|-<8pJ4aLpV63ojqKGKPVors;SneDCnY)a{Qir?^$h>3D!0EY~HZs=l|KZAXR8 zi{>aEMD|1usoGhA>hE2Q$&{EQ{f^jg=n5ukDF=`L+&4P8n(^)C@UeL)`8@JNlSx&! z;^I;Bxs#+n_3Eh2W~m_&aJ201OC8gDYo|c23O19WlJYYl=W(&b^QAv|ED7#@s&i^` z-TB4^>i7a;e1MlFq3lFK4W<&1U1s_7-tTj)A#Yc^ zxXE0%=577}YMNSbNL$O`2$j3rN4{F4T1acmu^dYYo?#a6r)nKm#MN|m$#XI_gdGAM z&_2N_TX0JZ1!gaU#Ug~6$7U$-z~0P$cY{31Nt;S>@#ybYC`B%6sVp4dW!_OYZfGz2 zQ@Z&dHto5l|LLN@BDr2OWLDRS^+B80QA4#K{g$JXF>3GZfTmX1e3%laJwE#5)AseO zI*q=GYF?X0D3l=v4g_cBR#*4QDl8XEXDtoJn#Y8N@1w*k1DoK-yO)6zu@o%*}N zaB-xJhp#CfggAk&1DP7|g8C6wTXo5L{(Qb{Zj;E)pkIL>$I|~I|)}y5B3pKaGv?tF~u+G;vQuC$odhWbGe#YPn zx~}S?+thfV&b<6_;}u*ej=;{y^3I_T)t}SL+$S5{ga9>Xloz?;ll2ovJ~EiQ6+y5= z$v#49vH%@Sa#uvM%5WeTKD*G7*S2?Pov9aQJVgh<5r2+5D@V;Q9hb>)1yL-uJ!a-b z(e-QhLdJO6^Sl>juQ53AR|jil<69YE3kG*k_5nEB!gJ~d@r8|`3nWBuZK0CwuvJf4 z4c}(kYv;)YkAI^g2JEM&n~w4frr87^*kR9-^d#f6651r=LohDk`4$Wcne{C?qEM5j z>oxFnuh+04R2KXiXj||n^W%1GmH=~`_&vz%`s(w0HW%+s1ED*CgIoS<3CHMTkJC!X z^fp6%1jP-xY2uEg%l15c$O0&w0Xx?xq-Cdb_<1@|c9pw*@g97pm#gCiY*4m70fLr` zB)^!{{JFs2NA*NEGPNl#dr`h``&oV;H(G8_n)8a7KgxMND19)b&Q3z6ETguoWNyex zqoX4jZ%4Pv?sYwi-}LANj5{yzyv=W2wdL~cMhbvffz@BBk>0Dn^rPn%{-OW<5Y`tE$~hIHa6l(d7ZqR z7=&a-P2OA3;~oU3sVyyJ?XL?xPC-6jL~}W5QIpvaal3HRQc$3B2@_&&M!8iydnTp0 z71iusT+r2?IQ;Tul=jk`u`yZtM`MK6mn4lI`Z-_bf^ z)^-L*I|RR;lign*JM7(qY>t(r>C~N#)yHk*>UJm~ZYD*4zz|~}B#U)}j&<;0DW87b zbYF9a^Xr`66BwilRXN4ag@6Z6bu`!`v4YbZ?O73eY>aRN>1p(n#A>+PcMlsE{sOh) z+^RVF4KKClT_8@`ZF+(#Mb|}NJtKyIg0PL%d7bQ+pBjlOte5nHFe0;E5Jowwk162{ z-LIc3S?|&+M$Nv3T;8kb1UiQ}m(&(e(L(hJkFYb5g!3Q+rd8or@6Hyc+ z5pg}xJq6GXBC7+rk(g!PkvYMVRP8BBmP5^b9?}KEFQ3ogPnSeeu9J5Q8!_LYo11pI z&Vwn=6wLncP0Y$BhS7i-4M z*Spf9F~)KHkt)_IMaJzOK(sW=8`U8DY)RIr)BWKU-tVe?YGolU`AQcdqdTBTD<@a) z3}@yd%VKb`eF4$H(THG)Y~O-kV244yR)6AR@nU=CSA^q$YHAnQX4Jhkk;Tv3Sbe_L zE;&2`6vBEmpGH0X6G5RKd>}s0uD5U<_At10gAZ}3g*9J*L-!N?JQc~0 z*Yl$+m>#tIP!YJ@L~1!U3fEXafq!J(3OvTUYnBV`PNiW{C8_3A_tB?$A>yF&Vk)S6 za8+1UbXk#-D^arYj!A9~+?@LTcC8|;G$f;LVAWB+H>Be3z&;B2b6k|mUq%r!jmQ5_ zmhOMkeb|hPzX~2lWa~7FOP;s`t3CU9gFAt2b;*Hn4BEHW;h*f{@e6Fz`hOEC@ITHI z|GzP}{ddjPMUz&ng0Ty*EV=1JprZVoUx0+M|o&X!@?21Y@EEl$NaW<#Gp%zCjQ)z+F$wsk{H(s=DeK34kTm=#VR$F_$Pcw=TjxT(|7KK-6u9^(eg7~BzPx2~Z9R&?C zwoJxDTt)kS=_R3#vm2@yh!H~^ZF@OwLU#G&L1xE1iWQ^14fUazeOT?)2T>YrZEJ5G z>hssC^yI*a4pT`EhsuOzUiX|dyP<*H$Bh#Q&|cGDTeAD+uElX0vS8QuN>J{y{$~k}@vVM7Zdow)oGuTVdz4UI zpMqwAk&69Xm(%AEjQew}OC@QQJ_Jt^6zgH~#J0q9>bAdz!Ta34W99VGpXobN)?wEr zB!uvZ&my|2I=;Kz9o&Pw=*i+SqSFg7B9S4kRLkbiko_Su6Y4(0Rqbi}TZF%aIl zX0o0>??^X4Y$N0~ZsBz}vvuc<@E1>Z2O6Pd>DK7(g<;)RJak+p0c$6CS4E2SrMsQ9 zwZyB}*W{FU<6%tvbU}^-WK&#)g4^bP+CcIZU*Djngpf^3pu?(TapFqXw>78k`_eg- z_Sm&~Vn-jhjekFPc;7YP3kF$+h;nr34qz5GoDgy5%NIb+zAn&`YP2Fx2?>|yIW58b zAqT@-m9_mBh8h_V4Idryy#z_fYyURxOAX{Kstk0^u_~$T{@SxlnBxeGQ9+Gu83%2C zL`8y?zc^y4gsA`f<4P#{7xVg&9G8;wYZ#rcB`Ogm{l<|f(kTV!%UUl+%uVX3h=dYoF|=M8hbct^EcH>+i`d zU;ugw7;1D#QJZ|=UF3-m+BGR2v{2Xbx^+v#I<;nGU3wT21uXAY%+KMT?c;TOjsg$fm!| zCi80;KcjxnwE5e$XmW3rp1OBA2@R7-{VbwBc#~@ZtqWXJ$?k4%88f56lKsycy&Nj; zbDOX4Dxt?D-)oCP;tl)no2(C5i@@%od536J+^=je_-eikWh=o{maCAyQ1QxklvG;` z(BS!*Qprdn@%Xf>tUEM(kR#BU)!5BD(oX>mYvz(elDMAtWRWY_-jB}|ZLDwY6byT^ z?C$uBe2b6{hAo+*7FG%EgnQ5WPPYl7wFxa@(P-8B$3dBB@A_=zF|h_NP)G_1Y9d>~>vYRT%{ zZ=d-4@>&0C1Dm?M%G_5{(i3tIrG>R_#_!DdVvx+z_ta|(!t>>+jfcNBS-P&687a6?$CyBpl)t2k-5tWoWk%K7ZX`nu5HfQJZVEkQ=mmeECL!MMYrkLY*>)s zR1K0|&zE|3@;>?A`P-SjE>G-s`iXS1#rvUlET7rG_I94g*~Vc!sGi!$ao|1NmZ^MN zpv3j0fneX%faabh0Uny$Vz-z;50}i&nXV{^c|7$|{87KF+G+H77A(a_8l*x6 zw%{hDay1?vGKl1{dfZ=6#}dDPN}~+L7D(`ZYoPvVdtojR05YB=WQ7w#^P38n#8$r7 zG~Ga7^jPQP{NU=Q_2>)IXV{GoD-kf5?`><;;>Lx=+x;~fvO;vHzuM)Oo?hx0Quk1{ zrT3bW*cpEHE=~_!Nk0Uysk43-laWp3A9p1rN|tk~!|CZ$6ZewrKfOKnc($K1*{f*L zV9^0MaD-`zZx&XFV@D=wt^@Ra$xxGM6v^bnlEn6S^>;6n2&-^8^3x}5G|;oC=iLW< z99&yzBzAEzScv|1Eyf~m78Qxi zs6+1%c+T+q_y~96i>O!g3W&mxzhCOVe7_UFGnW59@Xw6vfxek@v;_&coXBbgBCDGy zkHr|>E7dwea~Rqx@No3^Q-4P3XS?jH)YOP^f9|lqUG0SuC7#s?GW5c?E>uziQVi6% z4)uc8H!Osgu=74oQJ|@C_d7AZ{ac%izo2$d?sd#-6O}a0?`?h!;g?w`$H!i>SXt?E z7rWbXf!aG6ZD&SUqTlgRvv(*X&LM|cE-M#ImQ z*;Bw?W~a;HAAen|Ym4;J{{6^q6yEID6p~$k&-&l?IsS)zYEcn=mY8hmx z{!-8jSAV2SWTu5G*ZeTSDc0UJ4REL$h86OTC7IX!=y2NL8#f8%zhCD(5Eb40vcZ^u zLGFxb+Wday@05N(h5Z%}q-TA{7CB~>xxe}S10w;wEImbD z3s)qN8RYL#^S0Z?U>mewC{zj>9ZaBNA6!oTu=MM1Y(Je0P!fI@xPJp3?_g02Vk(lW zI<$z6LLx^yd`LP#;T`*NIq6f#Q7Ds(pq2e{U9!A17xoqO-z@BaHS2a8v763I^Xtf@ z)Lsse^s?U|N;CMf;OGmEjYtqN)$ak+C6z2by>FI&6yTM;|Ed#A(_Gf7$VhlP5}Dig z3vh7#n!N7*OOHn#bo~47(p0$(yGhwNkzLk|VrSv!d4!uq)ud3ROw@qlJ?I$CAzInN z_ULIlT=%+Mfun)MH4cvd%?9Nwee3dNA_HbUxJoo=_~Ubt9i-E!IMK1F}3#%M0{wVnI)8e zc{@L@;7dRJ9T+2c_qF?aNrfg*esq`9#Y5!3Y!r#DeYwc*XYNA;>v*Hj_aoR=wd>CJ z7y7IhDk`?djxnG<)*}pdm%jq+qi(PE;r?Hl})HK!(++kS!&M&Y?h5c*cP&Thn z9@pvyX>fTuuDHgXy+A);<$A+=@hNJDysY0PU(vIvG;qtO!=bqpOD}@iG%gLu)gXp? zU4KA+K_w*wL(k>iWm=WFWC$KqRHu-*{#JZT8bYa@1&II}=ix3Jm=rhc6E*1*R`FP$ zAq(&|4E8hb?%K(To=?KZqC|S--pHk$u5;adfTp;9Iml;k$T$=35ODD|v;@txn&w_vLy!C+M48+AU>&#l`Q{A;J zf8PCoLvcpE@2Ufs9AV8Ums&jJ2t~8IY=lAsiM1*Us)s$2K-;%vl2B?HfntXHnqVNB zGbFbzuOD(ci&;g^6MhzTgqXlH4J;w~`A?RgfkHm$bSh9_C(GQ#@P5}9yW3p?q+TjA z&G8!Vs-y5xxP|?+%9r|1gUm$bc21=o3CRE_^MiwAY$WdTdQQgzd<)1l?nU@3Z34}l zYTNmtql+34Cu?sfQFL|>@(1*o)zv9oB#m$$5K(9p+tjexlIa({z`hRM7=({o&C+9- zdpNpADfjE`eM5w3g5=rqNw{h_VLfes!XDyS`**dc(qciAIU(iPhCer^eRW`2-r?0U$$$>7)~~6Hc+!7 z%peuBaL_WV6Jw_x=ch4=qWwqO#emVH`ttU4F@QKrSQw&5{ERtrkF2tp9~g7Vh0MV_ z4(J9>l(J&kdB6DF7w_i(si($=GRSC{BiC~aEuRmmU zIRgW>kI4W!c{;!$ISH3BJ8l*7lY`N@Jr*>r%Ab!zG#TG_i6VUKJFh*CfNECE9xh=) z`ybf9|C`xHdOJrqVl0DsIkx}FxEWs%y65mb7&A)#sTJgRDHR`yGfL|J{x{7m{%5kG zf7!>wxQ*{1hqa)*ZO&g1dN!qey@XsndydtoeKIfIus}&r9oKJT1?=b&E=Bn9M?}J$ zX$$Q}=usVd{Vq`Axijb1sIB-&y&X;?$Hl8Zv_Wpjv9Fm~0ZM#1)Y;(BSR)W(WXQ_J zo2u!zb%;ba5b|A$_6#pz0Y+>N>XH}Lk*Pe& zZVAwKp2}z={Gh_PLftlK@FjJ@Y(|VylKm5FOp|S_#>sG&h z-Y>ss|8AdJ4azHj;gO1s_{?_U@4-<9q|jC}Nv~$vd*?HC@0gn@F5hgd9>0(3%7MZB zjPbd-ttX|(lXr}hZ-2xEEQtG*U*zlTj!eHB`1oJzgN+uHfUBoDJ*vCGf8OllyItOP z0Q6M&bovhpxv7Bvo9SF=Eajb}dl~{o4FdRsE;P{E)~@&cPwM!AMph)0)=(>cM{?+H?!8WlXYk?4o~rI z*)2?xhr~U+#2Fa+Nlk7RZwG+k-3!%`no-4zyboFf7(@9cSja0ZkA_T{Q(@hGV%?;y zH|PbOhK~m2LcSZtg1ct9UF5qrs`K2FOk9k?<;SQJOG$7!R5|50l6_X%Ffu@sC4C@W()%y~&a>Rc zqlNOt?sIy&1!NJI8^HOSYkrbecs!f)?|wU7@Y@8wjR$$bFHZr{;@`~m3Mr-3(GR~1 zix~k2zXUpl_PEt)e!8d)=QbFSMfC)?V*Im z$4iWlO!|O=C#1s#vYJQs=VI+j*V_u8l8}e~=&?SJ$K(0#M_qTGy6Bntq;(jOL<|xT z(f)6MY$3Kx?cf&sZWDo51b8M(Z+`fIwu>t^O?{_ckLMUYFQZrQeYw7VVg%cNX4Uju_(AAJT<_{v$1q@ z+UM(f1|eucGm~vR@kKZ4K57V|r$-g9PeOW$oaGxB6a*4hR{O(EpK~kYx!c^JAS{zn z$mvnXKUAp-pNjT)N$e?~DNUrPMIQj8PamwxyOE@G%D9&7yubpC{B3pPKQC5~~>S(`u#|FCpuHTur8yufPPOLUH z4yW1g0SN$AISLavmKZ8cVE^3DRCVf)p%&R2KcKH9t4LaTH`4bczg;KMCywohXk{qg z=XgfO^?MKae7jlOyn@H{=vBPM%7AKZ;o!~8JLwl{$EDpJ(8f1TPK+&gBCZ3XQJth59xoOcna`u^(1D!$vp`Hp&7)&86lhIBBz0$x{> z4-n<33iGIg3*oniPV0IboZw|%)IJa)(Je!G;P}J*ViY#cDGYq`A?`zAoN#yQGm*hN z3iMfg9o7s4l2$veP)hI$HoGQ@&D>BWds1mxERsv9O5ITOXZZ$ti{o-XJ^V`nib@?4 zaCaOm{WQj2wu>6n;wPCfQC(FI9svXVg&v!G^l z?+4E}q9J&?;#jOZeh4n@iQST5&SIVgYPWeWo&X75B^sIO zegDX^9I+v!w`X-H?vJ<;K|gj>^K2FGCSnpf-|@7#~ii%uLBnq81--5WK{P) za|2XK%H2?Z_TSsj;p>O)Ul$FWF1U}>c{$ggeCW{yRZ_8YKN%5l7lr!@_GWkZLABC7 z?&$ggBC+XYpl)hzc?Wqs{5aNx(Z1Rdt&>TkNVp;;L5yJ2q@8t;XJ7eLz_Z*u2pVJe zzn*s~?^nwAKl+V&T`u;!dFvx!K#^qW9%rQH!&+_=hq}1ED>$X-x5o?cN98-YRO?FH zT0*fwQBwTbNS-=b->hL=Ja<#PI5Dr&)FepNMI+vW$kXN(34LDio8bXGWAE-4{UoN{ zL!)-zefYJq_wNGo$-}IY`$-R3{m(Rw5~(UbzkZ_TvaR)a7_C=gl^y8j^#OzZN4<%d zPxeeR>Z~oMe-ed|S0d?3Qx>K*&Bmwa&Oe6{(q{>u67UpuQqSM;DCjTx@-#%~Ti$Qa z>~7D`t+@I%6nL$R*)h#-8}rNbM^pg?R{wNd_tUkw_*q(=Uhd;JK27s6d_M{*xQy}l zi1^RQ*KxmnbtJK;B0iI55gp$NCl|nz`?EVkOH*6!-evW{%H*HM$t??ytQeJys=D~u zzi^jU1u;?3SGBDeo0XYCn)474AIme4BVN*UeRUuGP)XhNy6jPL`0k8VzKX*g7%&F_ z8|t!u@2fuDkkodL;BMmRL9FdbKBc0_%r>5Pb*40w1tr4)|2e zuwaBjX6_?ugxXy3eEjnoT1@@b{X*hfx9%Cpe-j+}sd_WEQ~5Gb^g%?lGb5KiJ*9>|ts!sxg% z-=i5F0>n;A+ZyVUspSl$zELAQ)K+xs`-cxf4sq*`f23mg_4?4p(RMte#?fs3Y87M< z-E(4UgqIM!`TS$*1$ID%=)eR~eCb=A{&t0AzRp(afp!&CPH&@6p)0ZTt{?}$WDOh| zbqC2D?;*#N`lU?=3a*En_tn*@{<>!l7_t3)nB4$__`BQX`<+0DERK(Lf~C7V@p(i3 z-qRf@e-FF; z385%|w;erQ*p(PoK7(inbXR8Z`Wm}0h_c9c7Yq+I>A>o&k6y`Vb%hC8iNeDi?sod3 zg1GioRLrP=qlMW>5TZG)#sOM$(8k$r$3;uoJA(8Z#9q*TV4gODQ8F6s{6*w87M@|h(((ZuuP{`lwj5F+a__cCiDMx>mk5z`&EsmVh-p|v^7eo+n48QlHdx5r9 z_R0U+p7Ot{haRx%sCx7gI=kNFXU!eX@UYJ2J!BJD(4Jb>; z7KWk!*@QT7Tn+zW6MOtG6j~os;Q#LzyDt|l206pfVSS+fbwmOmCTCgyIU4(~k2C1T z(tkGb+`rD6f=EC8*I5PmUmHLDKYM-u{mA5KxW)hS-@hhykA2DoF}mV^xaYriW2h|p z=VX&E&9%;BQOz+K)5rgs{@3uo;=F&&1+AC(pWXi1&<|_zuMIuyLh?2#;sxB{$RV>z zTt)wSdkBk9-y<=`D(O(-vQUD^DqTHRQA|!u{j>KY+sH9!79acJ(+&UHApU)Z(hW#d z|7kp$!KQyMB96ZQx`zLWkMKV}q<=lP|M-ml?a_8|@fot||NH#^XV2}w|HS@d*CKt% zt~2z(fA2^F_22X)QV&8N$iJPbug5No|Mjc?TqpS-oKpO^Q~X=!{kPBmc1k>*Z#?{8 zIOV^3=f4k^|9;E-&+p6dpZ~LcIV(S;Ybj)!$Ur-J{RDAg*L^l%F+x8L>H*dUb|}af z$|wAN|GMUjKf`|2}gS>poK#?fbV3gS{<1KCv+DIINJni@Qf10Omg_Jqs(| z>;T=^Kiu1Czx$q&UHZ%ZHWt*~O{pg%mysR;?ETz9Kx7JD&mm;Y)qlBT$fQ$bNr!3s zKe&3cZbg-7Y4k6FqTnNq^t}S&8-nymqXP2lZ{(_d&K>95!(CO&g$POJ%-O_@fd9es zV|EVX>`Z|3tLEpw^s!zzG#J_+$sQ51m=AIbaMCj`T2psVYMyaMb!#B7PO)pK?b&0o^a^AqV zLWy;t95jyM1aaTXil&{<=LXx3=UpzMD4_ia)UEXKk4zWerbg#j?Vv;4Xi$GH1|yJ% z1fmsw6$ygL>~yOw`Qrb4p9YnJYm5eh zjN>?ss2pzqJv2E#n zV`y5p+eq_{y%vg^FWFNc;L#OnB+d5=RoC&0pkSb|K}Ky^pxvlREc6*&WN_s9)!7+~y6iExuUQdva#|2Me5&RWQnDckV z?{&hoB)BGG<=2zJC$=`oWWMVAHDRd9}NG>S)((mYIf(9Y|-iX_;*&ajz|2l$8nt@5e zdh?fFtM^PPjPeB9xcL*lXWS>q7aOtXu zaF-;CRqcJ7mKe(PCtL#$FNY$v7qW28UAIwK}+IyTpl0l_@B0U(_q7wz3=|7i*#9b^>qME^l51Mh0>0% z^nvRl_ieH)!$YghCgIR&I3}GiobXY+>JC@;NFHm!3dhfFqT=H#cmQ`vxeCwHr59lQ z1r|pOjH>jMB+c$?ok^mA?9ObqObWlU-45$fz{i!Gb1f`6|aa~#JB zFh^BAqCj)H(~ma0J;40=g@I>S;#Jlc@NFVOH(JQPl2AyDg*qJHEj^&<_ z$}h>Sgm}<2vqH;O3~oB=cI;Q>5Z`ED`xb zX4Lx?=j82IY~DWm;4OakNNGXWn?Bl4@K-Zf`D84dv#Y=$hEQX1_Yf6UnblRgU+Y_6hdI2}|XH9L)Du!BP?h*8- z;1o$LBq6r+77tg@$e(}AJuCa!W&ccG-Tm~w*Jq#F=q!=ZWOCHKJkX&NPsY@s>yQpPl)9xG%CwuwyU@Hq3TswwsR5s-E0a z_$7;VWw^XPZ1@*mPL{l**uvADiqq#auPZD9ukx((cPx%zSuWK~v>}--xXSQ`D@lLv z;A=z*=198Vv#cDz#jqp155gRP1({WL(KD|TS;9Ugn9xYaCl%K2Hr|skx!!ny|QQr;0o@yBBApH8I(`neJ-TRq1X#9hdp!eFsveZe;U4SQAB++zf%{Q46W zm9hG1;=rezI44vol2q?c&+QJwIzsmlYCkuK_acWmZzt?+O`Fe0h+neB>dbHla9U(R zp3h&FH{<&Sj|UH@{LGB?p6A8mf#(Wh>!O`6#oOdjteL?LHlRWOIp4HHXfSt3hP@S8 zrjOb^{lbmF+I@?7(jV^@?ra%)uf6emOEOOVzCpJ3gH@skaCArnJtwI6T7d4si7qW``?d7&1-R*7W1D0#(+6- z%rFA4Uv9+9a>J0^rHtYsHi_I-OD~i`425DHvk}ikC?HF~TFU1oV`O7jOIG2k{$FrGJ@oP^#c=V98*@eP^mj;SEGYpl11qzq9TTAF zgSZMy@~cRg(Dt_@kPdP>*ynD0!ckl>WYXUrS^n-?OI!>HjeYm=e4$z+B}2|090xx5 zBF1@goyih`T@yYXn^oh80rls7x!@6B`D60TUz25k9K~qw#WB0Uj@j^8zIydi!CmyM z;ZNfPn4nN3ET}{$7vsXyfVd+BKIml)Z#P+aeOfF|vaLlCR8uX*!F=!p9s+hhge(H+ zT1D!SeIs`NT30Y`C!b(M8aU`>xOyc{EJ(=*@}e$kg!1Q;J(u)p|E+al!LU4QulL+P z8Fh|3G}ISIIr@M8&(%8{NS{ND{2k!^qPsVbx8lsTcn+0U$_V=$)~ZhI0>o)2khUex z^x|TbUs#^Z$!C>k&Jx>R0UEbFZhOrB^^Ds($q#CiUMJ=#)~Cbilf(L! z5Sb*-g;0@u=RoxMdVM>+% z$=}LL|4)1js~Rv#u^-l-E@x?O>g&-6rHG#BHx5&}6DhBF;JB6U!mU1AP%W>Y!~TBe zR*%2M44HZxV*)OCDswZVGn5rGwXI#(8+X(*FsAEf zOA&>%b~h@2Z3EVHg+lacw3Ms8aA|PMkNe&0Raau@M`4$o)IKhO8bW<{$=&q;qw&v< zUu*bqDsKH|wwHcM9be0Hmj^fWWW3cq3ydh3{B|??-wtrOaqD@F+&!*_qG16q0-h{f zS@=twgWUHIpr`JtBh%nn3eoaaMO&@kkbNNgpG6#l{czoCIO5JqA_575QVIzHxC5Ce z>l>3!K1mv{A7Le{>7Py0s3g-+^Us_$#}>(OzD7aXGtZyPPEpnPjyD_SU&M-i8*e>k%_F>Q|HlGP*~Y1ww;wDPpD+U~`kblS@{yfI<7A>n{=a?Wsh)bly4xTi#B z0yuaf!z4*aK?`{^iwqra+N$xOriU=mzvG{E{hZ(& zto{Dc{}8bQfnuFiMS}09vVU~yLIvMM8I5sVrgCLYB6hhv&CrIyYalJ2dnnH&_JY&j zZa3oVL6yQtA@v)7RldaLKdu?~BDoEXFPCMZ_8Lmpn_jG>+~TS=_w0kj@h)Sq+^xc^ z1u#rCX`Www$M8gnOu>us4$T|F$~vl<|^UvAtS~c@`bWF8%pY z9I$^-J0;#`e!IOPKY4%sx0#X^=C)}>CnvaT?~DF*B~d&nhZLfSd$aIOu>PN+U5D{~ zq7PAVQGMG#26_REl}wc>qd!IqEIirEYLK2d7bD01A-Fa2E^@gP*Yx@QeqI*u5Z~f> z_1ROmS}&>aK_7qv9d6E#c&Ju11%}`OJc)TUz$NSg<3?PFQ|2w1Q+u!c)Bf*1rwP*6 zw`kwxfB^X%c^{2!hmgKpvzfnYUHeX+9K<9eHWU+3DxUrp5>7^TFf%Q=!+Aubf}61X z>Ga8}I)AavZ4PjR;bY?!ScQei-x15;{CvEC3Fyf1J!dr@CtQ>;5=5I;*GJC5j6Z4~ zj4P9j)6|&T;SK86!wT2?5y$wH>XHY3`38Bx?JhtAmSM&0> zYtco+hSak@?XN~)ziDYpzzZjKzxOEpsAQOKhxHe#R)AFD&eVU(-ykH|F@*SbdOt|8 zvnh3Q-~)Fl#LU@4yB+RlGHup^zt7TbYAFQrfg65na5Loaz{el%u=%z@S-`&j;O7m? zDT9ro5h?(YK^ONOYZte@?i1Oz5SIJ?quswV};udcKsv4sjbbDXRM)oi8nGO%{^SmCat6c+-wNZ# z7fWn=#PNV>QLF0mtVoxn0bQuoqV}M0fc?>q>NahEc{~mgNnV!{oDo5T=5E43Nwa~?|DQmt-Cy1Uya4YiI%eO!@wi>zg!&QZ$Y0PW$G5B3Yo3)Z zHrru4eGvSK16ZU2c*H%uP)+k<;`s4+3-HV6$UJPukDGy{qaTB;4Yo1`qjj8+ki;`U zJ{m&j`#l&(nvgWkVuZ$`wRG(7d*wtOa|lcS`Pjs=m0z=pNn~>C+L8Zr^GBo6FrX$@ zJ&hejhRiu!@2-B%(hFZ}dLy0AgKP{nZ+pyqXAx@#B6`!yplX8(GQUk6mw%iBIrO3a z5((T#VKZg^+vT1((-q+;V5P@|zKG2(v7Pe`qaYs;o8B~hiA3^z!kce?|MsJ6jmXr+ z=G|Ov1s)4I>EXY4M#sP1KQ0Z&A`AP78cQKAkBlVMeoS)%Hb96GN=gXt3`p$j=q~`iWPK@L;8h5a;v6odt14`|QQwf~?Us!*0C~of@$xE>H==fU)F>Ey zv0pV8#5ju<#!uu5ALR!LX?%#pl?TBXLJ=(X9}4;32lsvHay&((svy+PFB`+v;4yNgL=JJM5+DG-HXtf6r zL)m>t3|H{>stLe8A+n1b!hnHumrqFUuH$Y^Y~@-oA$p6H1@Up-BjsBDicXaT+!elN z|9KoM0I4pjRPMcZcQbd&7=+>|gHG}Ry&kn5@q2WoBP8BFetJ9>x|+2omjBl zIjN-q|MI7KH!lb6c|3f*;RezK_03_~fqsbjitsAfZ7j?hi6cYK1CBkSbt)gz+CRz! zA1Xb^gSDQXocVr^(`BlvxTnA_b1%Y&bq(y~B;BEGkX#I@iEa%G@@AVhCc~2AWi+UV zw?K-k2(u+x_kLe@c%nbahFGvS8ii*hfrn_j3cSgSkS4;)j~rK}&L`zN2*P2!E`g0! z((~bX|DCh7S^<{RPhw+p=f~}xf&-jj#=z3Se4f#9;dd?U>iG;^%ZdNX4?lJNz{Y`7 zzq4a)#^_nyu@Cv*YJv~HhiV7z5_Sz*+xe_rU+VVzJ!)9)&jK^LPj4D?=a@8ewzvuN zAOSthBl}dpL;Mjf$HSg3!#m!%G&v>jF-NmS4CMD&hh=(2liXg1QzZP$Ovogn9O^w7 zm<9uW%#pbhv-+27%)zi^zoZh}^oAP4Tw=ZLk>4yM6_Sns_hB zeCKzYGG#n0B#GI>6IF#jdo81?lcmKedp`e|dT{VZanthf(?$7s`L?J?zyx9LpHnOY zk}>#!WAZu5F<7x%!g?f=O5jV~?{>G~>7U^1gQ}=W1ikqs#DxHJh<22mXObL2!ys*yHFYXpE?sU+hPZ{&P~-ne^PG5 zK9A6*B|9iGSwOZnG}2ppD5{1lWvq9L^}l<6K*{51XIBPvx9oXr;SDO^s5>FwK3mO3 ze3rkLaQ^3&ddmH9f9)Tr(Y3M;@04NS9K^ik{;B!mSme@f+adjK@!NC%?R;MJg)1M5 z$P>|CKsyrQ)u82mRK8*RS3|W#p%|qsa5s0iA~-t!)~^E-FOUse9j$-YAVFby_M!Y7 zZ+<7Qmja%AX`p$Lzl$zHWgIWK+(yX|XeP0c;vkvuC#?4UbH~*OTcAtM$~beE??GIO zG(XO)-!^=d+$Xya!ZNNDn4S*gj<(E+X9_K4stnnx9RHR7`T8vW7QQrs;>k19D~}zf zTg)`as2a1gT`ApqP7E}naTuv^f-7&|NrQi8F=X%k{#Dmfh}h&BtwR!)ieegw9zf-K zj>UpSM`I+V?)CWyt9>qX(e?GV(?g$??BVns0li-(bnwyv$`Ebwj8vOBAkF3kazWB=tg`y0WVt<}jtP?|FNG{?H zL5uSXmh$q9?GDj(fz)1w3~wV$w}iWFe)a9A5V@cpx#|H$j6{%$ zj&i^&iTh{AR|di&%vnrROVck#c}O2ZDHFJ zh)skx~F2<`Kwlo0GXzz^k0TkJ}c2P{rlp-56RAx3@Kjd4kq&@ zxQ-dQGrabD@>Oh#(hv7~S4H5x)Aacp9MJng>ztT&vc)o~axf(ay+p(lF`NNh%y|1) z+h$DkoXL|u>PPZyK|yC+H|k2JVK^5-0%_*{Hfy(=jpH6)2$GS5nW7BF>6?O-I@(bX z@!TozVVM;cbFrF+Umk2GY;b8;HN&yaa+`Was8O%ShA zi?$b}Smy3eJs6!<2Zkp*a9|-;(cw_3Z%jSJUjHiJ>9wgnpFbb%1mtemiM6ikD-+NP zOD)7s-GLeNKZH=(Y;ctk{8jw^-$9wFCsEO7e6KXK~SfZlX*z; z5z`9}A<%Lcw=BNiXqCk!1} zIFF)+J0v6V!!AD6^))A}N$s=YK9z4du>n7hpNftB-R_S1CH)QaID{j- zzkVs+uz|JnG#FGcMCx^i+~P&IO z3g!OZucSV{m4`3+Zxis~YmV{o2xRXZ%EFzX8wO;=s6eLIg}g7#4&*>{bGt4RLk?a1eo#G1dI-!`l=9lC3l6U7u zI0en?6<>f2$SM-4BFQq!Au8~wxa(T(&$k2o%0mm;^cjU#%<=nLMMmzvsD;E6xr;i+ zsX`Sw9gQE-h`Z*36^hghCf;$ z+!XTPK&AcV`JV2K>Z)9?3kF zf)W9})kI(yqJX8+8|=~T8*vplSR+#r?w}4c(rEXGvogsf!RzJb10MhHx7EL&XdTWG zi*`5cb)UWQ1H+~J!tt(LUG?`)LLFI7s$on45_o=oYWE0-hI&l$NQ>ngixypLx6l1F zKOw1$D%%H2a4RT*Yw&*z*d4*UbAMYi)E0n}1g7r8aiv}F4w3QR`;-W;WQ&VQ$xlT( z2dAmNNPVf2+5)MIh<56qs`Q96Vk{2KY+jD$@&KB_(Vq4E%<=9pCo2B>3{PMv#nM0p zjyS?uPc0QSy-jd7nD}{CnlT2pq1!&r8$aVC*MVcmqoLjXk&OHuN!Jsnp489Ei@)~T>nVy=_*V$BYfz|VM{86sXe^#iTf#s!t0$zudj!# zuxkT0UyR+JctG#X{{$j2vWI(kW4^FQ+~dF69PzL3z$y|nz}Hn3<)lpEpX(cup?L6} ztJIeAm;YYt8+f1SOEDQ>Mya=>F(dtm(|%HjSpx%c$m&%q{%kbrR%q@VGO}mm2plD& zmgU;Smi+Gym*;7U-@?F?L%7_%h2aLY7J|T|;kfjx$(fnqpWRJ8VS58|q9l(VsN5eb z{I6&6Mh#^LNRshF!QXoQtKFR9p$Ky}>=h6M#3OM?1|=B6u&CKwhGcwXN(d^@Y$ zSdLk7;+o`lNldw-4|492H`p&8@f$P>NQJBa-m$TLz4w%tpbB~|2}z%PzsbkK9yS^% zJL#`RiZ|tdHd7*@GEVIDJ;TBhl401;sQ7PfL!JlaFhFMW09W||MwM)T@bDE0)gFpD z5q5NNlo4+ZFXSpC6LuU{X8ZuY6IsAKuB+p|ng$34g2&UvBNCAW`bE%@PX`{vUm8$I z&?=8iFo?_cr9j3|fj@8!^4j6ysjz)ZGV3++SoogxIDY3I7KT@lZLm~eM(z7L_?N$0 zUPh)dUg*~g;qf3Vuv1XZ5X5W`mrDM+(}P>W;v z2fTHKVm*_cdaWS{rrjS>ggLgd)}x%9?DyB*2vEC5`h>tPX8um?^%%k^2&B#qPjgwI zMpU&Fn@vz}YX4f4*^DD~=bbB-e8+I_9*^gcIm?1?Sg_L;r?7~ zwH%k2YZKMVRaCTeKF^aEmJd{L3wXg`@4;C+h1BSgz5}ZN6S08wjnAJumo2jk{&44u zl$r@hgSqo7CEmNdJrGuFyV{3%0ogjL>U%_+*ta>{@Kd4HU>cgs0slVTj^!5`T;zSc zR^cQ(9%J&2YAf3u2Km^`G59dD3N$ZN#PH0o_h;#@On`qsPn@i!`#?32%pt=GB{EE6 zIkf+sk6;`yQ)ut8k!)r=7jtjt~TEy=i}fxzyNybPav zad3}+zBE4fhnvBoXo4K%_l|p)F~Z$~3Yq+%;*(?I(5W@Xq`vdwTZES~%okc+*X zNaTHR8HT;TO_pq2f;~Q${rA-uNTD8I>r4>pB@pxlaM4|-TAd_whILUS|6i`OPk`qw zt=Dy2Atq>nLX^F@!g;k^Y+18f87UvtIA6) zveuE&K<~DSWc>{K#3N^5r+))^yfAxIefIgcoi7!z(o}N(0c!y*=e?_Z93y1bez^mD z^3xwMDY8|Z)%^x`?tj>MyhA%V8C1s7zpvZ$L1+OrAmVxK$w{q45}&j zf=Mq15Yym6QC}UXps_H4kw9j#Tn|SP2-#DrV}y6~ZAA-+3Jd9_0RH(sPUN(1&J9H3 zR#opgomtBnGQGDECdu{RV)kXz3ZedKe_vWSAIw6RRAYpA4}pj=2i5>>_!I}!gzL|1CC zK%xAzkUIrMrSIn-sy{=Bjv)DX6v|C0-!*TNV*A4uqPzWB1EGqx-vx3Th}o}5Ezetj ziB-tGmlXiD@`|hS+AKbw3a**Y%U{O~o{2knVVfxb8LJ~r|JBC7Uq>^b*s((TPGK_S zIJq0}E%v|qq6&G052szRwk2C)H!VI;4$UtPF7V)fqP&k=0KgXhX%csg~=0GVsjy|9@5J9CDlrQ^2DxkK%H1 z_(%DoQ25!YmkYi8KixsPYHZ+++u!EnA0mXEc^8xb7(b|${0U0e&0jCY|MV`Adw9Kd z41cv-G26q5xIMQ>%o}*_G_jNE-3|Wv@BiD07i~8tYX3t9grf+XpWV z{|u~T!qX9+*Lc?kC%x0r(*D0^`1^j9Pp*=im4RDC7o38uUFSy66~im&)~*Do5kz?g^~x!0KV?{n4{f?u@blEA!wlrsq_>;A^|nB?t2u= z;v)WW#J^4~KWjD;94((v+)KVFttfEsq?CE-^LEWdP!_gCj$HWND1+b8kMA>y1WUTs z)u`rf{~J%^w_MY=CGhR=M2&C% z!0|1&`QG-Md;(X711op%;DDnmt(>?|IrNacm3d2geFG(NIcO zhL;+gNL;}Ta^?6@;_d9kO}r1>E?&DRI-9hMZ9sHj+kH=WZ<$$UKq2R?#rI+-`@Wgb zLqr#Ac^K=9*v~27EOd5$=mN>f2)EfmKZAE^O=q{u`)eYz`nRN$yS|%d@k25yo~%{- zf@VyXz{dE(xsaW2ikjb%fL3MYXVp8O9ZH{4T;c&QIp2G{&?=|Q@P3~U5NKXHMpgAL z(35!6s}RG6Q{Yw27andRJX&FAmwX_l$48Io(8IPUghLY0VKb2}QhzpG+jHcB@1|35 z8v@<*tMIMuMjF}z6Lokwk6xk6svG~JEf)h$P5qj7 zD+KM@1CSEGlG@sq?AacjoJcMgAkt=JMPHjQu$&u`O%i5%2tL5jBLgZnu3_ zUwV@TE%kjPV?JnfTi|cv0+&;q^x!`i_{qaOmrAt#Xu0YRqZ-)HW_MOK4%?i7MC=|C z6SXG6+f(7w+I|e4|moVZQ{@`EadtWm&6mkPm z4x7F0H?#@FR`X_(wR*)E%m-b>K9xp4UT~ttc9zHXOJ&?Nh?_b*lA|bPuZ13CCb?=? z_bGTtAcYmU?j*30#YnJ&lE#Nm+`4D?ZU|tUVfqjBRbKR$zYAP8pG0MYRD^f3x8hG> z$}83Uc{?4Z@is?MEgu|p7lDyB2&L-lLGSx3EoS!lHODB?KjB*f*5Q{KWR<7MPyz&c z*LK$7suS83p*70(x4<)mypr)#Ah)7-#)Uyf_q?jRHzxuWhZxg3CcT6OJpLo`1y_0k)`doqANp+17iVCp^YemEUVJ?X zO>WRvy+((M%>O>t=Co=~xxZ)E9k|VZ4^MA4ngZsRYD=(==hnoe>y0eEGUlnzbT;{c zKWh)qi!M+G(S4}I2EH^OmjMP>)J{78Hn$KEe*ZRK~>=|{<9L#D;n{x!hy6nXcVV-@p`5Dz@-+gg;lYhbZZMN2z_w#RF%Muk_j(t8^o3(>A$VUu zBr-MzI&!*T5-;*BO@se167_EUU>}1JChVDeJJ#))4*fdgk*5NrZsc%k2340#sb5+s zSI|=6wngl``ov1EXukZuKTm!=c4WhF+4s}Dh1P}ow-fO&rpIN1uSap?m%d)hu#`G9jWTe5w`{vIs;J)jX1W|V{{i;xLJ>aG zMN`FJ&x_BOt(Ql;fn+#G+qS-IFSGSNpPmiUqtG#EkhE)FAQ8vnmrn_MtYA9mCw2ni z5=Wr`Ava1<6T#F*-ZCi8gJHbfI!OEK_1u?lm)<_j=+FseIlY3>6ol=e*JyMs@~ifI ztHNWc8dpz(;4sHcfnIFgRJRX*Pd>KwTJzF?=$s5w{|&iUbx)Fn4J_RWlHi+DP%U+r z-8FC$@22b4eP@sS z%i;!MmsZzDe-ErFFSk#9$HdI2_xOFsg~4aRXDSU@G0KqNEj}bs>;Nq!K0j7;Sq!p7 zk2^kMSW4)}$CEK9P+ZiHTKt%KbvYmr|6+f?H0}gZ(Gdj5(Mu$dY55Co3Hu{qRxk2yCo32=zRZh|Apq*rCcYTQkan{jU zwyT92>B!-??7IEi*2-aD$o1HKZV&y%6x)If(C#xqFP9rTCkGGl!57+3CCSBr+a zJorlPDSj2a=ufrMg~d?|heh2?XZePL!5K0mzRjw;fa@M$S}pQ>+DfWJ2omIO!5=gY zKySoe_Q2);T9E$^jK<}r+L_d!+@|WG%FlrTL5YM<{RE)4r%7ro zgojAh;vlQkmwnXFleCGFeZBN>5Do9J??q}$yJLb;f^x&v#L>T7t*uLQ&?8@X(@#Bb zh3U?z$<;(O!YjJ6&lHt!{SW`M4ffb%%qZVKUiE>X$91PAv_R&;9{)FoZaMYVqlMGv z|GH{Lqu4C zfH)odqecg6OC9K_zwbGtM$_4ToqMakK|m#y&;Dw=#uVM}gM7sh3RKlSV%Gi`&p+!C zw6|l6X(NDz&f}Qi_f2aMqnp=TxLWjP*Y~Rv+1km}XAT0wlxNhka73L2OGdrh*rIK} zOwJR)DwITqYwJWHAX8ph%Ay>4R25?8h%uCJvAF;1+`Q|T@KEqCgL3;3htvJAXp>Ol)*!b^QEqPpdrcWfy^}bgh60-##ROk^mQ(bw>mIx( z;q$d}a`<>Z6Z81fWMz0goVg5sPJfsB)1#(FQM@vh`?Cf8_Iyf#-oAyu5(PNE{he3} z^3ji4$7_Pk+54GpdH1>PkCMSh^Et|u@u=kjif-TY>+ZcY)o=pNExmodM_Lwa3t{(+bI0Zxz~=^Qh{a)-qc^ zK+2$$T&L?_Km`EczLVUF{R^0Lb?)?spj_|mB=jrTsTZ-R$TO_ehI#u*bU?f)Jd%v< ztO;!%5#(nwgjT116@)XLfK-});|QoK$`cf?uLi)Q!~NEk@vXR*FZQx>#3F+#GW-?v zqz_~9DDvpoY+C}l{M}e!&weB93V)V$0!rDVx`(OL+Raekr!y?B7elq}4wnxNO+O1A zy`Fgo!+M>5R)~1C`s@7p`aJ(0A7@;N-1-|-p@rR%_qy~wji7N{q$krJYO-I*sZ-rd zF3^2*5P!3txJ}Wz^y!=%jDnK+oOl?%tmIz3O+Od8-;@^4t#B0rztA4{&(gQ9H~PPK z(Xg4@(BZXA9=<_by?nPe2=~0t^8C(zc&ct+Y^D{Hfu&{VC&dr4G4IeX2Uj^;k@J+F zEHgThRx_PbpCfAhDNb&qpL$BbM3kWE+w~n1vq_gQuec4Qq7;|s6N#a^tz&rEqCxk& zxGB_1FHvU`Q#ZfN%4@Z^X0JYDgARXCXEv`=#o0rH=`=W2$h-Sd&DVA7ev|h zH6cJw`y$lmf`;&3v7&D=J*TAh&O9NYEhI^>pkD*^DGs$F=#GzFn#;d7pfn>GoZ09H zy9qe;%m)KLREimdr8kEop7;7TPk<0R?eiCTPcl}f+Cue(PLsXLyA7#;^4a)cD2-L8 zMC1~{Y_9vcHLS-nfIBD|<^iGxW%Im>$cf4O>KJWjjeLsN(;z;QdTUj<>jJ5onL1<;`=*avd_EjNE%owf&aH}8(n9AwM#zLE zN7V!Q|MziT{7!GdvK;YcAl_GSaRMKo+%8DWp`pOH`3F)kZBQt6-VJ5khaud$0`zX#)MzC4bv0&O|;u!zxBmiRH^nDf5q%aEq1Y+d;xk3pF*#o2Pc zuFile+aj{R#%9F3Bl8ApeC6mZ*%t+=s<++_Rj*qY#tuZold5H&6;JbqZm;zW{XB@{ z(!1c#*d=-fLVIy*%QB%FP3Q-zqBk>M9zdv;K7-DDD^wr>Yh?@d0`Dw)C$T zK^~qA$(iMs6K+KHZ;E4xtHUMLGkTXLqc>6+T3C8rcg3-^s?op`4aB~8urIu z6V-^AsM<_U3~c@f7qzn5oJ!kC4Xe zm)iOo7q0-Jh5IvkSjoCsEb38%^Wr>HEY(DC>g0WBJy{jV4KV+v8c(;;*H=JR!ui`H zc7Zba{J4vC6xD9-&6FD5d-PaCXUQSU<7ytHhvvdbRqa=3PpCnezkmk$Au8BPxFS{W z#;qxfdVS~;&}#^%8d&u#ArTG9*ZBh~A1C$f{+4wdRcZ$dEaHtO<~OQn|fc`BCP@gJsN&t;JiL_*1;k%lTGj{6vOVI!G8j_ zx?VpU-9!Nu=xgLhn%_?MGyH;=r%OR2ORmDb54C%e-@3ggEZES8cf98}J|&AU?N-a( zU(WgT`dz~+(4hLBYk)rMk1OM$VT+bmG%ZKydQAuGdil~P@P<9PAnia}j-C~-NzmW< z1u^{?sqp@lI$Rv_Gu^mN-^#H(z0)fPodx3<0jIVk$J>QogPTBL8#3HT;qmJ4R3U&B zHY!R=&D%7ypLkNnDbDG$bk;c|@!xtz$pM@)@Ih&;OlfWz z%O58A@6sLxxwv1RK*Xftmcq2vPU7lyR9;@qdQF@n2HHv2_g6>mpfeaUg+jMS4-zlP z2MFtSnnstZzlPqqZ@ESi_+Zu~EOpG|&wJeeVCfhBNA9*&YsmWIUw*_{E8q-{YF&N( zImX~5lOEF|-=AZjL9JjC&MVtJ7LN^@H_yu(+ z{UCZL2Slip{)`w+TI?Vm}kuG_n6;-%IwPv3zB-!PR_M|!b@ z_Nln{iQY8y-b`eILb_qkg}i&PNYm{lL0c@LmLfn~$?W zHS1%~DL={C>9DxRMyN;5EBe>i-T`YH$*n=>Tvgj?b31wm8kOct zR97f=YNj`pK)Sk*?`1&WPxGC*1Ft39$GoB?t$8;3UT5Fb1JB zU)hCBtx?z2-O@3h4z7rU+$=4;vE)o;E`?oiegr#?ry?K_aH75?&ViGCW7!W zv0n&=%U_WO0HjaEPg3pOk2|`ed#ckC;ml)e3|8*)s??z4MMv$7<1ky#Cnms&WHbB( ze^Bi$I+OI=d1sRit3>Hk)8hwN!nN^n+YQ-x1V5wMHi~t5(qhX%f6~;ltU=SqdvkVO z*+B)QYgc2_p1Ui@>w$vO@AtmIeQ?UV^J*{MGnJGv+|fNJ?S;k5q9OUNL9K+9$IJb% zJGdTSiOU^ak6e@F)k70owhZ5-;&xTfSbA{_VE1=7$UK4;^HlXkuS4$XehM9sPKM#C`!M+y1ulFw@q48Co z2x$0^gx1^r5D#D<+WX6TjUkIApq(0Q!q7QAjQqSn5joTrwqqiqtAu9!g1X7Y6`#EC z#+(zJAM-5$Fe`Vrwqf_iWlwXH-B_JgXs!P6)$gz5rr*sj3bX~sUcp0@+rOn_@!BU& zDcam+(^zvlx*SAFkSKPW8ynA(o>j@CYX3i)u4_wGY>WO9qNGQ15(LS-fv98RM zq|WFu>fWwXDyVGMUSS65cSrB`q{hMbv|Xk$&Q(=ZpTwG#M5dP7jl7v;aC=&>v+6yr z;akv|<66Q_s(m~*Lt*RiP9h5)3_yo2x3L4(Wh*XCwMOFl?x#-V!>5Gxpa_;`-!VOj zQTz6zRL{e0y*iXiE+1OEc{x2ZkYTuXf}P57Aasr#BfcBo)6~SskZqv~7pPod^2{Fr zMhUsoJ&leL^J|_tuU#PyeY8IQHyqq@&(D0LW2*F)QLLzJ6I!GDJ^{b>U-Xh(q9&hZ zE}d^&aUm1M)}nDUzt9r1$LzB72$MtG8IK5F zQ(E3z9qX&-60#z=r3YuALW~C+wUoNV!0_mvwVpHO4YfM!PBZlzs^8`+1`9A?cHu~8 zAwdfw_G)Fp{MRBK=qzpW{aU1e-=DUi<`z1_a5jlLQAHbH$w}KY1CR@Ti`6*2vI#29 zg{k+6LyahoE@lf-Gh%*I?FpbEO-~HiGbeY+=?>|+ce)Nkp1m`UR&#)zpS;}4Zny_9 z!yxUC|Db`1v8C3Iw5l_fz;VSr@}}-0k^!39Ys{_28m6DJ1BhbX7`Xf5#j_uLnVnT6 z#HI|N`kd@KL|4VEAiiytYUtb(sn>twA33OxIpTgr_)zY%-$&g1#g3LFCJE9Ru5R}t88-^?9WzrMvk$Ap7*W}uQ`oFZwcYfWtL@!k7;)X$~ z7$ia@3I$>AO|5(p>}~3B&nx-{Ee@QU%kL&3PQ2FM(WR?5-PNAvBlORQWSe>Afa3Jh zc(5^yTLA>Ela@<#u7uHtLU@k$dQW6;~Zjm?D!(s+v$*mAI(rV1vABTWh zIra%7t@sG16wH-H%fG;F`L(Nx?Ole;vt7z5yLoC*wrYCeV=Y>iTUmf2@H17QtrFL| z5%0@>TG~mjM;4(*!6@lXUBjpKrXlCO$RJ!d-eq^5P?$T+1Ji>Aw}o7v+gP<`1bIai z5u@Xw12f-o&%#{XlgdnsF2r&D@_vP0ygGP4e==rXqzoPYmlEuWMh}gOuqBRf%Ay-t zsLd$7MZ;(+1V(7qRIfd74%O#eoNuH>t{g|%N&n{OJ; ztLeWb0kh1psi|-~y{;2JPkLt$_wb}9Unt8w*pl@L11SV43tFN+cx z*3t9Zj;i~?l4fDij%Q~8Xuh)3N*-+(!|8o2z@}2Vt5Tz?kNlF9)@wTMW7)?E`XD#h zjW@SD^VX6Ams22`8p2Z8#FeLFde2}G(_)QtkC7mbyO1GSWz1=JYik0^Q5m(=^&9X6 z4phre6UE%5>#wJCr%ddsa?(W;BjfgcPsjY|B~8_M*3Fc|C1)qg&LD!esMNLplVe;9 zu6phl@->Cmz4VH%Dq>A~0x+*vpwobnFwE(xd_tJG2FbodqCg0|rT3V`%zZ8nD9 zp3;jqtvBvMGD~HmPeHXj_@rg>9?>Z$47053>wSOCll>h$^1cc`?<^DD2LtD9aql@G zj9bi%G9X%?9PUwca!$E7l*mKvwAf+Qbi(77kUk&1^8D1u#YsxE7re45Qe+QDQHF8! z@Hw2C&?;{F2BW+O<(8DUb!E#Mci7~e_Hg+|UWVmotN1ee-0d)Ee)QLdFla{k9A(wH zoQ`x)-nAmLW9&Htw$~0d$;+&XaOK*6Jzp3H-`P<|8inGGuzeyIO5Aeeu^H z)E{0!LJzgS$D^ONCrtR6MP9;wqgbXZP(h>KZ^%yPYpgyy;|7;YsEiuN_lplF$7c4h zmn@mwxEk?EP=rV&;F^v!s<*y9o6PuznQu5}IPv$95MPS@e%bI7V8*wRM-M$=#{j@uAjZh@|L)4R(GoTzY`Es>48ayzo`b}jNP?^ZD?Ge%$ z>%>Upb04afq)vzy;?&Vp(T;eG$}j<%JJxI5s6ZjM@%;NEy5qT-u1$q@T4!w9o^eM! z7P?l3j?#PVFd#kN%i1v*E6bYk15R1Yi^IcvhPnXM@@(a=?m$3^+lN}$HqN^hjZ$dJ zJ}QzuDF#clfl|JgWjWD%i4Zlhr}epKx%nHS8r?K zVoTR$c6UMfx-$>ZYIR8~)7gP4~9SPx3L3sX(F|v!lF?h>L@aopD zq#4`!(L1n;xl168HIH)%uiq8GOl|uI3c9zYD#B<#jIB`)#lFsOvtI zinytz3)87Py$L=Eo1{(y~6`7Bng!cP$ll2#YTZ~Sm(tsx=K zQJ5_fiuHZ9-*{fO0Xt~FR?Iah5s+CN7ICtfX7w1M8e;$q*eq+9M12_P$X zpJ{>luk{P%y&;Khm^9!yE*Sl0ufBf{r>^@a8SGj7q=$y`#4Fz(h6&2b#au}Tc?nXo zdDXK>ejio04!KWx)8~5lI?}CkO{pY!_6g?k z;ugJt&U2)W)IlMymu{d`4p8HpwAlB|rH3aZW32_EVJ}vk=h}Q9#1p5S$}i!_O*KHN z=PL$t7Xf-c51MW}%%gnj!b28Z^7=HwGlpW%=+VpDB@Rxd;gSdLM#vDbgG*mW%^|Dr zNgsavL;Ms@aVzgZCOz51x7^~qzs^M9F1u_!M_}?%ieSuLZ)f+*+(X!V6UQrDTl;VQ zjwcIlHy%IgXDxPtyw^eVEqLyjGMt_e2X#;Gz0bZG>r)n{kH@8<n}(b!MgrTuU77zCV+7jsN`Lq!4VO9H6Ps5-^1+(!PM~>Q9 zgBA*uqH99hiclO&FEhRy6tOaAfvJz2&Y5W6*3X@5SCmRk8=xg)r2tRE)Q*4fnNNF& zU@I)Q^R=UYrtY@xLyQV$BKM%@xk{g5UpMd(mHYxrZ50R=C)GhNQ$= z)3o#HYc}UzMNR2#FOh+C*`+S&AZ=L&R+r^4UzD``?KPr&w}qopV^%x}VkOyc*d=%| zBvzGAUWFVwm=DX`0~py*rvTFMueOrEl;!>s$k$wuqn3}u53VeyvJxL(wqg69nWxA1 zaG5o@u%gzAN_5gW|@`%|7ShHK_6-DE4IO(Km84; z+R5EzE`^5(Mue1yx6DHy>eVh_hL=id_6+(51N@%IS(DLzQQ;}EisXV9o=MIf^s7~~QYqt{ZT~icS%33+c;q_Zq zaPALolKE(iDi#vR(JR+-Wl#6yFzsnEwJk59usb!~g6+UhoPIMuvrD2=A z^%n&_*nD+Ly(y+rBz-OxpsW0~Ti#2O72(m{Z~Eu!%ZKn8de48d#^1OOox`KM)qB8~ z#~#E3jUvn2Nqr3T93Rny13&q+_KQMt$k~O-)~9o-pDT!yUEt0(%sqP;s<@-;%Rx{3 z+=7S7%q8E%xwx)_DGXlpZKC)0`E4tj|NY6H_WA_TN#?brte(oFisPldCyp*kfkU$d? z%lqI`6T+4N__pJkqtF2kQxe2IDS3Pp_CfJUF#x9X6$Wp#T3UVQg$c)>ggzGlY5 z7-sAEkX4HN*lDL`PwV%N??&8Za2H1fyQLCX1D~O3Of3`zN3dD*d)Qq5Xk=a)P42z| zijh#^4O9d=0P+d^!S|uZ&-I~c%R(8s9_16QpI%MTssYF^)t=9#7t5u6+>}%P@WG8l zznF-W4b$G%Bn{u5*(-fhzoPDZyjo3nU!t})Oea?@@xpZtV1v1G?H1)x9Te$>1X)oa zAeE0tT^@7)3$Q&jeb=|7MO(rq(X1 z*wlaSd(mxT-CJXv#K%aRCr8{qpHRN4#jk(PSfv*?31_yjUd045O=C)gvX|z)} zfW3OEJ|yx;pSbiz5-VRF8w@`7~FvaW9Wov%Ebp57l) zqO~RSsT0-yX^uSs?Z!uTwGYkB7wscppnDSsclI;AryxqC5Vy0Iw<=E|W4IoRm$&*x zaQsE2f2+WDKWzTH5!YM3Z@6_HU2n&wIyApUt?A#ZREpn22M(z+cnQd7<8b3LH%8sO z(tE{P{zBm{vqvY^#KTzB?Ymf(*OaSKitws5n*^MZz{c3~S1I>Sb7jZ52F!luO?>7F zx*CXs$2;Ps4uZp*HcOjC$9I(0T;#egbBn@q8qcpHC`@0EB`@CzxVPKhjmlW+oxKrQ zRv;1-^VU7ZXB3`m#c}-yII>~k0$))pfz?in@&X;Aq5AaTBT@^&@Vs8rR1A(2+N$#V zELT;9vBn4)>t{-1s&u-($uAF7b^*bk{R{ra7Li;6lK#$W=DxZm%RuwB8e$$)?YKt@ zg?;yFe7S6c)Qv_UQmfz|Ixj0_f5R{v8MhvtiKPdK+b*As3~F5vg8Pa|MYew*lexgI z4Y4+w1Dp}s8Y{HgP<#o;H5`SC?>2gyRWg|5HO6omGo+LENu2Ma*l#i`ya!ZTL!U$` zxxKR)-?Y^mF4B#;Wrp(sld~``N_-ZO52WYzatj1|$OepZ7M_N({~1j(n<%1-(H>3q zDxZ&wXV~U5(jUcws?$-`#@<)_MIj{DyLsSC$63AX$>RwOjr3kd=$m|5b-(mP`Kfs3 ztSVP%4q5s5631UF*z_$o<3H`Museu|XNj_oiNbSYdAV=c351%inmi+)8tdOd6rgde zmv3y){-z#BsrwYI)25vI{Y?o}FS@oo8q%=71@{LM;uiycJf?&+`$MnFGX;>++h zxsOaDVh;e+rQ(HgFWj?z7`^h^gTG>&jQA%fbHY~yt9{I)^c?T7Cm=CMR_sy$rW3#L zaIEfxt~rhQEqInj{{b27oJ(48vlIc=DE24&8sSWZZ9KUYdoofazBig@5A_&Vk=S|L zvNsK`&n(b$Qf<{{c}Ewa&t~RgtI9VH^pb3$yS#U)u_Gu6i$--U(!c;+kq_K+9p!iT+UH>ltOU#-c@?Q6~z;a3p%? z2Pt6&5r&4vr{IBYE2R_ZTiI85_CR&};Oz}!V!tpm_^m=4B7428Srn~WFt-W)`<$}w z8Z({;@=ml+!za_bgMUBbGn9x9!kg+E5;WPIqwX*Vz=TfU!(AsGn#@uC8zzH((s$d* zG~-(ZlM+0*)E}%ijUAP}(4#gM9erj!emCl}cCR4z#b>Qg->5S0&_n>|YrhOxHiRmI z6%0V>6Tnb_UYru~1^R{D6CX7M$L#SELzQn=OzOjMybkTBT_@QizTXe;W-GlvIt&XP?(O6%M@m2ZhfGTsC)XueW_YHI;9kG#PO2P z%LL-wNWX7@i}>pHR|&uSwoWb?VN;KqGozgA$?OC4f^S2oejaTudcvp*fYq~1OlTTo z$tn95lSRKX`MbRybD#Y+f9B|0xE}LtI5{1wENM)4BlDFag{us;1b)G>&Byr4 z`HApKYj|irj_?MrGJt27&i2a7U2&*hQT@PQA z2uit6dC;KO>r~Ux8~Px%D(cEc@)UF`{e2H)j5k%b4T+CA~)3e6|ew>Eym zjo6Ysam0^wq#Z5DIr0}>n%Y0N2dxC&ViVK20hW_!1zZ^gg0=5}IQf#j?Rf;|_G=Q! zd!Zij__xV@jZb5a^A5(+f86@vjnO*QXEqZ)gp;Mk26Js2TIGfO`jG2=`GM)tnSRX2 zNc1HDTUI4wW9cRo=&y4?mL9k#-*RE{`&p4{e}gZE)j)J&s3hLKZR`2-uy`(i(S|DO zreE}6-gI!-yUCcTQkhEbaEuj$|@QG7)*zlq}{Uda2M5|+o0z`J6X=@Sn7rmv;dW2}fJvj&!z%4DUn zxRvOpnTY?%T$Op(wa9_5>I;GZWPP99gLBDl^X0y;^0z-IcXy@@MVO5_)N5b0Admih zz#1e*ijAj4Zdw2FQfA;E1E-rr0z<$=#a_POp-lzXH`I$lrRcFY49eN;f8YR{9))PS zUtf*v5iSnL{p~*R?>!q&e@srEyr3yXv)VOmB=>$2kx|P^YrY^|UjwqczNzd3wTNRF z7st!F937G8oD{A`zR1?)WkN+(vC$EB{le(@pp9r?na%sY<} zf|qrB+;~M8dx~rF;BJCRC{)tiTs9Yg#`fRI5BgpDh4kPz=APd@h(CA*T3g-nene|BKw&sPx75b`+8fzEz-N&96-)S)7m2v%BJ6qGKec1+1^WJ+O~1wB z3?AI-iy;|V>%>CAoMW$OxgA-N)8?*bK+A#+k`Tr$04mF)5oCa??Ne_(tEf1R_<|_< zqt&eyl=hxix0z5Fbgx>(>>uSJ9P0xLvp~DlK=4Mkv)#-mcc1M2jdL0cu<1)yIHfq? zwV#N1-wMpl==#{otdKpFd>d2<=`(CJf-2a^H_#KWr_2`JF&my+0RZyT67AtfT(cLD z1>w*_@rHUeALsR?ZCE%=tM7y-fW-K7L8w`Cto{Z$Pvcc*FEs7Y`Q9$LTan$+$6nfQ z5~Gu;jB#`Rsb{oYE+2z?U%-C8q8nx2X7^3%C4=EX5`Vb0g1dX+x(ay6+~d}9udBH) zLa#rRx5+8u@Uum1|J@fqvzX1@t9a!LvBrcA8z;hDH0suc=B3-m6IrfO9?v}h`o+mk;p3*o;bk@A5v7%Sc`C488L`GMxA&(8K~FpB@BVlf zrPoz@zIEWcTFJ;M1Zff1nLP%QAXVQ)0=VsB{9r*yy z@ECNkfX)d0kzs>lfO`?7F7W!l5%xy?l|B(u_nx3pSLTut!?q4zFlkf!Xh(i7+=C$z z^DPG=h>_{bTlgMpODNQH_=om-z91^({KAiLarZ2!(Qk@Iac#7J%SIy1)hJB7QNT*k z9C=Cfv+wkiLKNh-tshhqX2kca9C#ba91j=VdRNym`SBPoVNQOsla4hlnUw<8Dg-Pgnwh;_3yKC0KI#BHU8)k0V-~r}qEP$`?)2b81 z%k$t#CMu?ao0CeFg$$dA4EMgI_IkTX4~h@X5hlL2WX#{MlhdH@)vikMFmh!wqkt6w z+-pdn7c3YMfMyxele`^(sM+Rw!Qoq%DkTr_<^_j?E?{;IX1L#geFOVz_uce*T)Or5 zC;%*9Z*q1|IsGGu01v3(@{+&ha-D?08iQ-iR>$W1#)0sI49i?MklqSI53haZ{)q2) zy*M2f1|uxRk}R7T2hDeURIbwbuVmVm-9=M5`au8}&*CAkM^Aku#$AQ^jQ>`h#yv6g z5&2<6-V+%1T%ehgecznlaO&MTzAhKmJSU+=u@Iv)oZmpdZt6)aD7MU~iuG&Th(c@pbBY^Er#J4F_21$UnpAbiYlV z)6MN#tM`c{td zED_UcU7vjTmGxC@rE-3x!9$3?do_d;QkVF7CwQy{0fO-`Ybh|j^x=$x%#IpAuX;UL zL7HGVi_|wZ@5%=0jF*O|o5Z_hpFYHKn+|YM$Ceh^IE7Rpz?rg>cq!rR`|Fc*mj-J| zK#^I9M}_T@(9BT-3Tnm^iL5c~H-N^7u&n8oQka(taj42wE5SZ6F3LA5yI~ZdxONK3 zkOu={hV1Z)_xFp6YI%|JCY17U_u>Th&itqOo)f6E1tSAPQ@6j$-@AAD7XHCI++Lc= zB#CyXW$9IjL@F6RnxiBRm4JVEqHb}sz%L~#-&wvb^K`_QRfEk!t88s_sW`5nJ_9Jq71xUtvKH0fMnd@KWH38SZ63 zMh3LqQ+B9w^~CV?wNSc!tDUYsuX>hv`=muMXQ!`aNz7HbWay~*$23YDf`CuOpS+;L zWZMg`iEN1FYXrakutq=JYv^!&*7LQvhdE`E=erX`FA!pHN zuykh7DL|1pUx6j@06u!K>yI2+eho?FxXN_l@7yHmOl;3jClY_kb~|{)B_Zgu8o!vb z^X3i!^Aj`Q1~fcY5_Z9R8iBEkZ$*9k>$nc|cJeB8mw5k})Qq}m^209efQ7tsn+NSW|}l3bxP+djP~h%)4clcEuP?)YPfyy?ULi6Ix*ze-u7Jn zMY_XLwr2?bllrn3pc6yr(i{x1FnQRZEWB&uVA zL>^4l;J_NgEW=~-^Ptv|{f4o~t}T^90EhNNKM-!fs{un!icQYE`uxts3zt)$SKE5O z<17Ld1NQi-E*{yDJ6(t%HL7fgVU-v@jqe1Q-{J82Nadm?WxV8|u(B}GQQZ@{!l9H) zt}lxM;F;zQ5gCC~F`#{5@s%b##&4zOhFHP^7jPN;dmZ8Bh7Yw!>sRqD-}XHTEKkb{ z^%+Xzbm%uy4Rw$sME!$1N2H0Fs8{zBDYAHm!irEVP$#i1(#1hm85ry8POroseN*IA z7>dcx9?TT`vIo_RqfS_mthD!i&Xo_9Q-U7H6Z40u2`?vN#wFM<1LUD7G7vqqg(u#e1yz+Jbl?c{}#{W8v{k{Rl~5yDCkUJx_?RVKBXG7pMp6&)?8KEuf?3X2L@r>X#np&^4ePMONw;S$@ z+K*|i)P@b4Iro>RH&)hGwHVe+f}LOYS}_7wfCQtR^s`W~px z1WfHOR`-rh33o`@+%IwNvtH5r^?cqBzjLIYU{g3gwFD9Xi?%^sx<}IJ&s^@g$L@&l zO86|!Q-q@bDbP-z@180A-XQkS*}RRbs?IqheN7iGT5@maZQ9qd>OYRJzMJnFfH|W3 zCy6=v=!8!c&@W=xIO8P z`-Q`=>A70$Gl+88CCcEN39p-xxJzic3Bt|%VVj%fYCYpL!kJ@R3@?4df$mewgRZx& zM4&d8GsHz_kA9{{x*v^qN&GK~yeS=!g@`RI@cN#Fn$ zpwDgF`jPCrX98}`6E8y2XjnPE&85ezrKg%p_ZorbsNyYn2CW>v$IK*_eHp`PZ*8=$ zKNlOf`U8vic^K2PB_u!SPsGRT)%~-QjHAsVoExUOK#TvTUkkY6$#cr~8ZRbuGz!jS za5%5OLtu-)JvU5oqMEg;-*yMk8HfF2+O-eIs#qP6)hh)(Nq3mGTz{FkD2+}v)ucGz2BLZOxJu0SXp(~Sdpl}Sc8sH?WX8qgUm!%wk< z`ud?i&xVB!`;110Y~A309&qPmw9(_mv(haA#Mt%#xraFT-@zZbbm+oB z4g*7F5dQT|tE)o{x+=4bzF9^X%YI@Ei8%4EjQhVrx0X z2MAAqsD0n$7-Kl=v#p7cpF6K8zUR88;B}_tR5*{HfxlJg(#P{Xf19Db-+(`*l2Fq) zoUPK){II9*2Y>xUTht~9agyOEx6asb?|%-EP~uyGC@7H3CVC{Z^Dzbihy$>5dndQ} zB|SFA$9Ajq$qxwTw8tPsQ^-WxG5lb$axi}; zUY#`T+%@;V4ob!b?fC$bqCE}E&p=N+dwze~V!hs{eT@h8$7QRSzvR-pEb9cW#n@RT z!mQ{G@= z^0@M_7g`bLYeMAUZFga5c&2+xVudmRm#Ei+O32k_2PlAz=_}4p$u$HN=mj^f*aWHK zi}~d!J7=O3&HM0sgxj$UYwm)+wO@AoYRImfUs&#+c^KRNAb+>WOe({78pNpj2T`m* zy}_Kl6u@G;Dr~TwO1k+CcI-x6VOj6?fS|nJ+N(;uRQ3am9@=SS859SX|7{ijb@n|1 zRh@rq_e`DZ_Sh0h+6qII9CMGo76c~|5lRWw%c^1MGrvA!OXqxw4No~su*7)T#`ldR zrz3dcu&;J_w7c)1p<@wDF3qUMdOT~XbsKC03fRjfx3{m}CI|o1Y)c9F5T)d&C@u|B z4Le1rcd=Yl@CWO9>x7RK5$hvMc_H^S{^jHN-4i|-SsJoo;joxv-kcPjS#v@u58cJH zq?V`I-cwY_|H3eO8Lo~9p+Aqi(MS^jCD>OPZZYe3L3Ra^jk0;qx67qK3t}0k!Yb20 z!i$NMDO=!8T(k!Gb;4(YKbcXwtq+%|b7?#GTxdVf>h*O)oylRy{?X}zkdzQPoiU3n zx%uQwBAF7NkWl|_5K-Zvw_4ELDa384cUENviF)T?@0bnO_j!HaIlI)~Ml-)Z{Qkv9 zjSt}-S`38YUNzd_R`c!rTd=Cy3x_zi*xRZ4vfw9LzcIif{2hen5pLwCG=vTyq^3WG zY|Frp%}}-Rr=B=GA-Ylr0OR$aL_gsi1+Qy$ISGe*u}6Q!5Rzj_f1}ULya&(!)a;l{ z>kzfxR-Mh1c;#F5i2K_WBERB$|9A)V?5qv8^7vhTSALl0JqGx>F&KCp{Zy@&73;|2&caK=5hC5Kc7i8GrBQa(k7tYr1 z5D32Me$+!-2bZj;U!TAF)I6T#9yhJJSfE=yP8*1hgqk;(wmmdZCd^v1Va&7nG@0(> zaN&U`1fSU+=&WtjTLR~;UYPL=Zw1f7EjNuz!e~$Hb^tc+1ic{mjK>ajD3T+53)UdB zlkWV@j?m(2$MzT!XVrE|%|M9^!N()NbUKt=AT(K5d)G3%7dh!9CcKRD;$s%I^|-U- z{XlB#mpwu8WDKEwb=lXvI;74eb(m=cAlW9SyDHc%I*mjy>N*5O@x^vGBh_z3QRTrONQD*q=~*pi27XmahL~GmUFs4$*D602P5p=N-#{qJKf{0b^6WnoA4iTyl)HO z6HH0x+`Ywo#$P8wnK$Kzm32o zo!p>2#jk19u420kKYn<|4IOW92rMK=#kVhUEgyS(q^iXBB6qP1iQ8z~H%))&Udf?8 zS4Pec594l`P4$wj3ke+-Jlwzhn~lmKA(wh=K7j3vaS9ePV_%|>dbJ0YLNWxAUFz{{ zZ$WBt;f>*)EZ+_<&YaUHiVcoY_bOJww)T+ zLK&r_*m^g3TsO+$i~oZA;*eu>_|V;by*yv|llyzi^{w?Ap}*svnQ2qDfV!{%4Vvf) zdcH5mT%EQ#ZLsS!jB8IJ6Q-j17aCRVf_>$Gh{L_DwfIgpFkw7C>_va71}8y=N{Iwe zZPxuQjIWDZ3TQkFtnHj zub3VQ`Zdx;y2oE3hsBApKrYXFicUC`i9eDYJ+5r6&=iyzStiRAg5!Qy9`LR^tKXU(1$oSfO^3B(Oq_p<_sLSfH>SA>T@8vgI#o64e=ACDlQ$s&JWDr{yb=>nT!KMV8qL#pYokQHTC zS??;d=}PKC5PpnnupT~U#=jb~W9qUn`{oE42SVa-`ltb2Yz^Q+fK$xs^O4+7mp2Ad zC;bra^%efSJAf#fL+($n&k?E{g;k-s4XEz^Fn$WSb8}4&v`#!cQodZ%_poQCGLTuO zR%EbG}Ib<&CeT%L!x%b!xDp4O+#Pn;sAG|t*_oPcJ7Rc z>$X>|1oA6#J=9aWyfTpRR(AZUVsSUCgbH^B@s|uGpo3w1q?|b(T{c@uB75C>Yhu5ip0I!6ksy;rvhS4ZbWf(9{E8Nd#<6=IHxn;b% z0pB8gJUMe5iRsbbw5ICB=k6w}bR_pE>PnN)_hYpqO=LJM&&*UYDSJNMKcmmbg7Epq zIGcVfz+5+5;vn708ptxc%7ZX}<#zniFHk%_JeUuZVa!Igi)IloM;B{NDFkR*~Z|!SAncC>2@-i+?3*55eA7IkxHd*NA)n5TDK4VSJZf zfA8O8Z9duWxxZ$RH$U78_KXs2H z#mpe-ex@b=5cJZ=ynfNsy%$H>XOFr0>4Mz31^}aGFhm+&h$~7in@Le@9xO~*{dYRu zH?x9bHTZ*2L@J<6sX&DX%C=PJ1`M8G0AC1GEK$-S(PB_RP1f&3i!VzOoD7RLM`yas zIVf+vV!vAC|K}r=WcP}~dqIg;?CwF@h|n-T3ylKL30lLJD0~eVuPb?VNFX-(i>0}A zBw4yho^;p@dj+S;u=b0$qr4ymhHQ(_mm2ugD0fHh+puYQg43 z$@Nh6(CN>Y2YbaWz%*}-#V&Y+lWur(cMjrID`rQ8+j;?i?FGYNH+;UW#q5*-Dkjdx za!DB+A0KOvi|sE4fII%C18EGWbafEKxjNYc3LgFUgFuPf=vdDcx|II602$CLl<%Rs z*~j07*POb37fQoY!fhN^1Ck}AXIJ55O9p-85jd3Z=oYOLT^Ip|=Iedz>ZWGU$`8Av zcRh+2NQPWO3*!^G!~x0ulI{Uh42|ORwcf{xwn0-CXt#9jE0MO(NxBaKNb~i$c&{vP z#mCaiWizZ5O7VM?7l|>X*kVF!)^T9{2IHP$dcH^#?v{kjV;Iz^k0%_e-*bHcV*i4S zUC*ET`Jmce`azpr;ZlLDtfI@VfFYZYe81`|>q6!rhbobEME|UH-c@rXkO?(#44WEL zUQQ4@<$#;~Lqn|ovHWQVWLQFfBe^+RY)B(;0k$b9i}WnS44G~|$%lKnP%W;zVn>V; z?nWBIivpn}yYo{+9EMLL2Z2Awe85BBu?5@Ap)l;l(`4mSH@zgCef)#sfC+p5wFQk6 zk*Lth%d^i`Y5RiQL1lYXVdQ)d^R(K)K$c|IrE%3W1Pnd?vtM$otxK0~O(E345grvv z_Uow>_Y^Au;w`(3s)c!cIL%+)o;^n8Moj~(z>8> zTV~u(CdQ>87UE9>6;s`@&rPuxrwndJy(*^l>2qWWGRA8JVN`qY=fn`+&TRC1KeF?4 z&px(@IqAe?5P%xMygm2z>!+tx+}_#Grq_uOMW~STs{Pyc?&(oWTQFU2>gR95iF;hx zzk?n$`j(2E>$KTrRH*?{hey`*`_L#(N;l+2*#H(JnKD+Kq zA(o!K^!ne${>@#l7vap9{qC8jXxpw+s=)hlEks#IHY495ahjJ0_L<%!8ouUxN)^aE zPGg)Xh*tdpun+r1f?ssnORRW!Q3=2|RCVYM$k&muDT8&&F2BS_RiYf3WJ~68%_&G% zPWPqo4tpJ*HvSxX$(fun1wZHzxpjbDaB0;6&lr!#BFK(Z<@doM51K`C#fb%ZowA9C z-cEaYh0%JE!Q=g{F!ZAI(3i7_^Z-@1#Or>aGYJ6m;q|dSIZP|>ABIU&kcD6 zRay&x+DJqzs=a+hwi$1HPhD~5hu?mo19Gz2?YHkDuj0PNj@fc{!1a))0AmoE`VY~D ze_VLnv`VhEhue=A@;LYFVK*}tFT)(k&0$~Ydt5o+n8e}hOM2^dkdUwT8bTKT_=u*h zkRN?^VUKqTnXSNbX=X|bvW;P4>sd1QZO#@IY#+_?*{`<48(&nZA=KonBLqgG1F;B{ zbX=iM*1KxvQ1m?asR;#X4sCLmjRF!l4uhnRNql%lK;@ioD-1tMSjK#A^mhqSvBSXW z7LFpZvp)7siyGw&Dm;H>q)*Zwl%JDrT8YC4NXTR8ZpLMN>>WObI8IVRul6$$z3<`r z@p;L+q0JcDZ|$hJPyu}*L-~!D9r@T_`<8tr=T0khqn~MQfIIF+fdN2IFr+JXUo6r^SVZ3XiI)OUy3!LQO@du9DBZ%*% zG*^Gp2jTJu$!EwI1P)R|Xxn!!MlSqc`KR@JM1P!FiChdmXN5@V6u1}am#iCUK`fj4 zqF#qyeB#rraf~0oe{=R9>yL)q9&AN0*|WY{8iQ{`kSj)#Y=X5{AMsW>*GANz4$S$J zz@O*_fwp4@jVjn?Jy=%Sx3I@E5Z_`)Okdp5lY1uSqwOgHgexxExR(KVPT%|b(UqVY zVtG0IO945M!|XuFF`lXYU}%s+`@xlX&#(__n;Tp6NHU z-C@Z7J+lfZF5k;N{qQ)2Pz68DPngi7^5tYkd^UZepP9*Xn*1bKApT*7fHCQgauCD5 zcHeU_st@4xCmA*T_cFm%LGrm8$mB$vQoRVdiu#h$6asNS%qcF#~{u@y|cBAM| zXp;;ub?`zKs#TkNUyb&hS(oMe`mT4E(9DPUq%t0@IX=v_@}}1i!l_O$;(&w8FyW2- z$I^8zsj5WLUm}M`5CH>Gl<+1|Q31*F^>_80TQxP~pdvOMcJI9cso0`(sw{s~Zf`Af zFoFBhnAhS#jgx0fEyKZiGVg~WSBY5>tP_KcfbRf-lxECOs;U?N$ab|^_j_K9q%W#+ z_}8hzY!^ei{C*ApghJR0_lBDE3XtQ8J)2X-`7vInAf?!%%=@-s`DI*D_5o7q!=H_J z96XYU%OEED_{-imC)M!%fE{CHfsVG2U2g$I3x4`Sg5$?H6b+RATsBS)T;@a#nLQW{5!p8zZBaXMu|b%Pdy6CiJ*3t*N9iqvwI z3nX&4za6j;{D~0aJh=q)64~_l^tqn}`08Y#?JAjVBwH4+5C{4HXL;@$5%$z$C z6DOE9i)+(|XNNlB`X!Jmy(R{3WIlNaCHZzOoLD#^EuVc9bohUlg^-Yl@Q4k%cqn41Dd8WFn$e5Y z-%EsO{|@CW9E2jQIis_$%ulU8+GAEKXzCJwk;!2~GFO=+{rj0wRLLbAvSE@y~ZLE4F6? zRg2r= zItyz&(A$@7a>f1AUvM<85Y`1{ZwvgJha)5om50p`>PATdC{IDFRPw%_a7N(=o{D;` z3x}Iq;qIxghKVat6uA@{Jdq@kn>deCIje<6An8wFFR&fxs>O`at4- zb}vtIfeRlE(I6#%;_#=x0dbyi&AJSc4m=-&M|l8hmU%AmzMp$NtoFw5oAZI8{QAD* zhFgW(16(6*-~X!BmFw`upR_^Km~nCADe3W^=kR(nQQ%NM1H9J?XK6XiB5%t{#{N+H zk9K-L>7)+b^9f00S?TKDq4d4w@@~6np9pz57*5Bwu^(63sxYJOaC-K}tHc3ZtiN#_SB14u)cL=k&;)wZ4Z!B)iZqxx%XuHW_ zsUIc9b|Rma(yzmwN_>$?#|P#p#~3CSdZc@Cyh?V(WPj5H&M>L3ge;aA0m6n+4*#b_ zb{zN0iOmGLeV$;2aI@9X9;d(UTd`WOKEuJiD~b6eD5L5MGL^wZ}&%Vt=58!)QL>$S1)*=J&@Lh zEbY)=NxPbG8%Mjk1D`g0carDc{z4EXGrsN{!v42u)ny>D&+bEc4#(|4b+7l{YOdMt z>C*CL^JaD$#cVeQCIYX=aK4^S4BTdwD?ae@9Jpn;bRsOOa+%%y34|So#_mI$wGb=XVc4zG<1lNhF$f%t2{i__@q6Z7m9*#IVE=7+%=@&fB?%6fu4Kl` z%csh-(cvw3vlomnb-MmwEuJ7LAjt0%TtRd&w^XlgnCc$)6U{_C)lF|IRiyO;xZOjd zJiV+>w{TbVlC(R<%L9`b5l?1*@T$JhK7WG~z%?@7-ie=$&N5>0ZQS-{mzA^IpE@wl z?$pWMuebN@r-<^<+{pCoFV|xD1H^yhl%GUz3!h00TrsR$|FsPANJ%l-gdXU zTXOm=3H%52D{Fd}&`JboMJRA(Q;+^0$}2C*q?(V;uaMkD%Rz-r{0d~Usgsi2H!|Jd zhZ(Uw>Dn5^VG4|P7W_}>V$b2!>ea95F0D`=xeJ(s8pFC(KMme4!!oWW=;1nuJ9A>u z=@+o1P@hgx09Ducu-wYqg8{4e+3i!jtgOwMnH3UVAjBiFz|1XYDD!<@Sypmla&u!+ zC{T^(G*6FH*^}wt6l)T?i*wET=o4hDs=toTDBsAhR%mct;9u`x9H|M; zt4|5Uw6*kb{heNya$$KqAy+4dorlvb@{QhpsJD2vjcoYs&At`p1a{+n22J0)B)r-6 zOs)1Ti zN$CXN2)Xs)kgO{&8Z2hv>il-MiR?IUc#eld4*mE!Pm@R>c0<}oSnPS48h5B}_) zuSPq=po6>vKmBrh{59E7yP(4q!J~15S!T`JpeNmIxXdrtCo{NR`KKk)oqgv_3kI?mXV8w|e?DzQ3kaPzBS&gs@ z;QLctUW1*%v{39Oga1!Z}ew4PxXT_sb^z+ zvHLC^NPWr^Cl_)kkvEkcSKviy%;L;AR-dm| zC&T#CQ-4(7WFhSb<5gs(vOyufgo4)xdNt+9gV5Vpcem!n-Jj|ju473-V01^LgNDQk z8IPHRjPoXBW(c3BKHKd6^y#E~OBEIeSDRz7TdS7cu@yj|P)dU{(VLq4yNC2+wq&Uj zy<0;ZN=TY+I~eB4Z%5n>4P1FibHnEM6NKM$|3MLsaa`^-Z*wSR75rYFvEeSW+r}g zXc99cjE0Nc;02)>qpY-xGw6awVq$X^e4-t45|kOO@CbIZQcjP!S$V^EV*f7q>vz$7rGn!wgyBt7veG7MCOTAJ1B|R6%QpeVFeV2=zTd=x*!@ZeC1PL3Zdtd-!OD1bSH=`=xX#b{?-0S&2hY3r@m21|HiwLSN!@?c*@u$e%8jQJHN=o|2w8SR@=_x+yL;b7 z#hN8YT?3x(E!TI@=6kpCL`o7VOW}CD8Sgj-rBf-!qjT3S&ct@iZXYpK15qb{(jd;t~vL(o27Px{;pPe-D_0qE)- zOc!2q0Tp8%E=#DG+tG9pdacnl$>m!ABYDYgI$2lPss&FZkx*0raJ*Hr+o`f327_;t z7gupAKOj3d$ZgAvu-}^&OJbC3>bY!JGHp3uQv9!a;ryi)9*P+O*w}N2LZ~c1e7e6q z;2lea+3OAGiq4u!>vg+M+}j`S9|430>M_Rqvb~a(&fbjJ?11OiR$0G5pW%6n_+1Eg zd`{-n>hR=H`T3j8P@N|in84C$T$-+TNsu&6T+H<_D>W7xuYX>anFhSa-SIN_Cf(H) zmgY~hqsMLs^HM9r(f$)jWbmJ7XqEBP$}D4ye_vO*gq#Mj7I>fe7j|&#a)bS~>SoeB z{N+x87fy*AETsO9<@sA^*sNr*69CE(?*hUOzX4&w={Be8WAl1>BY6wvPu*)LEgO=1 zqd(UV%xeNiveX2IS1ycoYw<(AFCbec-JKtJNY3`Rr?L6JPKh(pXfd_0L#UTEL{UXw zfAG1K&LdnTWd^&bd9*t+_nl7e;n_>qK&yMNMqs2D3J@gyQx{ggK-L>>s(4wBDTV|< zubjkA$@(ar4Png>f!nS?S)RQlBfmoXjnwlH>zt(ZWr4XXWx6 zO*^2Lb+%1kYLe@32~yFtay@@-;2TMlwx(-vaRc85Ph(LU z(GsIJDeh0b_>r#G6lhvdqu_olg)J-+8aQv^2>W@6O;OfSUt}Qj%#Hb|N^*tx*%uRD z;l6j!h%kSuy-kiQoy3L~$$DR1xG|E7rpdttJ9@#>_jej5@Hc)>%c{fHs zx7#tnfY-No3bcgfmni-iqk35fv7*qzrLLsoPWhSbtSIK8w0pHXy$=3T% zJb6I@R7P5E>(^(lU3G&G@V#O=%>8B59pq{e7h{^;k+!SriQG^}4li(cU0Ad5@>B%~ zw`Z>*5n-3t6mUdZc;wO~PJx4k>rEZePC4Ll7+6Ueli^v zE}*Z)?qnK>k#xn{D87ou^=Ifx)O;F7+2m5o_WrQ1?emVFW-mUz=iE0Chx(OV)6~<> z3bbopO=-i*iTOUM`BUm|qUa#qCk^_OljGN~sCH1W!(!SI=>qC{FXm`jCt%CUWCQ>F ztT5=__3qchf(}vLk#+a1{gN=KRWMT5FPU$iTnI_livdQggM#ntWgLf;y3+8a$FqOL zW4YLTc}Irh>p9Pnbv{jBd}&iWL|IX`3%Ou{zaNZGVY!pxh^1+viem7B=MCVK-2m z;S!||MM!OrPFB7rNLYE_5z;gL3l@d&6H?`1o12FoexvA`uNljE7Cg*^Kh!Cz@V{^W zc`WI)U1RS=kGu5Lx(8Pax&iJu=~b;BeNUE-d)Goeo)zp2 zzUnvBaOW3{+`b{X!QwA~h4~Py(KtUmDW~>O|CiE_HPU};o5}Kg<0LlraLpcua9VzX zb)WN~R+a40MxSmi?*gbc-N>xgFev7$qYD)t8y-PW>^Pp@EtL-!sWFjXK>^Gg$O?Mw zSl8guzekl!PRmh`BFlLZL?mM3OHnRa)%hDNML+1O!S704kzt26HY<%CrWU<$1Dr=6 zToyG`Kl{ZXhg6fA?62BrozKR7dB!Bj#E-RmbaYJ{ZAZ7|OF7b9bW`WW6bG_4D~h+I zR`&#RFxl9nX=d=uAzzL3?*KVi&`L@^jp?#wwE>h?kvGQ_%8fgcjfxg^rvMc$#*e#8 z78_RkWLe=EP`_ur99chJbRh{r!VFWfIGO*|MiI59$zGr0Di+Ap;HlzRo8!>6y`rBG z!Eg_UBpO%=rskJ?c+iG%Ef=df85@^>I*#W3s$xtt#VHvvZ^_Ob?exP2M&jA z5FT%J1H+Y+e5dm$UMLc_wf;g;CpxvZ6k41CF!cf4^R%zkgD+K|VeGOi9vy%EB!{@5 z94QQT$XVTia@iSiSwm2a^j)``c(S<1Y3|lvS=@L)mhiul<&ML(wQz`v^J{fU3Ja9{ z(ujXP9EhclYrespc_RG|840=I3atAokP7+y^f%|$z56m`hS4p?&}yu-R-f2B(1Lk8 zCtF}6bK*h}NDlmm2W4mdTHQ5cYAJ2^nQt@TSQDZH>OAT0kA-Ip_4`aD)dYj-^3Hvb z9?tk2LP>uORW0!fcV*MF_Ca}Im#f%)x$>Jl9-U%ptbXdH(dxc60k=GM&?`HekIi9` zird|pOV53KnzW|}vavQY)aoZF1n{2LM?F5VG_(u-zKt+ge%G+^VX;GyYrke4w~?w? zj1w9RyvVK@a%*#|55*lMo6Uhzx~e%CIlPZEsxCJe03LqV%t!qO!pY34K3 zx7E9g{QNG$3fVU3$e+SLUc#|Z>J858+gUl4A@GSZd%|=&^>OrPSks9l2cx@}9n{dI zN9@|8F{_u|=kTDWs0eUD5U+o~ZlRe;wJX9#;h4rOn~bxkL_N@wP_owSJ3MZZN4LL1 z|Ci5xzbAA~-%j`wGX(cU##9yb9GZK%hk?E2Q*tk_TYlZfdnqtg%6~nckt*TzeQHPV zZv07C={eG3yPG#!gF8Vk2d;$iiiK-l67cc8v6kI&%A_t<%=BrR+Djkb?EhraFoDaz|}aZGoxn{^la z#}Ra;x-Yp}rIB35<693`FrvYw2KG&ND|UUk{paEjIkuG$SJMuk6fC2JJGrX43Lxui zKTSI^D4p8H19UF312G(4F5Z05`ok7KpP#PSafAS&EBhobw^;GiLV z=UQv*=Lp1)c3`SA4~CTe436doji++GLQiRTl=fP6RRo}a)%J_MjTSUa$>2m!ESNZD zLvnz6=98s}JovpMZNza9V#spxa3&mu-&rnu8ueGp4HW@u9OvZ?>>VgMEk>v=3$|!e zhh@p_csYT){{g(Wc4BE3zb0KNPRvZl)?w?Nq1?kS+X(NRUU7avc^)^`Dw`KQ7j*4J zUu!QbwgkihEeu9xH6|GVyHMjdOV&+!`D0z|&wPAW`U4~*F)6BnJI34NXB#V*`=9wZ zWaDIC#G?LeBeZ%eDTb_oF*UdnH zq`|bfJ!Fl^H^)+&5)50NEz!|*mzIEi7!Lc-E13>3?xG%0yE@?{PYZ%XD>GA{EBATH zJghJZeK>n~6P{fl@7u;Oj^=GZ3+`lP8(Y%qhF0ViC-A=>y9F*gcM|n>kzEwXlblhT zUnqTtw`1Sk$~0b~4~rPplIy-`>1M#|Ae^=#X- zCK+&|}7J32SnMm!;=DK8*){R!=@2lkUch)v*wbZg&$W18QFsZ_jRVYYo4@|N^Z zg>Q~FRwmKLY*7ElZH zUf&jyrC0B{erX{Aj5P>4E%haO_h$XEzgu{QsXEV(S6>_M zoc{15c&yYA71;r!xU7x|blMKJC|%R81!&=V8o*T?*STq2=!%Pw-Zr~^6wBfza!K_L zlvnWVMAZ*K_^q^X+Ybp7kMdj2?>X%>?ia>!4Buv+R#HKX=NXzehI$kp(Gd3vX@b$>;M>qm8Ce5_N?9fA z0?nNnM#@VtckBzhFLhyH(Ex_G%UrL(u8`RH+_t|med)Oo7<)a?S?K`__&X3#%6Gt9 z_}~Sj2e1j-{ZkW>p%WoEn6X%ZG3@oMC6lO053F3Ti3`OwC?kwMf2{Pw#o5LY5(1B< z2g8B^XU0 zlZ-z-=fh3dJ%E?ogN4I6k7M*aCib_1f&58((W!BCqj>j3#YS6%w_ChnPEMtI77%6SOgy{$Wt_??boj_mn$hknpG@G;2EUw2WQsEXXKV~01! z?Qyw3(vhrH-_<@loGUoDe(X;q%;iYrE@KkFY#8Lt%sFLaUZ+&tr2m~T_0mi5n&ONd z))tY=X0R@R@M*ltH9G#ldahtBk3xdMu;$9zWA~e*9L-jTj(_}J(?Kd-M5S2s&;vLelhrLjy;J$s3Kf-OU>=txxkPe};B-r}expUac4< z?Af+KmXym+0~pXoqOki(VzY$=KKwAx5Fz59A|*n}X(xB8^1j6*7kyY;nJ?KAFVwaC zc0rmgex!+o8w&fNYN7Xl733=jU#~ z6pe&*dPM{1%`P}Kom9~8vz@|c?s^{8@>-jay}K-vM3$D3f|y50K~l@9gy)VU%S2au zZgsvCEV4KnR%Pd%y~3tAkAC7#=AYQ=fKr^M<}VOb=z;c2*Z z+8jY1hUw~yCTmmbqKz+%1^9x053xbtfF(5O6}Jjp4&w0LVndawri zrfsc5BU5HxKZi@mA**&)A6fMoy)Z0n<1zX07^=U?>71x!9ONh66pZ+|gF}*Xjr zfzP=7{dDYH$NQ<$Y@1Ap@iPI)e%9QSHFw$vK5Y=3clM!wI_Z(1E#ry1`R1+{*Wl>O zdb(Sv0XnQ}F$#)EZpj-XXh%GC*CGGSfkazICBtwt+wTSK^Ik5egNEw4^!+e)D_#fI zyI->J&lFn10))y>m*$87-N7hwJx{D77 zir=`iAXZGDpi6LSA19>`A1BWMJpQ%%`}^p0L};1V8+FpVP= z(b(NXSq1Ur`0niw^~lL5;Oh+B=`*_5IRyO&SfH1N68hb5=!JhX*i|@cz=4_R*<{Dw zKlWHE)G&`uRnZ8se(c#`4`?Fh_^Oh7)OeuTInyP}qKb024t?5h0+|@ay3$CgN0)zJ z0UQO{OlazT`@^K_W0|>j4>Ow;`p3AE3yARaJgSmL`cpg*mN-BEQyEBr`+7AEl+&+L z!vGBPM+zkO1L$++4Njd(uHym@Tw*A2P`&?Jsr1>~6oz^mGrM#Yj_}76_pgoAmG%U7 z)ge+)4eq2OIaL8+?yw!?@qTLmr4S;i)_eTnoK50h;EF8z=t{sOB`D7JooZ&XE&-TS zO?Dbtzvsgoqpjg<#VpN1i=kBylTIpgw)F~P9({UZ8PF++7?a@Z=+H>Rb&RG1;%iqU zHQe3cI-_F5)b?;nCM&!m5(y0N{c=?c(&DE2`MR1{ydU9eF~i}bUOhmYx!uQ?0L^w8 zxal?&(PvR%y%E0*rrGVhfPB@PS$+Y?TC#_ZkOxLr*a1fue%hTQtf>BCSQi2 zlVVyw$rn@_h4cOA3nDvLVxuH-=Y7epHL22#rf$oy)5Sa^>M` z<*2$azzVz{Ii!7QD~6=Be8z-5>%0T>$x2W7aWWspH!JRwE*W&`Tabz2S`#L zZ2NaijUCK+pdV~yPkr~S?f`1Rqj%4T5q;ryH9-2nZj)l{r^-snZNFNvd*p>*D&DNI zXD0X(Fi|wuX$AtL2l+Auc%tuY7r)>pr74^mcM*He08~4faKotwkdvQz9XJ&=sJn@y z_DT;I(xHNBG5^JPzQ2W}JF>4LF@oc6$IwmQeiItHk~BCG`HeRzDS?J&Sa3(`shtxy zZ($@e?su60k;Lc8Ss~mMh zpfW4Z%TZFs8;F}D{MbJgZMneXNn<<8h-Cr6RgfD-2JdUdQhDisuxS_uOF3!yee>&h z$Tx>ho?NvSeD){BcEWSK!G3lV=IxuloF+E-@*dIW45J5>@oqd^AW_snU zAR{viS-0>rNGsiycM022oxd5DIF`rd8}+Y|tzVPM1kww%;|3~!HgqEJ2LAId`yTF# zC!#ODJ>x5x0mqH>{*nb;=gTxrcWUap^S&?bfwo_pyqoo?ga{*9#w^$%;I-7#$3J*5 zb0bEQzP^GfY9I>MYBdZFm%J+A2B7`rnrfGi$N7~Te!~uct`Ct>ByRJ1KID5S35Nm> zJ)YIXFqy&yUdc%>DS9_{3d?mWuk%|2PuPP-1l<*Er3H@>ZcWVc{<7r7z={4b#mXtN z3Jtpss4~odWBp^GF7$owb1r`0qw5yrKiO}t{UJ0Tk+5pLdGaU~ViXUpY@2Twtj0RE z;0RS6$na$CgzZXsowN>?JY<#XP|3@mXt_g6HZM@#3P7CH$;~(DBgFoo8sSQOLx|Jr zd09zljgiduMFblne66MHquVwXLIygt0|;8ZTam$Dm;P9@{*m0-GV0HEEn5*!112qz zdHOe$Po#mB_C}7Lwj_LzBBl zTlX>EnLM>i*-P^X7CRhuet>IF?MOpsdh<6{nC%XQ{eq>=;7Z2xw{Oq6 z!`^>y@0D4n#g4Z&-Hi1$VAP4BL@BC{n8}r@3wx!7t)bIS(4^8V2KcKq8)tTWLhe@X znj5n_38Xn!c%Z;>cPmHf!d!0mZotx$-=5uZ4QT%YF5ru|)wIo5cvEZB9;Pp(*~^sx zY$3E*kDF0FABLGR_?D5WEbmp?J~r8J%~@@Ztmyj7CUJ@oL?Q2n$JAM`S=1kBZthfQ0KO69zZ&>l{O#93$lR6S)mPBm*Srf z%#wk@GPj#hse>7<*nz;Iy!gVSahC%~>wS@u55i>*?pC8uNAnCGL<*`GT>H4=b4Bm^ zxhHwZLglGxPo{P*_Q^*7BP-ZJVjCRy+bSl<@;Hyjx_Q(v63Y zm?Pcy0(X@KddZKHKvoI}P4RcQT|jB^2qU};HJvRN+#Xwhs;Aw4V~g4^7B?w@aDC~g zfHE(pfp30tBzRZu82i1P#rU{g-NG=V)97p7?GxP;uS%`cQIdC(eIXMLHTC zJCREx{cU+MqsQ~*@1En3x@W0NC&^F~_8W)>$oE%!sHI*R-@E46lSxGh;}1ahw>q|@ zM1Fn`u5*&?@ehi|m)FPit)(Na`SHq*r!cnLvo(f25$mq!Pm&2d-`g*40zP{$M;QF|*Dqsd(^|jCUa>R5 z2!qANGkKB3OfyC0?J^}Sy2efdT!4lm?W8NFj0H?p@;+DpM0EA@^>;^(_YZ}6T}Zt& zJ@?ki6!ztnPun-sj;I5i?@sZDRshuFAWCGfZ7p*G#%6&;6 zAYWn~#W@0thvD0I)Y;=_omkx5bnA5}Q^RbwMvBrA!GJA?&AsmIp zKJTb|R$?b?%MQ(cc{pOaBZolWFOti zZ^Kf6crx9d1`a7UKufuwm9lI*nF_1lv?NDr@_zSEC+LuieOlfM$lvu(_U8odT9L5Y z?jW|kcS|oLZfZ(9U3glq@De-!+N^|tS=mV)pebgzdBFo@mFuuUrW5#158 zwMv`g{?H23()SQfvFg7C#i?7*8vo2tYzjyiVA4P&npS`OVkeF!>rlD0D5FjQql@!% z_{pj_XgRfbL0KRMt}_?Uq@Suc;c5fI>mbN?+VJ-{?_0m$d8g!PGJECbef)l%uPp?0 z@>?-lLY)7EJH{elpSVlKZ_ZuJ<_`P#d3;KXKt|&5%tgIUEe|=k>>=Kq+!ufW4;m~t zWdk!4z`c1l87(-b{z2>1Ukv5Cjf-nzYcIt;k&eYxy{Aw->LCHClUxml*ct`v7nTOK zP_>UxrwA_oG|1MZsuVR}aX$|cmh<~VVwGky53G-ATI#17|*xq(k{Rob$^^%+{vFzr)+AXYmE00rmzG zD=Ry*G(ut8G`;q=3R1hb!ud*>D1oTyEU%SN2O=(RC$7KsDdlC9x!>p#jum*VIN#yb zWEoN}`9_P%m-sU1<7wfhRSZ+6(aQuX;(qBwb5TED^0P$TsAgn>q33xMhZ{ ztdJkW$_N;LPi@sR{meM$=luSfqE%3T%Bp08go07SpJ zui!o1#N#VmOL}ZUEO1|KU-#AkoVcH^agKecl;G_%zfES@YHkSysv`-vIDju^CIcP1 zJ26mVj&l^~2dEhANzcq44@uq|5G5v1NkG6mwS-~gb^WaI;{_5hUUNLp?OIHm8fm<& z=~Qn{p|6!+%2Lm{7AIa)0z7`hxZ_|=<1sI&H0>e-5Ncn}Q%QWSB*tT;lyaMFVcoib zbl6>9-}amu$(Zn%12-_4f~VKw;|ib|-mV*xmcVc$_gUsRGefD1+<#~z9sx7OQ9T^a zGZ>Ls>(55{JJ>0%R`tj-D20cFJGqtNHu@`ce!D8 zk)7cCyn5ChNl=mAq*RCqzjgT9mOM=}h7Ujl ziN`0_`hLv8t+>$QQn~Y?5FpniqQk412O!@s>=-8TohA?{%MP!WRFpk7i!HU$3duvo zO5o9vrd!a+2fMv!{pa?YQo)!o2kYfhfqGRxBSKMEL!B>KP!|N7Eae=xK5!5L0f`1J z65~2aWkzo#@Ayd&40NhRP<`WIX#DBoJ~SwCA!M{oEQ$lBFuWf7WmBfA+%_G=*)-(0hap z(^{x4+sppRGiOoGg~2MO=arCKDol$-5<5UEn?2LB+B;$}x#y>}AuWRAfHt*fd2QF{ z@9-rnQ~o_S_s4-fG4(>9rYPG*NsFkOyf)j2#*=Edf*8F;S7=%h6gaqc=B{Dw1fZR` z5+4S&fpNJHC%`~tHws_+D#!=uce5r3Pf;p$Lxq+gCQjj{&g-TThhBB}qTf;lO4qBf zsza+?7tL{m7P=c?re0mSGay!%FH{w7Dx`Mq!-009<&p%KHvAwa|H`*WaKLG+(i{$1 z+A&dnuP$}%0uYH)e(yH2AP_tFkMwqf!!}LNhC$7j3}wd5h55Y}!SB-kNqi*V%Ai3b z+rL)|DrxffkLgJXN7A{P1}44B!RMUW_n1ap>rP88+nb-1_EvA6xg2;d5s*5Qa-ceO zKTFexm9G1!DNL^MkE(V{!{C*#cH`cfGJi+&UF@K;aom8e>yL+u-i7(Q_O4!mVY1>^Tz(U^C9|n) zYN;65GQn=`m`DX6|-CMYkaciO@>RiXs zS&{41xn{q<%QFR;_XH;77~q9WX&J-YZsWyI%EYAoex>a}|0Y_W5c<3IM>1a|gH&1> z$(y@55U-EhscSo?6i-lhkfGhl^KTZOdKy5q3-`6aP=F@I9}yLA!3oqP!yFY`Wfb<#yBctF?a{;-|PBhgC6EM>(9-x0iX-X%Q7JZ$)H4 z{ga8DDsxW|{mZBOX*ZrtJ=q5kA@cW^Lkq$8C4TKjQ?2~xvsJ$R7j$}j4jJzf`nM{U ztP4XOEC_lokHS+)3#nwyZz-}&3Aq|kJUb@dp=bQ|gZAoLl@lqvU=mgj2(f;@3HA(J z<~pXNk{Aic{a6y0ym;C1_ zc+CFE!YGC`1OnKp7HM>etg=qnfL(_Nc&BZZ6*aZEdxr4sz%Oii#?|FVY_+2qSSnX68^h{8$nd^**2Tu^DRrasDw%jwh#Z___<54Y_s2#&iTEx&)$C# zte3NebFAH!cBjI6!~29p>KObiH>2~T6P+c4noAN}sHqC=69}I&mxDF4<>URU2I}F) zZ%Ce+=i><5(zD`BC(?3aM_S0jFMW_vq72*;P6#+OsUo+MGmDIYRl89i$e9oYKP+J6 zIN6@Kq<=lgY0&g~SyG7EB&|7+Wkmm-8e~#fIMstm*tiv`hN>s@hVHw8S_upz{pWsW&8BY|i zATe~-$v#>EmVjN^LMC<<`a)W`K(?ma%w^585FA9PyWGJQjQ$`v__9y(8d0qKY;@KY z{C&J{$BRPUme|ON^`WfcvCd^p(eMvLjIyl8M1jt3~xOlG!Xc-(EZA5LL?1 z4?EFIJd@gYUzp9sAY_ZDckqV%_3ObH_N@a7NGng8yoY5=L7ko35w${RcihC^HL6eG zg{DY9D5Q;d0+~~!&pa_VJW|iD;YB{_3dW8s18JL{U$(Y(PoU&CFEVkuw46 zC>f=}pS~wKw&$g>%Ut=8){|fEawO{(M+3~0h?+zC>UM@D*Iy@C>g*Y%sef7H1L=gv zKRz;QodP_${%}en?atM16Gvd9?N7jxvm({U?XT!SA^y|Fp5+dfhvFdyu*%93E|oL} zmUpy~YJ8>f9AsgHzInN3Uh?qPF9O4Tcy2E9<@18BVfTfkkY5|u4V1+2ZmPX}Vv$dc z_y9op1uH|mqd>Y+(?h0UyEw+Cc)iu1*v32}!w4b>8tn;3Ulz$gmB63z!2w`oA0Vhw zpUYX>tq%eeY)S7G{-)LrfK#5d-s^{oWV3%3v^z*4CZfA?E_YC%9@|ORJagZSvau}& z6B#sWuGIK2k1YLRs0#)aa+^-)XKg$uAU%+aDc)KXK;+38(oKR;nQ$v}IYpFs#-7 zy|U$&-SCh;$Lqt2z8y2^l~~?jP~e+nE@k3bgT}52Wf_Lg?D+`|MZjzDA=&R1*_1i6 zZU(#-`AP+J{peoGZ>6NZIbN2tnj)KWJS9T&VxLdz#7wh>9trhfGM?Z6FYGq#WXL(i zYK18co~Fl1fcD)3I=a+ppD23uyo~yf=JU2>L1E*|x-~VRqfhHM>8}Fk8Mhy0N=^KG z?|bG-rqfHhTBbZKT7#CtIpLX!MOFV(P$7eK-AID0{6G|DNU1Is)@ZFEue)DBn{WEqAsvOtUM!by5bYFfiIPxb5JTcD|7!z!JlLy!4 z!oy42Z>p7HNp??q2?Rg>aC>(vNOVkLg@9_iLUq3gi0Ki~590h^d$xZ)#WP+HnfemV*zOV0aM?ZH>!UK8<7ifkhrkDtC0y~poB ztNo6w0|MaVxv`79TOsVJ2v{}!8+4b(How+{`fS-NgVUzGMrK;F;HcgX5-!bUkZPZO zCEELXAM00kb;>h|D;6MMfAHcSQ`#?LCVKmL%LP=FQ@b~y)!*#H3!;jXl@2e6^SigK zJ45bxTTG96K-bj+h~UiK|L%F(>va4{zP&S6o;9ONI5oas@AKU=u57MJRiyt zN4kUvA3($`-T6pSwCt&yN3gy(6t5W~RA#t1uws(cO5_{M;lOlm5;W(S|7 z$!8yIPf_W8%@32(PVDUx#B)Qs>+8&7(-er#hU$Nif)E-}GsEyAw60_C!e8pcMD>U-D$oYfJG^PxXX$$j$5ZD2`F+2O{mfcrwFTB9PUdVck9^bFvb@CW zMRk$tH7wo{nHyhFnC3cCD^#6t{qkbpygi|o82U5DHhqpbz)A{Q@QDO z#ByCL#vH|(n-NM8lvb*Cpli}7_cMM7p`YhxXN~FbU2_=Q`)kV;Tb0)N5I6i5aix}x zPuH-p4;5TZdzHWZfyWe{C_yvzHPZ2Vol>T7$`AJn2^DEloqWqJ!+FTi6XiW^ORyA$ zed<2UBV@&|6|P+wj>%JMbs!<*4^GqU3uu*i7v;H7%ggYX;4>8G zQ*?SAq}3@(X0mO2p0wrJa2`N3=V)KsHcOB-?f{vyMdld{)S)UWp38pEO*-lQZf5v= zv}QJu#g&)#1&m+OidZg_b5o5}R^F6W-Oe9F{Q^87HPhJ=g@d>4i8B05LD!>gg1-mC zeCoR6cYpv~i(m%{zAeWmVwvind3KTx-@*qhwSRf1=<)cVplV>x)#UNXFZiJeJgy?0 z^$u>@8S}vM5}6;}#msrm8~9#C&(jxg2Um~}pAe${4)#TI*ra3(D!KXKkA=+6j#Qgz z;8FGGYDJIVYdj0kr=O;cn(N<{ahU!)c!2q|{6b}Zk)K4TybS0u?X2TNe7Z;A{c`G%vn_RsX+J9xl1 zj{Dj;fGzjcCc}5*C{VvdbO0x#1|$&*=8F8J6t`8Xphxf)3j0o6X_uv3rPvwG@<6kF zB286}{L?tW$I#RGkJ1-Ulx3o7uiAPT&vMNg5A~-GTd2Y>tMQ+Y>d;7V%l^u**{(`> zies-Bih%YHjOVqvy!0Xu+8XfLW*LOV-lg^D5nwF-+i*YcizWJT#OhIr}>!CV4n$#kh{* zz%dj}`tGTh9##2xp7#Uy%}y)H(m#rRo!alw+HRea%%>CvGk9m7Nsc78L9}jC1d5O$ zL9eR+eMCSD#7nZ>+c{$`-3iF0tW53N>Tpcv2Ysnt#{ENleRZH8-+je4Mh3Q8cgbj` zsZQ4oXHXt%YcX!O1M`Hbqgnr6)tFMM;=hM|h%yj`vhHJF0(NXU3c23SToP^}ik3g3 z=u*RA>brShj~+xsn!~5@aneNrwzyG#eMX&e%&mAHYK;Zbnq9~*J)yH}4h!nG5BtM- zWUtG_(dp=nFd?Gd4nntwWuqZC@v+RX(TfLJZlAkh?Z^(o! zaO35(lG}ZP#82-CJbJQr`oKBcuGZ-eF30{kloug550?m}vig{JHhGW?Yejo(%ToJj zjG(?Ww9CMtFAR^rUA%bo$FcJpS7?3Mu6+sZZ$Ic$B+!x%8Cvl3sDP!ZA@)8)C&s7H1mw;(9FMTjU_~4fg2`W9R8f9>2PE{->TdWG->qdUI_uU_HhakWwj=l|_u%}C+Zdug z)keQdP}?yoEO;|87I2&9{>Gt!#A%T6cQ=q;kBdvK<~%p z`3%!rB9pM^v@N&y=+q#4;<&=`1L8T`l;Q2mQQEKf3|@pe6&p&0iBx!Zb@sD*^sW%$ z%|+ss4;^RI`D?SEU&l@re|7C^@2hB{v>qVDfqnK%#GyNac?xM(di>+dfoi~vpb&X6 zn(u4x`w;d8+<5O-6uQ?_^GcE>q9LXD0TwYpPURPOCp=iJ(<8?fT7ks-d*r^Rq1KdX z7flDUcoIL}sR;`jhT)-KPH>0uKyI_!yw4L)>auY) zoKvpsTg^M@&KIn*?~iU4=wq{kPR_~MrQsJ;sZS%h8;gs>oab8vE>`tejn#U zFW#xP&XaRjTn+2Z8)LJ0dyxq~>SB@bcW1dcZsc08`NDs7mQ29(Y~@F{5N~VPXXvs{ z0Q+3gJ=(6-j~`k){FMks|`g)980vl zN$UgEEN1<2lrOg+1Ryzs2Q2Qzxi`wi3-%rOXG@XAeC2C|`(*iK11FmMKdm>D`n|r^ z)Ai!0CVW59fo87yX?~+s<^DV%3XrAMq6sXs!k7!*S~feiNw6Oi_mHjibg?KZ5keVO z&4qG4RsHOo{LdEYhE=|`X~qkjmK(r7M=IBHg$~bajta++`%Z#fTk58qn36`P3DAUOSaQ5_Oj|C0=4p3qs@LLx<`)-Ob&&6{|vPx&=; zzDa4%UdWd4yx6O4YXLaOFuxoFmi|nmZFG2+Q10v4cD`@#=*--fBfxewA;ZYRG2P}T zqq(buw9C0%Q9hfVBmwcW)-}HN*|_KDrx(+4FC6ZHbKlr@Wd-J>seTNGuAix z4CFZzw^a%#B>NfyxN47jSs2T8ZtgDM;?Xet!Ty1ne-FH&-5mAJ^IW&RTEae`Z-x(A zONUN6mM()X^atF?=RG$4;^UN;=;YPP0g^$b^y&Qia zaw+54D^0b8)`W>_<@WDT4=2j2V0ABfE57s5ZoaPwE$P*t!5w!1#qlxl%tzy%k%>Ni z9T1imcnlnyABeuY`+n}Lz6g#%kKCM`qPw17!-tnt>kTMP*al3u^4D30T(7w%2h*z~F+OG?Lc{CEk; z_Zz^zSetp+BlRP-#lhgxO~sK)#ET^dmq)w~9DK;rjNt8qwxxk@0VWqO*)T9$bKun6j1uBZfNhF8O?#(@)mHQ z0URYEGsXGAUSOG(bHCJhBZ#&;EzxW;i3GuxH5`Yh6`F=!hHA^+_Q$U=kIa+ z=@q1FzTPkI3-VH@m@Sy#)e4H(a>4Iy9wRZl91aii@X}QYNlV$R_o%KD3CSg}O1=$hhXV*^#)m&`qh> zI#mlkWqZ$jxg$-s9-8H`<6~a`k%TwI}ptjXJ0uzH)6X#&%S8M;X9`cyUNj z)KY80JH%HvV+i`Ea6GI7elBZ0_ptl%h#d8s&{sGQ8YaKmacRWUttRT@=_FBk%-v7S z`qb)6Ug(>H<0+L~skiOyth&b+!EGOy=n7HV&*lX7#U}9j%wVmwY`Ouc zgd4pdEo^iqasNcPm&Fw;*iV*z?V}LMYT&1jgp2>|H_ zD4RN*83E2<(;AH2*rQ{2KYQpGu)5nKzmTP2y+=>Z-=ts)>J7v;teWis(y)GpA?~l} zgDpw~{m023k!)7IN_akgl5qlBm*zN6=a1BRnjV|0kLM2Qf^2vaoxU2DdVgs5K>3+J zg}9kT z-@MUI2uAjpJE2)~KH|n3F1Qabnua7QQcJM(2*fY z8-g3mUDfMWRV!(Uvi19QM#C5IVqdaj5#eCXfmqWH&&PKnvZ8qCCkYkg?Vew8&xd(# z59lc;Y1&ub>#~7AZm<3Q6gCTKS(YDjNbum1I$L=L)E9^2LQ&?PKxInBePaK+*?uJ-FdVwe>O-adlTi4;1?jiDurwL2Hpbs~ zsxM<7rYJ{F?rQ=k{+YjX%YB|FnA{F$e%n7Y#OCkWS=fYZGLk>+(bwVuus6ryY5Brp z2m9P@DD=lDpd(_xdsW5E(91EYn9uRMQrEM=S}+Z~D?je{eE~oP0ChZ!Lm5`LyTfR7 z7rm38hgxSn?$_P3g|cRSeM0J(rX$^s33TXyvQzX!i6!4L9dL&(x#$oqI~DpRKmOD- zj1FjGYq-ejo|njXR_b%N>N%@DLOAUye4a-5D4)`vnE7*p)Smo&{N})qua)+ywk#m? z!Y7vsS-HuA9Qe&;rXI%a^r&GeBP#wnUVv5T#G*XW4Y%N$l))sTF7UK~M<&f+rVF|| zBtNwC3f5n2V-90l^z*SNJaqc9mX@P#^R1p{ajt*p?+ceGLmfB-9A+`YaJ^p*IK@Ud zs(3=lrkE)1E2@+F`*Iz@lPHE)aPaT?MD6LC8t#%(bc5a{8OK}pM8`2su0DRBWf&>& z=HgF_@+R+;^@Da2Rsry5m(RSdsJ9C`Fv+D;F`N|d94~Jo-SZs3qXWjCafJAhz5kWA z+G0)1+h&2A2DRKCmC18osn7i2aH}6S^kwfLflOMMw=ID59|CDTruxns1n?Q#)=6hqRb4vGcPRzkgx@8q60RhQ_qm;3y?lnSO0z0nuiei}$9LeD@&4 ziVNG5i*^Hiie#&rD^;Pok3T+*|J$Bg9|=NNX}=L4eUEu06jk^KDaXVEy%z=wm-TM! z8(Wkygue)usAZPy#tzVkchC3G-9`ocr0Y*i>^)(%ug3bpXY=yepf5@QPL{LKUf#36 zNaPs{G!FB|RoBjh4H$O-POUo{U-8{3i=tNOl(vY4eZUh}lI0_Z8Tg^>A6JHub7Dw8 z7Ntg-2&C&a3tPcs)j5eOnA_pqZBCgLF;d5JR4dZ5mZ~^fj|cI?nsFvIdV7p-f;3CO zOj3ukyFG%s8=KQTE%d^EjA%2#J%-<6?!?C7@d8nov+;Fge7ddKL&yYPp4Bn)_s=t8 z5|D5F-FpzU6z&W2wE|s!zlT?L5lk6L`*r=CmFnj2VPxpl#{HET1EgyGTqQUHJv-ZzN#xKWn{4U5W%5@L_ zJ67D_E@%FdoUQ(WCPA$dQ>)ld3hkF@Kt*--7?cobKB!Q%;K(B^*`hwTQ*tUv|NZMJ zXbFR(ptJx1+A15}D5d|7jfW7a^dAIr<-GM#?I~`#fXURp9=!Q?B8Y?A6P-l2 z3$~Kpi*|`ig2oAJefgHN7m!|`h3Q2?m#*&ol`dapAKOUC$NUl9T=CdLv50g*k@z-*HyBOxjcxK>O);+{eX0y=G%=k#-{L_2BVW zT50ss{U*O+Bk)WlbfKO5;*t6rEEWF1AMtw-!(14gP1iBzhiX<)m6+Sn&Y&-YwgS(q!jN6B}^SQ}$ z2d(KI7ixlWS-S|VNpel0Tt}`pTm5MB`v5#x8^As=`h~X0`Kn%>yz!Zf80*$npx@=< z!q1qx-pxHsyEKPWT6ALfEx70~{;?h6k zlJgEceV@1>|IX3%1|IMgsf6wn?vsZ~!NaL#*2(7F`z)FpPXcOY4`naXFgX#*0!mNw zC`8~oG>;Fs4y!aJ=0)}5-?b58Aso33KZmFgW_bXS z-T$;=c$7dB34+|)m~(f|`!K}S*@~<5>dwDzf7f5_-mdZmM)v+S-+AdWX|c0M!Iwxn z#VdU?2A&+6tfU{OYW|sSUt{IuANmI! zl&-GIFJEi_(q0=r`)h(%KgreIGbSEyTP+$$z2ztmki(>(0F)0nOp*m*jr?5k?-usJ zZ;BJd{wq+-;o&u{a?<7#y)W7-cjnmdPo`K#^b)+{zGGr;Th&1bf;GT2>$jWTl>XKR zBN`1xTS}AZUha`nOdi$FPn*O+Iys^=kBLwPI z(jo?0m9*G<)~$MuOkRX}DA1WbJ$_G**B+j}!B`FUUw$F2+^G(U+hX|iLUTW!O}l!e zdgJVwd#v)b4^;E-uk;`5(u?Qs^O{Vayds1D)JTFD;Wx{&->_kym5XH zR;?eTc^`jS0iA?=v=FD`FEr`eC}%@0&zNAuJVrJPPlvW5xJ5UuxiA{&a<3^pzXQh} zgtt^n7Zm+;rcY#GCx;ufHj%I2ae4hY*E7N5^nH0+f2n@$8)pP8Gk(aTr;=;qI|J80 z$5YZuU-8nRftP&GzkMYYh)+Q%?rlqk?-96={NAx4ci&LhBIkM{=mP|Th7Lg{b9D{y zxZ>DNX?VdfK>3tGRc78e1v><6TjSzs0tv1QCh>--osUr?cI@N`(2F z|Ah$pNym|!^1G;K{yX$vWt!}VbT(IrLuKU1DmYck-0G zwoM7O;V=zf zDK}s)9O-&6Yww`Fs@4$w6@aC?Q3I2~3To*s*{I}|<@Q7)@GuC*QGj_dN;cF@-5(P6 za7A~dh{A7>uMjQx4}AIkGf%#Ul=V7f5pRKI7`e!~Xkb7y3Jxi{l;WjO?d#w8`KgWXE9QHt zgExHq( zi&l4lIT#w-gVQ^aS!mj=l&^3f~#l`0-m5{S0X_3jrmOA`86QHF5p4qh>k($o?#>-g&)>}!`@<0GW zAnHc+R03q}w8Yea@u)7t;}!6D)%TRk4MiYak4%%{qH%aalAcP?C*IF&ZXG{*y`Xj{ zX~*tmn{P!XxoxYz*x?gkOW+mU?hTS$J~qCBS7T#{q15wvfXf0mI%lUHt<(7ir1$x0 z=Y;LdOgJscwMqfqYCY`{T^v#xbu zRY$@{<67Jhv?=LN*r$^QZ;sC6hwe}x3&~UYkrHq(?c8Xp;27p)3!)i7k}xj zubvgyM9NJqp9B+QL}Aqyg1|Y!ok#Xjsa(nW_CE1f`&`jq>|WK3c%*RZw$I9EL`In2 zQd&RsRi1J5$v+?T=1walxl+-$fiMZ!bd4O3B}~zK->~WOW|Rf#weX`qm}mma)OiwP zZOxSkLTd?T%5-?)m-8VAT%NwJI$a6hCskzXaTpc?hgKC2^myWqB!;WN{4!A6pDlk; zJ}vVKl3?C%bk$pP?d-=~;MF8JY#HlEge=Fu_s5>$f#u$XLz9|^sD59F zH|e4ji3fA!GRYpE|9IySbmNE!IP!Oe3W*z&@h$FDV_N&*SU5@ZEV~*Y$NHBrA zviiV2+QaY9Cby*TM9&}JX7O2y>97$Yow=))>&b;;6JpKc>u76?vfw?WE7EARaB~{N z3)qvYLtux!X9(YBziZmV7!+(RyVGlO!AuyQWK4ucPNibyr^ieXrhut0pCpa+bz(oO?249y~D9WilhPV4Mdfqt;i&K|r91 z(I}wt<;^-l)0dYdEW7=+i=n)#pZTNJDvGmuT5Bh!2}n3&o{2>RPL#>6KNmiI3k>qw z@@_muG$-}X4NE7niP3QG+=9Ba-EjyzoBgo#H+4mHxeU^jqn-W5hTv}QF|O*p{-P>9 z@+mh+7a*B(QhTfi){%$2$qgxmzjcG^T9fgw@du4he}AN*Dy7sr+AbGd0kXvz^^{-k zyqV*|AG|pFICJvpE$h3xQ$rxvBWHNA^XuV!lttp{j(cD>a&6Y`7xen4g)`!!xZac3 zUiw(ChqAir^pc#Zrz_Hz@*HHe>C}bsBj8sh9oM-!KN^eV|8y`-$N|)|Rm{1r7CDuk z@%;ocfKNz$7RK?#^Ey+Z@m8+|5jmE1{A$1#{T-ld18d{+B(7lgKWY{FXy%r|==ka? zp?#8C!j+npMfvx^myj945^mU(at{`A^}Z3Y`*DG0KRqQC&QIq6Yn*UA@9z|vqkLcN zANwFndjRUSm}Tf3+UN}g+dk&uaq`@^N-~w4--h?}*ES}&{gppoHro4tgz%R2AUzx& z_}zN23+OI(4Oa#qT_r}pKY7Eqk~Q9G6HAs?~Uqh;L7c`zjIb~cX$$&?IvI)lUKz(-Q=g!5fKZ)=SDi_a9L;+ zl-22FeA)ta88KyT)kLR3h*xF^i`jy&wb4+t9e}Z zyZ`_k%kb+syb;pf_;=WSH^wv+Sl>Ri_ncy7-V}XN>|3>e1`b6RXuIUWN~~a|KfTy7aq!S%*b^|^XJQ4!h#-8@$Bb?kT z!Tq-5k(mPeeeHr!6~_0Gm78h5sQ0v=3cZsDl{$0MlnqYkSM(fJI#G2dlep0sxGv)Yb7PkjBWMxD5r^=79~u&H!5knf{1U-lW3 zoNR&VzJD0?YU;nNsw>t4JYOxGuYL%5JQq%R8Gi^Y3lD6=`k51wTF5OlH<^veYA)O` z+9nu>p`6q9T6@cDTzzW(wWYH!%0VQ`uv5n|9H1lbZ&*)jx3vbyH-7Azbkc$N1vNUw z2sCzlsAZ8D^!gx57E5PO6Egg@0>#QA$$KFp2bp%6bko0r9p#m=MnAegv(MYwR{003 z?c$TR&fX^M1{Q97g_qc<3e}AFynLh#u@|b27~L=5`o6TVt+x#Bb6HnRt+bzWnFnMW zE-zHuKJ}W2pZx@wu3oJdT3|sgxo7cSI>fDT;%ocp&=@F;3&|w=9|h{{*~rE+IUx29 zz;N|(#%~(9Hcrp-ZhIo`2te^coVDTT5(QCNJacg;S3mnjAR|leS7sKV(edWBda}Ko z_KzsoyVDy0H;!BQ_C1VG25l>?T%l4TiA?CD<&o<>&HW3KMF;JYoe4MC>73==JyVjx zpVj45rS9z+CafyH5p<+D`Eql@j-(PdB8~a^of9q^-p2kwFK`~+KgxmRT3#WL2Ecn3%{ywx7bgC_hH{jYOl>0=CDq? zt$$6?22zt{wbIbPG0tNk9@_$ zS;AXCbVF0#KFMQug>ajQAWEl5iK3b>RjGA zk?s%L)xwrh7(ganf4ftlqI@l|CV;`oDuY9!=f)#lH}(4JxlAdM!<`LymWSt>jd^vfR3@ozQSlvl_|f*}eE~Nvzdu0$(*s16ufMxKtNWLyy*nfd3ryWx z#ALFqKKgqPIJ8|Nbpz+Pz$8DvypB<}KGWl;xpj{(oX^-S3;Ore!|no`Jau?Gf|E#> zQs*9m(RXH(%)-@(VG3qG;!C_w_58FY7S=8DmYcr{Jc`DeEWPKrb-jc`9BdcZ6!vG5 z!(vW8AsS>=4b23=L}{ARmV;dm>}nlMA3k6YeAG0X(T4=H!789jdQ5l_F_!y&t-L?c z9%Y#Luh_>y`13-;x?$1?LR*FrVNt~7C%oM{ND=6St-zd1eYxoUF^bP09;(T3w2EFU z{1>n`WAAz%(3wm6S)oXS(Mu{^iG1O|Yh8W#>Cnix__e8TpQRbOg$^ZYJF(w^dGb3n z`&mygcZ1qT6!%_a<>JNm9@`X0JUcyCOx&@(v5o|{J`P;jupOL$clwn8qPe*An0%3_ zxgW6!zX7o+s=mI&FgdfbEknsgWpQ$cjI z_`A3?8T8gQ**=&YDyh75D0%9qw(I`FJfu6-z9XOxx;gYO`%1}jS)Ipafn%}{8-TO6 z+5c%u25ed|g~|I%$5Lkc#I-x4QG@6eE5Ww0bTf)ob8u1r0=lP;o(@sh!snM-yG3X% z%=ui%-}7g6KkI0KH&?t`9D4qHt&m2Ao#z=HaImH4Jv2RN{>5peeT16#{$!&0hd5Q? zJc8;mK_gH#`KGwArgV)49TRjcjYu~nM3tO;^!YH{1%*fb7nj;YO0yCf?Ud@;+IrbZ zdo?bJvs|D0bu<--N)t@SYjZ(qN@GF}4i3kCU0uWwesOz>=stwk6E>{V;gjoSou45j z&NCub2Xs$J@O4{Cl`qQHLUOXT?o$a27eocU#lFM3>?=l7FW$7a_E=nD&$RDMO#&)C z&Yg?uvZ$R-5|wmcsQV%jj+@NQGtl;6cY)eTJU*>kzl=Dq@?y?&xQ&*DeQ^FfvE$y^ z1&e}_l>0rD08@qDDqIDEIr%j61G(Y)q>kr3{iSYaS-l*a;+Ov(8bupwMP4yi?NR3K z-fZ280S`R8MS>q(te!oLxMQ!*eqzjTXcI+?!Lu1UQ7 za@34l@#Np`Z-)yR4V|uj_fXVh8(E^&$PZKU(!A-hl71-Vic}44fgLV4bQS)U+dY7tdibKOrT_GkDUgOQmM4cL=e3hs7LwtuQ z$d~ymNwNFpgQ+G?i~g=|PWM>iZwrIbD==Uc`8Teh`EPT_+a3?smWBa2ehnR0R~4LV z*|4h5kuKA*>e?T-?<4R`wUnTf4kcZB% zulOUb?LMtD4;V$CC)4Qi-xCYZ0eik&ru_To_W|e#dtCWNO1}kWyUhFdl8VFQD)#7< z5ZHayUlJ}p1$+CY96oZ7se%Bm2VD%4XxYU878i0|=S=4lBP!93Y;t%K0BXV}o|9S0 zJ^1Z9rbYGM_+T3NY7bziuO}wj8lT*c)r|RAru4V5MOYl2&7jXo?@be--jd%w$90ls zc1Pv(A_xlLESAoq>SNu)*~Yf$+LR3B4I)&SYpq{KjB0^gIFFBRCG<_(lerQnDL&Q) ziMO$c#4#$(^aY`0Kgzj_KbmMvJa9n$OdI>;amDqFkn`@2hIr(%c~7q*uk_kW6AYSZ zL5l{STq^g=i~40${kwS2IE>AEil9!wIH^E_gP4;$+`LZ5sgnt6eoXoYy(jkX3TE{+ zz{o(-PSz9O?P6_{ih<0vyI`^B5+eMFEs6v+0y>5RmO)jsPP~59#{|!9J+;DI zVeR<6fP4P++L;BCcp>hP&oEeF#i9T(cOPCgrPd!FTP#vn!{EXia9&*^U}(dOe%2y! zAqu4E#C`Vi^Ml|my0BSs!_O(d# zsoUz}BvK3w3m_3Gv7PQN@P@2;&bbW5R=@5>TSEHMlEmH*X@v>PtC2Nm_;RL|A9+lJ z=-V56$lQ~(Slp2>PvMde0#L%}S8_r+QYsI@XFkg4j<17KC+>TowTFle@r2|F zHC>&kI&PEi8u2~nali0Gc9^Gp6W>Nls^!OmL9fR1RXXh<7@J$8IhW?LI zae{qe)zRX5>mdCaHd^O)O zDDv2&$KBhfmGgNYv+^cSbsI|?;D4%)WI3bumvVi~0CV|*gZv^6hzzqh;>JC*{ousc zJE_!X@lHgSZML=TIX$y?yUotqgmZUW%OC#~O6-RLub6a|yx9zAF9D&&xu@ z-VUJ(p2{`Lr1#^hm;Ho0wJLz@mr%qI+3BF$(v{z09RPL?#R3!&XQNfb8>nVR+<~SZ4_w}EI#*Zkq&EvTJ6_Z9h1o$i6kW_LQ5s9= zGy!i29(gm$EDqR-!}2M_Ogd~#m345Gd;3qKI9hpPliEQQ>4m&3=v`$u0aCw$Ph8&j zHTIr7OOnFu4BBhK(&>m8_*obDVo@ehm|BH**oxEFemzF4ie35r<%c#i6x@Ihgdg>H zNr+gw#7Fzw_dU2DO=xiY&=#_5iEX}2+z{4`(oQ~X_fAmce$;(-sm9;y!alq;mLux> zuD75p)Xln{-Y$j2s9`(O?|3K*bb>AvgfOY9 z>{->$C186`4M=%N>5V(>UTnn?zOY~2I_$FR4QNH%cmKeEU>e53x~d0M+-lA4d`7|n zz1K~BaiEjpQCLyq&jk_H*yw<)P!=dv>3 z%j45e)BDvzc$mE~s&8RWFM}7dm!R>#`PzEt)-+w1&U)YMcYx^OzAi6QMhC%qZB-?OzA$Y2L;o_vv?? zhQOY`*!RdOe-MYe^!*_pBYXoyLhDD%OitGm)Yh!d`y)`PiL)1ne=n!W9q$2pJ1S&+kYEfp^xCzr+kodqcx6OjX)9C(?Gk+&j12mr|G@$G%W8?pnq0hZG#cF z&`O83f6e$%0jx3}6gV65f$Bf&b2HlTOXb-43n9QDZ&_t#?+?;5S;Eo2o#XZ!nsfGyOX0{Q$2 z=gs3&Y~Uu>5Qpo-MD8ea(TTZ_xGCzDG*(&)t&7W>LH+1@AJhsqgcoWe?3*Th^Q)FN z`~mR63;`@99L2vn}p_sIatQ~p+p73TU&U<995orQrSa(#Gasff)7Qj z;ar|hOczyoDAaSz9%%V?QC`UmrLGH4EB~f53voExTH8Im)ZLfpBDvvTw~+KzZ62f@ zseaKt960Mt??_qltp!s{E9q=sU(EcX;L)=D$Du+0@A+F7DM|TRdfmCC!r&f;S6aV5 zBg*?#F-J1S=Kw+A@UjpB%2=muw9WfqtF69d9bQf*kuPv+aUXujY;27Gr#(hLKBW1(HCbOQ9^Y7fG@f{r{p8<`MMg($f3_fXQq9+&--P^ z&}XIKnT=IfsSjwGmNMAxEr+RFT4k(r7(80A?_fASr1*k5K8H?tgId77m6yQJYpZ<>Z9cJw$KE?=qQq;P zCmfaS3pY8e)Bb_Ea5(sYh^gcDTZ*XSe-6|f?tY-kTYzUCj>u9k=oHf+%T*4qVzrCD zGOIVl@HalsI-pxd%r!!On*lsx@yubXmSX?j-|018!}Zv8Etg6iyKi%cW_4#Sa`an6 z%x)$!djxhQOc@S1ck;z*YeJyk?L!lh{$WM$!IdoX!;v=mxw150QoT6WeIyiFM>-Y4 zn0=&*w!TLPdT-sp#c#=r&gEdTLl^N;3)%#`+3ip9*|#d_I{O;I;dVxB@UaP8Ii|;o z+S2Hx&Ixc+JO(p_$^laz}djwU-}tH4YyXfzlj$1v~}^E0sPY!YUz#Jya%EqS>zBaX%hGIV$LTr3a#~5@%%0 z4>U6~w~no9tgcD;`w+`$rB0)oWnPeudAGy=CbHm@##FX^rKepod(TW&m^U+fWRB9lXe*MnzJ}zbd z8U-D&t}FB9?%hS-rCu@&Y)RMDGVc;9hv9jOyqh)=2N<01_d1mWQVf2v*B0r+_{m`j zF*lQ4;8k_N)2{Z5Vp?r9aS1DZ76Sm`7K98EXGUu zd^>PkN(=4<=NwakAhrwE4D_A@{>}sQi>8MT4gk#jtUNV~D1DT~p-|%}wXtmwy#7!l zR_FEU8#_&qX683Vf2s ztJyS$Q=>B=@zKmD$R_uaml5-Y08KjDU=EC||E?d>Cdmh?YyI&_((k4GBRu0l!f2u; zQEW{)cvu}HjOz9BKq<*_p^%zyb&UWGeYawGExh*^$^T<(s?gM1wNksF_!S zzcifOfJw@?n@8{lNF0y0820fWs@&0l_$?>i)GLJBdNt3S{)$wn{7I@K^gE_HrGMA2j*eXTlkW#-(bs+) zURw$m_ZjyO$W6_F?t!GWoNrP~57EeK>KK*=*73Y4GJ^ zl9ZHPrahAv@8RHu8jSSFX`o#e^#W(vV|qjolr^Y*a=6v3M zXv^TXTjBWywF}wDI4cuah~a@i@G|zr6KQzka{Qf2*M+G~F&r;XtT56@9s9?5ZeVUB zy+gu33kTp#@NM2_v??l0T_o6bOdxIt1hd^?C z$P4NAVU8?vj~jODs!;lY@IFy~vA1m68@b1))_uFB6n-)L^-VtHnVw$QaficxlN1sF z!I_)?X3Jx7j~fLZC<`r|I1C6u+c*6Ju0FYiDP8!aH|bXjx9qTkaRHI?Vk|{J$Y2n^ z%OQ;#x0)E4^GS_;n-b)My8H0Tm+?h&%2%=Dub)b}?&_Aoz;r+q&?))F4rK4$aY*{0 zTk9iDARn>i;lHZ^9V0Lh=3T1g1u{xzzN+i)-fr~n^lWJLYfhJI5roJ zL(TgZrj@N_%sE(2@7S?|S4b(abKL4}T2sGovs6SV!!e0;qOC3 zp8VJAcBWoO(q$-2Pg)jM{1_N~+5G+iKHSzf z7R*S-5UgBpzSBo6V|Vf*VsglWyq+9t(0}Eq{*t5J%UvBk&ukk!j5Az;E_CXL#5MqX zpu3pOlm6Q8K@Yq;WoG57GP+JSGjZ>5djb9tNIP9eKA^vl1VDK7N-h@V_@KfgXzjYC z)P(&=0^%`zKqwx4o(W;F4AqAhqfQ1U68vKp)!0shWM<)}0~cWi$$gIfxk=?|ZPf9x z)+%oYj&wM}QaQZ!ZZaCh83qUjswnkUyJ3&uxeI!wl51AIoC5+7Y%cSmg!^E|kSEXK2i@n*-(X>SKDtwIw!}A*vsWEB1H*xVe_XWinO8#4X z>Eg)^$>STFT5$my^$vUR4-`bNGf&ajj6FD8Q{^T-X-@6$b7)annpBDAFrG^h9o8YZ zbYXzK8i4|bp4&GVgn`ty380U59AuOC*fp1v|Kc}B8l3RP4R;D{16L#DytiFt6Rcbs zV1u+h=GxCYx*A|CaJW9<3U%|sv8rw}qxaPq#9sfp5|Q?{FMEm{HY%C)e3UM+@6$Le zeP_tF)svsnxEHP~xK;P4(`tR@Ck@%o!d*W51a$GXVqB1WHkY>YQEdU-AGZr~!$)m; zxa8KlhsLlTln{R6H`#W}n!Kkkh=G)pxWA~)xH;DvhNH8-ngFAaAAuApV@KlZ+B zTUjmZ_La!tQba(BDiXXSiXf;Yfu}!xu3c4sJ;J%D*4EzNS}MWG3}cSbgZTN9G#@3L z%l3tBrWliDs{r4Wy1uzBg7>6p%A^~m3eVh|FgpSc1TpCQ1nt?E^!_8~M(>`iU{S2R zNYpk<5Py#JD|?OF4I9+oH+R~!f4!Wxe8U7-pD>+%s4;!%jtn6H?Bbe9T8^jcZe6D4 z6n~&pNUQdJcA9;A=C9M=EGCkWP8_h6&FURv`hPx6BglnzMc=}Hq`bVy%2#XOCGwRL zQ2_lJ!FIfk&tEWxw?oh0lkt)c^@6Q+ccM}}A;>gy+k3OqV1aRR#e5e~gm=$RzKf%X z<-av!8w}i}Z%}RWf1^Z0r#2>umUEjTMy??=H+1>MzpjB^Zadw$%Yx~(NH36O1``ti z(I?ivd5}KP_aw~j(r~GYL7a!P{o{9!=Zmslzl}FQ7ynd%P#H12!%+ zSTi6E2E?!~)>D3*@-Bf9@@GV_T+(MhZi4EM+V+)BS2I0qcaK~5ZVIW&7m7~F3Hz~yg*j-1G8|j(?SH6DR4C}wcJ*E zmnV950p=ihL+zvNwL{#lDe%L9*hkmvGyD$w4C}?9{D3NfH)B-;9RjO?)3f_!(d^zw zAAY5}$wzeJt_{5Eab>mDzOxyV9`BbkB4;0rrSK}Hwumq$Y%kOtX)R!-j zumk#r$%K>MdJhp)W|^AU z!$TmMeaxE9JqBQZ6e@k_KmO|a=YnB|Yx6l(xF&A@gIn~skZm-^d|no zrLzvTWehM6KDQ=+)(7FtZ+=_TWah@FKb3iWo!}%B|FGpfMsBBE(g^#fWtStxMH;~>3h&S076WB4dlIUV7}3#_<->>^U&*EawZLYI0@0| zx{{|cUy!lUa}E|r(VuChv=>bNRGhN?&3_1|))^cAJSLAva}&hVj()oDXnY7NQc~tF zvF}uXYU-b5YS5nIol*i87y@HEPj{?~3fI25>)f#sz?$0#W>Rx%H1_>A@3T7;E_}5p z=oZZD-cH}al%F4fNtZKp$~uT%8hYJ7o*-~1M{yUzwH}UJ(XInXihfG3?pqn(*7mlG zHBf8o_*3bzf{l8E?P%4O@}C za|*ps*e%*vr6I2QD1RVxnH2(hm=D2Ys$-#TQ9)L$6_b0J!9PB_O( z$v+``HhTU0Cb2X#qhP|>?u>|AdnJya2vBOfsF=%bo@M4s#faVxJQ9-ihYkqDCJX;! z+;YYB99DgE@89Jf)5IN3vsW%&`kkh-lz8`fvUx|r0D!Y}zNmTGqz^21%3F$!v)m{* z=XKaab1N9xxXGL}PYM=X#IqTh-ipuZ6?A6J=GJh%QwZoh!8TL54^8paNswDU-PBqg z7*`xNoB6U{n;L%9nf1v%-S1P`^7B^$-6w$zHbU4|qXF1u*IY2S=Ds4=fu5FyS&phJ`*nMqHGWb8y@RgAE%qv zWM7)sA6YLS()j&z<45FQA?1Mqp}-n>hQ*(Ib=tOk@d>O&1!Q;0;+~pNs+$oC$jV6` zo*tGR*pTneF1-V6`lk8UP&D_ugtY(7%D*0VO&z#*0VEu-$$7=%Pe>3dqXG*-ah1)c z8&^ZHeEk6e6Q>rDn^V5D8|;M&=4&Rqr?@`1z)$TNHr}a?M{Sz2>a*KeZy83fTKab|>zWY50E9_TQ zdvqvl2s9a~o!dpChb??=BValXq(8wdx+EWxUFo6E{wM&)XfDkZY2OV+ySZKp5=AY| zEy8*tP~mqXf$68@8~y`-YgZ>JlNPA6x>B!S4<%e}Lm*I1J>( z>2@~22#dGDz4%{o81?Ns4x4ejtO_;$MX0^G9lJ4}TwDEg(H~nHQau^HkVrR;?2nk` z?%qEgVIT33mV9mf9rW@T($1V@b_@y@8WY{>U%DL64lg$gYoUBo@A{4kc=}kdL3W%T zUAmAgx)xa$aPv|tvCez*ae?$wgK~n$V)PPtl{dKyJl*#K)AEip@PIko-X;led@DZeLzj8pngc!o95Q>ZSwpX`L%{g zJ@+x62UhDqDKNdaILG0>Qyp^|VbVC=KezieJf$2BGgkdTHZb=eR$i$&J}-ry0rTU; zZh;vkJ`VBlfRfvNQjf0Xb}}R;j4OLTH+9{Edv|Qqn7zZJG{3{Oqt-k_c;2Xng6jb0 zN|k!nB_XS5xl~4O#Vwy3^;fGJvhlQZlOL;4S=@)=4%UaXTvG=fa<+?(Ovp^KGB`4A zU|Vxr?#+`j;+FUhDo9fdM>c9y4i-craX;0lBg6am%Lg<5yu&D028C%W3<~A46+g?W z#LIXo9_f0TcVfTrMzxf%x}pF!*s;fVTUUKV`|oG(EifBPm)-8M{>b0R(dK!to9%m{E2Wkf^qFHN5`3Z0ji>SFt*ttgFU~vr)h+x){!#?PXoH2ADMAsn)`raFJ6nH zi?V}z25hsPvo#}%0~jpQo4~$1=jq7gKORsXd{9r{(LV8^hj{dLVErSoYD8ZvLbe$C z@oPW``gk4}t$mgzS&QIFB!fXwU!YR(s=iRK3KRN}v9;x@arjQm%fI|IA*>C26AxRg&y_L?mI(k<~n5aMFcEaOP~A0l|h0Al5%AJeikg* ztuWi4PK$Q9lXxeD{2i=s-mfimzJsug;vs#$w%sRO_g|)xQvHQv>?ocjP24e8YTd4z zE7F>CYn0l$w+j-OYqbf)^@&5R`pcnxkTB49O1{hUd@_!w$+@msIi==lUhwr{GXWU^ zRJOETAF*0{S4Y1kQ(1P%^^{$Zu~@p$LA}sBK9&)d^92alM!kku{8Kiu=#@*L3y>Foi$5gu*j74=fJYlO`6=;^I6|U@->rU|K&2|W$Mq9j<4Gq0(X>EH zVbHDPNB?@JAs&lMd3nF;DurK0ez&||j@+8CY&C3R+!p)J5xW*5O9CqnW(tG1XHnC# z^-Py6DhzNsQ}EdQ(8cqnVX5TY3+mq&>-}jU9bTsNsT5D&J6%2iN5L9-Zw(Db=7IP# zU`a>)y3!sHzCCsbvYpJP{e}=#Ko=o zOu2A}TAMS^d!Bz%krq2u{|xl2CeM`kNJ_(wVZprDmAv`d+u2%{=t38(w?KwT{zqmG zrYTGG{KZK+MB#R^m2tj2Z+GCo?E!8u;(-^fYF{j`bL;`ZlYMR^a#~*HL7Uh#d2Ea+ z>_Q(-%Byqn4S;neToWR3&?))!9s^0kY-nN47KxKEH6|y)VC}9Vw?SmG9iIa8`C4Xb4^Eax9i#7+ZR=+FK@2 zSIAlFRw6u~qTjQ}40@UumCP5--GWN2|Me=aZW<#xz8@ds(xEPTXbC)n@@GF%Xmh>~ zaA}J1%2}71lZG3Dso+ZmjWkPtVAVNzA&<=g`sO13?Nkh^8)2H+P`CMvDWfYIMe(a=B=a zn*i+#Ri;h>$EKQ?1_Esn8Gz| zXp}JZNlOGk@BgaOacopUE!EN(Y}fKDJmXaOJlzeWlA;y_^Ef3=KTCatz{Tluwp1EW z=TZ{%3smAPYPNozB|_5PwwvU(e5(`8mae7JSD>|uP&~r5lH(2YBb4Sd81zh&#q#ml zLLT*Y6qKrksg+m=x&rm4jk^U2+(5)v_gF13BBd=iq(BHF9KOHxGWvt{^6YDN%S3?+D1b5GnHNo;EuCh)xP9mZBKO1L zJlsE4B)vq(KVm{@n}f4l$fHxU(;HTW&7;|K+-u0ge`0Sh51~cCi!o^ZZUJrUIi) zeE%60(rvzFx9Ds?k1ws#b_Ut+f#@$k$FfK(RfL5Tg+&go)YE|)?@)wC?%~RlHeex7r_rNvYUs;0&%{5{^U&JgXHr6B1h2XV zgoL1@`9P?taO_!}PS*>B?h`WSIV?$|lU4D@%}+ieF%(`t^CvroxCJJ~wIS$%D7~A`OYF6>dNXA{ zBFsLYN0^1+B9bM?MGh0@`s@4Psurgo`-Nj<2*e#31bjyABU8|$3I>DL@%EP89h1o{ z)|h3XE_8d+Jm&Urc_?l96gJ(UNP>VWz_8hxOi=5QMY?Q5I_RS)jek@ zCTG8Pf&u5KGue;}CU`a7F`Kp)m3+`T1*s9Nz=Qw@g*uzO-cCT^DxV(0s2+DdOrp0c zoxM`r^5h8I9KCzlQo*@cbMHQ=YkfLur9lP}Q@oK6MYzVfwHM?s*dJC%>41t+n{id2 z_Gv-M9XBHxqt;a=n>Fy8>Fa&h9G>LzD>q}tejnr~AxvvP`C)R}BDL+@T|FKn*=n49 z7ZC=&Pj7Ls(gBiloeIG5t&Ts`;io_5oe>4!Z&rUZ8ThIho+Zt%ry47n?OuFr9jm`s zChe{e&ta$@Ys7e=j>mr3Zm2|_v#*lj?8eq;BljpZ7i%;OGOd@~NACI#x$le)PY06-Rj(H^ao@SjO8qJBD9 z&FpkMzAnPR&3M(iG2AMnNOM+T@^zGlW3163C#_rP!COW3#pe$4Q@ck|m){HBm-;zd zFET`6qYY=g*i;uY$Xbb{HC0q7=Bu(vR0}Q@Ucd#M+~M0B^Z+k*$=<{C!3z)QD=V>m zaH|{prTdR*3=kMa9dhK)=F{b=Pzh<>Lmn(!Z6H%V_978+e(id>9v#tRu?31$N7Gd```rE&3Dvg>XOh<0O;(O=HT%G5#v%;r59HBO{UwvY@FBr z!I%0)OsoJ<8wIr4%2QEb+6{D4X&0c=44{RJ>^k#@O!uC4#C<+#AF+GC3@664gBSnv z`l>#re;xJD>ks4T?m2RWf1eTjw+Cna*D?Ed4E@&s9rwR>K|lImf5BM!-*~_r^8dj+ zaaJFK>*bG~xsV`&oy$s+Buiu=05az-td&x8V_cLc4eO7Y2v!Q)kRW3I3L}o#5d^2! zkYml24WckY@<M`viOzu7cmosw!m&JCOVo&Eo}$ zx-rdIS1j3%%14%DuE;^lqdPDT4K<|)*&xY3vbO4}M5VX&->Vna7M*+X<`=xb?-;*; zyq1nG&2C?^f*!GjAZL0-oNq*(+6^BtR|hIVZcMAO0q9^L%;>pZ~RT z@3`mj4aCs;`^iiplT$7D504z|5ofDKI}nnG(p1to=P3TOEbM%sh4nn@sy*KQXaeVHUUM;AMK7Q{1 z7b^g#1Oa-F%QAIpctIi0iR6INFKk72YRrk>Xa+=V>Qs<*k1uZyQ@mY~4FJz~z^8}o z_z^i+qt}@5>Dq2D}{3^Jww~Dl=g`vrjVz06PdG@SAav2@)sYhfl?k?TR9a0 zziK;2-EcF?2>`D&-^VB~*nvz&F2S5Ar_yt6ZV65+ULl5G0*f|TrMAnh0CMQsA=O;7;ENBGvdVhI0x6sufl?z11P zd-&tWBaKSN7=GR#2hM9np^)w-MpH>@zWC`i@=a|WdNU-v=iJH3VV3sjJp4srx2o8d z6>;b#_?70!qf@V>zshw9-xP0mVmpf&E|@?y=nCThB4#HI)dKu~xzFB4mmHNkRG2S- z50}K_O!;6WYl2~H73Ot~3~Qt73|5M)5`Rys^sDb}GA?p@y~64t*U98359Grt<`MSG z?h{LUX61QLT5(tmjs=-Ahe!ww_|w^+J%G>tiH~cE&2F+WS3l1+?wfQ_y@@^@y!L&2 zBfic|Y@YikD9bpJ@psb(Pi|<$5~W`7;>?dfWL5OPR;^*;Ypcuqz`a20&~Up7TXHm+ zrSWs`HjX-aB54ebw3s$;g(s3hC=|YWVuk> z)?*vh>#p0beyZeZc+tQ#sd$*%(M>-bbC(QK0@U&W?wQ4NB7KcK>U`lSc5JhmbZV3} zvXb+pOzhKdMNxk{qFTx&`|l~0u8XdxJxF^ACAspB-1;I0k{1;d-k7H- zT}g{P>lq#z_~`iU%GWPnoDtP0aI7Dkc3%a2Lhs1)T{e2z*coD61<%b1#{!fAbB9jx zrZkm&5xM>_@+PC?FmlMl#dp+(4zlE|Cr+}Is|HIJlF~ipBIhH+lxErF(FIvC{^rds zB1ZraYTd^#Qs9cMy&#ONt{X<)-#X5bUR>6v(G9W$Izzco4a$qmIX!t!$FC9feXfY4 zTC3t!{9qCO8RUC**xBP{IsOxZG01u=U^Z6<(qhkrooaXTkk3oKoJ^~oA_=(-n_AMN z*h(r3h0$U0c_{6}<}FTSXj8#C$G#ub5hR(SW}W_sOe;WKI2^N*W9whYn@|$Y2Ilx0Awb*5KILqQ*5h(~wRcu#?hF-Y)xFdc1kw_5dASWXe zBKN+O&p&9na3~(HT*~Vij&Ow=M?p^K9>h4hybhtVL7o+Pd=wbbCowco)8zkL+O*YTCB>*Gc1PCY-AEc^QVToHGgL#e%(Lc-CNEx! zc{yY|(H8BiB|hp`iB;;v8h~&LS0&=kF9f|;JLPt}pxh$Hb3d0GrD{8=zW#e|R31A`+4ChtoZXxBQ=BMu%cc#=7n& zq5`w#^G{IE^j3#ZmDCkblf8SBrZ^4Oco+d#3(NCvAOEM<{eA2npH;e_Cq`diozlqywqD7TlUU(&O8Zu3!+=D;6d(t_~m-@RV z58IENI)K%yoOIqCZ8fFc^0Pm}_oxr(-OKYqP&FM;&O(eUg>|W%M8z6xT9%}NcI9~2 zcemMb2NzYV`}L#WE>FoYVVeR*GR2%oQuT2~(XngwK>rqu>ek;|xzj#deSQPyG#dyY z8~gd!%@6u`dj*#@%dTH|fQO-zbnD%t_B~%*ftBR)?t5(^`lX(*pG<~l0npO>#< zn_l50bb924_id~)cNcY!W6JRZ4u#?*tPj}*ZK1t7W`R_v4+HE3@PK=64&X{e)F}|} zj$29CWwSo?OmJ#tO7c7ml^+g_>k~ z+1=ozkk@HQR=$_Up%XS)e1bSv^q#~`J_fE}e~$8F$)p~$g}j3ilFysFcMqi|>Q%CBy{e|1 zc@n(Tk`Xn8cYhL&XsW-LcYOqy)7Q4stN7=2gE@-5Rq&;eH71$3>>{ht?8!`*sF9m_oYRUl>S;s6@j*P;Z4mzrkuM%G7lN4$2l z*`M#9eA-Myh;N%d(I2zjumNlPNb>awpp(D!!*$x@BKZ7q4!*)4?j9iWS(d%X6T$WE zP;n0N36!dI-@QinWV$1+<-{v|f@*#Udc&ae=s>{)Nf{3d&P3ghRAE8kRd!71G@3v z!CTV1Z;)$0!I}I!4+j!p!Sz_mv_@fN63?_E^c#y{Y8$KK`XI`QhQvnPpcZ~s=42YBpnGbu@z_XlW5 z;@|N)8-Adw7KGClNLqiFUr{)F(2j8`a_8KEUOmSU%J%@dJL+|PU;b&!!a7UCbO61l z5wbCPOWzzf4T{ihb0qq7ay#L0GrjAJhTJtyCO7%sBu^b?kT3cmVE<7uOw0k0TVn5# zINoh*`yrlK32Mi)y$6t<^%DmLWgN4bnY9yN-#5g~JSnnYQ7@lnt7j2m@OmIz&#SXu zU(D@+r;>X>{c=(z7;qgL_AaM=td#YRE_a#BRkp0QN^*8t}e_z*c^UrE# z)QxB3;qGrQ`$LM3gbEA9#r|o;?YMEH^RP3Rb16Y*tpxg1@`9l^p<*DoC@= z_OfyCFbR-JsO)^zWR^Z!oK0W~0rTsNmKVpAZ3@J_c zxFl|nfn{RmSo6U1`=4)2(QJ=Vq_Lj#a6h0jcgKzOFXo2rrvJHwqlF# z-2{;r+`m(lrdbb?1OMWmr&sAqu>9h8U61Zc@U3!)t${1b4t(=s|3ck3cl-e+DJ@qL z;FbyTNrN6l_~yBGwqDkOk#`4%uODYyJ+jxq{DK`V{QpN`$JZl7X2PR;f59pFyb9FMRR%=P%*L zmdwfM6Ki~Dzs2LJipraMRC;L%d7@wwe+k8^UM@CU%pV?v7Cb6Ve@cn^8opreD#?oP zqcCyndQmCT27OlbqT}m&lMnVB@zwPFuF%M2?t#Red#Ajibe@;1k5~e{`d+#I259qT zX8m1lV=pVma9o?j!nmdk$XSXPL59pEJQSbJ3I=J>3$Gp#vVy0$>)BI7a4@GeQ?l$nV z62zOdxxHSpS7x%a#p7oM&i_@sm-L)5Risz>?7Uk;{y2o&`W*TC9tYD$o5X+&2*{*p zSO{zB3*Z-XV2~jT;=k{Aem{+;ZW<)6W(D|Xrh#NtbMp8+k}YXSJ_vG1Ap%cExM{Ec zGJw`psz)H<>ByOwZ+KC!5Ad7zAhEwbSFT8b(OEY6$(6jO;;iO(+M)In?P5FCxdI`a zBB(LbI=5c)gBBe5_*iGFXYDlXrS`e-gs^1(d^!#9;j`lR>8TgxQ0=!t^mo+3y7DTm z##0AzdEA{ZzPmmAmQ~o9w-@y<_J8ViOq>pfZ@>ZuEeP>Z@}X;)oZEY1{h5Z8P*B<< zB2yQ1A0#xsaAy`D2M5;f#oy|ic^!2Kw^)PzKM3_~ZoFK3Ns30+at9+waeX)q z?X<5{^sJh!bbkG^=7%};u%fy|aCdI$zBu3LM&>>viwRcT+h6F7_hIN#8|qp2k21ZK zYF1uuO5rHzM?p@U-ft%;gFU}U`zrf~e~ES`!zIObs@_8@dTIdjcP`LRd%6r`QvIzC zxq2xa5`{4x!ZFgh&7CFA$Hv-S&u7Yt!>b7Cy@s=Pz09ZK;GWjY$O5)RF=%NGD!%-- z<<;}eYg+>A@=LSpdzI?#YxIH!=TX(`OEMX4aLD;5jBD&*6TTQa_W$pNFV$=TRUiA5I6yQbLz^pTeAGY1eB;Xmys)C-N6|e27 z)}cQg#tvz#@OjnsEt2OoFZ)lX^VbTtXpFB~2Vr7wRs7DobN9K|JShL)`6YQ^0fjT7 zOy*tH{%o@mfOIzr8f}-u?sAuP+vpHd?_sv_HJEtZZ^eYN+#7plGABr+k#RpddnNAS z*`DS0j9B^Zt@R>^4e$_T#V4o;Qc8<0!W0*SO9y88-6q#C*v}!wA?(rwGU45Q|8^tg z(XF~e6z%bjnQwdjW&=p2oRxIbg7I9U=!lO1p|z%m;Vb~^k3T=PTG^Y>sLbYklt!9u z>b)D2)#K(<=RnS=x+@Ro4gqeCOn-Kc7Q$gI>wh3JhTX&gz~A0fPmlG1AVkp-E&?@p zC`s8{3%KRPfA5f5Y80V2Z)G@G=3b_GbSc5~|halq5QrqKwY!zpn4;eQq}TbEYd|%cbF?1msC*mM-@d{)l$?9`3E(?0KF!S(hK2Hd zIO;PM!ynZE&WuWqzh9n*uWLo$^XNg3=5VuuI~eKp9K0i837_uwEkDI#38H=TFwEBn z3PU{G!~b2WJaa2X;i5nm3Q6JpZg;(1l;E)M6HB4wuig%lB+K9XTZ}ww zpTW{mHZkZZHr;rbFyq`_*W^|9Uajs>!4WW^o6AE*&67}l-BQcw5OpGqk-$K{tlVV@SllLN<@8l<7 zb+~6Y6GHQ&*ZMx83X+(I4k$i z8Y}N?np~68{jv#Xb>Fxg{S7jAKEn?=-Lq%jJYTa7{f11wUOd6L;WXokYBrZfdPgSE zZy~X^Q0~7x1FKqrV924CJr*mdwLDk*r<~?RN&b0>R;0o#khiUdk4=hx!%%@6S7ppL z5o?9JTxy&;M{!C4yyJb|%yp1R&=2bW$6@IG5(X19!~6U!2{J+~4VsVk_V$ch`vr0h zHr8`^(A}-^1DN(?m5qeC+G`C?t9TGi5dG41MmmL+H(t?$q?{ncdD#drUn}`@FW)~t z72N$tzi;E_ak`h3*YF@gul45=RmL4!5~nxCZGv`5H*6VLHnVQ;>mi7!B-fj-cYjX? z5~ zG9WL9Ij>rB&B($YuRdMjAIEikC~7?93Er;W4YS^z)1O<<-}Wdb5A0b`GwtZvgdP_I zh(_dZDr2bM8W8+Dvr}J_grH4J9-@RWTAgo?eM;~8fgv$j5rNMe8y;cOD%7ux=C(Z! z{qcn(pt=4Dw)7GuGW-P3-h+9~0{xikgKsIzoBGy1^yYH^i<~q*P9j4U>PAnCjs}Qa zjpw`MvwkFePH;t_Esy4prO|r*g`3D+Sl?xzV98*b-WsT@9OSYwJSJUJ&x@`dMXAp7 z36+!1Mygm{w&RP+-%BIIA`0F>+4DB#{d_KQf=5VFkv=)+QkEgR!X8clb!q0kkt*2o z*FY~RzP^BlSq42VDq6J5eN6@jWT|W@F$nmzP_wU|Yv$C2WyI3cu|CKKMm>01sq7Ro z`no1w*v)~bHL9NnHi9!3Ym_W$?X{QVY(oP$w=2EE*d|9(!|}e8XXuhEaqTz8WTe1n zPyt=pjp8DL{?ybtU>TG90Ns)s^uT$awM)z-fAR!*;ouz{Rhb$-+j<>%VC#K%)x}*A zr;4N;9)h)GDvbm-8DdlHkM@#3Z;`_}dowSy_ho0J%IUDnYdCCQ`N&D|2Z1+1LHD7Y z8DzbH=(L|vty%sK#fId5(V6Leu}p_QxZ90>832VtJN@^Dh@L!I)h~CTqNFgXu9Dc#)X0FhpBUYcvBp`=m9uK4X zr0}PlFLk(a_QfNqTR>Od6I-IfT(LKU`_v-n*18(>r^n^ht!LvlxwIs+K@Ua0`x0L} z3`5P+hj!#-79t4n{T`q|#K2#ryT8`0H@+1MO@#hF#cQ3M0(|_+^G&;{(`HGMx5nw) zyRNZEdeoH3*KZyCs8ITK{mtU+v6lVN_c`UQdmbX`@Nfp z88hl>ef33>1iMXzku#~2kXZ-nH<#%lIs4?0K^Zn$yw!uu9Xs`$+ztHnH-2l{H*D1c z^q}2FREDvo*08L^Qv5^81?jELV-q(3!TzrX1`vl#gUA_J<6@%_SU_lC@42&VljLOW zp2Pf?dKy(vfR>1#@#4HEP9!%xCrHFA;=Xiw<7+zye~vRfi`=5PCqL3+m)7#o+4l?E zWeh+WCk_*y=?TBXa@Py^!_wMi+;WTrh3ave%0s{D%5GLDKr1Epxc4S_h+b}&BZ|n+ zb6%GOk?#~gw8O`Z>DfR|QkRc$NtZ2G=v^0}3NaiU#5LQd6 zW1Q&Ye#k=Xrp|B&d-r&-8Ck~m;C6YD!sde-GVt%XT)~6pU7I$lXAiTS{Hfot3Cl@A zTya3Rm34FM4BeyEJqw}d@N@gZBQizx)Y>n&6*>PbZ(~oSd$hNxBa{kgL43PD-xnX4gd>Y|~6@qgO zIxh{LRoNpA{o=g0LiUQnA0z_s#+^mooj2M_p?Bgr4emt@#izJT*WYS}4|D$kIsWBB zcGzd&w3JIE2>iijp&g!Nwhqfv5)6vPW?DRvU?Pyj*JD{teRyFsYil2y(%}|PUnMn< zj34Ii3+yb)q{=?ba>&iDXVUt=H=?AE@N6Ko+;v-8?Bkei7w^c;VI=rTqh483?_knX z4mBE7M3>EHtv^k5y$*+yy!_-(X}mAwxwrZAGPDDDc+TcSk909Ez33#}eRHc<`gE(b*n>5IzBQM$Os4@G+z z+Cu2mOdB*LkUytJxE}X=o*qJVk0C1jIJMqCn(6hth0STTnc7uj8!o%)o9sI3<)*2_ zmxjj2s`1pXnat%L^N`mw-?yH-z0Tj&LM-<)D{i0sPU1W>_xvZw9GPrpU9d50fZ`hR zr%eH|IT_Bdll$SdIvUO`U80>KXXba6VpZSUeSHPn=5qXxy1gtv33KztSOer*fO)~x zskm^bcOO}#9-@cG8VAVocDuKvY{Gp+-=`w$GufJ|vbW*|%a5mnTmQIA`&|aRN)e)B z(-H1`IA``;p$`w3w9H${T;`T%u}jyE_xO`-{UAq%)%`&hUu_WfkCaaxDReqY8}aSw ztK~rtIxikU7Md<90?+F}78Cc&!=%SKC#^nl!~T$BQdfGXx_(OAQr*sfJ!6_=)lNfy zJ#&ug!* zlPZdr8lGSk6;qRzG7HYUB}xMHA6eX0Em8*!}qVY zc`$EBNEB$*2oZ4)YD(K2WsbHV)Ndw34!5A+I#($shUHOf23e9lt+H4Aw=Ioa)q`cd;9g-OemJyJF9 z`a=-(@mTwb^2fbwSk`R6mfhLVf;e0~*kg?19f$-!f9t)c)7SHo?OW0|YU=_g&I41u#neWhFDD_x`c`+b@jE z_Y>LXh?mxh%GcKyYD;|09OeAk0VVNNjxk6QwkgQL=>*-rOGNkPg|=BheQsA7If}tq zeZHapZY39)N!rgHmLYBl%|hJyFT7jt2+q+EzwYt(Wuh+<&zZy4Q^srO zkr~h{?NF5Py|lF0-9Yq#FdjXjZqyeIs-kg7PWQ~`-&T;Px)2t#GwM69ul-Gg#Yay4E# zZsPXWa=^|Kk+!m@Z?Rdzr0HXR9w&&gU{7ii@e6Wrsx>@kPS`v3N6=NkqAV7P_7=`B+vOngQ%iWbi*Z26w%eI~usGhK88?={h(?g#Cq+8<3VUDRMd%0DTl{*f@RLs}A~*$L!!jVy5{q}NyZz8DfD&@&a2c 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 literal 0 HcmV?d00001 From 4e393e4d2dc510599c6222a38ce28588b55067d1 Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:28:29 +0200 Subject: [PATCH 07/29] Update content-loader.md add folder based example png --- docs/content-loader-docs/content-loader.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index 91d9a581e..60d122400 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -116,7 +116,7 @@ Only the files (no Git history) are copied and committed to the target repo. - Specifically: The top two directory levels of the repository determine the target repositories in the GOP. - Example: The contents of the `example-tenant/petclinic-plain` folder are pushed to the `gitops` repository in the `example-tenant` namespace. -![content-hook-folderbased.png](Images/8Mc_Image_1.png) +![content-hooks-folder-based.png](content-hooks-folder-based.png) This allows, for example, additional Argo CD applications to be added and even your own tenants to be deployed. From 6775026ca858c39ce3184eb7bcc0c184c25db6d2 Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:51:13 +0200 Subject: [PATCH 08/29] Add files via upload --- .../applications/example-tenant.ftl.yaml | 23 +++++++++++++ .../argocd/projects/example-tenant.ftl.yaml | 33 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 docs/content-loader-docs/argocd/argocd/applications/example-tenant.ftl.yaml create mode 100644 docs/content-loader-docs/argocd/argocd/projects/example-tenant.ftl.yaml diff --git a/docs/content-loader-docs/argocd/argocd/applications/example-tenant.ftl.yaml b/docs/content-loader-docs/argocd/argocd/applications/example-tenant.ftl.yaml new file mode 100644 index 000000000..7f00d338f --- /dev/null +++ b/docs/content-loader-docs/argocd/argocd/applications/example-tenant.ftl.yaml @@ -0,0 +1,23 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: example-tenant + namespace: ${config.application.namePrefix}argocd +# finalizer disabled, because otherwise everything under this Application would be deleted as well, if this Application is deleted by accident +# finalizers: +# - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: ${config.application.namePrefix}argocd + server: https://kubernetes.default.svc + project: argocd + source: + path: argocd/ + repoURL: "http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops" + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: false # is set to false to prevent projects to be deleted by accident + selfHeal: true diff --git a/docs/content-loader-docs/argocd/argocd/projects/example-tenant.ftl.yaml b/docs/content-loader-docs/argocd/argocd/projects/example-tenant.ftl.yaml new file mode 100644 index 000000000..2c641da7e --- /dev/null +++ b/docs/content-loader-docs/argocd/argocd/projects/example-tenant.ftl.yaml @@ -0,0 +1,33 @@ +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: example-tenant + namespace: ${config.application.namePrefix}argocd + annotations: +<#if config.features.mail.active> + notifications.argoproj.io/subscribe.email: ${config.features.argocd.emailToUser} + +spec: + description: Contains examples of end-user applications + destinations: + - namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + - namespace: ${config.application.namePrefix}example-tenant-staging + server: https://kubernetes.default.svc + sourceRepos: + - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/nginx-helm-umbrella + - https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami + + # allow to only see application resources from the specified namespace + sourceNamespaces: + - '${config.application.namePrefix}example-tenant-staging' + - '${config.application.namePrefix}example-tenant-production' + + # Allow all namespaced-scoped resources to be created + namespaceResourceWhitelist: + - group: '*' + kind: '*' + + # Deny all cluster-scoped resources from being created. Least privilege. + clusterResourceWhitelist: From f7eb05b1425221a9438cddc0d14c5493be982b3d Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:53:18 +0200 Subject: [PATCH 09/29] Add files via upload --- .../example-tenant/gitops/README.md | 1 + .../apps/nginx-helm-umbrella/Chart.yaml | 7 + .../gitops/apps/nginx-helm-umbrella/README.md | 2 + .../apps/nginx-helm-umbrella/values.yaml | 10 + .../argocd/nginx-helm-umbrella.ftl.yaml | 25 +++ .../gitops/argocd/nginx-helm.ftl.yaml | 33 +++ .../gitops/argocd/petclinic-helm.ftl.yaml | 52 +++++ .../gitops/argocd/petclinic-plain.ftl.yaml | 53 +++++ .../petclinic-helm/Dockerfile.ftl | 15 ++ .../petclinic-helm/Jenkinsfile.ftl | 200 +++++++++++++++++ .../k8s/values-production.ftl.yaml | 13 ++ .../petclinic-helm/k8s/values-shared.ftl.yaml | 30 +++ .../k8s/values-staging.ftl.yaml | 13 ++ .../petclinic-plain/Dockerfile.ftl | 15 ++ .../petclinic-plain/Jenkinsfile.ftl | 206 ++++++++++++++++++ .../k8s/production/deployment.ftl.yaml | 49 +++++ .../k8s/production/ingress.ftl.yaml | 25 +++ .../k8s/production/service.ftl.yaml | 15 ++ .../k8s/staging/deployment.ftl.yaml | 70 ++++++ .../k8s/staging/ingress.ftl.yaml | 25 +++ .../k8s/staging/service.ftl.yaml | 15 ++ 21 files changed, 874 insertions(+) create mode 100644 docs/content-loader-docs/example-tenant/gitops/README.md create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/README.md b/docs/content-loader-docs/example-tenant/gitops/README.md new file mode 100644 index 000000000..143c98de3 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/README.md @@ -0,0 +1 @@ +Contains examples of end-user applications \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml new file mode 100644 index 000000000..62b99b38c --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +version: 13.2.21 +name: nginx +dependencies: + - name: nginx + version: 13.2.21 + repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md new file mode 100644 index 000000000..b5726758d --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md @@ -0,0 +1,2 @@ +3rd Party app (NGINX) with helm, templated by argo from a separate git repo, using helm's dependency mechanism. +This is an alternative approach to keeping the values.yaml inside the `application`. \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml new file mode 100644 index 000000000..347396191 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml @@ -0,0 +1,10 @@ +nginx: + service: + ports: + http: 80 + type: ClusterIP + + ingress: + enabled: true + pathType: Prefix + hostname: production.nginx-helm-umbrella.nginx.localhost diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml new file mode 100644 index 000000000..0426e32a2 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml @@ -0,0 +1,25 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: nginx-helm-umbrella +<#if config.features.argocd.operator> + namespace: ${config.application.namePrefix}argocd +<#else> + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + annotations: + myvar: ${config.content.variables.umbrella.nginxAnnotation} + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/nginx-helm-umbrella + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + + syncPolicy: + automated: + prune: true + selfHeal: true diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml new file mode 100644 index 000000000..47f2325b4 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml @@ -0,0 +1,33 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: nginx-helm + <#if config.features.argocd.operator> +namespace: ${config.application.namePrefix}argocd + <#else> +namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: '' + repoURL: >- + https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami + targetRevision: 13.2.21 + chart: nginx + helm: + values: |- + service: + ports: + http: 80 + type: ClusterIP + + ingress: + enabled: true + pathType: Prefix + hostname: production.nginx-helm.nginx.localhost + image: + repository: bitnamilegacy/nginx \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml new file mode 100644 index 000000000..c2677f1e7 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml @@ -0,0 +1,52 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-helm-staging + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-helm + namespace: ${config.application.namePrefix}example-tenant-staging + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-staging + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-helm/staging + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true + +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-helm-production + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-helm + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-helm/production + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml new file mode 100644 index 000000000..4f631b432 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml @@ -0,0 +1,53 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-plain-staging + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-plain + namespace: ${config.application.namePrefix}example-tenant-staging + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-staging + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-plain/staging + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true + +--- + +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-plain-production + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-plain + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-plain/production + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl new file mode 100644 index 000000000..c739682dc --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl @@ -0,0 +1,15 @@ +# TODO +# FROM {config.contentVariables.images.petclinic} +FROM ${config.images.petclinic} + +# Set permissions to group 0 for openshift compatibility +# See https://docs.openshift.com/container-platform/4.15/openshift_images/create-images.html#use-uid_create-images +RUN mkdir /app && chown 1000:0 /app \ + && chmod -R g=u /app + +COPY target/*.jar /app/petclinic.jar + +EXPOSE 8080 +USER 1000 + +ENTRYPOINT [ "java", "-server","-jar", "/app/petclinic.jar" ] diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl new file mode 100644 index 000000000..2dcbcf60a --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl @@ -0,0 +1,200 @@ +#!groovy + +String getApplication() { "spring-petclinic-helm" } +String getConfigRepositoryPRRepo() { '${(config.application.namePrefix?has_content)?then(config.application.namePrefix, "") + "example-tenant/gitops"}' } +String getScmManagerCredentials() { 'scmm-user' } +String getConfigRepositoryPRBaseUrl() { env.${config.application.namePrefixForEnvVars}SCMM_URL } + +String getDockerRegistryBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_URL } +String getDockerRegistryPath() { env.${config.application.namePrefixForEnvVars}REGISTRY_PATH } +String getDockerRegistryCredentials() { 'registry-user' } + +<#if config.registry.twoRegistries> +String getDockerRegistryProxyBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_PROXY_URL } +String getDockerRegistryProxyCredentials() { 'registry-proxy-user' } + + +<#noparse> + +String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } +String getCesBuildLibVersion() { '2.5.0' } +String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } +String getGitOpsBuildLibVersion() { '0.7.0'} +String getHelmChartRepository() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/spring-boot-helm-chart" } +String getHelmChartVersion() { "0.4.0" } +String getMainBranch() { 'main' } + +cesBuildLib = library(identifier: "ces-build-lib@${cesBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: cesBuildLibRepo, credentialsId: scmManagerCredentials]) +).com.cloudogu.ces.cesbuildlib + +gitOpsBuildLib = library(identifier: "gitops-build-lib@${gitOpsBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: gitOpsBuildLibRepo, credentialsId: scmManagerCredentials]) +).com.cloudogu.gitops.gitopsbuildlib + +properties([ + // Don't run concurrent builds, because the ITs use the same port causing random failures on concurrent builds. + disableConcurrentBuilds() +]) + +node { + + +<#if config.images.maven?has_content> + <#if config.registry.twoRegistries> + mvn = cesBuildLib.MavenInDocker.new(this, '${config.images.maven}', dockerRegistryProxyCredentials) + <#else> + mvn = cesBuildLib.MavenInDocker.new(this, '${config.images.maven}') + +<#else> + mvn = cesBuildLib.MavenWrapper.new(this) + + +<#if config.jenkins.mavenCentralMirror?has_content> + mvn.useMirrors([name: 'maven-central-mirror', mirrorOf: 'central', url: env.${config.application.namePrefixForEnvVars}MAVEN_CENTRAL_MIRROR]) + +<#noparse> + + catchError { + + stage('Checkout') { + checkout scm + } + + stage('Build') { + mvn 'clean package -DskipTests -Dcheckstyle.skip' + archiveArtifacts artifacts: '**/target/*.jar' + } + + stage('Test') { + // Disable database integration tests because they start docker images (which won't work in air-gapped envs and take a lot of time in demos) + mvn "test -Dmaven.test.failure.ignore=true -Dcheckstyle.skip " + + '-Dtest=!org.springframework.samples.petclinic.MySqlIntegrationTests,!org.springframework.samples.petclinic.PostgresIntegrationTests' + } + + String imageName = "" + stage('Docker') { + String imageTag = createImageTag() + +<#noparse> + String pathPrefix = !dockerRegistryPath?.trim() ? "" : "${dockerRegistryPath}/" + imageName = "${dockerRegistryBaseUrl}/${pathPrefix}${application}:${imageTag}" + +<#if config.registry.twoRegistries> +<#noparse> + docker.withRegistry("https://${dockerRegistryProxyBaseUrl}", dockerRegistryProxyCredentials) { + image = docker.build(imageName, '.') + } + +<#else> +<#noparse> + image = docker.build(imageName, '.') + + +<#noparse> + if (isBuildSuccessful()) { + docker.withRegistry("https://${dockerRegistryBaseUrl}", dockerRegistryCredentials) { + image.push() + } + } else { + echo 'Skipping docker push, because build not successful' + } + } + + stage('Deploy') { + if (isBuildSuccessful() && env.BRANCH_NAME in [mainBranch]) { + + def gitopsConfig = [ + scm : [ + provider : 'SCMManager', + credentialsId: scmManagerCredentials, + baseUrl : configRepositoryPRBaseUrl, + repositoryUrl : configRepositoryPRRepo, + ], + cesBuildLibRepo: cesBuildLibRepo, + cesBuildLibVersion: cesBuildLibVersion, + cesBuildLibCredentialsId: scmManagerCredentials, + application: application, + mainBranch: mainBranch, + gitopsTool: 'ARGO', + folderStructureStrategy: 'ENV_PER_APP', + + k8sVersion : env.${config.application.namePrefixForEnvVars}K8S_VERSION, + buildImages : [ +<#if config.registry.twoRegistries> + helm: [ + image: '${config.images.helm}', + credentialsId: dockerRegistryProxyCredentials + ], + kubectl: [ + image: '${config.images.kubectl}', + credentialsId: dockerRegistryProxyCredentials + ], + kubeval: [ + image: '${config.images.kubeval}', + credentialsId: dockerRegistryProxyCredentials + ], + helmKubeval: [ + image: '${config.images.helmKubeval}', + credentialsId: dockerRegistryProxyCredentials + ], + yamllint: [ + image: '${config.images.yamllint}', + credentialsId: dockerRegistryProxyCredentials + ] +<#else> + helm: '${config.images.helm}', + kubectl: '${config.images.kubectl}', + kubeval: '${config.images.kubeval}', + helmKubeval: '${config.images.helmKubeval}', + yamllint: '${config.images.yamllint}' + + ], + deployments: [ + sourcePath: 'k8s', + destinationRootPath: 'apps', + helm : [ + repoType : 'GIT', + credentialsId : scmManagerCredentials, + repoUrl : helmChartRepository, + version: helmChartVersion, + updateValues : [[fieldPath: "image.name", newValue: imageName]] + ] + ], + stages: [ + staging: [ + namespace: '${config.application.namePrefix}example-tenant-staging', + deployDirectly: true ], + production: [ + namespace: '${config.application.namePrefix}example-tenant-production', + deployDirectly: false ] + ] + ] +<#noparse> + deployViaGitops(gitopsConfig) + } else { + echo 'Skipping deploy, because build not successful or not on main branch' + } + } + } + + // Archive Unit and integration test results, if any + junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/surefire-reports/TEST-*.xml' +} + + +String createImageTag() { + def git = cesBuildLib.Git.new(this) + String branch = git.simpleBranchName + String branchSuffix = "" + + if (!"develop".equals(branch)) { + branchSuffix = "-${branch}" + } + + return "${new Date().format('yyyyMMddHHmm')}-${git.commitHashShort}${branchSuffix}" +} + +def cesBuildLib +def gitOpsBuildLib + \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml new file mode 100644 index 000000000..b7528242d --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml @@ -0,0 +1,13 @@ +service: + port: 80 + +<#if config.features.exampleApps.petclinic.baseDomain?has_content> +ingress: + hosts: + <#if config.application.urlSeparatorHyphen> + - host: production-petclinic-helm-${config.features.exampleApps.petclinic.baseDomain} + <#else> + - host: production.petclinic-helm.${config.features.exampleApps.petclinic.baseDomain} + + paths: ['/'] + diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml new file mode 100644 index 000000000..2aa824334 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml @@ -0,0 +1,30 @@ +extraEnv: | + - name: TZ + value: Europe/Berlin + +service: + type: <#if config.application.remote>LoadBalancer<#else>ClusterIP + +ingress: + enabled: <#if config.features.exampleApps.petclinic.baseDomain?has_content>true<#else>false + + +<#if config.application.openshift == true> +securityContext: + runAsUser: null + runAsGroup: null + + +<#if config.application.podResources == true> +resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 300m + memory: 650Mi +<#else> +<#-- Explicitly set to null, because the chart sets memory by default + https://github.com/cloudogu/spring-boot-helm-chart/blob/0.3.2/values.yaml#L40 --> +resources: null + diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml new file mode 100644 index 000000000..b0eab58c7 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml @@ -0,0 +1,13 @@ +service: + port: 80 + +<#if config.features.exampleApps.petclinic.baseDomain?has_content> +ingress: + hosts: + <#if config.application.urlSeparatorHyphen> + - host: staging-petclinic-helm-${config.features.exampleApps.petclinic.baseDomain} + <#else> + - host: staging.petclinic-helm.${config.features.exampleApps.petclinic.baseDomain} + + paths: ['/'] + diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl new file mode 100644 index 000000000..c739682dc --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl @@ -0,0 +1,15 @@ +# TODO +# FROM {config.contentVariables.images.petclinic} +FROM ${config.images.petclinic} + +# Set permissions to group 0 for openshift compatibility +# See https://docs.openshift.com/container-platform/4.15/openshift_images/create-images.html#use-uid_create-images +RUN mkdir /app && chown 1000:0 /app \ + && chmod -R g=u /app + +COPY target/*.jar /app/petclinic.jar + +EXPOSE 8080 +USER 1000 + +ENTRYPOINT [ "java", "-server","-jar", "/app/petclinic.jar" ] diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl new file mode 100644 index 000000000..1c6b5b268 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl @@ -0,0 +1,206 @@ +#!groovy + +String getApplication() { 'spring-petclinic-plain' } +String getConfigRepositoryPRRepo() { '${(config.application.namePrefix?has_content)?then(config.application.namePrefix, "") + "example-tenant/gitops"}' } +String getScmManagerCredentials() { 'scmm-user' } +String getConfigRepositoryPRBaseUrl() { env.${config.application.namePrefixForEnvVars}SCMM_URL } + +String getDockerRegistryBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_URL } +String getDockerRegistryPath() { env.${config.application.namePrefixForEnvVars}REGISTRY_PATH } +String getDockerRegistryCredentials() { 'registry-user' } + +<#if config.registry.twoRegistries> +String getDockerRegistryProxyBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_PROXY_URL } +String getDockerRegistryProxyCredentials() { 'registry-proxy-user' } + +<#noparse> +String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } +String getCesBuildLibVersion() { '2.5.0' } +String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } +String getGitOpsBuildLibVersion() { '0.7.0'} + +loadLibraries() + +properties([ + // Don't run concurrent builds, because the ITs use the same port causing random failures on concurrent builds. + disableConcurrentBuilds() +]) + +node { + + mvn = cesBuildLib.MavenWrapper.new(this) + +<#if config.jenkins.mavenCentralMirror?has_content> + mvn.useMirrors([name: 'maven-central-mirror', mirrorOf: 'central', url: env.${config.application.namePrefixForEnvVars}MAVEN_CENTRAL_MIRROR]) + +<#noparse> + + catchError { + + stage('Checkout') { + checkout scm + } + + stage('Build') { + mvn 'clean package -DskipTests -Dcheckstyle.skip' + archiveArtifacts artifacts: '**/target/*.jar' + } + + stage('Test') { + // Tests skipped for faster demo and exercise purposes + //mvn 'test -Dmaven.test.failure.ignore=true -Dcheckstyle.skip' + } + + String imageName = "" + stage('Docker') { + String imageTag = createImageTag() + +<#if config.registry.twoRegistries> +<#noparse> + String pathPrefix = !dockerRegistryPushPath?.trim() ? "" : "${dockerRegistryPushPath}/" + imageName = "${dockerRegistryPushBaseUrl}/${pathPrefix}${application}:${imageTag}" + docker.withRegistry("http://${dockerRegistryPullBaseUrl}", dockerRegistryPullCredentials) { + image = docker.build(imageName, '.') + } + +<#else> +<#noparse> + String pathPrefix = !dockerRegistryPath?.trim() ? "" : "${dockerRegistryPath}/" + imageName = "${dockerRegistryBaseUrl}/${pathPrefix}${application}:${imageTag}" + image = docker.build(imageName, '.') + + + + if (isBuildSuccessful()) { +<#if config.registry.twoRegistries> +<#noparse> + docker.withRegistry("https://${dockerRegistryPushBaseUrl}", dockerRegistryPushCredentials) { + +<#else> +<#noparse> + docker.withRegistry("https://${dockerRegistryBaseUrl}", dockerRegistryCredentials) { + + +<#noparse> + image.push() + } + } else { + echo 'Skipping docker push, because build not successful' + } + } + + stage('Deploy') { + if (isBuildSuccessful() && env.BRANCH_NAME in ['main']) { + + def gitopsConfig = [ + scm: [ + provider : 'SCMManager', + credentialsId: scmManagerCredentials, + baseUrl : configRepositoryPRBaseUrl, + repositoryUrl : configRepositoryPRRepo, + ], + application: application, + gitopsTool: 'ARGO', + folderStructureStrategy: 'ENV_PER_APP', + + k8sVersion : env.${config.application.namePrefixForEnvVars}K8S_VERSION, + deployments: [ + sourcePath: 'k8s', + destinationRootPath: 'apps', + plain: [ + updateImages: [ + [ filename: 'deployment.yaml', + containerName: application, + imageName: imageName ] + ] + ] + ], + fileConfigmaps: [ + // Showcase for gitops-build-lib: Convert file into a config map + [ + name : 'messages', + sourceFilePath : '../src/main/resources/messages/messages.properties', + stage: ['staging', 'production'] + ] + ], + stages: [ + staging: [ + namespace: '${config.application.namePrefix}example-tenant-staging', + deployDirectly: true ], + production: [ + namespace: '${config.application.namePrefix}example-tenant-production', + deployDirectly: false ], + ] + ] +<#noparse> + addSpecificGitOpsConfig(gitopsConfig) + + deployViaGitops(gitopsConfig) + } else { + echo 'Skipping deploy, because build not successful or not on main branch' + } + } + } + + // Archive Unit and integration test results, if any + junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/surefire-reports/TEST-*.xml' +} + +/** Initializations might not be needed in a real-world setup, but are necessary for GitOps playground */ +void addSpecificGitOpsConfig(gitopsConfig) { + gitopsConfig += [ + // In the GitOps playground, we're loading the build libs from our local SCM so it also works in an offline context + // As the gitops-build-lib also uses the ces-build-lib we need to pass those parameters on. + // If you can access the internet, you can rely on the defaults, which load the lib from GitHub. + cesBuildLibRepo: cesBuildLibRepo, + cesBuildLibVersion: cesBuildLibVersion, + cesBuildLibCredentialsId: scmManagerCredentials, + + + // The GitOps playground provides parameters for overwriting the build images used by gitops-build-lib, so + // it also works in an offline context. + // Those parameters overwrite the following parameters. + // If you can access the internet, you can rely on the defaults, which load the images from public registries. + buildImages : [ + + helm: '${config.images.helm}', + kubectl: '${config.images.kubectl}', + kubeval: '${config.images.kubeval}', + helmKubeval: '${config.images.helmKubeval}', + yamllint: '${config.images.yamllint}' +<#noparse> + ] + ] +} + +String createImageTag() { + def git = cesBuildLib.Git.new(this) + String branch = git.simpleBranchName + String branchSuffix = "" + + if (!"develop".equals(branch)) { + branchSuffix = "-${branch}" + } + + return "${new Date().format('yyyyMMddHHmm')}-${git.commitHashShort}${branchSuffix}" +} + +def loadLibraries() { + // In the GitOps playground, we're loading the build libs from our local SCM so it also works in an offline context + // If you can access the internet, you could also load the libraries directly from github like so + // @Library(["github.com/cloudogu/ces-build-lib@${cesBuildLibVersion}", "github.com/cloudogu/gitops-build-lib@${gitOpsBuildLibRepo}"]) _ + //import com.cloudogu.ces.cesbuildlib.* + //import com.cloudogu.ces.gitopsbuildlib.* + + cesBuildLib = library(identifier: "ces-build-lib@${cesBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: cesBuildLibRepo, credentialsId: scmManagerCredentials]) + ).com.cloudogu.ces.cesbuildlib + + library(identifier: "gitops-build-lib@${gitOpsBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: gitOpsBuildLibRepo, credentialsId: scmManagerCredentials]) + ).com.cloudogu.gitops.gitopsbuildlib +} + +def cesBuildLib +def gitOpsBuildLib + diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml new file mode 100644 index 000000000..61be07b4c --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml @@ -0,0 +1,49 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-petclinic-plain +spec: + replicas: 1 + selector: + matchLabels: + app: spring-petclinic-plain + template: + metadata: + labels: + app: spring-petclinic-plain + spec: + containers: + - name: spring-petclinic-plain + image: localhost:30000/petclinic-plain:1 + ports: + - containerPort: 8080 + name: http + env: + - name: MANAGEMENT_SERVER_PORT + value: "9080" + - name: SPRING_MESSAGES_BASENAME + value: "file:/tmp/messages/messages" + - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK + value: INFO + readinessProbe: + failureThreshold: 3 + httpGet: + path: /actuator/health/readiness + port: 9080 + scheme: HTTP + volumeMounts: + - name: messages + mountPath: /tmp/messages +<#if config.application.podResources == true> + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 300m + memory: 650Mi + + volumes: + - name: messages + configMap: + name: messages diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml new file mode 100644 index 000000000..510da81fe --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml @@ -0,0 +1,25 @@ +<#if config.features.exampleApps.petclinic.baseDomain?has_content> +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: spring-petclinic-plain + labels: + app: spring-petclinic-plain +spec: + rules: + <#if config.application.urlSeparatorHyphen> + - host: production-petclinic-plain-${config.features.exampleApps.petclinic.baseDomain} + <#else> + - host: production.petclinic-plain.${config.features.exampleApps.petclinic.baseDomain} + + http: + paths: + - backend: + service: + name: spring-petclinic-plain + port: + name: http + path: / + pathType: Prefix + + diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml new file mode 100644 index 000000000..e88130722 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: spring-petclinic-plain + labels: + app: spring-petclinic-plain +spec: + type: <#if config.application.remote>LoadBalancer<#else>NodePort + ports: + - name: http + port: 80 + nodePort: 30021 + targetPort: http + selector: + app: spring-petclinic-plain diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml new file mode 100644 index 000000000..9a47ea7b9 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml @@ -0,0 +1,70 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-petclinic-plain +spec: + replicas: 1 + selector: + matchLabels: + app: spring-petclinic-plain + template: + metadata: + labels: + app: spring-petclinic-plain + spec: + containers: + - name: spring-petclinic-plain + image: localhost:30000/petclinic-plain:1 + ports: + - containerPort: 8080 + name: http + env: + - name: MANAGEMENT_SERVER_PORT + value: "9080" + - name: SPRING_MESSAGES_BASENAME + value: "file:/tmp/messages/messages" + - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK + value: INFO + readinessProbe: + failureThreshold: 3 + httpGet: + path: /actuator/health/readiness + port: 9080 + scheme: HTTP + volumeMounts: + - name: messages + mountPath: /tmp/messages + - name: tmp + # Make /tmp writable with readOnlyRootFilesystem + mountPath: /tmp +<#if config.application.podResources == true> + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 300m + memory: 650Mi + + securityContext: # Implement some least privilege good practices + runAsNonRoot: true + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + # These two seem to cause problems with OpenShift, so we disable them for now + #runAsUser: 65312 + #seccompProfile: + # type: RuntimeDefault + # With k8s 1.30 apparmor is added + # Won't work on k3d, though, because apparmor is not enabled + # apparmorProfile: "runtime/default" + enableServiceLinks: false + automountServiceAccountToken: false # When not communicating with API Server + volumes: + - name: messages + configMap: + name: messages + - name: tmp + emptyDir: {} \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml new file mode 100644 index 000000000..05e50faf5 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml @@ -0,0 +1,25 @@ +<#if config.features.exampleApps.petclinic.baseDomain?has_content> +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: spring-petclinic-plain + labels: + app: spring-petclinic-plain +spec: + rules: + <#if config.application.urlSeparatorHyphen> + - host: staging-petclinic-plain-${config.features.exampleApps.petclinic.baseDomain} + <#else> + - host: staging.petclinic-plain.${config.features.exampleApps.petclinic.baseDomain} + + http: + paths: + - backend: + service: + name: spring-petclinic-plain + port: + name: http + path: / + pathType: Prefix + + diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml new file mode 100644 index 000000000..77f87b98d --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: spring-petclinic-plain + labels: + app: spring-petclinic-plain +spec: + type: <#if config.application.remote>LoadBalancer<#else>NodePort + ports: + - name: http + port: 80 + nodePort: 30020 + targetPort: http + selector: + app: spring-petclinic-plain From 732e3f357cf98d1983e7684bbdf5c338fc568ecc Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:28:36 +0200 Subject: [PATCH 10/29] Update content-loader.md --- docs/content-loader-docs/content-loader.md | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index 60d122400..2d3dec2e5 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -4,8 +4,8 @@ This documentation shows the Content Loader feature and its usage. The Content L Example for a GOP (GitOps Playground) content repository: -- Sample [configuration file](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/gop-config.yaml/). -- [Directory structure](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources) as an example of a folder-based content repository. +- Sample [configuration file](content-loader-config.yaml). +- [Directory structure](.) as an example of a folder-based content repository. # Purpose of the Content Loader @@ -33,11 +33,11 @@ It also applies to end-user applications, for example, replacing the example Pet - The content deployed by GOP can be completely defined via configuration. - The content is defined in Git repositories, known as content repos. -- There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` ([see below](# Different Types of Content Repos)). -- For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET` ([see below](# The overrideMode)) -- Templating with [Freemarker](https://freemarker.apache.org/) is available in the content files ([see below](# Templating)). +- There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` ([see below](#different-types-of-content-repos)). +- For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET` ([see below](#the-overridemode)) +- Templating with [Freemarker](https://freemarker.apache.org/) is available in the content files ([see below](#templating)). - Multiple content repos can be specified in the `content.repos` field. - - See the [sample configuration file](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/gop-config.yaml). + - See the [sample configuration file](content-loader-config.yaml). - These are merged by the GOP in the defined order in a directory structure. - This allows you to overwrite files from all repos created by GOP. - One use case for this is, for example, a base repository that specifies the basic structure of all GOP instances in a cloud environment and more specialized repositories that contain specific applications. @@ -74,7 +74,7 @@ There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` Default: - `COPY` / `FOLDER_BASED`: Default branch of Repo. - `MIRROR`: All branches und tags of Repo -- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle pre-existing files in the repository ([see below](# The overrideMode). +- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle pre-existing files in the repository ([see below](#the-overridemode)). - `username` - `password` - `createJenkinsJob` - If `true` and Jenkins is active in GOP, and there is a `Jenkinsfile` in one of the content repositories or the specified `refs`, a Jenkins job is created for the associated SCM Manager namespace. @@ -103,12 +103,12 @@ Only the files (no Git history) are copied and committed to the target repo. **Properties** - `target` (required) Target repo, e.g. `namespace/name` -- `targetRef` - Git reference in `target` to which is pushed (branch or tag). \ - - If ref is a tag, targetRef is also treated as a tag. \ - - Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. \ +- `targetRef` - Git reference in `target` to which is pushed (branch or tag). + - If ref is a tag, targetRef is also treated as a tag. + - Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. - If` targetRef` is empty, the source `ref `is used by default. - `path `- Folder within the content repo from which to copy -- `templating `- If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see below](# Templating)). +- `templating `- If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see below](#templating)). #### `FOLDER_BASED` @@ -124,14 +124,14 @@ This allows, for example, additional Argo CD applications to be added and even y - `target` (required) - `path` - source folder in the content repository used for copying< -- `templating` - If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see below](# Templating)). +- `templating` - If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see below](#templating)). # The overrideMode For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET`. - `INIT` (default): Only push if the repository does not exist - `UPGRADE`: Delete all files after cloning the source – files that are not in the content will be deleted. -- `RESET`: Clone and copy – existing files are overwritten, files that are not in the content are retained. \ +- `RESET`: Clone and copy – existing files are overwritten, files that are not in the content are retained. **Note** \ With `MIRROR`, `RESET` does not reset the entire repository. Specific effect: Branches that exist in the target but not in the source are retained. @@ -160,7 +160,7 @@ image: # Example-Use Cases -## [Mirror the entire repository on every call](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/main/#komplettes-repo-bei-jedem-aufruf-spiegeln) +## Mirror the entire repository on every call ```yaml - url: 'https://github.com/cloudogu/spring-boot-helm-chart' target: '3rd-party/spring-boot-helm' @@ -178,7 +178,7 @@ image: overrideMode: UPGRADE ``` -In this repo, the folder structure is as follows: [argocd/argocd.](https://ecosystem.cloudogu.com/scm/repo/gop/content/code/sources/argocd/argocd) +In this repo, the folder structure is as follows: [argocd/argocd.](argocd/argocd) ## Mirror/copy repo and add specific files For example, to create a `Dockerfile` and `Jenkinsfile` and then create a Jenkins job. This example shows the `MIRROR` use case. As an alternative you can add type `COPY` in the first repo (petclinic). Reminder: no type means MIRROR (default). From c884142614552951c8cc965af2ce3693ce11035b Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:33:15 +0200 Subject: [PATCH 11/29] Update content-loader.md --- docs/content-loader-docs/content-loader.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index 2d3dec2e5..ca8cad0dc 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -33,9 +33,9 @@ It also applies to end-user applications, for example, replacing the example Pet - The content deployed by GOP can be completely defined via configuration. - The content is defined in Git repositories, known as content repos. -- There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` ([see below](#different-types-of-content-repos)). -- For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET` ([see below](#the-overridemode)) -- Templating with [Freemarker](https://freemarker.apache.org/) is available in the content files ([see below](#templating)). +- There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` ([see different types of content repos below](#different-types-of-content-repos)). +- For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET` ([see overrideMode below](#the-overridemode)) +- Templating with [Freemarker](https://freemarker.apache.org/) is available in the content files ([see templating below](#templating)). - Multiple content repos can be specified in the `content.repos` field. - See the [sample configuration file](content-loader-config.yaml). - These are merged by the GOP in the defined order in a directory structure. @@ -63,7 +63,7 @@ It also applies to end-user applications, for example, replacing the example Pet ## Different Types of Content Repos There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED`. -- `MIRROR` (default): The entire content repo is mirrored to the target repo if it does not yet exist (see overrideMode). +- `MIRROR` (default): The entire content repo is mirrored to the target repo if it does not yet exist ([see overrideMode below](#the-overridemode). - `COPY`: Only the files (no Git history) are copied to the target repository and committed. - `FOLDER_BASED`: Using the folder structure in the content repository, multiple repositories can be created and initialized or expanded in the target. @@ -74,7 +74,7 @@ There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` Default: - `COPY` / `FOLDER_BASED`: Default branch of Repo. - `MIRROR`: All branches und tags of Repo -- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle pre-existing files in the repository ([see below](#the-overridemode)). +- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle pre-existing files in the repository ([see overrideMode below](#the-overridemode)). - `username` - `password` - `createJenkinsJob` - If `true` and Jenkins is active in GOP, and there is a `Jenkinsfile` in one of the content repositories or the specified `refs`, a Jenkins job is created for the associated SCM Manager namespace. @@ -108,7 +108,7 @@ Only the files (no Git history) are copied and committed to the target repo. - Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. - If` targetRef` is empty, the source `ref `is used by default. - `path `- Folder within the content repo from which to copy -- `templating `- If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see below](#templating)). +- `templating `- If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see templating below](#templating)). #### `FOLDER_BASED` @@ -124,7 +124,7 @@ This allows, for example, additional Argo CD applications to be added and even y - `target` (required) - `path` - source folder in the content repository used for copying< -- `templating` - If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see below](#templating)). +- `templating` - If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see templating below](#templating)). # The overrideMode From 1f3ea41480ad6587403ffcb9aed1b1c56a64de5a Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:36:48 +0200 Subject: [PATCH 12/29] Delete docs/content-loader-docs/example-tenant directory --- .../example-tenant/gitops/README.md | 1 - .../apps/nginx-helm-umbrella/Chart.yaml | 7 - .../gitops/apps/nginx-helm-umbrella/README.md | 2 - .../apps/nginx-helm-umbrella/values.yaml | 10 - .../argocd/nginx-helm-umbrella.ftl.yaml | 25 --- .../gitops/argocd/nginx-helm.ftl.yaml | 33 --- .../gitops/argocd/petclinic-helm.ftl.yaml | 52 ----- .../gitops/argocd/petclinic-plain.ftl.yaml | 53 ----- .../petclinic-helm/Dockerfile.ftl | 15 -- .../petclinic-helm/Jenkinsfile.ftl | 200 ----------------- .../k8s/values-production.ftl.yaml | 13 -- .../petclinic-helm/k8s/values-shared.ftl.yaml | 30 --- .../k8s/values-staging.ftl.yaml | 13 -- .../petclinic-plain/Dockerfile.ftl | 15 -- .../petclinic-plain/Jenkinsfile.ftl | 206 ------------------ .../k8s/production/deployment.ftl.yaml | 49 ----- .../k8s/production/ingress.ftl.yaml | 25 --- .../k8s/production/service.ftl.yaml | 15 -- .../k8s/staging/deployment.ftl.yaml | 70 ------ .../k8s/staging/ingress.ftl.yaml | 25 --- .../k8s/staging/service.ftl.yaml | 15 -- 21 files changed, 874 deletions(-) delete mode 100644 docs/content-loader-docs/example-tenant/gitops/README.md delete mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md delete mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/README.md b/docs/content-loader-docs/example-tenant/gitops/README.md deleted file mode 100644 index 143c98de3..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/README.md +++ /dev/null @@ -1 +0,0 @@ -Contains examples of end-user applications \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml deleted file mode 100644 index 62b99b38c..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v2 -version: 13.2.21 -name: nginx -dependencies: - - name: nginx - version: 13.2.21 - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md deleted file mode 100644 index b5726758d..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md +++ /dev/null @@ -1,2 +0,0 @@ -3rd Party app (NGINX) with helm, templated by argo from a separate git repo, using helm's dependency mechanism. -This is an alternative approach to keeping the values.yaml inside the `application`. \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml deleted file mode 100644 index 347396191..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml +++ /dev/null @@ -1,10 +0,0 @@ -nginx: - service: - ports: - http: 80 - type: ClusterIP - - ingress: - enabled: true - pathType: Prefix - hostname: production.nginx-helm-umbrella.nginx.localhost diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml deleted file mode 100644 index 0426e32a2..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: nginx-helm-umbrella -<#if config.features.argocd.operator> - namespace: ${config.application.namePrefix}argocd -<#else> - namespace: ${config.application.namePrefix}example-tenant-production - -spec: - destination: - annotations: - myvar: ${config.content.variables.umbrella.nginxAnnotation} - namespace: ${config.application.namePrefix}example-tenant-production - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/nginx-helm-umbrella - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - - syncPolicy: - automated: - prune: true - selfHeal: true diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml deleted file mode 100644 index 47f2325b4..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: nginx-helm - <#if config.features.argocd.operator> -namespace: ${config.application.namePrefix}argocd - <#else> -namespace: ${config.application.namePrefix}example-tenant-production - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-production - server: https://kubernetes.default.svc - project: example-tenant - source: - path: '' - repoURL: >- - https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami - targetRevision: 13.2.21 - chart: nginx - helm: - values: |- - service: - ports: - http: 80 - type: ClusterIP - - ingress: - enabled: true - pathType: Prefix - hostname: production.nginx-helm.nginx.localhost - image: - repository: bitnamilegacy/nginx \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml deleted file mode 100644 index c2677f1e7..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml +++ /dev/null @@ -1,52 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: -<#if config.features.argocd.operator> - name: petclinic-helm-staging - namespace: ${config.application.namePrefix}argocd -<#else> - name: petclinic-helm - namespace: ${config.application.namePrefix}example-tenant-staging - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-staging - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/spring-petclinic-helm/staging - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: true - selfHeal: true - ---- -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: -<#if config.features.argocd.operator> - name: petclinic-helm-production - namespace: ${config.application.namePrefix}argocd -<#else> - name: petclinic-helm - namespace: ${config.application.namePrefix}example-tenant-production - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-production - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/spring-petclinic-helm/production - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: true - selfHeal: true \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml deleted file mode 100644 index 4f631b432..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: -<#if config.features.argocd.operator> - name: petclinic-plain-staging - namespace: ${config.application.namePrefix}argocd -<#else> - name: petclinic-plain - namespace: ${config.application.namePrefix}example-tenant-staging - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-staging - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/spring-petclinic-plain/staging - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: true - selfHeal: true - ---- - -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: -<#if config.features.argocd.operator> - name: petclinic-plain-production - namespace: ${config.application.namePrefix}argocd -<#else> - name: petclinic-plain - namespace: ${config.application.namePrefix}example-tenant-production - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-production - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/spring-petclinic-plain/production - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: true - selfHeal: true diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl deleted file mode 100644 index c739682dc..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl +++ /dev/null @@ -1,15 +0,0 @@ -# TODO -# FROM {config.contentVariables.images.petclinic} -FROM ${config.images.petclinic} - -# Set permissions to group 0 for openshift compatibility -# See https://docs.openshift.com/container-platform/4.15/openshift_images/create-images.html#use-uid_create-images -RUN mkdir /app && chown 1000:0 /app \ - && chmod -R g=u /app - -COPY target/*.jar /app/petclinic.jar - -EXPOSE 8080 -USER 1000 - -ENTRYPOINT [ "java", "-server","-jar", "/app/petclinic.jar" ] diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl deleted file mode 100644 index 2dcbcf60a..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl +++ /dev/null @@ -1,200 +0,0 @@ -#!groovy - -String getApplication() { "spring-petclinic-helm" } -String getConfigRepositoryPRRepo() { '${(config.application.namePrefix?has_content)?then(config.application.namePrefix, "") + "example-tenant/gitops"}' } -String getScmManagerCredentials() { 'scmm-user' } -String getConfigRepositoryPRBaseUrl() { env.${config.application.namePrefixForEnvVars}SCMM_URL } - -String getDockerRegistryBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_URL } -String getDockerRegistryPath() { env.${config.application.namePrefixForEnvVars}REGISTRY_PATH } -String getDockerRegistryCredentials() { 'registry-user' } - -<#if config.registry.twoRegistries> -String getDockerRegistryProxyBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_PROXY_URL } -String getDockerRegistryProxyCredentials() { 'registry-proxy-user' } - - -<#noparse> - -String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } -String getCesBuildLibVersion() { '2.5.0' } -String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } -String getGitOpsBuildLibVersion() { '0.7.0'} -String getHelmChartRepository() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/spring-boot-helm-chart" } -String getHelmChartVersion() { "0.4.0" } -String getMainBranch() { 'main' } - -cesBuildLib = library(identifier: "ces-build-lib@${cesBuildLibVersion}", - retriever: modernSCM([$class: 'GitSCMSource', remote: cesBuildLibRepo, credentialsId: scmManagerCredentials]) -).com.cloudogu.ces.cesbuildlib - -gitOpsBuildLib = library(identifier: "gitops-build-lib@${gitOpsBuildLibVersion}", - retriever: modernSCM([$class: 'GitSCMSource', remote: gitOpsBuildLibRepo, credentialsId: scmManagerCredentials]) -).com.cloudogu.gitops.gitopsbuildlib - -properties([ - // Don't run concurrent builds, because the ITs use the same port causing random failures on concurrent builds. - disableConcurrentBuilds() -]) - -node { - - -<#if config.images.maven?has_content> - <#if config.registry.twoRegistries> - mvn = cesBuildLib.MavenInDocker.new(this, '${config.images.maven}', dockerRegistryProxyCredentials) - <#else> - mvn = cesBuildLib.MavenInDocker.new(this, '${config.images.maven}') - -<#else> - mvn = cesBuildLib.MavenWrapper.new(this) - - -<#if config.jenkins.mavenCentralMirror?has_content> - mvn.useMirrors([name: 'maven-central-mirror', mirrorOf: 'central', url: env.${config.application.namePrefixForEnvVars}MAVEN_CENTRAL_MIRROR]) - -<#noparse> - - catchError { - - stage('Checkout') { - checkout scm - } - - stage('Build') { - mvn 'clean package -DskipTests -Dcheckstyle.skip' - archiveArtifacts artifacts: '**/target/*.jar' - } - - stage('Test') { - // Disable database integration tests because they start docker images (which won't work in air-gapped envs and take a lot of time in demos) - mvn "test -Dmaven.test.failure.ignore=true -Dcheckstyle.skip " + - '-Dtest=!org.springframework.samples.petclinic.MySqlIntegrationTests,!org.springframework.samples.petclinic.PostgresIntegrationTests' - } - - String imageName = "" - stage('Docker') { - String imageTag = createImageTag() - -<#noparse> - String pathPrefix = !dockerRegistryPath?.trim() ? "" : "${dockerRegistryPath}/" - imageName = "${dockerRegistryBaseUrl}/${pathPrefix}${application}:${imageTag}" - -<#if config.registry.twoRegistries> -<#noparse> - docker.withRegistry("https://${dockerRegistryProxyBaseUrl}", dockerRegistryProxyCredentials) { - image = docker.build(imageName, '.') - } - -<#else> -<#noparse> - image = docker.build(imageName, '.') - - -<#noparse> - if (isBuildSuccessful()) { - docker.withRegistry("https://${dockerRegistryBaseUrl}", dockerRegistryCredentials) { - image.push() - } - } else { - echo 'Skipping docker push, because build not successful' - } - } - - stage('Deploy') { - if (isBuildSuccessful() && env.BRANCH_NAME in [mainBranch]) { - - def gitopsConfig = [ - scm : [ - provider : 'SCMManager', - credentialsId: scmManagerCredentials, - baseUrl : configRepositoryPRBaseUrl, - repositoryUrl : configRepositoryPRRepo, - ], - cesBuildLibRepo: cesBuildLibRepo, - cesBuildLibVersion: cesBuildLibVersion, - cesBuildLibCredentialsId: scmManagerCredentials, - application: application, - mainBranch: mainBranch, - gitopsTool: 'ARGO', - folderStructureStrategy: 'ENV_PER_APP', - - k8sVersion : env.${config.application.namePrefixForEnvVars}K8S_VERSION, - buildImages : [ -<#if config.registry.twoRegistries> - helm: [ - image: '${config.images.helm}', - credentialsId: dockerRegistryProxyCredentials - ], - kubectl: [ - image: '${config.images.kubectl}', - credentialsId: dockerRegistryProxyCredentials - ], - kubeval: [ - image: '${config.images.kubeval}', - credentialsId: dockerRegistryProxyCredentials - ], - helmKubeval: [ - image: '${config.images.helmKubeval}', - credentialsId: dockerRegistryProxyCredentials - ], - yamllint: [ - image: '${config.images.yamllint}', - credentialsId: dockerRegistryProxyCredentials - ] -<#else> - helm: '${config.images.helm}', - kubectl: '${config.images.kubectl}', - kubeval: '${config.images.kubeval}', - helmKubeval: '${config.images.helmKubeval}', - yamllint: '${config.images.yamllint}' - - ], - deployments: [ - sourcePath: 'k8s', - destinationRootPath: 'apps', - helm : [ - repoType : 'GIT', - credentialsId : scmManagerCredentials, - repoUrl : helmChartRepository, - version: helmChartVersion, - updateValues : [[fieldPath: "image.name", newValue: imageName]] - ] - ], - stages: [ - staging: [ - namespace: '${config.application.namePrefix}example-tenant-staging', - deployDirectly: true ], - production: [ - namespace: '${config.application.namePrefix}example-tenant-production', - deployDirectly: false ] - ] - ] -<#noparse> - deployViaGitops(gitopsConfig) - } else { - echo 'Skipping deploy, because build not successful or not on main branch' - } - } - } - - // Archive Unit and integration test results, if any - junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/surefire-reports/TEST-*.xml' -} - - -String createImageTag() { - def git = cesBuildLib.Git.new(this) - String branch = git.simpleBranchName - String branchSuffix = "" - - if (!"develop".equals(branch)) { - branchSuffix = "-${branch}" - } - - return "${new Date().format('yyyyMMddHHmm')}-${git.commitHashShort}${branchSuffix}" -} - -def cesBuildLib -def gitOpsBuildLib - \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml deleted file mode 100644 index b7528242d..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml +++ /dev/null @@ -1,13 +0,0 @@ -service: - port: 80 - -<#if config.features.exampleApps.petclinic.baseDomain?has_content> -ingress: - hosts: - <#if config.application.urlSeparatorHyphen> - - host: production-petclinic-helm-${config.features.exampleApps.petclinic.baseDomain} - <#else> - - host: production.petclinic-helm.${config.features.exampleApps.petclinic.baseDomain} - - paths: ['/'] - diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml deleted file mode 100644 index 2aa824334..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml +++ /dev/null @@ -1,30 +0,0 @@ -extraEnv: | - - name: TZ - value: Europe/Berlin - -service: - type: <#if config.application.remote>LoadBalancer<#else>ClusterIP - -ingress: - enabled: <#if config.features.exampleApps.petclinic.baseDomain?has_content>true<#else>false - - -<#if config.application.openshift == true> -securityContext: - runAsUser: null - runAsGroup: null - - -<#if config.application.podResources == true> -resources: - limits: - cpu: '1' - memory: 1Gi - requests: - cpu: 300m - memory: 650Mi -<#else> -<#-- Explicitly set to null, because the chart sets memory by default - https://github.com/cloudogu/spring-boot-helm-chart/blob/0.3.2/values.yaml#L40 --> -resources: null - diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml deleted file mode 100644 index b0eab58c7..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml +++ /dev/null @@ -1,13 +0,0 @@ -service: - port: 80 - -<#if config.features.exampleApps.petclinic.baseDomain?has_content> -ingress: - hosts: - <#if config.application.urlSeparatorHyphen> - - host: staging-petclinic-helm-${config.features.exampleApps.petclinic.baseDomain} - <#else> - - host: staging.petclinic-helm.${config.features.exampleApps.petclinic.baseDomain} - - paths: ['/'] - diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl deleted file mode 100644 index c739682dc..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl +++ /dev/null @@ -1,15 +0,0 @@ -# TODO -# FROM {config.contentVariables.images.petclinic} -FROM ${config.images.petclinic} - -# Set permissions to group 0 for openshift compatibility -# See https://docs.openshift.com/container-platform/4.15/openshift_images/create-images.html#use-uid_create-images -RUN mkdir /app && chown 1000:0 /app \ - && chmod -R g=u /app - -COPY target/*.jar /app/petclinic.jar - -EXPOSE 8080 -USER 1000 - -ENTRYPOINT [ "java", "-server","-jar", "/app/petclinic.jar" ] diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl deleted file mode 100644 index 1c6b5b268..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl +++ /dev/null @@ -1,206 +0,0 @@ -#!groovy - -String getApplication() { 'spring-petclinic-plain' } -String getConfigRepositoryPRRepo() { '${(config.application.namePrefix?has_content)?then(config.application.namePrefix, "") + "example-tenant/gitops"}' } -String getScmManagerCredentials() { 'scmm-user' } -String getConfigRepositoryPRBaseUrl() { env.${config.application.namePrefixForEnvVars}SCMM_URL } - -String getDockerRegistryBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_URL } -String getDockerRegistryPath() { env.${config.application.namePrefixForEnvVars}REGISTRY_PATH } -String getDockerRegistryCredentials() { 'registry-user' } - -<#if config.registry.twoRegistries> -String getDockerRegistryProxyBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_PROXY_URL } -String getDockerRegistryProxyCredentials() { 'registry-proxy-user' } - -<#noparse> -String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } -String getCesBuildLibVersion() { '2.5.0' } -String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } -String getGitOpsBuildLibVersion() { '0.7.0'} - -loadLibraries() - -properties([ - // Don't run concurrent builds, because the ITs use the same port causing random failures on concurrent builds. - disableConcurrentBuilds() -]) - -node { - - mvn = cesBuildLib.MavenWrapper.new(this) - -<#if config.jenkins.mavenCentralMirror?has_content> - mvn.useMirrors([name: 'maven-central-mirror', mirrorOf: 'central', url: env.${config.application.namePrefixForEnvVars}MAVEN_CENTRAL_MIRROR]) - -<#noparse> - - catchError { - - stage('Checkout') { - checkout scm - } - - stage('Build') { - mvn 'clean package -DskipTests -Dcheckstyle.skip' - archiveArtifacts artifacts: '**/target/*.jar' - } - - stage('Test') { - // Tests skipped for faster demo and exercise purposes - //mvn 'test -Dmaven.test.failure.ignore=true -Dcheckstyle.skip' - } - - String imageName = "" - stage('Docker') { - String imageTag = createImageTag() - -<#if config.registry.twoRegistries> -<#noparse> - String pathPrefix = !dockerRegistryPushPath?.trim() ? "" : "${dockerRegistryPushPath}/" - imageName = "${dockerRegistryPushBaseUrl}/${pathPrefix}${application}:${imageTag}" - docker.withRegistry("http://${dockerRegistryPullBaseUrl}", dockerRegistryPullCredentials) { - image = docker.build(imageName, '.') - } - -<#else> -<#noparse> - String pathPrefix = !dockerRegistryPath?.trim() ? "" : "${dockerRegistryPath}/" - imageName = "${dockerRegistryBaseUrl}/${pathPrefix}${application}:${imageTag}" - image = docker.build(imageName, '.') - - - - if (isBuildSuccessful()) { -<#if config.registry.twoRegistries> -<#noparse> - docker.withRegistry("https://${dockerRegistryPushBaseUrl}", dockerRegistryPushCredentials) { - -<#else> -<#noparse> - docker.withRegistry("https://${dockerRegistryBaseUrl}", dockerRegistryCredentials) { - - -<#noparse> - image.push() - } - } else { - echo 'Skipping docker push, because build not successful' - } - } - - stage('Deploy') { - if (isBuildSuccessful() && env.BRANCH_NAME in ['main']) { - - def gitopsConfig = [ - scm: [ - provider : 'SCMManager', - credentialsId: scmManagerCredentials, - baseUrl : configRepositoryPRBaseUrl, - repositoryUrl : configRepositoryPRRepo, - ], - application: application, - gitopsTool: 'ARGO', - folderStructureStrategy: 'ENV_PER_APP', - - k8sVersion : env.${config.application.namePrefixForEnvVars}K8S_VERSION, - deployments: [ - sourcePath: 'k8s', - destinationRootPath: 'apps', - plain: [ - updateImages: [ - [ filename: 'deployment.yaml', - containerName: application, - imageName: imageName ] - ] - ] - ], - fileConfigmaps: [ - // Showcase for gitops-build-lib: Convert file into a config map - [ - name : 'messages', - sourceFilePath : '../src/main/resources/messages/messages.properties', - stage: ['staging', 'production'] - ] - ], - stages: [ - staging: [ - namespace: '${config.application.namePrefix}example-tenant-staging', - deployDirectly: true ], - production: [ - namespace: '${config.application.namePrefix}example-tenant-production', - deployDirectly: false ], - ] - ] -<#noparse> - addSpecificGitOpsConfig(gitopsConfig) - - deployViaGitops(gitopsConfig) - } else { - echo 'Skipping deploy, because build not successful or not on main branch' - } - } - } - - // Archive Unit and integration test results, if any - junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/surefire-reports/TEST-*.xml' -} - -/** Initializations might not be needed in a real-world setup, but are necessary for GitOps playground */ -void addSpecificGitOpsConfig(gitopsConfig) { - gitopsConfig += [ - // In the GitOps playground, we're loading the build libs from our local SCM so it also works in an offline context - // As the gitops-build-lib also uses the ces-build-lib we need to pass those parameters on. - // If you can access the internet, you can rely on the defaults, which load the lib from GitHub. - cesBuildLibRepo: cesBuildLibRepo, - cesBuildLibVersion: cesBuildLibVersion, - cesBuildLibCredentialsId: scmManagerCredentials, - - - // The GitOps playground provides parameters for overwriting the build images used by gitops-build-lib, so - // it also works in an offline context. - // Those parameters overwrite the following parameters. - // If you can access the internet, you can rely on the defaults, which load the images from public registries. - buildImages : [ - - helm: '${config.images.helm}', - kubectl: '${config.images.kubectl}', - kubeval: '${config.images.kubeval}', - helmKubeval: '${config.images.helmKubeval}', - yamllint: '${config.images.yamllint}' -<#noparse> - ] - ] -} - -String createImageTag() { - def git = cesBuildLib.Git.new(this) - String branch = git.simpleBranchName - String branchSuffix = "" - - if (!"develop".equals(branch)) { - branchSuffix = "-${branch}" - } - - return "${new Date().format('yyyyMMddHHmm')}-${git.commitHashShort}${branchSuffix}" -} - -def loadLibraries() { - // In the GitOps playground, we're loading the build libs from our local SCM so it also works in an offline context - // If you can access the internet, you could also load the libraries directly from github like so - // @Library(["github.com/cloudogu/ces-build-lib@${cesBuildLibVersion}", "github.com/cloudogu/gitops-build-lib@${gitOpsBuildLibRepo}"]) _ - //import com.cloudogu.ces.cesbuildlib.* - //import com.cloudogu.ces.gitopsbuildlib.* - - cesBuildLib = library(identifier: "ces-build-lib@${cesBuildLibVersion}", - retriever: modernSCM([$class: 'GitSCMSource', remote: cesBuildLibRepo, credentialsId: scmManagerCredentials]) - ).com.cloudogu.ces.cesbuildlib - - library(identifier: "gitops-build-lib@${gitOpsBuildLibVersion}", - retriever: modernSCM([$class: 'GitSCMSource', remote: gitOpsBuildLibRepo, credentialsId: scmManagerCredentials]) - ).com.cloudogu.gitops.gitopsbuildlib -} - -def cesBuildLib -def gitOpsBuildLib - diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml deleted file mode 100644 index 61be07b4c..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml +++ /dev/null @@ -1,49 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: spring-petclinic-plain -spec: - replicas: 1 - selector: - matchLabels: - app: spring-petclinic-plain - template: - metadata: - labels: - app: spring-petclinic-plain - spec: - containers: - - name: spring-petclinic-plain - image: localhost:30000/petclinic-plain:1 - ports: - - containerPort: 8080 - name: http - env: - - name: MANAGEMENT_SERVER_PORT - value: "9080" - - name: SPRING_MESSAGES_BASENAME - value: "file:/tmp/messages/messages" - - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK - value: INFO - readinessProbe: - failureThreshold: 3 - httpGet: - path: /actuator/health/readiness - port: 9080 - scheme: HTTP - volumeMounts: - - name: messages - mountPath: /tmp/messages -<#if config.application.podResources == true> - resources: - limits: - cpu: '1' - memory: 1Gi - requests: - cpu: 300m - memory: 650Mi - - volumes: - - name: messages - configMap: - name: messages diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml deleted file mode 100644 index 510da81fe..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml +++ /dev/null @@ -1,25 +0,0 @@ -<#if config.features.exampleApps.petclinic.baseDomain?has_content> -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: spring-petclinic-plain - labels: - app: spring-petclinic-plain -spec: - rules: - <#if config.application.urlSeparatorHyphen> - - host: production-petclinic-plain-${config.features.exampleApps.petclinic.baseDomain} - <#else> - - host: production.petclinic-plain.${config.features.exampleApps.petclinic.baseDomain} - - http: - paths: - - backend: - service: - name: spring-petclinic-plain - port: - name: http - path: / - pathType: Prefix - - diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml deleted file mode 100644 index e88130722..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: spring-petclinic-plain - labels: - app: spring-petclinic-plain -spec: - type: <#if config.application.remote>LoadBalancer<#else>NodePort - ports: - - name: http - port: 80 - nodePort: 30021 - targetPort: http - selector: - app: spring-petclinic-plain diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml deleted file mode 100644 index 9a47ea7b9..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml +++ /dev/null @@ -1,70 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: spring-petclinic-plain -spec: - replicas: 1 - selector: - matchLabels: - app: spring-petclinic-plain - template: - metadata: - labels: - app: spring-petclinic-plain - spec: - containers: - - name: spring-petclinic-plain - image: localhost:30000/petclinic-plain:1 - ports: - - containerPort: 8080 - name: http - env: - - name: MANAGEMENT_SERVER_PORT - value: "9080" - - name: SPRING_MESSAGES_BASENAME - value: "file:/tmp/messages/messages" - - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK - value: INFO - readinessProbe: - failureThreshold: 3 - httpGet: - path: /actuator/health/readiness - port: 9080 - scheme: HTTP - volumeMounts: - - name: messages - mountPath: /tmp/messages - - name: tmp - # Make /tmp writable with readOnlyRootFilesystem - mountPath: /tmp -<#if config.application.podResources == true> - resources: - limits: - cpu: '1' - memory: 1Gi - requests: - cpu: 300m - memory: 650Mi - - securityContext: # Implement some least privilege good practices - runAsNonRoot: true - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - # These two seem to cause problems with OpenShift, so we disable them for now - #runAsUser: 65312 - #seccompProfile: - # type: RuntimeDefault - # With k8s 1.30 apparmor is added - # Won't work on k3d, though, because apparmor is not enabled - # apparmorProfile: "runtime/default" - enableServiceLinks: false - automountServiceAccountToken: false # When not communicating with API Server - volumes: - - name: messages - configMap: - name: messages - - name: tmp - emptyDir: {} \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml deleted file mode 100644 index 05e50faf5..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml +++ /dev/null @@ -1,25 +0,0 @@ -<#if config.features.exampleApps.petclinic.baseDomain?has_content> -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: spring-petclinic-plain - labels: - app: spring-petclinic-plain -spec: - rules: - <#if config.application.urlSeparatorHyphen> - - host: staging-petclinic-plain-${config.features.exampleApps.petclinic.baseDomain} - <#else> - - host: staging.petclinic-plain.${config.features.exampleApps.petclinic.baseDomain} - - http: - paths: - - backend: - service: - name: spring-petclinic-plain - port: - name: http - path: / - pathType: Prefix - - diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml deleted file mode 100644 index 77f87b98d..000000000 --- a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: spring-petclinic-plain - labels: - app: spring-petclinic-plain -spec: - type: <#if config.application.remote>LoadBalancer<#else>NodePort - ports: - - name: http - port: 80 - nodePort: 30020 - targetPort: http - selector: - app: spring-petclinic-plain From f20e974ebdb6818eed84a820968d8f77135bea2e Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:45:34 +0200 Subject: [PATCH 13/29] Add files via upload --- .../example-tenant/gitops/README.md | 1 + .../apps/nginx-helm-umbrella/Chart.yaml | 7 + .../gitops/apps/nginx-helm-umbrella/README.md | 2 + .../apps/nginx-helm-umbrella/values.yaml | 10 + .../argocd/nginx-helm-umbrella.ftl.yaml | 25 +++ .../gitops/argocd/nginx-helm.ftl.yaml | 33 +++ .../gitops/argocd/petclinic-helm.ftl.yaml | 52 +++++ .../gitops/argocd/petclinic-plain.ftl.yaml | 53 +++++ .../petclinic-helm/Dockerfile.ftl | 15 ++ .../petclinic-helm/Jenkinsfile.ftl | 200 +++++++++++++++++ .../k8s/values-production.ftl.yaml | 13 ++ .../petclinic-helm/k8s/values-shared.ftl.yaml | 30 +++ .../k8s/values-staging.ftl.yaml | 13 ++ .../petclinic-plain/Dockerfile.ftl | 15 ++ .../petclinic-plain/Jenkinsfile.ftl | 206 ++++++++++++++++++ .../k8s/production/deployment.ftl.yaml | 49 +++++ .../k8s/production/ingress.ftl.yaml | 25 +++ .../k8s/production/service.ftl.yaml | 15 ++ .../k8s/staging/deployment.ftl.yaml | 70 ++++++ .../k8s/staging/ingress.ftl.yaml | 25 +++ .../k8s/staging/service.ftl.yaml | 15 ++ 21 files changed, 874 insertions(+) create mode 100644 docs/content-loader-docs/example-tenant/gitops/README.md create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/README.md b/docs/content-loader-docs/example-tenant/gitops/README.md new file mode 100644 index 000000000..143c98de3 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/README.md @@ -0,0 +1 @@ +Contains examples of end-user applications \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml new file mode 100644 index 000000000..62b99b38c --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +version: 13.2.21 +name: nginx +dependencies: + - name: nginx + version: 13.2.21 + repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md new file mode 100644 index 000000000..b5726758d --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md @@ -0,0 +1,2 @@ +3rd Party app (NGINX) with helm, templated by argo from a separate git repo, using helm's dependency mechanism. +This is an alternative approach to keeping the values.yaml inside the `application`. \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml new file mode 100644 index 000000000..347396191 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml @@ -0,0 +1,10 @@ +nginx: + service: + ports: + http: 80 + type: ClusterIP + + ingress: + enabled: true + pathType: Prefix + hostname: production.nginx-helm-umbrella.nginx.localhost diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml new file mode 100644 index 000000000..0426e32a2 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml @@ -0,0 +1,25 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: nginx-helm-umbrella +<#if config.features.argocd.operator> + namespace: ${config.application.namePrefix}argocd +<#else> + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + annotations: + myvar: ${config.content.variables.umbrella.nginxAnnotation} + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/nginx-helm-umbrella + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + + syncPolicy: + automated: + prune: true + selfHeal: true diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml new file mode 100644 index 000000000..47f2325b4 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml @@ -0,0 +1,33 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: nginx-helm + <#if config.features.argocd.operator> +namespace: ${config.application.namePrefix}argocd + <#else> +namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: '' + repoURL: >- + https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami + targetRevision: 13.2.21 + chart: nginx + helm: + values: |- + service: + ports: + http: 80 + type: ClusterIP + + ingress: + enabled: true + pathType: Prefix + hostname: production.nginx-helm.nginx.localhost + image: + repository: bitnamilegacy/nginx \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml new file mode 100644 index 000000000..c2677f1e7 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml @@ -0,0 +1,52 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-helm-staging + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-helm + namespace: ${config.application.namePrefix}example-tenant-staging + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-staging + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-helm/staging + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true + +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-helm-production + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-helm + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-helm/production + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml new file mode 100644 index 000000000..4f631b432 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml @@ -0,0 +1,53 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-plain-staging + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-plain + namespace: ${config.application.namePrefix}example-tenant-staging + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-staging + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-plain/staging + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true + +--- + +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-plain-production + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-plain + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-plain/production + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl new file mode 100644 index 000000000..c739682dc --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl @@ -0,0 +1,15 @@ +# TODO +# FROM {config.contentVariables.images.petclinic} +FROM ${config.images.petclinic} + +# Set permissions to group 0 for openshift compatibility +# See https://docs.openshift.com/container-platform/4.15/openshift_images/create-images.html#use-uid_create-images +RUN mkdir /app && chown 1000:0 /app \ + && chmod -R g=u /app + +COPY target/*.jar /app/petclinic.jar + +EXPOSE 8080 +USER 1000 + +ENTRYPOINT [ "java", "-server","-jar", "/app/petclinic.jar" ] diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl new file mode 100644 index 000000000..2dcbcf60a --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl @@ -0,0 +1,200 @@ +#!groovy + +String getApplication() { "spring-petclinic-helm" } +String getConfigRepositoryPRRepo() { '${(config.application.namePrefix?has_content)?then(config.application.namePrefix, "") + "example-tenant/gitops"}' } +String getScmManagerCredentials() { 'scmm-user' } +String getConfigRepositoryPRBaseUrl() { env.${config.application.namePrefixForEnvVars}SCMM_URL } + +String getDockerRegistryBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_URL } +String getDockerRegistryPath() { env.${config.application.namePrefixForEnvVars}REGISTRY_PATH } +String getDockerRegistryCredentials() { 'registry-user' } + +<#if config.registry.twoRegistries> +String getDockerRegistryProxyBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_PROXY_URL } +String getDockerRegistryProxyCredentials() { 'registry-proxy-user' } + + +<#noparse> + +String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } +String getCesBuildLibVersion() { '2.5.0' } +String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } +String getGitOpsBuildLibVersion() { '0.7.0'} +String getHelmChartRepository() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/spring-boot-helm-chart" } +String getHelmChartVersion() { "0.4.0" } +String getMainBranch() { 'main' } + +cesBuildLib = library(identifier: "ces-build-lib@${cesBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: cesBuildLibRepo, credentialsId: scmManagerCredentials]) +).com.cloudogu.ces.cesbuildlib + +gitOpsBuildLib = library(identifier: "gitops-build-lib@${gitOpsBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: gitOpsBuildLibRepo, credentialsId: scmManagerCredentials]) +).com.cloudogu.gitops.gitopsbuildlib + +properties([ + // Don't run concurrent builds, because the ITs use the same port causing random failures on concurrent builds. + disableConcurrentBuilds() +]) + +node { + + +<#if config.images.maven?has_content> + <#if config.registry.twoRegistries> + mvn = cesBuildLib.MavenInDocker.new(this, '${config.images.maven}', dockerRegistryProxyCredentials) + <#else> + mvn = cesBuildLib.MavenInDocker.new(this, '${config.images.maven}') + +<#else> + mvn = cesBuildLib.MavenWrapper.new(this) + + +<#if config.jenkins.mavenCentralMirror?has_content> + mvn.useMirrors([name: 'maven-central-mirror', mirrorOf: 'central', url: env.${config.application.namePrefixForEnvVars}MAVEN_CENTRAL_MIRROR]) + +<#noparse> + + catchError { + + stage('Checkout') { + checkout scm + } + + stage('Build') { + mvn 'clean package -DskipTests -Dcheckstyle.skip' + archiveArtifacts artifacts: '**/target/*.jar' + } + + stage('Test') { + // Disable database integration tests because they start docker images (which won't work in air-gapped envs and take a lot of time in demos) + mvn "test -Dmaven.test.failure.ignore=true -Dcheckstyle.skip " + + '-Dtest=!org.springframework.samples.petclinic.MySqlIntegrationTests,!org.springframework.samples.petclinic.PostgresIntegrationTests' + } + + String imageName = "" + stage('Docker') { + String imageTag = createImageTag() + +<#noparse> + String pathPrefix = !dockerRegistryPath?.trim() ? "" : "${dockerRegistryPath}/" + imageName = "${dockerRegistryBaseUrl}/${pathPrefix}${application}:${imageTag}" + +<#if config.registry.twoRegistries> +<#noparse> + docker.withRegistry("https://${dockerRegistryProxyBaseUrl}", dockerRegistryProxyCredentials) { + image = docker.build(imageName, '.') + } + +<#else> +<#noparse> + image = docker.build(imageName, '.') + + +<#noparse> + if (isBuildSuccessful()) { + docker.withRegistry("https://${dockerRegistryBaseUrl}", dockerRegistryCredentials) { + image.push() + } + } else { + echo 'Skipping docker push, because build not successful' + } + } + + stage('Deploy') { + if (isBuildSuccessful() && env.BRANCH_NAME in [mainBranch]) { + + def gitopsConfig = [ + scm : [ + provider : 'SCMManager', + credentialsId: scmManagerCredentials, + baseUrl : configRepositoryPRBaseUrl, + repositoryUrl : configRepositoryPRRepo, + ], + cesBuildLibRepo: cesBuildLibRepo, + cesBuildLibVersion: cesBuildLibVersion, + cesBuildLibCredentialsId: scmManagerCredentials, + application: application, + mainBranch: mainBranch, + gitopsTool: 'ARGO', + folderStructureStrategy: 'ENV_PER_APP', + + k8sVersion : env.${config.application.namePrefixForEnvVars}K8S_VERSION, + buildImages : [ +<#if config.registry.twoRegistries> + helm: [ + image: '${config.images.helm}', + credentialsId: dockerRegistryProxyCredentials + ], + kubectl: [ + image: '${config.images.kubectl}', + credentialsId: dockerRegistryProxyCredentials + ], + kubeval: [ + image: '${config.images.kubeval}', + credentialsId: dockerRegistryProxyCredentials + ], + helmKubeval: [ + image: '${config.images.helmKubeval}', + credentialsId: dockerRegistryProxyCredentials + ], + yamllint: [ + image: '${config.images.yamllint}', + credentialsId: dockerRegistryProxyCredentials + ] +<#else> + helm: '${config.images.helm}', + kubectl: '${config.images.kubectl}', + kubeval: '${config.images.kubeval}', + helmKubeval: '${config.images.helmKubeval}', + yamllint: '${config.images.yamllint}' + + ], + deployments: [ + sourcePath: 'k8s', + destinationRootPath: 'apps', + helm : [ + repoType : 'GIT', + credentialsId : scmManagerCredentials, + repoUrl : helmChartRepository, + version: helmChartVersion, + updateValues : [[fieldPath: "image.name", newValue: imageName]] + ] + ], + stages: [ + staging: [ + namespace: '${config.application.namePrefix}example-tenant-staging', + deployDirectly: true ], + production: [ + namespace: '${config.application.namePrefix}example-tenant-production', + deployDirectly: false ] + ] + ] +<#noparse> + deployViaGitops(gitopsConfig) + } else { + echo 'Skipping deploy, because build not successful or not on main branch' + } + } + } + + // Archive Unit and integration test results, if any + junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/surefire-reports/TEST-*.xml' +} + + +String createImageTag() { + def git = cesBuildLib.Git.new(this) + String branch = git.simpleBranchName + String branchSuffix = "" + + if (!"develop".equals(branch)) { + branchSuffix = "-${branch}" + } + + return "${new Date().format('yyyyMMddHHmm')}-${git.commitHashShort}${branchSuffix}" +} + +def cesBuildLib +def gitOpsBuildLib + \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml new file mode 100644 index 000000000..b7528242d --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml @@ -0,0 +1,13 @@ +service: + port: 80 + +<#if config.features.exampleApps.petclinic.baseDomain?has_content> +ingress: + hosts: + <#if config.application.urlSeparatorHyphen> + - host: production-petclinic-helm-${config.features.exampleApps.petclinic.baseDomain} + <#else> + - host: production.petclinic-helm.${config.features.exampleApps.petclinic.baseDomain} + + paths: ['/'] + diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml new file mode 100644 index 000000000..2aa824334 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml @@ -0,0 +1,30 @@ +extraEnv: | + - name: TZ + value: Europe/Berlin + +service: + type: <#if config.application.remote>LoadBalancer<#else>ClusterIP + +ingress: + enabled: <#if config.features.exampleApps.petclinic.baseDomain?has_content>true<#else>false + + +<#if config.application.openshift == true> +securityContext: + runAsUser: null + runAsGroup: null + + +<#if config.application.podResources == true> +resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 300m + memory: 650Mi +<#else> +<#-- Explicitly set to null, because the chart sets memory by default + https://github.com/cloudogu/spring-boot-helm-chart/blob/0.3.2/values.yaml#L40 --> +resources: null + diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml new file mode 100644 index 000000000..b0eab58c7 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml @@ -0,0 +1,13 @@ +service: + port: 80 + +<#if config.features.exampleApps.petclinic.baseDomain?has_content> +ingress: + hosts: + <#if config.application.urlSeparatorHyphen> + - host: staging-petclinic-helm-${config.features.exampleApps.petclinic.baseDomain} + <#else> + - host: staging.petclinic-helm.${config.features.exampleApps.petclinic.baseDomain} + + paths: ['/'] + diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl new file mode 100644 index 000000000..c739682dc --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl @@ -0,0 +1,15 @@ +# TODO +# FROM {config.contentVariables.images.petclinic} +FROM ${config.images.petclinic} + +# Set permissions to group 0 for openshift compatibility +# See https://docs.openshift.com/container-platform/4.15/openshift_images/create-images.html#use-uid_create-images +RUN mkdir /app && chown 1000:0 /app \ + && chmod -R g=u /app + +COPY target/*.jar /app/petclinic.jar + +EXPOSE 8080 +USER 1000 + +ENTRYPOINT [ "java", "-server","-jar", "/app/petclinic.jar" ] diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl b/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl new file mode 100644 index 000000000..1c6b5b268 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl @@ -0,0 +1,206 @@ +#!groovy + +String getApplication() { 'spring-petclinic-plain' } +String getConfigRepositoryPRRepo() { '${(config.application.namePrefix?has_content)?then(config.application.namePrefix, "") + "example-tenant/gitops"}' } +String getScmManagerCredentials() { 'scmm-user' } +String getConfigRepositoryPRBaseUrl() { env.${config.application.namePrefixForEnvVars}SCMM_URL } + +String getDockerRegistryBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_URL } +String getDockerRegistryPath() { env.${config.application.namePrefixForEnvVars}REGISTRY_PATH } +String getDockerRegistryCredentials() { 'registry-user' } + +<#if config.registry.twoRegistries> +String getDockerRegistryProxyBaseUrl() { env.${config.application.namePrefixForEnvVars}REGISTRY_PROXY_URL } +String getDockerRegistryProxyCredentials() { 'registry-proxy-user' } + +<#noparse> +String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } +String getCesBuildLibVersion() { '2.5.0' } +String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } +String getGitOpsBuildLibVersion() { '0.7.0'} + +loadLibraries() + +properties([ + // Don't run concurrent builds, because the ITs use the same port causing random failures on concurrent builds. + disableConcurrentBuilds() +]) + +node { + + mvn = cesBuildLib.MavenWrapper.new(this) + +<#if config.jenkins.mavenCentralMirror?has_content> + mvn.useMirrors([name: 'maven-central-mirror', mirrorOf: 'central', url: env.${config.application.namePrefixForEnvVars}MAVEN_CENTRAL_MIRROR]) + +<#noparse> + + catchError { + + stage('Checkout') { + checkout scm + } + + stage('Build') { + mvn 'clean package -DskipTests -Dcheckstyle.skip' + archiveArtifacts artifacts: '**/target/*.jar' + } + + stage('Test') { + // Tests skipped for faster demo and exercise purposes + //mvn 'test -Dmaven.test.failure.ignore=true -Dcheckstyle.skip' + } + + String imageName = "" + stage('Docker') { + String imageTag = createImageTag() + +<#if config.registry.twoRegistries> +<#noparse> + String pathPrefix = !dockerRegistryPushPath?.trim() ? "" : "${dockerRegistryPushPath}/" + imageName = "${dockerRegistryPushBaseUrl}/${pathPrefix}${application}:${imageTag}" + docker.withRegistry("http://${dockerRegistryPullBaseUrl}", dockerRegistryPullCredentials) { + image = docker.build(imageName, '.') + } + +<#else> +<#noparse> + String pathPrefix = !dockerRegistryPath?.trim() ? "" : "${dockerRegistryPath}/" + imageName = "${dockerRegistryBaseUrl}/${pathPrefix}${application}:${imageTag}" + image = docker.build(imageName, '.') + + + + if (isBuildSuccessful()) { +<#if config.registry.twoRegistries> +<#noparse> + docker.withRegistry("https://${dockerRegistryPushBaseUrl}", dockerRegistryPushCredentials) { + +<#else> +<#noparse> + docker.withRegistry("https://${dockerRegistryBaseUrl}", dockerRegistryCredentials) { + + +<#noparse> + image.push() + } + } else { + echo 'Skipping docker push, because build not successful' + } + } + + stage('Deploy') { + if (isBuildSuccessful() && env.BRANCH_NAME in ['main']) { + + def gitopsConfig = [ + scm: [ + provider : 'SCMManager', + credentialsId: scmManagerCredentials, + baseUrl : configRepositoryPRBaseUrl, + repositoryUrl : configRepositoryPRRepo, + ], + application: application, + gitopsTool: 'ARGO', + folderStructureStrategy: 'ENV_PER_APP', + + k8sVersion : env.${config.application.namePrefixForEnvVars}K8S_VERSION, + deployments: [ + sourcePath: 'k8s', + destinationRootPath: 'apps', + plain: [ + updateImages: [ + [ filename: 'deployment.yaml', + containerName: application, + imageName: imageName ] + ] + ] + ], + fileConfigmaps: [ + // Showcase for gitops-build-lib: Convert file into a config map + [ + name : 'messages', + sourceFilePath : '../src/main/resources/messages/messages.properties', + stage: ['staging', 'production'] + ] + ], + stages: [ + staging: [ + namespace: '${config.application.namePrefix}example-tenant-staging', + deployDirectly: true ], + production: [ + namespace: '${config.application.namePrefix}example-tenant-production', + deployDirectly: false ], + ] + ] +<#noparse> + addSpecificGitOpsConfig(gitopsConfig) + + deployViaGitops(gitopsConfig) + } else { + echo 'Skipping deploy, because build not successful or not on main branch' + } + } + } + + // Archive Unit and integration test results, if any + junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/surefire-reports/TEST-*.xml' +} + +/** Initializations might not be needed in a real-world setup, but are necessary for GitOps playground */ +void addSpecificGitOpsConfig(gitopsConfig) { + gitopsConfig += [ + // In the GitOps playground, we're loading the build libs from our local SCM so it also works in an offline context + // As the gitops-build-lib also uses the ces-build-lib we need to pass those parameters on. + // If you can access the internet, you can rely on the defaults, which load the lib from GitHub. + cesBuildLibRepo: cesBuildLibRepo, + cesBuildLibVersion: cesBuildLibVersion, + cesBuildLibCredentialsId: scmManagerCredentials, + + + // The GitOps playground provides parameters for overwriting the build images used by gitops-build-lib, so + // it also works in an offline context. + // Those parameters overwrite the following parameters. + // If you can access the internet, you can rely on the defaults, which load the images from public registries. + buildImages : [ + + helm: '${config.images.helm}', + kubectl: '${config.images.kubectl}', + kubeval: '${config.images.kubeval}', + helmKubeval: '${config.images.helmKubeval}', + yamllint: '${config.images.yamllint}' +<#noparse> + ] + ] +} + +String createImageTag() { + def git = cesBuildLib.Git.new(this) + String branch = git.simpleBranchName + String branchSuffix = "" + + if (!"develop".equals(branch)) { + branchSuffix = "-${branch}" + } + + return "${new Date().format('yyyyMMddHHmm')}-${git.commitHashShort}${branchSuffix}" +} + +def loadLibraries() { + // In the GitOps playground, we're loading the build libs from our local SCM so it also works in an offline context + // If you can access the internet, you could also load the libraries directly from github like so + // @Library(["github.com/cloudogu/ces-build-lib@${cesBuildLibVersion}", "github.com/cloudogu/gitops-build-lib@${gitOpsBuildLibRepo}"]) _ + //import com.cloudogu.ces.cesbuildlib.* + //import com.cloudogu.ces.gitopsbuildlib.* + + cesBuildLib = library(identifier: "ces-build-lib@${cesBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: cesBuildLibRepo, credentialsId: scmManagerCredentials]) + ).com.cloudogu.ces.cesbuildlib + + library(identifier: "gitops-build-lib@${gitOpsBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: gitOpsBuildLibRepo, credentialsId: scmManagerCredentials]) + ).com.cloudogu.gitops.gitopsbuildlib +} + +def cesBuildLib +def gitOpsBuildLib + diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml new file mode 100644 index 000000000..61be07b4c --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml @@ -0,0 +1,49 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-petclinic-plain +spec: + replicas: 1 + selector: + matchLabels: + app: spring-petclinic-plain + template: + metadata: + labels: + app: spring-petclinic-plain + spec: + containers: + - name: spring-petclinic-plain + image: localhost:30000/petclinic-plain:1 + ports: + - containerPort: 8080 + name: http + env: + - name: MANAGEMENT_SERVER_PORT + value: "9080" + - name: SPRING_MESSAGES_BASENAME + value: "file:/tmp/messages/messages" + - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK + value: INFO + readinessProbe: + failureThreshold: 3 + httpGet: + path: /actuator/health/readiness + port: 9080 + scheme: HTTP + volumeMounts: + - name: messages + mountPath: /tmp/messages +<#if config.application.podResources == true> + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 300m + memory: 650Mi + + volumes: + - name: messages + configMap: + name: messages diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml new file mode 100644 index 000000000..510da81fe --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml @@ -0,0 +1,25 @@ +<#if config.features.exampleApps.petclinic.baseDomain?has_content> +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: spring-petclinic-plain + labels: + app: spring-petclinic-plain +spec: + rules: + <#if config.application.urlSeparatorHyphen> + - host: production-petclinic-plain-${config.features.exampleApps.petclinic.baseDomain} + <#else> + - host: production.petclinic-plain.${config.features.exampleApps.petclinic.baseDomain} + + http: + paths: + - backend: + service: + name: spring-petclinic-plain + port: + name: http + path: / + pathType: Prefix + + diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml new file mode 100644 index 000000000..e88130722 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: spring-petclinic-plain + labels: + app: spring-petclinic-plain +spec: + type: <#if config.application.remote>LoadBalancer<#else>NodePort + ports: + - name: http + port: 80 + nodePort: 30021 + targetPort: http + selector: + app: spring-petclinic-plain diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml new file mode 100644 index 000000000..9a47ea7b9 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml @@ -0,0 +1,70 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-petclinic-plain +spec: + replicas: 1 + selector: + matchLabels: + app: spring-petclinic-plain + template: + metadata: + labels: + app: spring-petclinic-plain + spec: + containers: + - name: spring-petclinic-plain + image: localhost:30000/petclinic-plain:1 + ports: + - containerPort: 8080 + name: http + env: + - name: MANAGEMENT_SERVER_PORT + value: "9080" + - name: SPRING_MESSAGES_BASENAME + value: "file:/tmp/messages/messages" + - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK + value: INFO + readinessProbe: + failureThreshold: 3 + httpGet: + path: /actuator/health/readiness + port: 9080 + scheme: HTTP + volumeMounts: + - name: messages + mountPath: /tmp/messages + - name: tmp + # Make /tmp writable with readOnlyRootFilesystem + mountPath: /tmp +<#if config.application.podResources == true> + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 300m + memory: 650Mi + + securityContext: # Implement some least privilege good practices + runAsNonRoot: true + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + # These two seem to cause problems with OpenShift, so we disable them for now + #runAsUser: 65312 + #seccompProfile: + # type: RuntimeDefault + # With k8s 1.30 apparmor is added + # Won't work on k3d, though, because apparmor is not enabled + # apparmorProfile: "runtime/default" + enableServiceLinks: false + automountServiceAccountToken: false # When not communicating with API Server + volumes: + - name: messages + configMap: + name: messages + - name: tmp + emptyDir: {} \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml new file mode 100644 index 000000000..05e50faf5 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml @@ -0,0 +1,25 @@ +<#if config.features.exampleApps.petclinic.baseDomain?has_content> +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: spring-petclinic-plain + labels: + app: spring-petclinic-plain +spec: + rules: + <#if config.application.urlSeparatorHyphen> + - host: staging-petclinic-plain-${config.features.exampleApps.petclinic.baseDomain} + <#else> + - host: staging.petclinic-plain.${config.features.exampleApps.petclinic.baseDomain} + + http: + paths: + - backend: + service: + name: spring-petclinic-plain + port: + name: http + path: / + pathType: Prefix + + diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml new file mode 100644 index 000000000..77f87b98d --- /dev/null +++ b/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: spring-petclinic-plain + labels: + app: spring-petclinic-plain +spec: + type: <#if config.application.remote>LoadBalancer<#else>NodePort + ports: + - name: http + port: 80 + nodePort: 30020 + targetPort: http + selector: + app: spring-petclinic-plain From d2666967238d9fa99e9126d987860dd6e36543f4 Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:52:50 +0200 Subject: [PATCH 14/29] Delete docs/content-loader-docs/example-tenant/gitops directory --- .../example-tenant/gitops/README.md | 1 - .../apps/nginx-helm-umbrella/Chart.yaml | 7 --- .../gitops/apps/nginx-helm-umbrella/README.md | 2 - .../apps/nginx-helm-umbrella/values.yaml | 10 ---- .../argocd/nginx-helm-umbrella.ftl.yaml | 25 --------- .../gitops/argocd/nginx-helm.ftl.yaml | 33 ------------ .../gitops/argocd/petclinic-helm.ftl.yaml | 52 ------------------ .../gitops/argocd/petclinic-plain.ftl.yaml | 53 ------------------- 8 files changed, 183 deletions(-) delete mode 100644 docs/content-loader-docs/example-tenant/gitops/README.md delete mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md delete mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml delete mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/README.md b/docs/content-loader-docs/example-tenant/gitops/README.md deleted file mode 100644 index 143c98de3..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/README.md +++ /dev/null @@ -1 +0,0 @@ -Contains examples of end-user applications \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml deleted file mode 100644 index 62b99b38c..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v2 -version: 13.2.21 -name: nginx -dependencies: - - name: nginx - version: 13.2.21 - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md deleted file mode 100644 index b5726758d..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md +++ /dev/null @@ -1,2 +0,0 @@ -3rd Party app (NGINX) with helm, templated by argo from a separate git repo, using helm's dependency mechanism. -This is an alternative approach to keeping the values.yaml inside the `application`. \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml deleted file mode 100644 index 347396191..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml +++ /dev/null @@ -1,10 +0,0 @@ -nginx: - service: - ports: - http: 80 - type: ClusterIP - - ingress: - enabled: true - pathType: Prefix - hostname: production.nginx-helm-umbrella.nginx.localhost diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml deleted file mode 100644 index 0426e32a2..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: nginx-helm-umbrella -<#if config.features.argocd.operator> - namespace: ${config.application.namePrefix}argocd -<#else> - namespace: ${config.application.namePrefix}example-tenant-production - -spec: - destination: - annotations: - myvar: ${config.content.variables.umbrella.nginxAnnotation} - namespace: ${config.application.namePrefix}example-tenant-production - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/nginx-helm-umbrella - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - - syncPolicy: - automated: - prune: true - selfHeal: true diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml deleted file mode 100644 index 47f2325b4..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: nginx-helm - <#if config.features.argocd.operator> -namespace: ${config.application.namePrefix}argocd - <#else> -namespace: ${config.application.namePrefix}example-tenant-production - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-production - server: https://kubernetes.default.svc - project: example-tenant - source: - path: '' - repoURL: >- - https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami - targetRevision: 13.2.21 - chart: nginx - helm: - values: |- - service: - ports: - http: 80 - type: ClusterIP - - ingress: - enabled: true - pathType: Prefix - hostname: production.nginx-helm.nginx.localhost - image: - repository: bitnamilegacy/nginx \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml deleted file mode 100644 index c2677f1e7..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml +++ /dev/null @@ -1,52 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: -<#if config.features.argocd.operator> - name: petclinic-helm-staging - namespace: ${config.application.namePrefix}argocd -<#else> - name: petclinic-helm - namespace: ${config.application.namePrefix}example-tenant-staging - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-staging - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/spring-petclinic-helm/staging - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: true - selfHeal: true - ---- -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: -<#if config.features.argocd.operator> - name: petclinic-helm-production - namespace: ${config.application.namePrefix}argocd -<#else> - name: petclinic-helm - namespace: ${config.application.namePrefix}example-tenant-production - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-production - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/spring-petclinic-helm/production - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: true - selfHeal: true \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml deleted file mode 100644 index 4f631b432..000000000 --- a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: -<#if config.features.argocd.operator> - name: petclinic-plain-staging - namespace: ${config.application.namePrefix}argocd -<#else> - name: petclinic-plain - namespace: ${config.application.namePrefix}example-tenant-staging - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-staging - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/spring-petclinic-plain/staging - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: true - selfHeal: true - ---- - -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: -<#if config.features.argocd.operator> - name: petclinic-plain-production - namespace: ${config.application.namePrefix}argocd -<#else> - name: petclinic-plain - namespace: ${config.application.namePrefix}example-tenant-production - -spec: - destination: - namespace: ${config.application.namePrefix}example-tenant-production - server: https://kubernetes.default.svc - project: example-tenant - source: - path: apps/spring-petclinic-plain/production - repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: true - selfHeal: true From 7cf8d3bdcddb6bd12b00c17be5ca877e346df3ba Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:54:04 +0200 Subject: [PATCH 15/29] Add files via upload --- .../example-tenant/gitops/README.md | 1 + .../apps/nginx-helm-umbrella/Chart.yaml | 7 +++ .../gitops/apps/nginx-helm-umbrella/README.md | 2 + .../apps/nginx-helm-umbrella/values.yaml | 10 ++++ .../argocd/nginx-helm-umbrella.ftl.yaml | 25 +++++++++ .../gitops/argocd/nginx-helm.ftl.yaml | 33 ++++++++++++ .../gitops/argocd/petclinic-helm.ftl.yaml | 52 ++++++++++++++++++ .../gitops/argocd/petclinic-plain.ftl.yaml | 53 +++++++++++++++++++ 8 files changed, 183 insertions(+) create mode 100644 docs/content-loader-docs/example-tenant/gitops/README.md create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml create mode 100644 docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/README.md b/docs/content-loader-docs/example-tenant/gitops/README.md new file mode 100644 index 000000000..143c98de3 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/README.md @@ -0,0 +1 @@ +Contains examples of end-user applications \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml new file mode 100644 index 000000000..62b99b38c --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +version: 13.2.21 +name: nginx +dependencies: + - name: nginx + version: 13.2.21 + repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md new file mode 100644 index 000000000..b5726758d --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md @@ -0,0 +1,2 @@ +3rd Party app (NGINX) with helm, templated by argo from a separate git repo, using helm's dependency mechanism. +This is an alternative approach to keeping the values.yaml inside the `application`. \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml new file mode 100644 index 000000000..347396191 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml @@ -0,0 +1,10 @@ +nginx: + service: + ports: + http: 80 + type: ClusterIP + + ingress: + enabled: true + pathType: Prefix + hostname: production.nginx-helm-umbrella.nginx.localhost diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml new file mode 100644 index 000000000..0426e32a2 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml @@ -0,0 +1,25 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: nginx-helm-umbrella +<#if config.features.argocd.operator> + namespace: ${config.application.namePrefix}argocd +<#else> + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + annotations: + myvar: ${config.content.variables.umbrella.nginxAnnotation} + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/nginx-helm-umbrella + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + + syncPolicy: + automated: + prune: true + selfHeal: true diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml new file mode 100644 index 000000000..47f2325b4 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml @@ -0,0 +1,33 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: nginx-helm + <#if config.features.argocd.operator> +namespace: ${config.application.namePrefix}argocd + <#else> +namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: '' + repoURL: >- + https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami + targetRevision: 13.2.21 + chart: nginx + helm: + values: |- + service: + ports: + http: 80 + type: ClusterIP + + ingress: + enabled: true + pathType: Prefix + hostname: production.nginx-helm.nginx.localhost + image: + repository: bitnamilegacy/nginx \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml new file mode 100644 index 000000000..c2677f1e7 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml @@ -0,0 +1,52 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-helm-staging + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-helm + namespace: ${config.application.namePrefix}example-tenant-staging + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-staging + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-helm/staging + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true + +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-helm-production + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-helm + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-helm/production + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true \ No newline at end of file diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml new file mode 100644 index 000000000..4f631b432 --- /dev/null +++ b/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml @@ -0,0 +1,53 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-plain-staging + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-plain + namespace: ${config.application.namePrefix}example-tenant-staging + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-staging + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-plain/staging + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true + +--- + +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: +<#if config.features.argocd.operator> + name: petclinic-plain-production + namespace: ${config.application.namePrefix}argocd +<#else> + name: petclinic-plain + namespace: ${config.application.namePrefix}example-tenant-production + +spec: + destination: + namespace: ${config.application.namePrefix}example-tenant-production + server: https://kubernetes.default.svc + project: example-tenant + source: + path: apps/spring-petclinic-plain/production + repoURL: http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}example-tenant/gitops + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: true + selfHeal: true From cb72e6cc2967e5852f2299aaa8c821ce9c1f6f84 Mon Sep 17 00:00:00 2001 From: Johannes Schnatterer Date: Thu, 18 Sep 2025 16:15:02 +0200 Subject: [PATCH 16/29] Add empty folders --- .../example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep | 0 docs/content-loader-docs/example-tenant/gitops/misc/.gitkeep | 0 .../example-tenant/petclinic-helm/k8s/production/.gitkeep | 0 .../example-tenant/petclinic-helm/k8s/staging/.gitkeep | 0 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/content-loader-docs/example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep create mode 100644 docs/content-loader-docs/example-tenant/gitops/misc/.gitkeep create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/production/.gitkeep create mode 100644 docs/content-loader-docs/example-tenant/petclinic-helm/k8s/staging/.gitkeep diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep b/docs/content-loader-docs/example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/content-loader-docs/example-tenant/gitops/misc/.gitkeep b/docs/content-loader-docs/example-tenant/gitops/misc/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/production/.gitkeep b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/production/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/staging/.gitkeep b/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/staging/.gitkeep new file mode 100644 index 000000000..e69de29bb From 5b628b76afd36634f0f05ce966572a01e7850bfc Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Fri, 19 Sep 2025 07:51:27 +0200 Subject: [PATCH 17/29] Update content-loader.md link formatting --- docs/content-loader-docs/content-loader.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index ca8cad0dc..e75c1aea7 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -63,7 +63,7 @@ It also applies to end-user applications, for example, replacing the example Pet ## Different Types of Content Repos There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED`. -- `MIRROR` (default): The entire content repo is mirrored to the target repo if it does not yet exist ([see overrideMode below](#the-overridemode). +- `MIRROR` (default): The entire content repo is mirrored to the target repo if it does not yet exist ([see overrideMode below](#the-overridemode)). - `COPY`: Only the files (no Git history) are copied to the target repository and committed. - `FOLDER_BASED`: Using the folder structure in the content repository, multiple repositories can be created and initialized or expanded in the target. From d9f27a43b60784015b4823ff9af7a4d49b91bb2f Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Fri, 19 Sep 2025 08:05:26 +0200 Subject: [PATCH 18/29] Update content-loader.md --- docs/content-loader-docs/content-loader.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index e75c1aea7..a8b0fa0d5 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -123,7 +123,7 @@ This allows, for example, additional Argo CD applications to be added and even y **Properties** - `target` (required) -- `path` - source folder in the content repository used for copying< +- `path` - source folder in the content repository used for copying - `templating` - If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see templating below](#templating)). # The overrideMode @@ -172,7 +172,7 @@ image: ```yaml - url: 'https://example.com/scm/repo/gop/content' username: 'abc' - password: 'ey...' # zB API Token von SCM-Manager + password: 'ey...' # e.g. API Token from SCM-Manager templating: true type: FOLDER_BASED overrideMode: UPGRADE From 299b103997e6d838dedc43a4249e9ac73c164437 Mon Sep 17 00:00:00 2001 From: flxebrt <101174909+flxebrt@users.noreply.github.com> Date: Fri, 19 Sep 2025 09:18:40 +0200 Subject: [PATCH 19/29] Update README.md add short content loader feature description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c2d28a02..997c9113b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Creates a complete GitOps-based operational stack that can be used as an internal developer platform (IDP) on your Kubernetes clusters: - +* Content Loader: Customization and extension of GOP content enables to deploy and operate any application ([content-loader-docs](docs/content-loader-docs)) * Deployment: GitOps via Argo CD with a ready-to-use [repo structure](#argo-cd) * Monitoring: [Prometheus and Grafana](#monitoring-tools) * Secrets Management: [Vault and External Secrets Operator](#secrets-management-tools) From 10e33579e1da5eb4a7a974fea98ff6f40783d0c9 Mon Sep 17 00:00:00 2001 From: Thomas Michael Date: Fri, 19 Sep 2025 11:32:49 +0200 Subject: [PATCH 20/29] adopt docs for content loader --- .../content-loader-config.yaml | 5 ++-- docs/content-loader-docs/content-loader.md | 29 +++++++++++++++---- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/docs/content-loader-docs/content-loader-config.yaml b/docs/content-loader-docs/content-loader-config.yaml index 078849db9..f1de1d356 100644 --- a/docs/content-loader-docs/content-loader-config.yaml +++ b/docs/content-loader-docs/content-loader-config.yaml @@ -23,10 +23,9 @@ content: targetRef: main overwriteMode: UPGRADE createJenkinsJob: true - - url: 'https://ecosystem.cloudogu.com/scm/repo/gop/content' + - url: 'https://github.com/cloudogu/gitops-playground.git' + path: 'docs/content-loader-docs' ref: main - username: '' - password: '' templating: true type: FOLDER_BASED overwriteMode: UPGRADE diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index a8b0fa0d5..b1256ba2e 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -160,6 +160,19 @@ image: # Example-Use Cases +## How to start with content? +Use this file as config ``` --config-file=/docs/content-loader-docs/content-loader-config.yaml ``` +```shell +bash <(curl -s \ + https://raw.githubusercontent.com/cloudogu/gitops-playground/main/scripts/init-cluster.sh) \ + && docker run --rm -t --pull=always -u $(id -u) \ + -v ~/.config/k3d/kubeconfig-gitops-playground.yaml:/home/.kube/config \ + --net=host \ + ghcr.io/cloudogu/gitops-playground --config-file=https://raw.githubusercontent.com/cloudogu/gitops-playground/main/docs/content-loader-docs/content-loader-config.yaml +# More IDP-features: --mailhog --monitoring --vault=dev --cert-manager +# More features for developers: --jenkins --registry --content-examples +``` + ## Mirror the entire repository on every call ```yaml - url: 'https://github.com/cloudogu/spring-boot-helm-chart' @@ -170,8 +183,10 @@ image: ## Create additional tenant in Argo CD ```yaml - - url: 'https://example.com/scm/repo/gop/content' - username: 'abc' + - url: 'https://github.com/cloudogu/gitops-playground.git' + path: 'docs/content-loader-docs' + ref: main + username: 'abc' # not necessary if git repo is openSource password: 'ey...' # e.g. API Token from SCM-Manager templating: true type: FOLDER_BASED @@ -184,14 +199,16 @@ In this repo, the folder structure is as follows: [argocd/argocd.](argocd/argocd For example, to create a `Dockerfile` and `Jenkinsfile` and then create a Jenkins job. This example shows the `MIRROR` use case. As an alternative you can add type `COPY` in the first repo (petclinic). Reminder: no type means MIRROR (default). ```yaml - url: https://github.com/cloudogu/spring-petclinic - target: argocd/petclinic-plain + target: example-tenant/petclinic-plain ref: feature/gitops_ready targetRef: main overrideMode: UPGRADE createJenkinsJob: true - - url: 'https://example.com/scm/repo/gop/content' - username: 'abc' - password: 'ey...' # e.g., API token from SCM-Manager + - url: https://github.com/cloudogu/gitops-playground.git + path: 'docs/content-loader-docs' + ref: main + username: 'abc' # not necessary if git repo is openSource + password: 'ey...' # e.g. API Token from SCM-Manager templating: true type: FOLDER_BASED overrideMode: UPGRADE From fdd650eda60eec285fbf0f5216307732ec7cf6a7 Mon Sep 17 00:00:00 2001 From: Thomas Michael Date: Mon, 22 Sep 2025 15:15:53 +0200 Subject: [PATCH 21/29] adopt docs for content loader --- docs/content-loader-docs/content-loader.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index b1256ba2e..c4b7f4160 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -161,14 +161,17 @@ image: # Example-Use Cases ## How to start with content? -Use this file as config ``` --config-file=/docs/content-loader-docs/content-loader-config.yaml ``` +Use this file as config ``` --config-file=/docs/content-loader-docs/content-loader-config.yaml +This command uses included content-config-file. ```shell bash <(curl -s \ https://raw.githubusercontent.com/cloudogu/gitops-playground/main/scripts/init-cluster.sh) \ + && curl -s "https://raw.githubusercontent.com/cloudogu/gitops-playground/main/docs/content-loader-docs/content-loader-config.yaml" > contentConfig.yaml \ && docker run --rm -t --pull=always -u $(id -u) \ -v ~/.config/k3d/kubeconfig-gitops-playground.yaml:/home/.kube/config \ + -v "$(pwd)/contentConfig.yaml:/app/contentConfig.yaml" \ --net=host \ - ghcr.io/cloudogu/gitops-playground --config-file=https://raw.githubusercontent.com/cloudogu/gitops-playground/main/docs/content-loader-docs/content-loader-config.yaml + ghcr.io/cloudogu/gitops-playground --config-file=contentConfig.yaml # More IDP-features: --mailhog --monitoring --vault=dev --cert-manager # More features for developers: --jenkins --registry --content-examples ``` From 09f123951a390c90b9ffb08eb5d376c2cf157f6c Mon Sep 17 00:00:00 2001 From: flxebrt Date: Mon, 22 Sep 2025 16:07:20 +0200 Subject: [PATCH 22/29] add short instruction how to start with content loader --- docs/content-loader-docs/content-loader.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index c4b7f4160..bec50aa3e 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -1,8 +1,8 @@ # Content Loader Documentation -This documentation shows the Content Loader feature and its usage. The Content Loader offers the ability of hooking into the GOP installation to deliver your own content. +This documentation shows the Content Loader feature and its usage. The Content Loader offers the ability of hooking into the GitOps Playground (GOP) installation to deliver your own content. -Example for a GOP (GitOps Playground) content repository: +Example for a GOP content repository: - Sample [configuration file](content-loader-config.yaml). - [Directory structure](.) as an example of a folder-based content repository. @@ -160,9 +160,13 @@ image: # Example-Use Cases -## How to start with content? -Use this file as config ``` --config-file=/docs/content-loader-docs/content-loader-config.yaml -This command uses included content-config-file. +## TL;DR: How to start with content loader? +The following chapter describes sample use cases that can be tried after executing the TL;DR command. \ +Use this file as config ``` --config-file=/docs/content-loader-docs/content-loader-config.yaml```. However, you can apply individual config.yaml files to deploy your own content. + +### Start the GOP +The following command uses the `content-loader-config-file.yaml` mentioned above. Run this command once to set up GOP with Content Loader: + ```shell bash <(curl -s \ https://raw.githubusercontent.com/cloudogu/gitops-playground/main/scripts/init-cluster.sh) \ @@ -176,6 +180,8 @@ bash <(curl -s \ # More features for developers: --jenkins --registry --content-examples ``` +Once the GOP is started you can try the following sample use cases. Most applications mentioned in the [Stack-chapter](https://github.com/cloudogu/gitops-playground?tab=readme-ov-file#stack) are deployed now. + ## Mirror the entire repository on every call ```yaml - url: 'https://github.com/cloudogu/spring-boot-helm-chart' From b4fdcb221ecaf991cb7a15973195b85c94ce20c2 Mon Sep 17 00:00:00 2001 From: flxebrt Date: Tue, 23 Sep 2025 12:41:49 +0200 Subject: [PATCH 23/29] adapt purpose of content loader --- docs/content-loader-docs/content-loader.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index bec50aa3e..36269ce20 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -9,8 +9,8 @@ Example for a GOP content repository: # Purpose of the Content Loader -The content loader feature makes your application cloud ready. It gives you the ability to deploy and operate your own application in cloud environments with the GOP. \ -It provides the flexibility to deliver more applications using GOP. This customization applies to the Internal Developer Platform (IDP), for example, other ops tools such as monitoring. \ +The content loader feature makes your application cloud ready. It gives you the ability to deploy and operate any application in cloud environments with the GOP. \ +This customization applies to the Internal Developer Platform (IDP), for example, other ops tools such as monitoring. \ It also applies to end-user applications, for example, replacing the example Petclinic content with real-world applications. # What does the term “content” mean? From 026965c5e6a088a5e29966ae45aef4fa0f3d4a54 Mon Sep 17 00:00:00 2001 From: flxebrt Date: Tue, 23 Sep 2025 15:29:16 +0200 Subject: [PATCH 24/29] adapt content loader docs and add table of contents --- docs/content-loader-docs/content-loader.md | 40 +++++++++++++++------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader-docs/content-loader.md index 36269ce20..c8c467f35 100644 --- a/docs/content-loader-docs/content-loader.md +++ b/docs/content-loader-docs/content-loader.md @@ -7,6 +7,23 @@ Example for a GOP content repository: - Sample [configuration file](content-loader-config.yaml). - [Directory structure](.) as an example of a folder-based content repository. +# Table of contents +- [Purpose of the Content Loader](#purpose-of-the-content-loader) +- [What does the term “content” mean?](#what-does-the-term-content-mean) +- [Content Loader Concepts](#content-loader-concepts) + - [Different Types of Content Repos](#different-types-of-content-repos) + - [`MIRROR`](#mirror) + - [`COPY`](#copy) + - [`FOLDER_BASED`](#folder_based) +- [The OverrideMode](#the-overridemode) +- [Templating](#templating) +- [TL;DR: How to start with content loader?](#tldr-how-to-start-with-content-loader) +- [Example Use Cases](#example-use-cases) + - [Mirror the entire repository on every call](#mirror-the-entire-repository-on-every-call) + - [Create additional tenant in Argo CD](#create-additional-tenant-in-argo-cd) + - [Mirror/copy repo and add specific files](#mirrorcopy-repo-and-add-specific-files) + + # Purpose of the Content Loader The content loader feature makes your application cloud ready. It gives you the ability to deploy and operate any application in cloud environments with the GOP. \ @@ -79,9 +96,8 @@ There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` - `password` - `createJenkinsJob` - If `true` and Jenkins is active in GOP, and there is a `Jenkinsfile` in one of the content repositories or the specified `refs`, a Jenkins job is created for the associated SCM Manager namespace. -### Different Types of Content Repos in Detail -#### `MIRROR` +### `MIRROR` A content repo is mirrored completely (or only a `ref`) to the target repo (including Git history). Caution: Force push is used here! By default, however, only on new repos. If existing repos are also to be written, `overrideMode: RESET` must be set. Note: The default branch of the source repo is not explicitly set. @@ -96,7 +112,7 @@ If the source repo has a default branch != `main`, it is not applied. - If `targetRef` is empty, the source ref is used by default. -#### `COPY` +### `COPY` Only the files (no Git history) are copied and committed to the target repo. @@ -111,7 +127,7 @@ Only the files (no Git history) are copied and committed to the target repo. - `templating `- If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see templating below](#templating)). -#### `FOLDER_BASED` +### `FOLDER_BASED` - Using the folder structure in the content repository, multiple repositories can be created in the target and initialized or expanded using `COPY`. - Specifically: The top two directory levels of the repository determine the target repositories in the GOP. - Example: The contents of the `example-tenant/petclinic-plain` folder are pushed to the `gitops` repository in the `example-tenant` namespace. @@ -140,7 +156,7 @@ With `MIRROR`, `RESET` does not reset the entire repository. Specific effect: Br If existing repositories of the GOP are to be extended, e.g., `cluster-resources`, the `overrideMode` must be set to `UPGRADE`. # Templating -When `templating `is enabled, all files ending in `.ftl` are rendered using [Freemarker](https://freemarker.apache.org/) during GOP installation and the result is created under the same name without the `.ftl` extension. +When `templating` is enabled, all files ending in `.ftl` are rendered using [Freemarker](https://freemarker.apache.org/) during GOP installation and the result is created under the same name without the `.ftl` extension. The entire configuration of the GOP is available as` config` in the templates. In addition, the people who write the content have the option of defining their own variables (`content.variables`). This makes it possible to write parameterizable content that can be used for many instances. @@ -158,14 +174,8 @@ image: ``` -# Example-Use Cases - -## TL;DR: How to start with content loader? -The following chapter describes sample use cases that can be tried after executing the TL;DR command. \ -Use this file as config ``` --config-file=/docs/content-loader-docs/content-loader-config.yaml```. However, you can apply individual config.yaml files to deploy your own content. - -### Start the GOP -The following command uses the `content-loader-config-file.yaml` mentioned above. Run this command once to set up GOP with Content Loader: +# TL;DR: How to start with content loader? +To start with the content loader feature start the GOP with the `content-loader-config-file.yaml`. Run this command once to set up GOP with Content Loader: ```shell bash <(curl -s \ @@ -182,6 +192,10 @@ bash <(curl -s \ Once the GOP is started you can try the following sample use cases. Most applications mentioned in the [Stack-chapter](https://github.com/cloudogu/gitops-playground?tab=readme-ov-file#stack) are deployed now. +# Example-Use Cases +This chapter describes sample use cases that can be tried after executing the TL;DR command. \ +However, you can apply individual config.yaml files to deploy your own content. + ## Mirror the entire repository on every call ```yaml - url: 'https://github.com/cloudogu/spring-boot-helm-chart' From de333466b256ab610b80a29c68125e132381caf7 Mon Sep 17 00:00:00 2001 From: Johannes Schnatterer Date: Thu, 25 Sep 2025 17:31:47 +0200 Subject: [PATCH 25/29] Content Loader: Simply path structure Remove redundant "docs" from docs/content-loader-docs --- README.md | 3 ++- .../argocd/applications/example-tenant.ftl.yaml | 0 .../argocd/argocd/projects/example-tenant.ftl.yaml | 0 .../content-hooks-folder-based.png | Bin .../content-loader-config.yaml | 0 .../content-loader.md | 0 .../example-tenant/gitops/README.md | 0 .../gitops/apps/nginx-helm-umbrella/Chart.yaml | 0 .../gitops/apps/nginx-helm-umbrella/README.md | 0 .../gitops/apps/nginx-helm-umbrella/values.yaml | 0 .../gitops/apps/spring-petclinic-plain/.gitkeep | 0 .../gitops/argocd/nginx-helm-umbrella.ftl.yaml | 0 .../gitops/argocd/nginx-helm.ftl.yaml | 0 .../gitops/argocd/petclinic-helm.ftl.yaml | 0 .../gitops/argocd/petclinic-plain.ftl.yaml | 0 .../example-tenant/gitops/misc/.gitkeep | 0 .../example-tenant/petclinic-helm/Dockerfile.ftl | 0 .../example-tenant/petclinic-helm/Jenkinsfile.ftl | 0 .../petclinic-helm/k8s/production/.gitkeep | 0 .../petclinic-helm/k8s/staging/.gitkeep | 0 .../petclinic-helm/k8s/values-production.ftl.yaml | 0 .../petclinic-helm/k8s/values-shared.ftl.yaml | 0 .../petclinic-helm/k8s/values-staging.ftl.yaml | 0 .../example-tenant/petclinic-plain/Dockerfile.ftl | 0 .../example-tenant/petclinic-plain/Jenkinsfile.ftl | 0 .../k8s/production/deployment.ftl.yaml | 0 .../petclinic-plain/k8s/production/ingress.ftl.yaml | 0 .../petclinic-plain/k8s/production/service.ftl.yaml | 0 .../petclinic-plain/k8s/staging/deployment.ftl.yaml | 0 .../petclinic-plain/k8s/staging/ingress.ftl.yaml | 0 .../petclinic-plain/k8s/staging/service.ftl.yaml | 0 31 files changed, 2 insertions(+), 1 deletion(-) rename docs/{content-loader-docs => content-loader}/argocd/argocd/applications/example-tenant.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/argocd/argocd/projects/example-tenant.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/content-hooks-folder-based.png (100%) rename docs/{content-loader-docs => content-loader}/content-loader-config.yaml (100%) rename docs/{content-loader-docs => content-loader}/content-loader.md (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/README.md (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/apps/nginx-helm-umbrella/README.md (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/argocd/nginx-helm.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/gitops/misc/.gitkeep (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-helm/Dockerfile.ftl (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-helm/Jenkinsfile.ftl (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-helm/k8s/production/.gitkeep (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-helm/k8s/staging/.gitkeep (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-plain/Dockerfile.ftl (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-plain/Jenkinsfile.ftl (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml (100%) rename docs/{content-loader-docs => content-loader}/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml (100%) diff --git a/README.md b/README.md index 997c9113b..6062b2c2c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Creates a complete GitOps-based operational stack that can be used as an internal developer platform (IDP) on your Kubernetes clusters: -* Content Loader: Customization and extension of GOP content enables to deploy and operate any application ([content-loader-docs](docs/content-loader-docs)) + * Deployment: GitOps via Argo CD with a ready-to-use [repo structure](#argo-cd) * Monitoring: [Prometheus and Grafana](#monitoring-tools) * Secrets Management: [Vault and External Secrets Operator](#secrets-management-tools) @@ -10,6 +10,7 @@ Kubernetes clusters: * Pipelines: Example applications using [Jenkins](#jenkins) with the [gitops-build-lib](https://github.com/cloudogu/gitops-build-lib) and [SCM-Manager](#scm-manager) * Ingress Controller: [ingress-nginx](https://github.com/kubernetes/ingress-nginx/) * Certificate Management: [cert-manager](#certificate-management) +* [Content Loader](docs/content-loader/content-loader.md): Completely customize what is pushed to Git during installation * Runs on: * local cluster (try it [with only one command](#tldr)), * in the public cloud, diff --git a/docs/content-loader-docs/argocd/argocd/applications/example-tenant.ftl.yaml b/docs/content-loader/argocd/argocd/applications/example-tenant.ftl.yaml similarity index 100% rename from docs/content-loader-docs/argocd/argocd/applications/example-tenant.ftl.yaml rename to docs/content-loader/argocd/argocd/applications/example-tenant.ftl.yaml diff --git a/docs/content-loader-docs/argocd/argocd/projects/example-tenant.ftl.yaml b/docs/content-loader/argocd/argocd/projects/example-tenant.ftl.yaml similarity index 100% rename from docs/content-loader-docs/argocd/argocd/projects/example-tenant.ftl.yaml rename to docs/content-loader/argocd/argocd/projects/example-tenant.ftl.yaml diff --git a/docs/content-loader-docs/content-hooks-folder-based.png b/docs/content-loader/content-hooks-folder-based.png similarity index 100% rename from docs/content-loader-docs/content-hooks-folder-based.png rename to docs/content-loader/content-hooks-folder-based.png diff --git a/docs/content-loader-docs/content-loader-config.yaml b/docs/content-loader/content-loader-config.yaml similarity index 100% rename from docs/content-loader-docs/content-loader-config.yaml rename to docs/content-loader/content-loader-config.yaml diff --git a/docs/content-loader-docs/content-loader.md b/docs/content-loader/content-loader.md similarity index 100% rename from docs/content-loader-docs/content-loader.md rename to docs/content-loader/content-loader.md diff --git a/docs/content-loader-docs/example-tenant/gitops/README.md b/docs/content-loader/example-tenant/gitops/README.md similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/README.md rename to docs/content-loader/example-tenant/gitops/README.md diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml b/docs/content-loader/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml rename to docs/content-loader/example-tenant/gitops/apps/nginx-helm-umbrella/Chart.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md b/docs/content-loader/example-tenant/gitops/apps/nginx-helm-umbrella/README.md similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/README.md rename to docs/content-loader/example-tenant/gitops/apps/nginx-helm-umbrella/README.md diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml b/docs/content-loader/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml rename to docs/content-loader/example-tenant/gitops/apps/nginx-helm-umbrella/values.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep b/docs/content-loader/example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep rename to docs/content-loader/example-tenant/gitops/apps/spring-petclinic-plain/.gitkeep diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml b/docs/content-loader/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml rename to docs/content-loader/example-tenant/gitops/argocd/nginx-helm-umbrella.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml b/docs/content-loader/example-tenant/gitops/argocd/nginx-helm.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/argocd/nginx-helm.ftl.yaml rename to docs/content-loader/example-tenant/gitops/argocd/nginx-helm.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml b/docs/content-loader/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml rename to docs/content-loader/example-tenant/gitops/argocd/petclinic-helm.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml b/docs/content-loader/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml rename to docs/content-loader/example-tenant/gitops/argocd/petclinic-plain.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/gitops/misc/.gitkeep b/docs/content-loader/example-tenant/gitops/misc/.gitkeep similarity index 100% rename from docs/content-loader-docs/example-tenant/gitops/misc/.gitkeep rename to docs/content-loader/example-tenant/gitops/misc/.gitkeep diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl b/docs/content-loader/example-tenant/petclinic-helm/Dockerfile.ftl similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-helm/Dockerfile.ftl rename to docs/content-loader/example-tenant/petclinic-helm/Dockerfile.ftl diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl b/docs/content-loader/example-tenant/petclinic-helm/Jenkinsfile.ftl similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-helm/Jenkinsfile.ftl rename to docs/content-loader/example-tenant/petclinic-helm/Jenkinsfile.ftl diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/production/.gitkeep b/docs/content-loader/example-tenant/petclinic-helm/k8s/production/.gitkeep similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-helm/k8s/production/.gitkeep rename to docs/content-loader/example-tenant/petclinic-helm/k8s/production/.gitkeep diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/staging/.gitkeep b/docs/content-loader/example-tenant/petclinic-helm/k8s/staging/.gitkeep similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-helm/k8s/staging/.gitkeep rename to docs/content-loader/example-tenant/petclinic-helm/k8s/staging/.gitkeep diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml b/docs/content-loader/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-helm/k8s/values-production.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml b/docs/content-loader/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-helm/k8s/values-shared.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml b/docs/content-loader/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-helm/k8s/values-staging.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl b/docs/content-loader/example-tenant/petclinic-plain/Dockerfile.ftl similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-plain/Dockerfile.ftl rename to docs/content-loader/example-tenant/petclinic-plain/Dockerfile.ftl diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl b/docs/content-loader/example-tenant/petclinic-plain/Jenkinsfile.ftl similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-plain/Jenkinsfile.ftl rename to docs/content-loader/example-tenant/petclinic-plain/Jenkinsfile.ftl diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml b/docs/content-loader/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-plain/k8s/production/deployment.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml b/docs/content-loader/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-plain/k8s/production/ingress.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml b/docs/content-loader/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-plain/k8s/production/service.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml b/docs/content-loader/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-plain/k8s/staging/deployment.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml b/docs/content-loader/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-plain/k8s/staging/ingress.ftl.yaml diff --git a/docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml b/docs/content-loader/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml similarity index 100% rename from docs/content-loader-docs/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml rename to docs/content-loader/example-tenant/petclinic-plain/k8s/staging/service.ftl.yaml From 5126e44aeba300b0f7c83be48b44a332c39d15f8 Mon Sep 17 00:00:00 2001 From: Johannes Schnatterer Date: Thu, 25 Sep 2025 17:32:11 +0200 Subject: [PATCH 26/29] Polishing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Have another go of simplifying the "concepts" chapter: Introduce schematic config file and more subheadings, remove duplicate bullet points - Make "Purpose of Content Loader" more concrete - overrideMode: We mixed up UPGRADE and RESET 😱 - Consistently use "example" instead of sample - introduce term turnkey-solution - Minor orthographic fixes - Minor translation changes e.g. extended instead of expanded - Minor clarifications here and there - remove unnecessary slashes (replace by double space if necessary) - Fix heading positions ... --- README.md | 3 +- docs/content-loader/content-loader.md | 281 ++++++++++++++++---------- 2 files changed, 180 insertions(+), 104 deletions(-) diff --git a/README.md b/README.md index 6062b2c2c..5807c16aa 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ Kubernetes clusters: * Pipelines: Example applications using [Jenkins](#jenkins) with the [gitops-build-lib](https://github.com/cloudogu/gitops-build-lib) and [SCM-Manager](#scm-manager) * Ingress Controller: [ingress-nginx](https://github.com/kubernetes/ingress-nginx/) * Certificate Management: [cert-manager](#certificate-management) -* [Content Loader](docs/content-loader/content-loader.md): Completely customize what is pushed to Git during installation +* [Content Loader](docs/content-loader/content-loader.md): Completely customize what is pushed to Git during installation. + This allows for adding your own end-user or IDP apps, creating repos, adding Argo CD tenants, etc. * Runs on: * local cluster (try it [with only one command](#tldr)), * in the public cloud, diff --git a/docs/content-loader/content-loader.md b/docs/content-loader/content-loader.md index c8c467f35..12b0455f0 100644 --- a/docs/content-loader/content-loader.md +++ b/docs/content-loader/content-loader.md @@ -1,6 +1,10 @@ # Content Loader Documentation -This documentation shows the Content Loader feature and its usage. The Content Loader offers the ability of hooking into the GitOps Playground (GOP) installation to deliver your own content. +This documentation shows the Content Loader feature and its usage. + +Content Loader offers the ability of hooking into the GitOps Playground (GOP) installation process, allowing for +customization of what is pushed to Git. +This can be used to deploy your own content, e.g. your own applications, or adding tenants to Argo CD, etc. Example for a GOP content repository: @@ -8,34 +12,46 @@ Example for a GOP content repository: - [Directory structure](.) as an example of a folder-based content repository. # Table of contents -- [Purpose of the Content Loader](#purpose-of-the-content-loader) -- [What does the term “content” mean?](#what-does-the-term-content-mean) -- [Content Loader Concepts](#content-loader-concepts) - - [Different Types of Content Repos](#different-types-of-content-repos) - - [`MIRROR`](#mirror) - - [`COPY`](#copy) - - [`FOLDER_BASED`](#folder_based) -- [The OverrideMode](#the-overridemode) -- [Templating](#templating) -- [TL;DR: How to start with content loader?](#tldr-how-to-start-with-content-loader) -- [Example Use Cases](#example-use-cases) + + + + +- [Purpose of Content Loader](#purpose-of-content-loader) +- [Meaning of the term "content"](#meaning-of-the-term-content) +- [Content Loader concepts](#content-loader-concepts) + - [Content repos](#content-repos) + - [Additional options](#additional-options) + - [Different types of content repos](#different-types-of-content-repos) + - [The overrideMode](#the-overridemode) + - [Templating](#templating) +- [TL;DR](#tldr) +- [Example use cases](#example-use-cases) - [Mirror the entire repository on every call](#mirror-the-entire-repository-on-every-call) - [Create additional tenant in Argo CD](#create-additional-tenant-in-argo-cd) - [Mirror/copy repo and add specific files](#mirrorcopy-repo-and-add-specific-files) + + + +# Purpose of Content Loader + +You like the idea of automatically rolling out IDPs using GOP but -# Purpose of the Content Loader +* want to initialize it with your own real-world end-user application that is automatically deployed as a turnkey solution, +* want to add multiple tenants with Argo CD, +* want to have different or additional IDP tools, e.g. logging/backup/tracing, etc. -The content loader feature makes your application cloud ready. It gives you the ability to deploy and operate any application in cloud environments with the GOP. \ -This customization applies to the Internal Developer Platform (IDP), for example, other ops tools such as monitoring. \ -It also applies to end-user applications, for example, replacing the example Petclinic content with real-world applications. +Then Content Loader is for you! +It allows you to define content using a folder structure inside a Git repo (so-called content repo) that is picked up +during GOP apply optionally run through a templating engine and then pushed to the target Git. -# What does the term “content” mean? +# Meaning of the term "content" -- Currently, the GOP (version > 0.11.0) consists of sample applications and exercises and their dependencies, in addition to the actual IDP (ArgoCD, Prometheus, etc.). - - ➡️ “Ready-to-use” provision of GitOps pipelines -- We refer to this as “content”. -- When rolling out GOP the `--content-examples` parameter leads to sample applications being pushed to Git. +- Currently, GOP (version > 0.11.0) consists of example applications and exercises and their dependencies, + in addition to the actual IDP (ArgoCD, Prometheus, etc.). + ➡️ Turnkey-solution deployed via GitOps pipelines +- We refer to these applications as "content". +- When rolling out GOP, the `--content-examples` parameter leads to example applications being pushed to Git. - These applications include: - Code (e.g., repo `argocd/petclinic-helm`) - Configuration (Argo CD `Application` and YAML resources in the GitOps repo `argocd/example-tenant`) @@ -43,73 +59,117 @@ It also applies to end-user applications, for example, replacing the example Pet - Some of them contain Jenkins files that describe how to build and push images and start the GitOps process. - Dependencies, e.g., `3rd-party-dependencies/gitops-build-lib` and `3rd-party-dependencies/spring-boot-helm-chart` - Jenkins job that clones the repos, builds images, and triggers the GitOps process -- After installing the GOP, the sample applications are built by Jenkins and deployed by ArgoCD via GitOps. -- The content loader feature provides the possibility to deliver your own custom content, i.e. real-world applications instead of demos. - -# Content Loader Concepts - -- The content deployed by GOP can be completely defined via configuration. -- The content is defined in Git repositories, known as content repos. -- There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` ([see different types of content repos below](#different-types-of-content-repos)). -- For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET` ([see overrideMode below](#the-overridemode)) -- Templating with [Freemarker](https://freemarker.apache.org/) is available in the content files ([see templating below](#templating)). -- Multiple content repos can be specified in the `content.repos` field. - - See the [sample configuration file](content-loader-config.yaml). -- These are merged by the GOP in the defined order in a directory structure. +- After installing GOP, the example applications are built by Jenkins and deployed by ArgoCD via GitOps. + Finally, these end-user applications can be reached via HTTP(S) via their ingress (turnkey-solution). +- The content loader feature provides the possibility to deliver your own custom content, i.e. real-world applications instead of examples. + +# Content Loader concepts + +The content deployed by GOP can be completely defined via configuration. + +This allows for +* changing all Git repos created by GOP. +* adding new Git repos, e.g. for end-user applications (including their dependencies such as Helm charts or build libraries) as well as IDP applications, such as monitoring tools. + +This is done by means of a `content` section within GOP's config file (the one being specified by `--config-file`). + +Here is a schematic example of the `content` section that will be described in the following: + +```yaml +content: + repos: + - url: 'https://...' + path: 'a/b' + ref: branch + templating: true + type: FOLDER_BASED + overwriteMode: UPGRADE + createJenkinsJob: true + - ... + + namespaces: + - prod + - ... + + variables: + my: value + another: value + + examples: true +``` + +See [here for a full example](content-loader-config.yaml). +The [TL;DR](#tldr) sections shows how to see this example in action. + +## Content repos +- The content is defined in Git repositories, known as content repos (`content.repos`) +- There are different `type`s of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` ([see different types of content repos](#different-types-of-content-repos)). +- For these types of content repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET` ([see overrideMode](#the-overridemode)). +- Templating with [Freemarker](https://freemarker.apache.org/) can be enabled for each content repo. + - The templates can access the config and custom variables defined in `content.variables`. + - See [templating](#templating). +- Multiple content repos can be specified in the `content.repos` field +- GOP merges these repos in the defined order into a directory structure. - This allows you to overwrite files from all repos created by GOP. - - One use case for this is, for example, a base repository that specifies the basic structure of all GOP instances in a cloud environment and more specialized repositories that contain specific applications. - - Another use case is to keep the configuration (YAML) in one repo and the code in another in order to deploy multiple examples with the same code. \ - Current examples are `petclinic-plain` and `petclinic-helm`. -- This also allows you to control the configuration of Argo CD and, for example, define different tenants. -- Different content repositories can be created for end-user applications (including their dependencies such as Helm charts or build libraries) as well as IDP applications, such as monitoring tools. -- To accommodate these different tasks, each repository can be parameterized differently. -- ArgoCD `AppProjects` and `Applications` can be defined in the content. -- Existing repositories, e.g., `argocd/argocd`, can be extended by content (“merge” or git clone + push). -- Jenkins: Automatic generation of Jenkins jobs based on the content. - - For each SCM Manager namespace found in the content and - - that contains a `Jenkinsfile`. -- The example content can be activated via the `content.examples` field. -- You have the option to change this via `content.repos`. -- Kubernetes namespaces, e.g., for sample applications (currently `example-tenant-staging`), can be specified via a separate `content.namespaces` field. - - The namespaces listed therein are deployed by the GOP via GitOps. - - In each namespace, the configured ImagePullSecrets are automatically generated and RBAC resources and `NetworkPolicies` are set up, which enable Prometheus to access the metrics. - - This also allows the GOP to create `ProjectRequests` instead of `Namespaces` under OpenShift. - - The list may contain more namespaces than are used in the content. - - The namespaces allow templating, e.g., `‘${config.application.namePrefix}example-tenant-staging’, ‘${config.application.namePrefix}example-tenant-production’` - -## Different Types of Content Repos + - One use case for this is, for example, a base repository that specifies the basic structure of all GOP instances in a cloud environment and more specialized repositories that contain specific applications. + - Another use case is to keep the configuration (YAML) in one repo and the code in another to deploy different configg with the same code. + Current examples are `petclinic-plain` and `petclinic-helm`. +- Existing repositories, e.g., `argocd/argocd`, can be extended by `COPY`, and `FOLDER_BASED` content repos. + - ArgoCD `AppProjects` and `Applications` can be defined in the content. + - This also allows you to hook into the configuration of Argo CD and, for example, define different tenants. + +## Additional options + +- **Kubernetes namespaces** needed for the content (e.g. `example-tenant-staging`) can be specified via the `content.namespaces` field. + - GOP deploys the namespaces listed therein via GitOps. + - In each namespace, the configured ImagePullSecrets are automatically generated and RBAC resources and `NetworkPolicies` are set up, which enable Prometheus to access the metrics. + - This also allows GOP to create `ProjectRequests` instead of `Namespaces` under OpenShift. + - The list may contain more namespaces than are used in the content. + - The namespaces allow templating, e.g., `‘${config.application.namePrefix}example-tenant-staging’, ‘${config.application.namePrefix}example-tenant-production’` +- **Jenkins**: Automatic generation of Jenkins jobs based on the content is possible. + When enable for a content repo (via `content.repos.createJenkinsJob` set to `true`) a job is created... + - for each SCM Manager namespace found in the content + - that contains a `Jenkinsfile`. +- The **example content** (see [README/Example Applications](../../README.md#example-applications)) can be activated via the `content.examples` field. + + +## Different types of content repos There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED`. -- `MIRROR` (default): The entire content repo is mirrored to the target repo if it does not yet exist ([see overrideMode below](#the-overridemode)). +- `MIRROR` (default): The entire content repo is mirrored to the target repo if it does not yet exist ([see overrideMode](#the-overridemode)). - `COPY`: Only the files (no Git history) are copied to the target repository and committed. -- `FOLDER_BASED`: Using the folder structure in the content repository, multiple repositories can be created and initialized or expanded in the target. +- `FOLDER_BASED`: Using the folder structure in the content repository, multiple repositories can be created and initialized or changed in the target. **Global Properties** -- `url` (required field) -- `ref` - Git Reference, that is cloned in Content Repo (branch, tag, commit). \ - Default: +- `url` (required) — url of the content repo +- `ref` - Git reference that is cloned in Content Repo (branch, tag, commit). + Defaults: - `COPY` / `FOLDER_BASED`: Default branch of Repo. - `MIRROR`: All branches und tags of Repo -- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle pre-existing files in the repository ([see overrideMode below](#the-overridemode)). -- `username` -- `password` +- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle existing files in the target repository ([see overrideMode](#the-overridemode)). +- `username`, `password` - credentials - `createJenkinsJob` - If `true` and Jenkins is active in GOP, and there is a `Jenkinsfile` in one of the content repositories or the specified `refs`, a Jenkins job is created for the associated SCM Manager namespace. ### `MIRROR` -A content repo is mirrored completely (or only a `ref`) to the target repo (including Git history). Caution: Force push is used here! By default, however, only on new repos. If existing repos are also to be written, `overrideMode: RESET` must be set. +A content repo is mirrored completely (or only a `ref`) to the target repo (including Git history). + +Caution: Force push is used here! +Note that by default only new repos are mirrored. +To overwrite `overrideMode: RESET` must be set ([see overrideMode](#the-overridemode)). + Note: The default branch of the source repo is not explicitly set. If the source repo has a default branch != `main`, it is not applied. **Properties** -- `target` (required field) target repo, e.g. `namespace/name` -- `targetRef` - Git reference in `target` to which it is pushed(branch or tag). +- `target` (required) - target repo, e.g. `namespace/name` +- `targetRef` - Git reference in `target` to which it is pushed (branch or tag). - If `ref `is a tag,` targetRef` is also treated as a tag. - Exception:` targetRef` is a full ref such as` refs/heads/my-branch` or `refs/tags/my-tag`. - - If `targetRef` is empty, the source ref is used by default. + - If `targetRef` is empty, the source `ref` is used by default. ### `COPY` @@ -118,18 +178,18 @@ Only the files (no Git history) are copied and committed to the target repo. **Properties** -- `target` (required) Target repo, e.g. `namespace/name` +- `target` (required) - target repo, e.g. `namespace/name` - `targetRef` - Git reference in `target` to which is pushed (branch or tag). - - If ref is a tag, targetRef is also treated as a tag. + - If `ref `is a tag,` targetRef` is also treated as a tag. - Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. - If` targetRef` is empty, the source `ref `is used by default. - `path `- Folder within the content repo from which to copy -- `templating `- If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see templating below](#templating)). +- `templating `- If `true`, all `.ftl` files are rendered using [Freemarker](https://freemarker.apache.org/) before being pushed to `target` ([see templating](#templating)). ### `FOLDER_BASED` -- Using the folder structure in the content repository, multiple repositories can be created in the target and initialized or expanded using `COPY`. -- Specifically: The top two directory levels of the repository determine the target repositories in the GOP. +- Using the folder structure in the content repository, multiple repositories can be created in the target and initialized or extended using `COPY`. +- That is, The top two directory levels of the repository determine the target repositories in GOP. - Example: The contents of the `example-tenant/petclinic-plain` folder are pushed to the `gitops` repository in the `example-tenant` namespace. ![content-hooks-folder-based.png](content-hooks-folder-based.png) @@ -138,29 +198,34 @@ This allows, for example, additional Argo CD applications to be added and even y **Properties** -- `target` (required) +- `target` (required) - target repo, e.g. `namespace/name` - `path` - source folder in the content repository used for copying -- `templating` - If `true`, all `.ftl` files are rendered by [Freemarker](https://freemarker.apache.org/) before being pushed to the target ([see templating below](#templating)). +- `templating` - If `true`, all `.ftl` files are rendered using [Freemarker](https://freemarker.apache.org/) before being pushed to `target` ([see templating](#templating)). -# The overrideMode +## The overrideMode -For these types of Content Repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET`. +For all types of content repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET`. - `INIT` (default): Only push if the repository does not exist -- `UPGRADE`: Delete all files after cloning the source – files that are not in the content will be deleted. -- `RESET`: Clone and copy – existing files are overwritten, files that are not in the content are retained. +- `UPGRADE`: Clone and copy – existing files are overwritten, files that are not in the content are retained. +- `RESET`: Delete all files after cloning the source, then copy new files. + This results in files that are not in the content being deleted. -**Note** \ +**Note** With `MIRROR`, `RESET` does not reset the entire repository. Specific effect: Branches that exist in the target but not in the source are retained. -**Important** \ -If existing repositories of the GOP are to be extended, e.g., `cluster-resources`, the `overrideMode` must be set to `UPGRADE`. +**Important** +If existing repositories of GOP are to be extended, e.g., `cluster-resources`, the `overrideMode` must be set to `UPGRADE`. -# Templating +## Templating When `templating` is enabled, all files ending in `.ftl` are rendered using [Freemarker](https://freemarker.apache.org/) during GOP installation and the result is created under the same name without the `.ftl` extension. -The entire configuration of the GOP is available as` config` in the templates. -In addition, the people who write the content have the option of defining their own variables (`content.variables`). -This makes it possible to write parameterizable content that can be used for many instances. -In [Freemarker](https://freemarker.apache.org/), you can use static methods from GOP and JDK. An [example from the GOP code](https://github.com/cloudogu/gitops-playground/blob/0.11.0/applications/cluster-resources/monitoring/prometheus-stack-helm-values.ftl.yaml#L111): + +The entire configuration of GOP is available as` config` variable in the templates. + +In addition, you can define your own variables (`content.variables`). +This makes it possible to write parameterizable content that can be used for different instances. + +In [Freemarker](https://freemarker.apache.org/), you can use static methods from GOP and JDK. +An [example from GOP code](https://github.com/cloudogu/gitops-playground/blob/0.11.0/applications/cluster-resources/monitoring/prometheus-stack-helm-values.ftl.yaml#L111): ```yaml <#assign DockerImageParser=statics['com.cloudogu.gitops.utils.DockerImageParser']> @@ -174,27 +239,32 @@ image: ``` -# TL;DR: How to start with content loader? -To start with the content loader feature start the GOP with the `content-loader-config-file.yaml`. Run this command once to set up GOP with Content Loader: +# TL;DR + +How to get started with Content Loader? + +You can deploy the GitOps Playground with customized content defined in a config file on a local Kubernetes by running +a single command: ```shell bash <(curl -s \ https://raw.githubusercontent.com/cloudogu/gitops-playground/main/scripts/init-cluster.sh) \ - && curl -s "https://raw.githubusercontent.com/cloudogu/gitops-playground/main/docs/content-loader-docs/content-loader-config.yaml" > contentConfig.yaml \ + && curl -s "https://raw.githubusercontent.com/cloudogu/gitops-playground/main/docs/content-loader/content-loader-config.yaml" > contentConfig.yaml \ && docker run --rm -t --pull=always -u $(id -u) \ -v ~/.config/k3d/kubeconfig-gitops-playground.yaml:/home/.kube/config \ -v "$(pwd)/contentConfig.yaml:/app/contentConfig.yaml" \ --net=host \ - ghcr.io/cloudogu/gitops-playground --config-file=contentConfig.yaml -# More IDP-features: --mailhog --monitoring --vault=dev --cert-manager -# More features for developers: --jenkins --registry --content-examples + ghcr.io/cloudogu/gitops-playground --config-file=contentConfig.yaml --jenkins --registry ``` -Once the GOP is started you can try the following sample use cases. Most applications mentioned in the [Stack-chapter](https://github.com/cloudogu/gitops-playground?tab=readme-ov-file#stack) are deployed now. +Once GOP is started, you can try the following example use cases. +Most applications mentioned in [README/Example Applications](../../README.md#example-applications) are deployed now. + +# Example use cases + +This chapter describes real-world use cases that can be done via Content Loader. -# Example-Use Cases -This chapter describes sample use cases that can be tried after executing the TL;DR command. \ -However, you can apply individual config.yaml files to deploy your own content. +You can try them out by editing `content-loader-config.yaml` created in [TL;DR](#tldr). ## Mirror the entire repository on every call ```yaml @@ -207,10 +277,10 @@ However, you can apply individual config.yaml files to deploy your own content. ## Create additional tenant in Argo CD ```yaml - url: 'https://github.com/cloudogu/gitops-playground.git' - path: 'docs/content-loader-docs' + path: 'docs/content-loader' ref: main - username: 'abc' # not necessary if git repo is openSource - password: 'ey...' # e.g. API Token from SCM-Manager + # username: 'abc' # necessary if git repo requires credentials + # password: 'ey...' # e.g. API Token from SCM-Manager templating: true type: FOLDER_BASED overrideMode: UPGRADE @@ -219,7 +289,12 @@ However, you can apply individual config.yaml files to deploy your own content. In this repo, the folder structure is as follows: [argocd/argocd.](argocd/argocd) ## Mirror/copy repo and add specific files -For example, to create a `Dockerfile` and `Jenkinsfile` and then create a Jenkins job. This example shows the `MIRROR` use case. As an alternative you can add type `COPY` in the first repo (petclinic). Reminder: no type means MIRROR (default). + +This example first `MIRROR`s a repo, then adds a `Dockerfile` and `Jenkinsfile` and a Jenkins job. + +As an alternative you can add type `COPY` in the first repo (petclinic), resulting in only the files not the git history being pushed to `target`. +Reminder: no type means MIRROR (default). + ```yaml - url: https://github.com/cloudogu/spring-petclinic target: example-tenant/petclinic-plain @@ -228,10 +303,10 @@ For example, to create a `Dockerfile` and `Jenkinsfile` and then create a Jenkin overrideMode: UPGRADE createJenkinsJob: true - url: https://github.com/cloudogu/gitops-playground.git - path: 'docs/content-loader-docs' + path: 'docs/content-loader' ref: main - username: 'abc' # not necessary if git repo is openSource - password: 'ey...' # e.g. API Token from SCM-Manager + # username: 'abc' # necessary if git repo requires credentials + # password: 'ey...' # e.g. API Token from SCM-Manager templating: true type: FOLDER_BASED overrideMode: UPGRADE From 118348cedf0dbd04215098d8dde973be6dfd6603 Mon Sep 17 00:00:00 2001 From: flxebrt Date: Fri, 26 Sep 2025 12:08:52 +0200 Subject: [PATCH 27/29] * fix typos * ensure consistent spelling --- docs/content-loader/content-loader.md | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/content-loader/content-loader.md b/docs/content-loader/content-loader.md index 12b0455f0..4d5082103 100644 --- a/docs/content-loader/content-loader.md +++ b/docs/content-loader/content-loader.md @@ -1,8 +1,8 @@ -# Content Loader Documentation +# Content loader Documentation -This documentation shows the Content Loader feature and its usage. +This documentation shows the content loader feature and its usage. -Content Loader offers the ability of hooking into the GitOps Playground (GOP) installation process, allowing for +Content loader offers the ability of hooking into the GitOps Playground (GOP) installation process, allowing for customization of what is pushed to Git. This can be used to deploy your own content, e.g. your own applications, or adding tenants to Argo CD, etc. @@ -16,9 +16,9 @@ Example for a GOP content repository: -- [Purpose of Content Loader](#purpose-of-content-loader) +- [Purpose of content loader](#purpose-of-content-loader) - [Meaning of the term "content"](#meaning-of-the-term-content) -- [Content Loader concepts](#content-loader-concepts) +- [Content loader concepts](#content-loader-concepts) - [Content repos](#content-repos) - [Additional options](#additional-options) - [Different types of content repos](#different-types-of-content-repos) @@ -33,7 +33,7 @@ Example for a GOP content repository: -# Purpose of Content Loader +# Purpose of content loader You like the idea of automatically rolling out IDPs using GOP but @@ -41,7 +41,7 @@ You like the idea of automatically rolling out IDPs using GOP but * want to add multiple tenants with Argo CD, * want to have different or additional IDP tools, e.g. logging/backup/tracing, etc. -Then Content Loader is for you! +Then content loader is for you! It allows you to define content using a folder structure inside a Git repo (so-called content repo) that is picked up during GOP apply optionally run through a templating engine and then pushed to the target Git. @@ -63,7 +63,7 @@ during GOP apply optionally run through a templating engine and then pushed to t Finally, these end-user applications can be reached via HTTP(S) via their ingress (turnkey-solution). - The content loader feature provides the possibility to deliver your own custom content, i.e. real-world applications instead of examples. -# Content Loader concepts +# Content loader concepts The content deployed by GOP can be completely defined via configuration. @@ -112,7 +112,7 @@ The [TL;DR](#tldr) sections shows how to see this example in action. - GOP merges these repos in the defined order into a directory structure. - This allows you to overwrite files from all repos created by GOP. - One use case for this is, for example, a base repository that specifies the basic structure of all GOP instances in a cloud environment and more specialized repositories that contain specific applications. - - Another use case is to keep the configuration (YAML) in one repo and the code in another to deploy different configg with the same code. + - Another use case is to keep the configuration (YAML) in one repo and the code in another to deploy different config with the same code. Current examples are `petclinic-plain` and `petclinic-helm`. - Existing repositories, e.g., `argocd/argocd`, can be extended by `COPY`, and `FOLDER_BASED` content repos. - ArgoCD `AppProjects` and `Applications` can be defined in the content. @@ -180,11 +180,11 @@ Only the files (no Git history) are copied and committed to the target repo. - `target` (required) - target repo, e.g. `namespace/name` - `targetRef` - Git reference in `target` to which is pushed (branch or tag). - - If `ref `is a tag,` targetRef` is also treated as a tag. + - If `ref `is a tag, `targetRef` is also treated as a tag. - Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. - If` targetRef` is empty, the source `ref `is used by default. - `path `- Folder within the content repo from which to copy -- `templating `- If `true`, all `.ftl` files are rendered using [Freemarker](https://freemarker.apache.org/) before being pushed to `target` ([see templating](#templating)). +- `templating`- If `true`, all `.ftl` files are rendered using [Freemarker](https://freemarker.apache.org/) before being pushed to `target` ([see templating](#templating)). ### `FOLDER_BASED` @@ -219,7 +219,7 @@ If existing repositories of GOP are to be extended, e.g., `cluster-resources`, t ## Templating When `templating` is enabled, all files ending in `.ftl` are rendered using [Freemarker](https://freemarker.apache.org/) during GOP installation and the result is created under the same name without the `.ftl` extension. -The entire configuration of GOP is available as` config` variable in the templates. +The entire configuration of GOP is available as `config` variable in the templates. In addition, you can define your own variables (`content.variables`). This makes it possible to write parameterizable content that can be used for different instances. @@ -241,9 +241,9 @@ image: # TL;DR -How to get started with Content Loader? +How to get started with content loader? -You can deploy the GitOps Playground with customized content defined in a config file on a local Kubernetes by running +You can deploy the GOP with customized content defined in a config file on a local Kubernetes cluster by running a single command: ```shell @@ -262,7 +262,7 @@ Most applications mentioned in [README/Example Applications](../../README.md#exa # Example use cases -This chapter describes real-world use cases that can be done via Content Loader. +This chapter describes real-world use cases that can be done via content loader. You can try them out by editing `content-loader-config.yaml` created in [TL;DR](#tldr). From 49da023944bb4ae807062e0310e8542133a9c210 Mon Sep 17 00:00:00 2001 From: Johannes Schnatterer Date: Fri, 26 Sep 2025 12:17:41 +0200 Subject: [PATCH 28/29] Content Loader: Adapt TLDR after testing Remove prefix because that makes the TLDR example more complex than necessary for content loader --- docs/content-loader/content-loader-config.yaml | 10 ++++++---- docs/content-loader/content-loader.md | 4 ++-- .../example-tenant/gitops/argocd/nginx-helm.ftl.yaml | 6 +++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/content-loader/content-loader-config.yaml b/docs/content-loader/content-loader-config.yaml index f1de1d356..e1c60fb3f 100644 --- a/docs/content-loader/content-loader-config.yaml +++ b/docs/content-loader/content-loader-config.yaml @@ -24,15 +24,17 @@ content: overwriteMode: UPGRADE createJenkinsJob: true - url: 'https://github.com/cloudogu/gitops-playground.git' - path: 'docs/content-loader-docs' + path: 'docs/content-loader' ref: main templating: true type: FOLDER_BASED overwriteMode: UPGRADE namespaces: - - ${config.application.namePrefix}example-tenant-production - - ${config.application.namePrefix}example-tenant-staging +# - ${config.application.namePrefix}example-tenant-production +# - ${config.application.namePrefix}example-tenant-staging + - example-tenant-production + - example-tenant-staging variables: umbrella: nginxAnnotation: 'my value' @@ -41,7 +43,7 @@ content: application: yes: true baseUrl: http://localhost - namePrefix: customer-1 +# namePrefix: customer-1 jenkins: active: true registry: diff --git a/docs/content-loader/content-loader.md b/docs/content-loader/content-loader.md index 4d5082103..ff36fc2a3 100644 --- a/docs/content-loader/content-loader.md +++ b/docs/content-loader/content-loader.md @@ -243,7 +243,7 @@ image: How to get started with content loader? -You can deploy the GOP with customized content defined in a config file on a local Kubernetes cluster by running +You can deploy GOP with customized content defined in a config file on a local Kubernetes cluster by running a single command: ```shell @@ -254,7 +254,7 @@ bash <(curl -s \ -v ~/.config/k3d/kubeconfig-gitops-playground.yaml:/home/.kube/config \ -v "$(pwd)/contentConfig.yaml:/app/contentConfig.yaml" \ --net=host \ - ghcr.io/cloudogu/gitops-playground --config-file=contentConfig.yaml --jenkins --registry + ghcr.io/cloudogu/gitops-playground --config-file=contentConfig.yaml --debug ``` Once GOP is started, you can try the following example use cases. diff --git a/docs/content-loader/example-tenant/gitops/argocd/nginx-helm.ftl.yaml b/docs/content-loader/example-tenant/gitops/argocd/nginx-helm.ftl.yaml index 47f2325b4..884c459db 100644 --- a/docs/content-loader/example-tenant/gitops/argocd/nginx-helm.ftl.yaml +++ b/docs/content-loader/example-tenant/gitops/argocd/nginx-helm.ftl.yaml @@ -30,4 +30,8 @@ spec: pathType: Prefix hostname: production.nginx-helm.nginx.localhost image: - repository: bitnamilegacy/nginx \ No newline at end of file + repository: bitnamilegacy/nginx + syncPolicy: + automated: + prune: true + selfHeal: true \ No newline at end of file From 422e3522b228d157c6b38ccdd93ce3c1bc89b516 Mon Sep 17 00:00:00 2001 From: Johannes Schnatterer Date: Fri, 26 Sep 2025 15:49:00 +0200 Subject: [PATCH 29/29] Content Loader docs: Finishing touches --- docs/content-loader/content-loader.md | 135 ++++++++++++++------------ 1 file changed, 74 insertions(+), 61 deletions(-) diff --git a/docs/content-loader/content-loader.md b/docs/content-loader/content-loader.md index ff36fc2a3..c49e192fe 100644 --- a/docs/content-loader/content-loader.md +++ b/docs/content-loader/content-loader.md @@ -11,6 +11,8 @@ Example for a GOP content repository: - Sample [configuration file](content-loader-config.yaml). - [Directory structure](.) as an example of a folder-based content repository. +This document will use the short for "repo" from here on, for brevity. + # Table of contents @@ -26,7 +28,7 @@ Example for a GOP content repository: - [Templating](#templating) - [TL;DR](#tldr) - [Example use cases](#example-use-cases) - - [Mirror the entire repository on every call](#mirror-the-entire-repository-on-every-call) + - [Mirror the entire repo on every call](#mirror-the-entire-repo-on-every-call) - [Create additional tenant in Argo CD](#create-additional-tenant-in-argo-cd) - [Mirror/copy repo and add specific files](#mirrorcopy-repo-and-add-specific-files) @@ -54,11 +56,11 @@ during GOP apply optionally run through a templating engine and then pushed to t - When rolling out GOP, the `--content-examples` parameter leads to example applications being pushed to Git. - These applications include: - Code (e.g., repo `argocd/petclinic-helm`) - - Configuration (Argo CD `Application` and YAML resources in the GitOps repo `argocd/example-tenant`) + - Configuration (Argo CD `Application` and YAML resources in the GitOps repo `example-tenant/gitops`) - Basic configuration of the tenant (Argo CD `AppProject` and `Application` of Applications in the repo `argocd/argocd`) - - Some of them contain Jenkins files that describe how to build and push images and start the GitOps process. - - Dependencies, e.g., `3rd-party-dependencies/gitops-build-lib` and `3rd-party-dependencies/spring-boot-helm-chart` - - Jenkins job that clones the repos, builds images, and triggers the GitOps process + - Potentially dependencies, e.g., `3rd-party-dependencies/gitops-build-lib` and `3rd-party-dependencies/spring-boot-helm-chart` + - Potentially `Jenkinsfile`s that describe how to build and push images and start the GitOps process by writing resources to Git that are then picked up by ArgoCD. + In addition, a Jenkins job that pulls and executes the `Jenkinsfile`. - After installing GOP, the example applications are built by Jenkins and deployed by ArgoCD via GitOps. Finally, these end-user applications can be reached via HTTP(S) via their ingress (turnkey-solution). - The content loader feature provides the possibility to deliver your own custom content, i.e. real-world applications instead of examples. @@ -72,6 +74,7 @@ This allows for * adding new Git repos, e.g. for end-user applications (including their dependencies such as Helm charts or build libraries) as well as IDP applications, such as monitoring tools. This is done by means of a `content` section within GOP's config file (the one being specified by `--config-file`). +This config holds references to Git repos that contain the actual content to be pushed to Git. Here is a schematic example of the `content` section that will be described in the following: @@ -82,91 +85,100 @@ content: path: 'a/b' ref: branch templating: true - type: FOLDER_BASED - overwriteMode: UPGRADE + type: FOLDER_BASED # MIRROR, COPY + overwriteMode: UPGRADE # INIT, RESET createJenkinsJob: true - ... namespaces: - - prod + - prod # templating allowed, e.g. ${config.application.namePrefix}prod - ... - variables: + variables: # can be used within templates my: value another: value - examples: true + examples: true # deploy example content described in https://github.com/cloudogu/gitops-playground ``` See [here for a full example](content-loader-config.yaml). The [TL;DR](#tldr) sections shows how to see this example in action. ## Content repos -- The content is defined in Git repositories, known as content repos (`content.repos`) -- There are different `type`s of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` ([see different types of content repos](#different-types-of-content-repos)). +- The content is defined in Git repos, known as content repos (`content.repos`) +- There are different `type`s of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED` (see [here](#different-types-of-content-repos) for details). - For these types of content repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET` ([see overrideMode](#the-overridemode)). -- Templating with [Freemarker](https://freemarker.apache.org/) can be enabled for each content repo. +- Templating with [Freemarker](https://freemarker.apache.org/) can be enabled via `templating: true` for each content repo. - The templates can access the config and custom variables defined in `content.variables`. - - See [templating](#templating). + - See [templating](#templating) for more details. - Multiple content repos can be specified in the `content.repos` field - GOP merges these repos in the defined order into a directory structure. - This allows you to overwrite files from all repos created by GOP. - - One use case for this is, for example, a base repository that specifies the basic structure of all GOP instances in a cloud environment and more specialized repositories that contain specific applications. + - One use case for this is, for example, a base repo that specifies the basic structure of all GOP instances (e.g. repo structure for tenants) in a cloud environment and more specialized repos that contain specific applications (e.g. per tenant). - Another use case is to keep the configuration (YAML) in one repo and the code in another to deploy different config with the same code. - Current examples are `petclinic-plain` and `petclinic-helm`. -- Existing repositories, e.g., `argocd/argocd`, can be extended by `COPY`, and `FOLDER_BASED` content repos. + Current examples is `petclinic-plain` (see [Mirror/copy example](#mirrorcopy-repo-and-add-specific-files)). +- Existing repos, e.g., `argocd/argocd`, can be extended by `COPY`, and `FOLDER_BASED` content repos. - ArgoCD `AppProjects` and `Applications` can be defined in the content. - - This also allows you to hook into the configuration of Argo CD and, for example, define different tenants. + - This also allows you to hook into the configuration of Argo CD and, for example, define tenants. ## Additional options - **Kubernetes namespaces** needed for the content (e.g. `example-tenant-staging`) can be specified via the `content.namespaces` field. - - GOP deploys the namespaces listed therein via GitOps. - - In each namespace, the configured ImagePullSecrets are automatically generated and RBAC resources and `NetworkPolicies` are set up, which enable Prometheus to access the metrics. - - This also allows GOP to create `ProjectRequests` instead of `Namespaces` under OpenShift. - - The list may contain more namespaces than are used in the content. + - GOP deploys the namespaces listed therein via GitOps (repo `argocd/cluster-resources`, application `misc`) + - In each namespace, the following is set up: + - the configured ImagePullSecrets + - RBAC resources + - `NetworkPolicies` (e.g. to enable Prometheus to access the metrics). - The namespaces allow templating, e.g., `‘${config.application.namePrefix}example-tenant-staging’, ‘${config.application.namePrefix}example-tenant-production’` + - Note that you can add arbitrary namespaces. They don't necessarily need to be related to your content. + - With `--openshift` GOP creates `ProjectRequests` instead of `Namespaces`. - **Jenkins**: Automatic generation of Jenkins jobs based on the content is possible. - When enable for a content repo (via `content.repos.createJenkinsJob` set to `true`) a job is created... + When enable for a content repo (via `content.repos.createJenkinsJob` set to `true`) a job is created - for each SCM Manager namespace found in the content - that contains a `Jenkinsfile`. -- The **example content** (see [README/Example Applications](../../README.md#example-applications)) can be activated via the `content.examples` field. +- The **example content** (see [README/Example Applications](../../README.md#example-applications)) can be activated via the `content.examples` field. + This content is defined in the [repo](https://github.com/cloudogu/gitops-playground/) and shipped with the image (does not require internet access at runtime) ## Different types of content repos There are different types of content repos: `MIRROR`, `COPY`, and `FOLDER_BASED`. - `MIRROR` (default): The entire content repo is mirrored to the target repo if it does not yet exist ([see overrideMode](#the-overridemode)). -- `COPY`: Only the files (no Git history) are copied to the target repository and committed. -- `FOLDER_BASED`: Using the folder structure in the content repository, multiple repositories can be created and initialized or changed in the target. +- `COPY`: Only the files (no Git history) are copied to the target repo, then committed and pushed. +- `FOLDER_BASED`: Using the folder structure in the content repo, multiple repos can be created and initialized or changed in the target. **Global Properties** - `url` (required) — url of the content repo -- `ref` - Git reference that is cloned in Content Repo (branch, tag, commit). +- `ref` — Git reference that is cloned from content repo (branch, tag, commit). Defaults: - - `COPY` / `FOLDER_BASED`: Default branch of Repo. - - `MIRROR`: All branches und tags of Repo -- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle existing files in the target repository ([see overrideMode](#the-overridemode)). -- `username`, `password` - credentials -- `createJenkinsJob` - If `true` and Jenkins is active in GOP, and there is a `Jenkinsfile` in one of the content repositories or the specified `refs`, a Jenkins job is created for the associated SCM Manager namespace. + - `COPY` / `FOLDER_BASED`: Default branch of repo. + - `MIRROR`: All branches and tags of repo +- `overrideMode` (`INIT`, `UPGRADE`, `RESET`) defines how to handle existing files in the target repo ([see overrideMode](#the-overridemode)). +- `username`, `password` — credentials +- `createJenkinsJob` — If `true` a Jenkins job is created for the associated SCM Manager namespace, when the following is also true: + - Jenkins is active in GOP (`--jenkins`), and + - there is a `Jenkinsfile` in one of the content repos or the specified `refs`. ### `MIRROR` A content repo is mirrored completely (or only a `ref`) to the target repo (including Git history). -Caution: Force push is used here! +**Caution** +Force push is used here! Note that by default only new repos are mirrored. To overwrite `overrideMode: RESET` must be set ([see overrideMode](#the-overridemode)). -Note: The default branch of the source repo is not explicitly set. -If the source repo has a default branch != `main`, it is not applied. +**Note** +The default branch of the source repo is not explicitly set. +If the source repo has a default branch != `main`, it is not set at the moment. +This might be implemented at a later point. **Properties** -- `target` (required) - target repo, e.g. `namespace/name` -- `targetRef` - Git reference in `target` to which it is pushed (branch or tag). +- `target` (required) — target repo, e.g. `namespace/name` +- `targetRef` — Git reference in `target` to which it is pushed (branch or tag). - If `ref `is a tag,` targetRef` is also treated as a tag. - Exception:` targetRef` is a full ref such as` refs/heads/my-branch` or `refs/tags/my-tag`. - If `targetRef` is empty, the source `ref` is used by default. @@ -178,8 +190,8 @@ Only the files (no Git history) are copied and committed to the target repo. **Properties** -- `target` (required) - target repo, e.g. `namespace/name` -- `targetRef` - Git reference in `target` to which is pushed (branch or tag). +- `target` (required) — target repo, e.g. `namespace/name` +- `targetRef` — Git reference in `target` to which is pushed (branch or tag). - If `ref `is a tag, `targetRef` is also treated as a tag. - Exception:` targetRef` is a complete `ref `such as `refs/heads/my-branch` or `refs/tags/my-tag`. - If` targetRef` is empty, the source `ref `is used by default. @@ -188,43 +200,45 @@ Only the files (no Git history) are copied and committed to the target repo. ### `FOLDER_BASED` -- Using the folder structure in the content repository, multiple repositories can be created in the target and initialized or extended using `COPY`. -- That is, The top two directory levels of the repository determine the target repositories in GOP. -- Example: The contents of the `example-tenant/petclinic-plain` folder are pushed to the `gitops` repository in the `example-tenant` namespace. +- Using the folder structure in the content repo, multiple repos can be created in the target and initialized or extended using `COPY`. +- That is, The top two directory levels of the repo determine the target repos in GOP. +- Example: The contents of the `example-tenant/gitops` folder are pushed to the `gitops` repo in the `example-tenant` namespace. ![content-hooks-folder-based.png](content-hooks-folder-based.png) -This allows, for example, additional Argo CD applications to be added and even your own tenants to be deployed. +This allows, for example, adding additional Argo CD applications and even your own tenants to be deployed. **Properties** -- `target` (required) - target repo, e.g. `namespace/name` -- `path` - source folder in the content repository used for copying -- `templating` - If `true`, all `.ftl` files are rendered using [Freemarker](https://freemarker.apache.org/) before being pushed to `target` ([see templating](#templating)). +- `target` (required) — target repo, e.g. `namespace/name` +- `path` — source folder in the content repo used for copying +- `templating` — If `true`, all `.ftl` files are rendered using [Freemarker](https://freemarker.apache.org/) before being pushed to `target` ([see templating](#templating)). ## The overrideMode For all types of content repos, the `overrideMode` determines how to handle previously existing files in the repo: `INIT`, `UPGRADE`, `RESET`. -- `INIT` (default): Only push if the repository does not exist +- `INIT` (default): Only push if the repo does not exist - `UPGRADE`: Clone and copy – existing files are overwritten, files that are not in the content are retained. - `RESET`: Delete all files after cloning the source, then copy new files. This results in files that are not in the content being deleted. **Note** -With `MIRROR`, `RESET` does not reset the entire repository. Specific effect: Branches that exist in the target but not in the source are retained. +With `MIRROR`, `RESET` does not reset the entire repo. Specific effect: Branches that exist in the target but not in the source are retained. **Important** -If existing repositories of GOP are to be extended, e.g., `cluster-resources`, the `overrideMode` must be set to `UPGRADE`. +If existing repos of GOP are to be extended, e.g., `cluster-resources`, the `overrideMode` must be set to `UPGRADE`. ## Templating -When `templating` is enabled, all files ending in `.ftl` are rendered using [Freemarker](https://freemarker.apache.org/) during GOP installation and the result is created under the same name without the `.ftl` extension. +When `templating` is enabled, all files ending in `.ftl` are rendered using [Freemarker](https://freemarker.apache.org/) during GOP installation and the result is created under the same name without the `.ftl` extension. +Example`values.yam;.ftl` is written to `values.yaml`. The entire configuration of GOP is available as `config` variable in the templates. In addition, you can define your own variables (`content.variables`). -This makes it possible to write parameterizable content that can be used for different instances. +This makes it possible to write parameterizable content that can be used for different instances. +Example: `config.content.variables.my` from the schematic example in [concepts](#content-loader-concepts). -In [Freemarker](https://freemarker.apache.org/), you can use static methods from GOP and JDK. +In Freemarker you can use static methods from GOP and JDK. An [example from GOP code](https://github.com/cloudogu/gitops-playground/blob/0.11.0/applications/cluster-resources/monitoring/prometheus-stack-helm-values.ftl.yaml#L111): ```yaml @@ -234,7 +248,7 @@ An [example from GOP code](https://github.com/cloudogu/gitops-playground/blob/0. <#assign operatorImageObject = DockerImageParser.parse(config.features.monitoring.helm.prometheusOperatorImage)> image: registry : ${operatorImageObject.registry} - repository: ${operatorImageObject.repository} + repo: ${operatorImageObject.repo} tag : ${operatorImageObject.tag} ``` @@ -243,8 +257,7 @@ image: How to get started with content loader? -You can deploy GOP with customized content defined in a config file on a local Kubernetes cluster by running -a single command: +You can deploy GOP with customized content on a local Kubernetes cluster like this: ```shell bash <(curl -s \ @@ -264,9 +277,9 @@ Most applications mentioned in [README/Example Applications](../../README.md#exa This chapter describes real-world use cases that can be done via content loader. -You can try them out by editing `content-loader-config.yaml` created in [TL;DR](#tldr). +You can try them out using the [`content-loader-config.yaml`](content-loader-config.yaml) used in [TL;DR](#tldr). -## Mirror the entire repository on every call +## Mirror the entire repo on every call ```yaml - url: 'https://github.com/cloudogu/spring-boot-helm-chart' target: '3rd-party/spring-boot-helm' @@ -286,14 +299,14 @@ You can try them out by editing `content-loader-config.yaml` created in [TL;DR]( overrideMode: UPGRADE ``` -In this repo, the folder structure is as follows: [argocd/argocd.](argocd/argocd) +In this repo, the folder structure defines the target repos, e.g. [argocd/argocd](argocd/argocd). ## Mirror/copy repo and add specific files -This example first `MIRROR`s a repo, then adds a `Dockerfile` and `Jenkinsfile` and a Jenkins job. +This example first `MIRROR`s a repo, then adds a `Dockerfile` and `Jenkinsfile` and creates a Jenkins job. -As an alternative you can add type `COPY` in the first repo (petclinic), resulting in only the files not the git history being pushed to `target`. -Reminder: no type means MIRROR (default). +As an alternative, you can add the type `COPY` in the first repo (petclinic), resulting in only the files being pushed to `target` (without the git history). +Reminder: no type means `MIRROR` (default). ```yaml - url: https://github.com/cloudogu/spring-petclinic