diff --git a/Makefile b/Makefile index b444e69..387bd9a 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 1.1.0 +VERSION ?= 1.1.1 # Image URL to use all building/pushing image targets IMG ?= ghcr.io/inditextech/k8s-overcommit-operator:$(VERSION) # IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. diff --git a/bundle/manifests/k8s-overcommit.clusterserviceversion.yaml b/bundle/manifests/k8s-overcommit.clusterserviceversion.yaml index e510d07..55ea301 100644 --- a/bundle/manifests/k8s-overcommit.clusterserviceversion.yaml +++ b/bundle/manifests/k8s-overcommit.clusterserviceversion.yaml @@ -30,10 +30,10 @@ metadata: } ] capabilities: Basic Install - createdAt: "2025-10-06T15:18:15Z" + createdAt: "2025-10-16T11:56:42Z" operators.operatorframework.io/builder: operator-sdk-v1.40.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 - name: k8s-overcommit.v1.1.0 + name: k8s-overcommit.v1.1.1 namespace: placeholder spec: apiservicedefinitions: {} @@ -221,7 +221,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: ghcr.io/inditextech/k8s-overcommit-operator:1.1.0 + image: ghcr.io/inditextech/k8s-overcommit-operator:1.1.1 livenessProbe: httpGet: path: /healthz @@ -313,4 +313,4 @@ spec: minKubeVersion: 1.22.0 provider: name: inditexTech - version: 1.1.0 + version: 1.1.1 diff --git a/chart/Chart.yaml b/chart/Chart.yaml index ac8354e..6a0f4fe 100644 --- a/chart/Chart.yaml +++ b/chart/Chart.yaml @@ -9,7 +9,7 @@ name: k8s-overcommit-operator description: K8s overcommit operator Helm chart for deploying the overcommit operator type: application version: "1.0.0" -appVersion: "1.1.0" +appVersion: "1.1.1" maintainers: - name: Enrique Andrés Villar email: enriqueavi@inditex.dev diff --git a/chart/values.yaml b/chart/values.yaml index 7928837..d5b1138 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -32,7 +32,7 @@ deployment: # -- Image name image: inditextech/k8s-overcommit-operator # -- Image tag - tag: 1.1.0 + tag: 1.1.1 resources: requests: # -- CPU request for the container diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 2125126..183b0b8 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -5,4 +5,4 @@ kind: Kustomization images: - name: controller newName: ghcr.io/inditextech/k8s-overcommit-operator - newTag: 1.1.0 + newTag: 1.1.1 diff --git a/deploy/catalog_source.yaml b/deploy/catalog_source.yaml index 85dbfb4..81c683e 100644 --- a/deploy/catalog_source.yaml +++ b/deploy/catalog_source.yaml @@ -5,6 +5,6 @@ metadata: namespace: olm spec: sourceType: grpc - image: ghcr.io/inditextech/k8s-overcommit-operator-catalog:1.1.0 + image: ghcr.io/inditextech/k8s-overcommit-operator-catalog:1.1.1 displayName: K8s Overcommit Operator Catalog publisher: Inditex Tech diff --git a/deploy/chart/1.1.1/Chart.yaml b/deploy/chart/1.1.1/Chart.yaml new file mode 100644 index 0000000..6a0f4fe --- /dev/null +++ b/deploy/chart/1.1.1/Chart.yaml @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: v2 +name: k8s-overcommit-operator +description: K8s overcommit operator Helm chart for deploying the overcommit operator +type: application +version: "1.0.0" +appVersion: "1.1.1" +maintainers: + - name: Enrique Andrés Villar + email: enriqueavi@inditex.dev + - name: Javier Terceiro López + email: javiertl@inditex.dev +keywords: + - kubernetes + - openshift + - operator + - overcommit + - resource-management + - cluster-optimization + - scheduling + - performance + - inditex +sources: + - https://github.com/InditexTech/k8s-overcommit-operator diff --git a/deploy/chart/1.1.1/crds/overcommit.yaml b/deploy/chart/1.1.1/crds/overcommit.yaml new file mode 100644 index 0000000..13c6506 --- /dev/null +++ b/deploy/chart/1.1.1/crds/overcommit.yaml @@ -0,0 +1,186 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: overcommits.overcommit.inditex.dev +spec: + group: overcommit.inditex.dev + names: + kind: Overcommit + listKind: OvercommitList + plural: overcommits + singular: overcommit + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Label to apply to the pods to make overcommit + jsonPath: .spec.overcommitLabel + name: Target Label + type: string + name: v1alphav1 + schema: + openAPIV3Schema: + description: Overcommit is the Schema for the overcommits API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: OvercommitSpec defines the desired state of Overcommit + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + nodeSelector: + additionalProperties: + type: string + type: object + overcommitLabel: + minLength: 1 + type: string + tolerations: + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + required: + - overcommitLabel + type: object + status: + description: OvercommitStatus defines the observed state of Overcommit + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + resources: + items: + properties: + name: + type: string + ready: + type: boolean + required: + - ready + type: object + type: array + type: object + type: object + x-kubernetes-validations: + - message: overcommit is a singleton, .metadata.name must be 'cluster' + rule: self.metadata.name == 'cluster' + served: true + storage: true + subresources: + status: {} diff --git a/deploy/chart/1.1.1/crds/overcommitClass.yaml b/deploy/chart/1.1.1/crds/overcommitClass.yaml new file mode 100644 index 0000000..ddf6f1f --- /dev/null +++ b/deploy/chart/1.1.1/crds/overcommitClass.yaml @@ -0,0 +1,209 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: overcommitclasses.overcommit.inditex.dev +spec: + group: overcommit.inditex.dev + names: + kind: OvercommitClass + listKind: OvercommitClassList + plural: overcommitclasses + shortNames: + - oc + - ocs + singular: overcommitclass + scope: Cluster + versions: + - additionalPrinterColumns: + - description: CPU overcommit ratio + jsonPath: .spec.cpuOvercommit + name: CPU + type: number + - description: Memory overcommit ratio + jsonPath: .spec.memoryOvercommit + name: Memory + type: number + - description: Is default overcommit class + jsonPath: .spec.isDefault + name: Default + type: boolean + name: v1alphav1 + schema: + openAPIV3Schema: + description: OvercommitClass is the Schema for the overcommitclasses API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: OvercommitClassSpec defines the desired state of OvercommitClass + properties: + annotations: + additionalProperties: + type: string + type: object + cpuOvercommit: + maximum: 1 + minimum: 0.0001 + type: number + excludedNamespaces: + type: string + isDefault: + default: false + type: boolean + labels: + additionalProperties: + type: string + type: object + memoryOvercommit: + maximum: 1 + minimum: 0.0001 + type: number + nodeSelector: + additionalProperties: + type: string + type: object + tolerations: + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + required: + - cpuOvercommit + - excludedNamespaces + - memoryOvercommit + type: object + status: + description: OvercommitClassStatus defines the observed state of OvercommitClass + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + resources: + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file + items: + properties: + name: + type: string + ready: + type: boolean + required: + - ready + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy/chart/1.1.1/templates/01-namespace.yaml b/deploy/chart/1.1.1/templates/01-namespace.yaml new file mode 100644 index 0000000..7c3d1ae --- /dev/null +++ b/deploy/chart/1.1.1/templates/01-namespace.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +{{ if $.Values.createNamespace }} +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ $.Values.namespace }} +{{ end }} diff --git a/deploy/chart/1.1.1/templates/02-overcommit.yaml b/deploy/chart/1.1.1/templates/02-overcommit.yaml new file mode 100644 index 0000000..2ddceef --- /dev/null +++ b/deploy/chart/1.1.1/templates/02-overcommit.yaml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +{{ if .Values.createOvercommit}} +apiVersion: overcommit.inditex.dev/v1alphav1 +kind: Overcommit +metadata: + name: cluster +spec: + overcommitLabel: {{ $.Values.overcommit.overcommitClassLabel }} + labels: + example.com/label: "true" + annotations: + example.com/annotation: "true" + {{- if .Values.overcommit.nodeSelector }} + nodeSelector: + {{- toYaml .Values.overcommit.nodeSelector | nindent 4 }} + {{- end }} + {{- if .Values.overcommit.tolerations }} + tolerations: + {{- toYaml .Values.overcommit.tolerations | nindent 4 }} + {{- end }} +{{ end }} diff --git a/deploy/chart/1.1.1/templates/02-rbac.yaml b/deploy/chart/1.1.1/templates/02-rbac.yaml new file mode 100644 index 0000000..560adcb --- /dev/null +++ b/deploy/chart/1.1.1/templates/02-rbac.yaml @@ -0,0 +1,128 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: k8s-overcommit-clusterrole +rules: + - apiGroups: + - '*' + resources: + - '*' + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - update + - apiGroups: + - "" + resources: + - services + - namespaces + verbs: + - create + - get + - list + - watch + - delete + - update + - patch + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - create + - get + - list + - watch + - delete + - update + - patch + - apiGroups: + - apps + resources: + - deployments + - replicasets + verbs: + - create + - get + - list + - delete + - update + - watch + - update + - apiGroups: + - cert-manager.io + resources: + - certificates + - issuers + verbs: + - create + - delete + - get + - list + - update + - watch + - apiGroups: + - overcommit.inditex.dev + resources: + - "*" + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "coordination.k8s.io" + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: mutating-k8s-overcommit-binding +subjects: + - kind: ServiceAccount + name: {{ $.Values.serviceAccount.name }} + namespace: {{ $.Values.namespace }} +roleRef: + kind: ClusterRole + name: k8s-overcommit-clusterrole + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: k8s-overcommit-view +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: view +subjects: + - kind: ServiceAccount + name: {{ $.Values.serviceAccount.name }} + namespace: {{ $.Values.namespace }} \ No newline at end of file diff --git a/deploy/chart/1.1.1/templates/02-sa.yaml b/deploy/chart/1.1.1/templates/02-sa.yaml new file mode 100644 index 0000000..4127227 --- /dev/null +++ b/deploy/chart/1.1.1/templates/02-sa.yaml @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ $.Values.serviceAccount.name }} + namespace: {{ $.Values.namespace }} diff --git a/deploy/chart/1.1.1/templates/03-deployment.yaml b/deploy/chart/1.1.1/templates/03-deployment.yaml new file mode 100644 index 0000000..9e9fa46 --- /dev/null +++ b/deploy/chart/1.1.1/templates/03-deployment.yaml @@ -0,0 +1,70 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +--- +{{- include "run_checks" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: k8s-overcommit-operator + namespace: {{ $.Values.namespace }} + labels: + app: k8s-overcommit-operator +spec: + replicas: 1 + selector: + matchLabels: + app: k8s-overcommit-operator + template: + metadata: + labels: + app: k8s-overcommit-operator + {{- with .Values.deployment.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- with .Values.deployment.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ $.Values.serviceAccount.name }} + containers: + - name: k8s-overcommit + command: + - /manager + args: + - --metrics-bind-address=:8080 + - -metrics-secure=false + image: {{$.Values.deployment.image.registry}}/{{$.Values.deployment.image.image}}:{{$.Values.deployment.image.tag}} + env: + - name: ENABLE_OVERCOMMIT_CONTROLLER + value: 'true' + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 8080 + name: metrics + protocol: TCP + resources: + requests: + memory: {{ $.Values.deployment.resources.requests.memory }} + cpu: {{ $.Values.deployment.resources.requests.cpu }} + limits: + memory: {{ $.Values.deployment.resources.limits.memory }} + cpu: {{ $.Values.deployment.resources.limits.cpu }} + {{- if .Values.deployment.tolerations }} + tolerations: + {{- toYaml .Values.deployment.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.deployment.nodeSelector }} + nodeSelector: + {{- toYaml .Values.deployment.nodeSelector | nindent 8 }} + {{- end }} diff --git a/deploy/chart/1.1.1/templates/04-overcommitClass.yaml b/deploy/chart/1.1.1/templates/04-overcommitClass.yaml new file mode 100644 index 0000000..10eee87 --- /dev/null +++ b/deploy/chart/1.1.1/templates/04-overcommitClass.yaml @@ -0,0 +1,51 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +{{ if $.Values.createClasses}} +--- +apiVersion: overcommit.inditex.dev/v1alphav1 +kind: OvercommitClass +metadata: + name: high +spec: + cpuOvercommit: 0.1 + memoryOvercommit: 0.8 + isDefault: false + excludedNamespaces: "{{ .Values.overcommit.excludedNamespaces }}" + labels: + example.com/label: "true" + annotations: + example.com/annotation: "true" + {{- if .Values.overcommit.nodeSelector }} + nodeSelector: + {{- toYaml .Values.overcommit.nodeSelector | nindent 4 }} + {{- end }} + {{- if .Values.overcommit.tolerations }} + tolerations: + {{- toYaml .Values.overcommit.tolerations | nindent 4 }} + {{- end }} +--- +apiVersion: overcommit.inditex.dev/v1alphav1 +kind: OvercommitClass +metadata: + name: low +spec: + cpuOvercommit: 0.8 + memoryOvercommit: 1 + isDefault: false + excludedNamespaces: "{{ .Values.overcommit.excludedNamespaces }}" + labels: + example.com/label: "true" + annotations: + example.com/annotation: "true" + {{- if .Values.overcommit.nodeSelector }} + nodeSelector: + {{- toYaml .Values.overcommit.nodeSelector | nindent 4 }} + {{- end }} + {{- if .Values.overcommit.tolerations }} + tolerations: + {{- toYaml .Values.overcommit.tolerations | nindent 4 }} + {{- end }} +{{- end }} diff --git a/deploy/chart/1.1.1/templates/_checks.tpl b/deploy/chart/1.1.1/templates/_checks.tpl new file mode 100644 index 0000000..3d112dc --- /dev/null +++ b/deploy/chart/1.1.1/templates/_checks.tpl @@ -0,0 +1,14 @@ +{{- define "checks" -}} +{{- $kubeVersion := lookup "v1" "Namespace" "" "kube-system" }} +{{- if $kubeVersion }} +{{- $certCRD := lookup "apiextensions.k8s.io/v1" "CustomResourceDefinition" "" "certificates.cert-manager.io" }} +{{- if not $certCRD }} +{{- fail "Required CRD 'certificates.cert-manager.io' not found in the cluster. Please install cert-manager first." }} +{{- end }} + +{{- $issuerCRD := lookup "apiextensions.k8s.io/v1" "CustomResourceDefinition" "" "issuers.cert-manager.io" }} +{{- if not $issuerCRD }} +{{- fail "Required CRD 'issuers.cert-manager.io' not found in the cluster. Please install cert-manager first." }} +{{- end }} +{{- end }} +{{- end -}} diff --git a/deploy/chart/1.1.1/templates/_helpers.tpl b/deploy/chart/1.1.1/templates/_helpers.tpl new file mode 100644 index 0000000..363dc42 --- /dev/null +++ b/deploy/chart/1.1.1/templates/_helpers.tpl @@ -0,0 +1,3 @@ +{{- define "run_checks" -}} +{{- include "checks" . }} +{{- end -}} \ No newline at end of file diff --git a/deploy/chart/1.1.1/values.yaml b/deploy/chart/1.1.1/values.yaml new file mode 100644 index 0000000..d5b1138 --- /dev/null +++ b/deploy/chart/1.1.1/values.yaml @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +# SPDX-FileContributor: enriqueavi@inditex.com +# +# SPDX-License-Identifier: Apache-2.0 + +--- +# -- The namespace to deploy the resources +namespace: k8s-overcommit +# -- Whether to create the namespace if it does not exist +createNamespace: true +createOvercommit: false +createClasses: false + +# -- Configuration for the Overcommit controllers +overcommit: + # -- Label of the overcommit class + overcommitClassLabel: inditex.com/overcommit-class + excludedNamespaces: ".*(^(openshift|k8s-overcommit|kube).*).*" + # -- Node selector for the deployments created by the overcommit operator + nodeSelector: {} + # -- Tolerations for the deployments created by the overcommit operator + tolerations: [] + +# -- Controller deployment configuration +deployment: + # -- Number of replicas for the deployment + replicas: 1 + # -- Image configuration for the deployment + image: + # -- Docker registry for the image + registry: ghcr.io + # -- Image name + image: inditextech/k8s-overcommit-operator + # -- Image tag + tag: 1.1.1 + resources: + requests: + # -- CPU request for the container + cpu: "250m" + # -- Memory request for the container + memory: "64Mi" + limits: + # -- CPU limit for the container + cpu: "500m" + # -- Memory limit for the container + memory: "1Gi" + podAnnotations: + example-annotation: example-value + podLabels: + example-label: example-value + # -- Node selector for the deployment pods + nodeSelector: {} + # -- Tolerations for the deployment pods + tolerations: [] + +serviceAccount: + name: overcommit-sa diff --git a/deploy/olm/1.1.1/k8s-overcommit-k8s-overcommit-view_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml b/deploy/olm/1.1.1/k8s-overcommit-k8s-overcommit-view_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml new file mode 100644 index 0000000..596c8da --- /dev/null +++ b/deploy/olm/1.1.1/k8s-overcommit-k8s-overcommit-view_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + creationTimestamp: null + name: k8s-overcommit-k8s-overcommit-view +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: view +subjects: +- kind: ServiceAccount + name: k8s-overcommit-controller-manager + namespace: k8s-overcommit diff --git a/deploy/olm/1.1.1/k8s-overcommit-manager-cluster-reader_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml b/deploy/olm/1.1.1/k8s-overcommit-manager-cluster-reader_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml new file mode 100644 index 0000000..7fdd647 --- /dev/null +++ b/deploy/olm/1.1.1/k8s-overcommit-manager-cluster-reader_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + creationTimestamp: null + name: k8s-overcommit-manager-cluster-reader +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-reader +subjects: +- kind: ServiceAccount + name: k8s-overcommit-controller-manager + namespace: k8s-overcommit diff --git a/deploy/olm/1.1.1/k8s-overcommit-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/deploy/olm/1.1.1/k8s-overcommit-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 0000000..862b900 --- /dev/null +++ b/deploy/olm/1.1.1/k8s-overcommit-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,10 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: k8s-overcommit-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get diff --git a/deploy/olm/1.1.1/k8s-overcommit-overcommit-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/deploy/olm/1.1.1/k8s-overcommit-overcommit-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 0000000..5944e6d --- /dev/null +++ b/deploy/olm/1.1.1/k8s-overcommit-overcommit-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,27 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: k8s-overcommit + name: k8s-overcommit-overcommit-editor-role +rules: +- apiGroups: + - overcommit.inditex.dev + resources: + - overcommits + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - overcommit.inditex.dev + resources: + - overcommits/status + verbs: + - get diff --git a/deploy/olm/1.1.1/k8s-overcommit-overcommit-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/deploy/olm/1.1.1/k8s-overcommit-overcommit-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 0000000..f263aaf --- /dev/null +++ b/deploy/olm/1.1.1/k8s-overcommit-overcommit-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: k8s-overcommit + name: k8s-overcommit-overcommit-viewer-role +rules: +- apiGroups: + - overcommit.inditex.dev + resources: + - overcommits + verbs: + - get + - list + - watch +- apiGroups: + - overcommit.inditex.dev + resources: + - overcommits/status + verbs: + - get diff --git a/deploy/olm/1.1.1/k8s-overcommit-overcommitclass-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/deploy/olm/1.1.1/k8s-overcommit-overcommitclass-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 0000000..7c2652c --- /dev/null +++ b/deploy/olm/1.1.1/k8s-overcommit-overcommitclass-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,27 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: k8s-overcommit + name: k8s-overcommit-overcommitclass-editor-role +rules: +- apiGroups: + - overcommit.inditex.dev + resources: + - overcommitclasses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - overcommit.inditex.dev + resources: + - overcommitclasses/status + verbs: + - get diff --git a/deploy/olm/1.1.1/k8s-overcommit-overcommitclass-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/deploy/olm/1.1.1/k8s-overcommit-overcommitclass-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 0000000..2b891b5 --- /dev/null +++ b/deploy/olm/1.1.1/k8s-overcommit-overcommitclass-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: k8s-overcommit + name: k8s-overcommit-overcommitclass-viewer-role +rules: +- apiGroups: + - overcommit.inditex.dev + resources: + - overcommitclasses + verbs: + - get + - list + - watch +- apiGroups: + - overcommit.inditex.dev + resources: + - overcommitclasses/status + verbs: + - get diff --git a/deploy/olm/1.1.1/k8s-overcommit.clusterserviceversion.yaml b/deploy/olm/1.1.1/k8s-overcommit.clusterserviceversion.yaml new file mode 100644 index 0000000..55ea301 --- /dev/null +++ b/deploy/olm/1.1.1/k8s-overcommit.clusterserviceversion.yaml @@ -0,0 +1,316 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "overcommit.inditex.dev/v1alphav1", + "kind": "Overcommit", + "metadata": { + "labels": { + "app.kubernetes.io/managed-by": "kustomize", + "app.kubernetes.io/name": "k8s-overcommit" + }, + "name": "overcommit-sample" + }, + "spec": null + }, + { + "apiVersion": "overcommit.inditex.dev/v1alphav1", + "kind": "OvercommitClass", + "metadata": { + "labels": { + "app.kubernetes.io/managed-by": "kustomize", + "app.kubernetes.io/name": "k8s-overcommit" + }, + "name": "overcommitclass-sample" + }, + "spec": null + } + ] + capabilities: Basic Install + createdAt: "2025-10-16T11:56:42Z" + operators.operatorframework.io/builder: operator-sdk-v1.40.0 + operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 + name: k8s-overcommit.v1.1.1 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - kind: OvercommitClass + name: overcommitclasses.overcommit.inditex.dev + version: v1alphav1 + - kind: Overcommit + name: overcommits.overcommit.inditex.dev + version: v1alphav1 + required: + - description: Certificate resource from cert-manager + displayName: Certificate + kind: Certificate + name: certificates.cert-manager.io + version: v1 + - description: Issuer resource from cert-manager + displayName: Issuer + kind: Issuer + name: issuers.cert-manager.io + version: v1 + description: Operator for make overcommit to pods based in classes + displayName: k8s-overcommit-operator + icon: + - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLSBHZW5lcmF0ZWQgYnkgUGl4ZWxtYXRvciBQcm8gMy43IC0tPgo8c3ZnIHdpZHRoPSI3NTAiIGhlaWdodD0iMTAwMCIgdmlld0JveD0iMCAwIDc1MCAxMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogICAgPGcgaWQ9Ikdyb3VwIj4KICAgICAgICA8cGF0aCBpZD0iU2hhcGUiIGZpbGw9IiM4NGQ2ZTQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTSA0MTIgODA0LjM1NDQ5MiBDIDQwNC41NzUwMTIgODA0LjU5MzUwNiAzOTIuMTMzNDg0IDgwNC40MjIzMDIgMzg0LjM1MjIwMyA4MDMuOTc0MTIxIEMgMzc2LjU3MDkyMyA4MDMuNTI1ODc5IDM2NS40MTEyODUgODAyLjQ0NzE0NCAzNTkuNTUzMDQgODAxLjU3Njc4MiBDIDM1My42OTQ3OTQgODAwLjcwNjQ4MiAzNDMuNjM2MzIyIDc5OC44MTQ2OTcgMzM3LjIwMDgzNiA3OTcuMzcyOTI1IEMgMzMwLjc2NTM4MSA3OTUuOTMxMDkxIDMyMSA3OTMuMjAxNzgyIDMxNS41IDc5MS4zMDc3MzkgQyAzMTAgNzg5LjQxMzY5NiAzMDAuNDk2NDYgNzg1LjQ3NDU0OCAyOTQuMzgxMDQyIDc4Mi41NTQxMzggQyAyODguMjY1NjI1IDc3OS42MzM3MjggMjc5LjI3OTYwMiA3NzQuNjAxODA3IDI3NC40MTIxMDkgNzcxLjM3MjEzMSBDIDI2OS41NDQ2MTcgNzY4LjE0MjQ1NiAyNjEuMDk2NDk3IDc2MS4yMjQ5NzYgMjU1LjYzODU1IDc1NiBDIDI1MC4xODA1ODggNzUwLjc3NTAyNCAyNDMuNDg3NjQgNzQzLjM0OTk3NiAyNDAuNzY1MzUgNzM5LjUgQyAyMzguMDQzMDYgNzM1LjY1MDAyNCAyMzQuMDI4NTY0IDcyOC45NjU1NzYgMjMxLjg0NDIzOCA3MjQuNjQ1NjMgQyAyMjkuNjU5OTEyIDcyMC4zMjU3NDUgMjI2LjYwOTkyNCA3MTMuMzUwNzA4IDIyNS4wNjY0OTggNzA5LjE0NTYzIEMgMjIzLjUyMzA1NiA3MDQuOTQwNTUyIDIyMS4yNTY2NjggNjk3LjIyNDk3NiAyMjAuMDMwMDc1IDY5MiBDIDIxOC44MDM0ODIgNjg2Ljc3NTAyNCAyMTcuMTc3OTk0IDY3OC40NTAwMTIgMjE2LjQxNzg5MiA2NzMuNSBDIDIxNS42NTc3NzYgNjY4LjU0OTk4OCAyMTUuMDI3ODAyIDY2Mi4xMTIgMjE1LjAxNzk0NCA2NTkuMTkzMzU5IEMgMjE1IDY1My44ODY1OTcgMjE1IDY1My44ODY1OTcgMjE5LjI1IDY1Ni40OTIxODggQyAyMjEuNTg3NDk0IDY1Ny45MjUxNzEgMjI2Ljk3OTE4NyA2NjAuODc2NTI2IDIzMS4yMzE1MzcgNjYzLjA1MDY1OSBDIDIzNS40ODM4NzEgNjY1LjIyNDg1NCAyNDMuMTMzODgxIDY2OC41NDc2NjggMjQ4LjIzMTUzNyA2NzAuNDM0NjkyIEMgMjUzLjMyOTE5MyA2NzIuMzIxNjU1IDI2MiA2NzUuMjI5NzM2IDI2Ny41IDY3Ni44OTcwOTUgQyAyNzMgNjc4LjU2NDQ1MyAyODIuNDUwMDEyIDY4MS4wMjgxOTggMjg4LjUgNjgyLjM3MjA3IEMgMjk0LjU0OTk4OCA2ODMuNzE1OTQyIDMwNS4xMjUgNjg1Ljc2MTQ3NSAzMTIgNjg2LjkxNzg0NyBDIDMxOC44NzUgNjg4LjA3NDE1OCAzMzAuNTc1MDEyIDY4OS43MTEzNjUgMzM4IDY5MC41NTYwMyBDIDM0NS40MjQ5ODggNjkxLjQwMDc1NyAzNjMuMjAwMDEyIDY5Mi4zNjg1MyAzNzcuNSA2OTIuNzA2NjA0IEMgMzkzLjg2MzQ5NSA2OTMuMDkzNTA2IDQxMC41NDIwODQgNjkyLjg3MjE5MiA0MjIuNSA2OTIuMTA5NzQxIEMgNDMyLjk1MDAxMiA2OTEuNDQzMzU5IDQ0Ny43OTk5ODggNjkwLjAwMzA1MiA0NTUuNSA2ODguOTA5MDU4IEMgNDYzLjIwMDAxMiA2ODcuODE1MTI1IDQ3OC4yNzQ5OTQgNjg1LjE1NzY1NCA0ODkgNjgzLjAwMzY2MiBDIDQ5OS43MjUwMDYgNjgwLjg0OTYwOSA1MTQuMzQ5OTc2IDY3Ny40ODMxNTQgNTIxLjUgNjc1LjUyMjU4MyBDIDUyOC42NTAwMjQgNjczLjU2MjA3MyA1NDAuNzk5OTg4IDY2OS45MDU5NDUgNTQ4LjUgNjY3LjM5Nzg4OCBDIDU1Ni4yMDAwMTIgNjY0Ljg4OTc3MSA1NjcuNDUwMDEyIDY2MC44OTQwNDMgNTczLjUgNjU4LjUxODMxMSBDIDU3OS41NDk5ODggNjU2LjE0MjYzOSA1ODguNzc1MDI0IDY1Mi4xNjYwMTYgNTk0IDY0OS42ODEzOTYgQyA2MDMuNDU4MzEzIDY0NS4xODM3MTYgNjAzLjUwMTM0MyA2NDUuMTc0MTk0IDYwMy44MDkyMDQgNjQ3LjUwNjk1OCBDIDYwMy45NzkyNDggNjQ4Ljc5NTY1NCA2MDMuMzc1MTgzIDY1NC4yMTMwNzQgNjAyLjQ2Njc5NyA2NTkuNTQ1NjU0IEMgNjAxLjU1ODQxMSA2NjQuODc4MTc0IDU5OS43NjA5ODYgNjczLjU3NDQ2MyA1OTguNDcyNTk1IDY3OC44NzA2MDUgQyA1OTcuMTg0MTQzIDY4NC4xNjY3NDggNTk0LjUzNTMzOSA2OTMuMDY2MTYyIDU5Mi41ODYzMDQgNjk4LjY0NzA5NSBDIDU5MC42MzczMjkgNzA0LjIyODAyNyA1ODcuMjEyNjQ2IDcxMi42MjczOCA1ODQuOTc1OTUyIDcxNy4zMTIzMTcgQyA1ODIuNzM5MjU4IDcyMS45OTczMTQgNTc5LjA2NzIgNzI4LjY4MTAzIDU3Ni44MTU4NTcgNzMyLjE2NTE2MSBDIDU3NC41NjQ1MTQgNzM1LjY0OTM1MyA1NzAuMDEzMDYyIDc0MS43NzYyNDUgNTY2LjcwMTQ3NyA3NDUuNzgwNTE4IEMgNTYzLjM4OTg5MyA3NDkuNzg0ODUxIDU1Ny40ODk4NjggNzU1Ljc4MTM3MiA1NTMuNTkwMjEgNzU5LjEwNjE0IEMgNTQ5LjY5MDYxMyA3NjIuNDMwOTY5IDU0Mi45MDAwMjQgNzY3LjU0NDMxMiA1MzguNSA3NzAuNDY5MTE2IEMgNTM0LjA5OTk3NiA3NzMuMzkzOTgyIDUyNS45NTY0ODIgNzc4LjA1NDQ0MyA1MjAuNDAzMzIgNzgwLjgyNTY4NCBDIDUxNC44NTAxNTkgNzgzLjU5NjkyNCA1MDUuNjYwMzcgNzg3LjQ4MTYyOCA0OTkuOTgxNTM3IDc4OS40NTgyNTIgQyA0OTQuMzAyNzA0IDc5MS40MzQ5MzcgNDg1LjIzNjExNSA3OTQuMTcyNzI5IDQ3OS44MzM1ODggNzk1LjU0MjE3NSBDIDQ3NC40MzEwNjEgNzk2LjkxMTYyMSA0NjQuOTQ1ODkyIDc5OC44ODcxNDYgNDU4Ljc1NTQwMiA3OTkuOTMyMTkgQyA0NTIuNTY0OTQxIDgwMC45NzcxNzMgNDQyLjU0OTk4OCA4MDIuMzAyMDAyIDQzNi41IDgwMi44NzYwOTkgQyA0MzAuNDUwMDEyIDgwMy40NTAyNTYgNDE5LjQyNDk4OCA4MDQuMTE1NTQgNDEyIDgwNC4zNTQ0OTIgWiIvPgogICAgICAgIDxwYXRoIGlkPSJwYXRoMSIgZmlsbD0iI2ZmZGViMiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNIDI1MS4yOTc3MTQgODEyIEMgMjQ3LjkxOTYxNyA4MTIgMjQ2LjMxODE3NiA4MTEuNDA5MDU4IDI0NC4zNDI4MDQgODA5LjQzMzcxNiBDIDI0Mi4zMDk1MDkgODA3LjQwMDM5MSAyNDAuNTIxMzQ3IDgwNS4zOTMzMTEgMjQxIDgwMyBDIDI0MS4zMzIyNzUgODAxLjMzODYyMyAyNDMuMDkzMjQ2IDc5OC4xMTQ2ODUgMjQ1IDc5NSBDIDI0Ni45MDY3NjkgNzkxLjg4NTMxNSAyNDcuNjQzNzIzIDc5MC45NjI1MjQgMjQ4IDc5MCBDIDI0OC40Mzk4NjUgNzg4LjgxMTcwNyAyNTIuMDQzMDkxIDc4NyAyNTEgNzg3IEMgMjUwLjE1NTEyMSA3ODcgMjQ4Ljc3Mjc5NyA3ODkuMzg3NTEyIDI0NyA3OTIgQyAyNDUuMjI3MjAzIDc5NC42MTI0ODggMjQzLjA0MTkxNiA3OTcuNjYyNDc2IDI0MiA4MDAgQyAyNDAuOTU4MDk5IDgwMi4zMzc1MjQgMjM3LjQ1NDUxNCA4MDQgMjM2LjkwMjE3NiA4MDQgQyAyMzYuMzQ5ODU0IDgwNCAyMzUuMjQ1OTExIDgwMi40Mzk0NTMgMjM0LjQ0ODk3NSA4MDAuNTMyMTA0IEMgMjMzLjY1MjAzOSA3OTguNjI0NzU2IDIzMyA3OTUuNDYwMzI3IDIzMyA3OTMuNSBDIDIzMyA3OTEuNTM5NjczIDIzMy42MzgwNzcgNzg4LjQwODYzIDIzNC40MTc5MzggNzg2LjU0MjExNCBDIDIzNS4xOTc4MTUgNzg0LjY3NTY1OSAyMzguNTA1MDY2IDc4MC41Mjc1ODggMjQxLjc2NzQxIDc3Ny4zMjQyOCBDIDI0NS4wMjk3NTUgNzc0LjEyMDkxMSAyNTAuOTExODk2IDc2OS4yOTIzNTggMjU0LjgzODgzNyA3NjYuNTk0MTE2IEMgMjYxLjk3ODcyOSA3NjEuNjg4MjMyIDI2MS45Nzg3MjkgNzYxLjY4ODIzMiAyNjcuNzM5MzggNzY2LjIwODg2MiBDIDI3MC45MDc3MTUgNzY4LjY5NTI1MSAyNzYuMjMwODk2IDc3Mi40Nzc5MDUgMjc5LjU2ODY2NSA3NzQuNjE0NzQ2IEMgMjgyLjkwNjQzMyA3NzYuNzUxNjQ4IDI4Ny45NjE5NDUgNzc5LjYyNSAyOTAuODAzMTMxIDc4MSBDIDI5My42NDQyODcgNzgyLjM3NSAyOTUuOTY2OTggNzgzLjcyNDk3NiAyOTUuOTY0NjYxIDc4NCBDIDI5NS45NjIzMTEgNzg0LjI3NTAyNCAyOTIuOTMxNzkzIDc4NS45MjY2OTcgMjg5LjIzMDE5NCA3ODcuNjcwNDEgQyAyODUuNTI4NTk1IDc4OS40MTQxMjQgMjc5LjU3NTAxMiA3OTMuNDAxMjQ1IDI3NiA3OTYuNTMwNzYyIEMgMjcyLjQyNDk4OCA3OTkuNjYwMjc4IDI2Ni4zOTE5MzcgODA0LjQyMTA4MiAyNjIuNTkzMTcgODA3LjExMDM1MiBDIDI1Ni44NTY5OTUgODExLjE3MTI2NSAyNTQuOTQyNDkgODEyIDI1MS4yOTc3MTQgODEyIFoiLz4KICAgICAgICA8cGF0aCBpZD0icGF0aDIiIGZpbGw9IiNmZmRlYjIiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTSA1MjkuMDMzNTA4IDc3Ny4wNDc2MDcgQyA1NDIuMzQwNjk4IDc2OC4xOTI4MSA1NDguNDE1NDA1IDc2My42MzM4NSA1NTEuMTE4MTY0IDc2MS4yMDM4NTcgQyA1NTYuMDMyMzQ5IDc1Ni43ODU1ODMgNTU2LjAzMjM0OSA3NTYuNzg1NTgzIDU2MC4zMjY3MjEgNzYwLjMwNDUwNCBDIDU2Mi42ODg1OTkgNzYyLjIzOTg2OCA1NjcuMTM5MjgyIDc2Ni41NDMzOTYgNTcwLjIxNzE2MyA3NjkuODY3ODU5IEMgNTczLjI5NTA0NCA3NzMuMTkyMzIyIDU3Ni45ODAyODYgNzc4LjM3OTE1IDU3OC40MDY2MTYgNzgxLjM5NDIyNiBDIDU3OS44MzMwMDggNzg0LjQwOTMwMiA1ODAuOTk4MjkxIDc4OC41OTE1NTMgNTgwLjk5NjI3NyA3OTAuNjg4MTEgQyA1ODAuOTk0MjAyIDc5Mi43ODQ2NjggNTgwLjA2NDI3IDc5Ni4wMjI1ODMgNTc4LjkyOTc0OSA3OTcuODgzNTQ1IEMgNTc3Ljc5NTIyNyA3OTkuNzQ0NDQ2IDU3Ni41MjEzMDEgODAwLjg2OTQ0NiA1NzYuMDk4ODE2IDgwMC4zODM1NDUgQyA1NzUuNjc2MjcgNzk5Ljg5NzU4MyA1NzIuOTA4OTk3IDc5OC40NzQ5NzYgNTcyIDc5NiBDIDU3MS4wOTA5NDIgNzkzLjUyNTAyNCA1NjguNDAxNjcyIDc5MC4wNjI1IDU2NyA3ODggQyA1NjUuNTk4MzI4IDc4NS45Mzc1IDU2NC44NDU1MiA3ODQgNTY0IDc4NCBDIDU2My4xNTQ0OCA3ODQgNTY0LjgyMjE0NCA3ODMuMzEyNSA1NjUgNzg0IEMgNTY1LjE3Nzc5NSA3ODQuNjg3NSA1NjcuNDYyNDAyIDc4OC40MzM4MzggNTY5IDc5MSBDIDU3MC41Mzc1OTggNzkzLjU2NjE2MiA1NzEuNTMyNDEgNzk0LjQ0MTE2MiA1NzIgNzk2IEMgNTcyLjQ2NzY1MSA3OTcuNTU4ODM4IDU3Mi42MjMxMDggNzk5LjA3NDcwNyA1NzMgODAwIEMgNTczLjQ5OTUxMiA4MDEuMjI2NTYzIDU3Mi4zNDA4MiA4MDQuMjg5NTUxIDU3MC4xMzA3MzcgODA1LjQzMjM3MyBDIDU2OC40NjM0NCA4MDYuMjk0NTU2IDU2NS44Mzk0NzggODA2Ljk5NTc4OSA1NjQuMjk5NjgzIDgwNi45OTA2MDEgQyA1NjIuNzU5ODI3IDgwNi45ODU0NzQgNTU5LjE3MTYzMSA4MDUuNjQ1ODc0IDU1Ni4zMjU4NjcgODA0LjAxMzY3MiBDIDU1My40ODAwNDIgODAyLjM4MTU5MiA1NDkuNjU1MDkgNzk5LjEyNjE2IDU0Ny44MjU4NjcgNzk2Ljc3OTQxOSBDIDU0NS45OTY2NDMgNzk0LjQzMjczOSA1NDEuMDIwMDIgNzg5LjAzMzAyIDUzNi43NjY3MjQgNzg0Ljc4MDE1MSBMIDUyOS4wMzM1MDggNzc3LjA0NzYwNyBaIi8+CiAgICA8L2c+CiAgICA8ZyBpZD0iZzEiPgogICAgICAgIDxnIGlkPSJnMiI+CiAgICAgICAgICAgIDxwYXRoIGlkPSJwYXRoMyIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNIDM5Ny43NTEwMzggNjk0LjI3MTM2MiBDIDM5My43NjI5NyA2OTQuMzk3MDk1IDM4NS43NzQ5OTQgNjk0LjQwNjYxNiAzODAgNjk0LjI5MjQ4IEMgMzc0LjIyNTAwNiA2OTQuMTc4MzQ1IDM2My4xMjE3MDQgNjkzLjYxNDg2OCAzNTUuMzI1OTg5IDY5My4wNDA0MDUgQyAzNDcuNTMwMjczIDY5Mi40NjU5NDIgMzM1LjYwNTI4NiA2OTEuMjg3NzIgMzI4LjgyNTk4OSA2OTAuNDIyMDU4IEMgMzIyLjA0NjY5MiA2ODkuNTU2NDU4IDMxMC42NDk5OTQgNjg3LjcyNzI5NSAzMDMuNSA2ODYuMzU3MyBDIDI5Ni4zNTAwMDYgNjg0Ljk4NzMwNSAyODUuMzI1MDEyIDY4Mi41NjgxMTUgMjc5IDY4MC45ODEzMjMgQyAyNzIuNjc0OTg4IDY3OS4zOTQ1MzEgMjYyLjIzMDQ2OSA2NzYuMjc5MTE0IDI1NS43ODk5NDggNjc0LjA1ODIyOCBDIDI0OS4zNDk0MjYgNjcxLjgzNzI4IDI0MC4zNDk0MjYgNjY4LjI4MzgxMyAyMzUuNzg5OTQ4IDY2Ni4xNjE2MjEgQyAyMzEuMjMwNDg0IDY2NC4wMzk0OSAyMjQuMjExOTYgNjYwLjA1MTgxOSAyMjAuMTkzMjM3IDY1Ny4zMDAxNzEgQyAyMTYuMTc0NTMgNjU0LjU0ODU4NCAyMTEuNzk0NzA4IDY1MC42OTA1NTIgMjEwLjQ2MDMxMiA2NDguNzI2ODA3IEMgMjA5LjEyNTkxNiA2NDYuNzYzMDYyIDIwNy41MTY2NDcgNjQzLjIwODY3OSAyMDYuODg0MTQgNjQwLjgyODE4NiBDIDIwNi4wMTYzNTcgNjM3LjU2MjEzNCAyMDYuMDIwNzM3IDYzMC4zNjQ3NDYgMjA2LjkwMTkzMiA2MTEuNSBDIDIwNy41NDQyMiA1OTcuNzUgMjA4LjcyODY1MyA1NzguODQ5OTc2IDIwOS41MzQwMjcgNTY5LjUgQyAyMTAuMzM5Mzg2IDU2MC4xNTAwMjQgMjExLjI3NDg1NyA1NDkuOTc0MTIxIDIxMS42MTI4MzkgNTQ2Ljg4Njk2MyBDIDIxMi4yMDA0MjQgNTQxLjUxOTc3NSAyMTIuMTE4NSA1NDEuMjQ2NTgyIDIwOS43NDI0OTMgNTQwLjY1MDIwOCBDIDIwOC4zNzU4MjQgNTQwLjMwNzE5IDIwNi4xMzMzNjIgNTM4LjU1MjU1MSAyMDQuNzU5Mjc3IDUzNi43NTEwMzggQyAyMDMuMDk4NTI2IDUzNC41NzM2NjkgMjAxLjg0MzgyNiA1MzEuMDAyNzQ3IDIwMS4wMTY4NzYgNTI2LjEwMDAzNyBDIDIwMC4yOTU5NzUgNTIxLjgyNjA1IDIwMC4wNDg5ODEgNTE2LjE1NDE3NSAyMDAuNDI5NTIgNTEyLjYxMjI0NCBDIDIwMC43OTA2OTUgNTA5LjI1MDUxOSAyMDEuNTY5OTQ2IDUwNC45MjQ5ODggMjAyLjE2MTE5NCA1MDMgQyAyMDIuNzUyNDI2IDUwMS4wNzUwMTIgMjAzLjg3OTczIDQ5OC4wOTk4NTQgMjA0LjY2NjI3NSA0OTYuMzg4NTUgQyAyMDUuNDUyODM1IDQ5NC42NzcyNDYgMjA3LjIyMDg3MSA0OTIuNzY0NzcxIDIwOC41OTUyNDUgNDkyLjEzODU1IEMgMjA5Ljk2OTYyIDQ5MS41MTIzMjkgMjExLjk4MDAyNiA0OTEgMjEzLjA2MjgzNiA0OTEgQyAyMTQuNzgyMzE4IDQ5MSAyMTQuNjU3NjA4IDQ5MC42NTE4NTUgMjEyLjA3NzcyOCA0ODguMjUgQyAyMTAuMDE0OTA4IDQ4Ni4zMjk1MjkgMjA4LjM2MjIxMyA0ODMuMDMwOTQ1IDIwNi41OTg2OTQgNDc3LjMxNDY5NyBDIDIwNS4yMDk4MjQgNDcyLjgxMjc0NCAyMDMuNTQxNDI4IDQ2Ni4yNDE4MjEgMjAyLjg5MTE1OSA0NjIuNzEyNzA4IEMgMjAyLjI0MDg5MSA0NTkuMTgzNTk0IDIwMS45ODQxNzcgNDU1LjIxNjk4IDIwMi4zMjA2OTQgNDUzLjg5ODA3MSBDIDIwMi43MDU0NDQgNDUyLjM5MDAxNSAyMDQuNzQ2MjkyIDQ1MC40ODg1MjUgMjA3LjgxOTQ4OSA0NDguNzc0NzggQyAyMTIuMDk1ODU2IDQ0Ni4zOTAxMzcgMjEzLjAzMTM3MiA0NDYuMjAyNzU5IDIxNS4zMDY5NjEgNDQ3LjI3NDc4IEMgMjE3LjI2MDA3MSA0NDguMTk0OTQ2IDIxNy45ODEyMzIgNDQ5LjM2OTIwMiAyMTguMjAzNzM1IDQ1MS45OTE1MTYgQyAyMTguNSA0NTUuNDgzMDMyIDIxOC41IDQ1NS40ODMwMzIgMjI4LjUgNDU4LjI3ODE5OCBDIDIzNCA0NTkuODE1NTUyIDI0NS4wMjQ5OTQgNDYyLjYwNTU5MSAyNTMgNDY0LjQ3ODI3MSBDIDI2MC45NzUwMDYgNDY2LjM1MDk1MiAyNzQuNDc1MDA2IDQ2OS4yMzA3MTMgMjgzIDQ3MC44Nzc4MDggQyAyOTEuNTI0OTk0IDQ3Mi41MjQ4NDEgMzA1LjkyNDk4OCA0NzUuMDI0OTYzIDMxNSA0NzYuNDMzNzE2IEMgMzI0LjA3NTAxMiA0NzcuODQyNDA3IDM0MS42MjUgNDgwLjAwODYwNiAzNTQgNDgxLjI0NzQ5OCBDIDM3Mi40OTI3OTggNDgzLjA5ODgxNiAzODIuNTU1MzU5IDQ4My41IDQxMC41IDQ4My41IEMgNDM1LjU1MDA3OSA0ODMuNSA0NDkuMjUyNTAyIDQ4My4wMzQzNjMgNDYyLjU1NDI5MSA0ODEuNzMwOTU3IEMgNDcyLjQ4NDE2MSA0ODAuNzU3OTk2IDQ4OS4xMzQxNTUgNDc4LjYyMTM5OSA0OTkuNTU0MjkxIDQ3Ni45ODMwMzIgQyA1MDkuOTc0NDI2IDQ3NS4zNDQ2MDQgNTI2LjU5OTk3NiA0NzIuMzkyODgzIDUzNi41IDQ3MC40MjM1MjMgQyA1NDYuNDAwMDI0IDQ2OC40NTQyMjQgNTYyLjE1MDAyNCA0NjUuMDYxMTU3IDU3MS41IDQ2Mi44ODM0MjMgQyA1ODAuODQ5OTc2IDQ2MC43MDU2ODggNTkxLjQyNDk4OCA0NTguMTQ5MTcgNTk1IDQ1Ny4yMDIzMzIgQyA1OTkuMzEyOTg4IDQ1Ni4wNjAwNTkgNjAxLjUwMjYyNSA0NTQuOTc5MzcgNjAxLjUwNzgxMyA0NTMuOTkwNDE3IEMgNjAxLjUxMjU3MyA0NTMuMDg2OTc1IDYwMi40OTcxMzEgNDUyLjQ3NjEzNSA2MDQuMDA3ODEzIDQ1Mi40Mzk0NTMgQyA2MDUuMzc4NTQgNDUyLjQwNjEyOCA2MDguMTg0NTcgNDUyLjAxOTA0MyA2MTAuMjQzNDA4IDQ1MS41NzkzNDYgQyA2MTIuMzAyMzA3IDQ1MS4xMzk2NDggNjE1LjA1Nzg2MSA0NTEuMDQ4NzA2IDYxNi4zNjY4MjEgNDUxLjM3NzE5NyBDIDYxNy43NDk4NzggNDUxLjcyNDM2NSA2MTkuMjY3NTc4IDQ1My4yMzE3NSA2MTkuOTkwMDUxIDQ1NC45NzU5NTIgQyA2MjAuODAzNzExIDQ1Ni45NDAyNDcgNjIwLjk5NjE1NSA0NTkuODc1MjQ0IDYyMC41NDcwNTggNDYzLjQ2OTY2NiBDIDYyMC4xNjk2NzggNDY2LjQ5MDQxNyA2MTguOTg2Njk0IDQ3Mi42ODI5ODMgNjE3LjkxODI3NCA0NzcuMjMwOTU3IEMgNjE2LjQ3NTk1MiA0ODMuMzcwNjA1IDYxNS4zMDUyOTggNDg2LjA5MjU5IDYxMy4zNzI0MzcgNDg3LjgwMTI3IEMgNjExLjk0MDY3NCA0ODkuMDY2OTg2IDYxMC45MzM2NTUgNDkwLjI0NjY3NCA2MTEuMTM0NjQ0IDQ5MC40MjI3OTEgQyA2MTEuMzM1NTcxIDQ5MC41OTg5MzggNjEzLjg5NjcyOSA0OTAuOTYzMTA0IDYxNi44MjYxNzIgNDkxLjIzMjA1NiBDIDYyMS4xNDIyMTIgNDkxLjYyODI5NiA2MjIuNjc4NDY3IDQ5Mi4yOTcxMTkgNjI0LjkyNjUxNCA0OTQuNzU4MzYyIEMgNjI2LjkxNjU2NSA0OTYuOTM3MjI1IDYyNy45NDgzNjQgNDk5LjQ0OTY0NiA2MjguNTc3MTQ4IDUwMy42NDc4MjcgQyA2MjkuMDU5MzI2IDUwNi44NjY1MTYgNjI5LjQ1NDM0NiA1MTMuNzc1MDI0IDYyOS40NTUwNzggNTE5IEMgNjI5LjQ1NTgxMSA1MjQuMjI0OTc2IDYyOS4xNjYyNiA1MzAuMTU4MjAzIDYyOC44MTE2NDYgNTMyLjE4NDkzNyBDIDYyOC40NDcwMjEgNTM0LjI2OTIyNiA2MjYuNzUxNDA0IDUzNy40MjU0MTUgNjI0LjkwODAyIDUzOS40NTExNzIgQyA2MjIuNjEyMTIyIDU0MS45NzQxODIgNjIwLjQ3ODM5NCA1NDMuMjE5NjY2IDYxNy42ODc1IDU0My42NjU5NTUgQyA2MTMuNzI1ODMgNTQ0LjI5OTQzOCA2MTMuNzI1ODMgNTQ0LjI5OTQzOCA2MTQuMzUwOTUyIDU1My4zOTk3MTkgQyA2MTQuNjk0NzYzIDU1OC40MDQ5MDcgNjE1LjQ3NzY2MSA1NzMuMjk5OTg4IDYxNi4wOTA4MiA1ODYuNSBDIDYxNi45MDkzNjMgNjA0LjEyMjMxNCA2MTYuOTEwMDk1IDYxMy45NTI1NzYgNjE2LjA5MzYyOCA2MjMuNDkyNDMyIEMgNjE1LjAwNTQ5MyA2MzYuMjA3MzM2IDYxNC45MTI0NzYgNjM2LjU1Mjg1NiA2MTEuNzQwODQ1IDYzOS42NjI1OTggQyA2MDkuOTU4Mzc0IDY0MS40MTA0IDYwNC4yMjQ5NzYgNjQ1LjA5NzE2OCA1OTkgNjQ3Ljg1NTUzIEMgNTkzLjc3NTAyNCA2NTAuNjEzODkyIDU4NC4zMjUwMTIgNjU0Ljk4ODA5OCA1NzggNjU3LjU3NjA1IEMgNTcxLjY3NDk4OCA2NjAuMTY0MDYzIDU2MC42NTAwMjQgNjY0LjI1MDczMiA1NTMuNSA2NjYuNjU3NjU0IEMgNTQ2LjM0OTk3NiA2NjkuMDY0NTc1IDUzNC44ODY0NzUgNjcyLjY0NDc3NSA1MjguMDI1NDUyIDY3NC42MTM3MDggQyA1MjEuMTY0NDI5IDY3Ni41ODI2NDIgNTA5LjkxNDQ1OSA2NzkuNDgxOTM0IDUwMy4wMjU0NTIgNjgxLjA1NjcwMiBDIDQ5Ni4xMzY0NDQgNjgyLjYzMTQ3IDQ4NC4yMTE0NTYgNjg1LjA3NjA1IDQ3Ni41MjU0ODIgNjg2LjQ4OTEzNiBDIDQ2OC44Mzk1MDggNjg3LjkwMjIyMiA0NTUuNjM4MzA2IDY4OS45MzU3MyA0NDcuMTg5NTE0IDY5MS4wMDgxMTggQyA0MzguNzQwNzIzIDY5Mi4wODA0NDQgNDI1Ljc5MjIwNiA2OTMuMjAxOTY1IDQxOC40MTUwNyA2OTMuNTAwMzA1IEMgNDExLjAzNzkwMyA2OTMuNzk4NjQ1IDQwMS43MzkxMDUgNjk0LjE0NTYzIDM5Ny43NTEwMzggNjk0LjI3MTM2MiBaIi8+CiAgICAgICAgICAgIDxwYXRoIGlkPSJwYXRoNCIgZmlsbD0iIzNlODRlYSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNIDM3OC41IDY1Ny45Mjg1ODkgQyAzNTQuNDc1MDA2IDYyNy42Njc2NjQgMzQ1LjEzNjM4MyA2MTUuODQzMzg0IDM0Mi4yNDc0OTggNjEyLjEyOTE1IEwgMzM2Ljk5NTAyNiA2MDUuMzc2MDM4IEwgMzQyLjAzNzMyMyA1ODMuMTk2OTYgQyAzNDQuODEwNTc3IDU3MC45OTg0MTMgMzQ4LjExMjI0NCA1NTYuNDk4MjkxIDM0OS4zNzQzNTkgNTUwLjk3NDM2NSBDIDM1MC42MzY0NDQgNTQ1LjQ1MDQzOSAzNTIuMDgxMDI0IDU0MC41NTI0OSAzNTIuNTg0NTM0IDU0MC4wOTAwODggQyAzNTMuMDg4MDQzIDUzOS42Mjc1NjMgMzY0LjUyNDk5NCA1MzMuOTY5ODQ5IDM3OCA1MjcuNTE3MzM0IEMgMzkxLjQ3NTAwNiA1MjEuMDY0ODggNDA0LjgxMzA4IDUxNC43MzYzMjggNDA3LjY0MDE2NyA1MTMuNDUzOTc5IEMgNDEyLjc4MDMzNCA1MTEuMTIyMzc1IDQxMi43ODAzMzQgNTExLjEyMjM3NSA0NDIuNjQwMTY3IDUyNS41MTUxMzcgQyA0NzIuMTg5OTQxIDUzOS43NTg0MjMgNDcyLjUxMjgxNyA1MzkuOTQ3MzI3IDQ3My43MzQwMzkgNTQzLjcwMzk3OSBDIDQ3NC40MTI3ODEgNTQ1Ljc5MTc0OCA0NzYuMzQ2NDY2IDU1My42ODI3MzkgNDc4LjAzMTEyOCA1NjEuMjM5MzggQyA0NzkuNzE1NzkgNTY4Ljc5NjAyMSA0ODIuNjQ4MDEgNTgxLjgxMjM3OCA0ODQuNTQ3MjExIDU5MC4xNjQ2NzMgQyA0ODcuNjAzNjA3IDYwMy42MDYyMDEgNDg3LjgzNzM3MiA2MDUuNTg4OTg5IDQ4Ni41ODIxMjMgNjA3LjQyNTI5MyBDIDQ4NS44MDIxMjQgNjA4LjU2NjQwNiA0NzYuNDY0NTM5IDYyMC4yOTk5ODggNDY1LjgzMTk3IDYzMy41IEwgNDQ2LjUgNjU3LjUgTCA0MTIuNSA2NTcuNzE0Mjk0IEwgMzc4LjUgNjU3LjkyODU4OSBaIi8+CiAgICAgICAgICAgIDxwYXRoIGlkPSJwYXRoNSIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDRkODEiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNIDQxMSA2MjUgQyA0MTAuNzg5Mzk4IDYyNC45OTIzMSA0MDguMzcwMTE3IDYyMy42NjIyMzEgNDA3LjY5MzI5OCA2MjMuMzE1MTI1IEMgNDA3LjAxNjQ3OSA2MjIuOTY4MDc5IDQwNS42NzE2IDYyMi4yNDMyODYgNDA0LjcwNDcxMiA2MjEuNzA0NDY4IEMgNDAzLjczNzgyMyA2MjEuMTY1NTg4IDQwMi4xNTU2NCA2MjAuMjg3MDQ4IDQwMS4xODg3NTEgNjE5Ljc1MjA3NSBDIDQwMC4yMjE4NjMgNjE5LjIxNzE2MyAzOTguNDAyMzc0IDYxOC4yMjAwMzIgMzk3LjE0NTQxNiA2MTcuNTM2MzE2IEMgMzk1Ljg4ODQyOCA2MTYuODUyNiAzOTMuMTE5NjI5IDYxNS4zMTkzMzYgMzkwLjk5MjQ2MiA2MTQuMTI5MTUgQyAzODguODY1Mjk1IDYxMi45Mzg5MDQgMzg2LjI5MTM4MiA2MTEuNTA3OTk2IDM4NS4yNzI2NDQgNjEwLjk0OTM0MSBDIDM4NC4yNTM5MDYgNjEwLjM5MDYyNSAzODIuNTEzNDg5IDYwOS40Mzk5NDEgMzgxLjQwNTA5IDYwOC44MzY2NyBDIDM4MC4yOTY2NjEgNjA4LjIzMzM5OCAzNzguNTE5NTkyIDYwNy4yNDk3NTYgMzc3LjQ1NTk5NCA2MDYuNjUwNzU3IEMgMzc2LjM5MjQyNiA2MDYuMDUxODggMzc1LjQwNTk3NSA2MDUuMzkzMTI3IDM3NS4yNjM5MTYgNjA1LjE4NzAxMiBDIDM3NS4xMjE4MjYgNjA0Ljk4MDgzNSAzNzUuMDAzMTc0IDU5Ni4wNjU2NzQgMzc1LjAwMDIxNCA1ODUuMzc1NDI3IEMgMzc0Ljk5NTU0NCA1NjguNTc4MzA4IDM3NC41NTI0NiA1NjIuMTcxNzUzIDM3NSA1NjIgQyAzNzUuMjg0ODIxIDU2MS44OTA3NDcgMzc2Ljg4Mjg0MyA1NjMuNzA0MDQxIDM3OCA1NjQgQyAzNzkuMTE3MTU3IDU2NC4yOTU4OTggMzgwLjY0NjM2MiA1NjUuNTg0NDczIDM4MiA1NjYgQyAzODMuMzUzNjY4IDU2Ni40MTU1MjcgMzg2LjQxOTg2MSA1NjcuODM4NTAxIDM4NyA1NjggQyAzODcuNTgwMTA5IDU2OC4xNjE0OTkgMzkwLjM4OTQwNCA1NjkuMjI1NTg2IDM5MyA1NzAgQyAzOTUuNjEwNTk2IDU3MC43NzQ0MTQgMzk4LjA0MTk2MiA1NzEuOTQ4NDg2IDM5OS43ODIzNzkgNTcyLjQ1NzY0MiBDIDQwMS41MjI3NjYgNTcyLjk2NjkxOSA0MDQuNDk5MzkgNTczLjg2MjYxIDQwNi4zOTcwOTUgNTc0LjQ0ODA1OSBDIDQwOC4yOTQ3NjkgNTc1LjAzMzUwOCA0MTAuOTA3NjIzIDU3NS43NTkyMTYgNDExIDU3NiBDIDQxMS4wOTI0MDcgNTc2LjI0MDcyMyA0MTEuMTM1NzczIDU4Ni45MTM4MTggNDExIDYwMCBDIDQxMC44MjU4MDYgNjE2Ljc4NjM3NyA0MTEuMjcwMTExIDYyNS4wMDk4ODggNDExIDYyNSBaIE0gNDE2Ljg5ODg5NSA2MjMuNDk2MzM4IEMgNDE2LjAxODQ5NCA2MjMuODA2NzYzIDQxNC4wOTI3MTIgNjI1LjMwNjY0MSA0MTQgNjI1IEMgNDEzLjkzMjQ2NSA2MjQuNzc2NTUgNDE0LjEwNTUzIDYxMy4wMTIyMDcgNDE0IDYwMCBDIDQxMy44MDgxNjcgNTc2LjM0MTQzMSA0MTQuMDQ2MjM0IDU3Ni4zNjc5MiA0MTUgNTc2IEMgNDE1LjUyNDU2NyA1NzUuNzk3NjA3IDQxOS4wOTkzMzUgNTczLjg2NjI3MiA0MjIgNTczIEMgNDI0LjkwMDY2NSA1NzIuMTMzNjY3IDQyOC4xMTQzNDkgNTcwLjU2Njk1NiA0MzAgNTcwIEMgNDMxLjg4NTY1MSA1NjkuNDMzMDQ0IDQzNS42OTQ5MTYgNTY3LjM4NTQzNyA0MzcgNTY3IEMgNDM4LjMwNTA4NCA1NjYuNjE0NTYzIDQ0MC42Nzk0NDMgNTY1LjY5OTk1MSA0NDMgNTY1IEMgNDQ1LjMyMDUyNiA1NjQuMzAwMDQ5IDQ0OS4zMjMxODEgNTYzLjAyNzEgNDUwIDU2MyBDIDQ1MS4yMzA1OTEgNTYyLjk1MDgwNiA0NTAuMDYwNjY5IDU2NS43ODQ5NzMgNDUwLjM1NTg5NiA1NjguMDcwMzEzIEMgNDUwLjUxODI1IDU2OS4zMjcyNzEgNDUwLjU5NzM1MSA1NzguMDY0NjM2IDQ1MC41MzE2NzcgNTg3LjQ4NjYzMyBDIDQ1MC40MTYwNDYgNjA0LjA3MzA1OSA0NTAuMzg5ODkzIDYwNC42MzkyMjEgNDQ5LjcwOTA3NiA2MDUuMzAxMDI1IEMgNDQ5LjMyMjI5NiA2MDUuNjc3MDAyIDQ0Ni45NDkwMzYgNjA3LjEzMDQ5MyA0NDQuNDM1MTIgNjA4LjUzMDk0NSBDIDQ0MS45MjEyMDQgNjA5LjkzMTQ1OCA0MzcuNzYzODI0IDYxMi4yMzEyMDEgNDM1LjE5NjUwMyA2MTMuNjQxMzU3IEMgNDMyLjYyOTE4MSA2MTUuMDUxNjM2IDQyOS4zNTA0MDMgNjE2Ljg1MzU3NyA0MjcuOTEwMjc4IDYxNy42NDU3NTIgQyA0MjYuNDcwMTg0IDYxOC40Mzc5ODggNDIzLjY2NTk1NSA2MTkuOTg1ODQgNDIxLjY3ODY1IDYyMS4wODU1NzEgQyA0MTkuNjkxMzQ1IDYyMi4xODUyNDIgNDE3LjU0MDQ2NiA2MjMuMjcwMDgxIDQxNi44OTg4OTUgNjIzLjQ5NjMzOCBaIE0gMzc1IDU2MiBDIDM3NS44MTc0NzQgNTYxLjIwNDgzNCAzNzkuNzc2NTUgNTU5LjIzMzU4MiAzODMuMjU3MzU1IDU1OC4yNTA2MSBDIDM4Ni43MzgxNTkgNTU3LjI2NzYzOSAzOTAuNjE0NTAyIDU1Ni4xNTU3NjIgMzkxLjg3MTQ2IDU1NS43Nzk3MjQgQyAzOTMuMTI4NDE4IDU1NS40MDM2ODcgMzk4LjM0MjUyOSA1NTMuODk4NDk5IDQwMy40NTg0MDUgNTUyLjQzNDc1MyBDIDQxMi43NTk5NDkgNTQ5Ljc3MzQzOCA0MTIuNzU5OTQ5IDU0OS43NzM0MzggNDE1LjA2MTA2NiA1NTAuNDU1MDE3IEMgNDE2LjMyNjY5MSA1NTAuODI5ODM0IDQxOS4wMjM0OTkgNTUxLjYyMDIzOSA0MjEuMDUzOTU1IDU1Mi4yMTE0MjYgQyA0MjMuMDg0NDEyIDU1Mi44MDI2MTIgNDI3LjE5ODEyIDU1My45OTM3NzQgNDMwLjE5NTQ2NSA1NTQuODU4Mzk4IEMgNDMzLjE5MjgxIDU1NS43MjMwMjIgNDM4LjQ5MzEzNCA1NTcuMjQyMDY1IDQ0MS45NzM5MzggNTU4LjIzNDEzMSBDIDQ0NS40NTQ3NDIgNTU5LjIyNjE5NiA0NDguNTQwMDA5IDU2MC4yNjg2NzcgNDQ4LjgzMDA3OCA1NjAuNTUwODQyIEwgNDUwIDU2MiBMIDQ0OSA1NjIgQyA0NDguNzA5OTMgNTYyLjE4Nzk4OCA0NDcuNTQ3MDI4IDU2Mi41MjQ5NjMgNDQ2IDU2MyBDIDQ0NC40NTI5NzIgNTYzLjQ3NTAzNyA0NDEuMDk0MDI1IDU2NS4xMDE4NjggNDM4IDU2NiBDIDQzNC45MDU5NDUgNTY2Ljg5ODE5MyA0MzQuMjU2OTU4IDU2Ny42NDg5MjYgNDMzIDU2OCBDIDQzMS43NDMwMTEgNTY4LjM1MTA3NCA0MjUuMzM1MjA1IDU3MC44NDgxNDUgNDIyIDU3MiBDIDQxOC43MjY2NTQgNTczLjEzMDQ5MyA0MTMuODcwMTc4IDU3My45MzA5MDggNDEzIDU3NCBDIDQxMS45OTQyMDIgNTc0LjA3OTgzNCA0MDkuMDMwMDYgNTcyLjc0MDIzNCA0MDcgNTcyIEMgNDA1LjU3MDI4MiA1NzEuNDc4NjM4IDQwMi45OTczNDUgNTcwLjg3MDU0NCA0MDAgNTcwIEMgMzk3LjAwMjYyNSA1NjkuMTI5NDU2IDM5Mi44MDM5ODYgNTY3Ljc5MDgzMyAzOTAgNTY3IEMgMzg3LjE5NjAxNCA1NjYuMjA5MTA2IDM4My4zNTM2NjggNTY0LjQwMjEgMzgyIDU2NCBDIDM4MC42NDYzNjIgNTYzLjU5ODAyMiAzNzkuMzgwOTgxIDU2Mi40OTk3NTYgMzc4LjUxMDgwMyA1NjIuMjI3MDUxIEMgMzc3LjY0MDU5NCA1NjEuOTU0MzQ2IDM3Ni42OTEyODQgNTYxLjU4MTA1NSAzNzYuNDAxMjE1IDU2MS4zOTc1ODMgTCAzNzUgNTYyIFoiLz4KICAgICAgICA8L2c+CiAgICAgICAgPHBhdGggaWQ9InBhdGg2IiBmaWxsPSIjNjQ2NDY0IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0gMTkwLjUzODA1NSA1MjQuNzI5MTI2IEMgMTg5LjA3MTc3NyA1MjYuMjMyNzg4IDE4Ni42ODQ4MyA1MjguMDY4MjM3IDE4NS4yMzM3MTkgNTI4LjgwNzczOSBDIDE4My43ODI1OTMgNTI5LjU0NzE4IDE4MC43OTIyMDYgNTMwLjMxNTA2MyAxNzguNTg4MzQ4IDUzMC41MTQwMzggQyAxNzYuMzQ2NjM0IDUzMC43MTY0MzEgMTcyLjc5MTgwOSA1MzAuMzE3MzgzIDE3MC41MTkyMjYgNTI5LjYwODE1NCBDIDE2Ny4yMDExNDEgNTI4LjU3Mjc1NCAxNjUuODEyNDI0IDUyNy43MjkwNjUgMTYyLjkzNzQ1NCA1MjUuMDAyMTk3IEMgMTU5Ljk5NTYyMSA1MjIuMjExOTc1IDE1OS4xOTU0NSA1MjEuMDE0NjQ4IDE1OC4wNjMyNjMgNTE3LjcwODgwMSBDIDE1Ny4zMTgyNTMgNTE1LjUzMzQ0NyAxNTYuODA0NTk2IDUxMi4zNTE1NjMgMTU2LjkyMTg0NCA1MTAuNjM4IEMgMTU3LjAzOTA0NyA1MDguOTI0Mzc3IDE1Ny41NzAwMDcgNTA2LjE1MDE0NiAxNTguMTAxNzYxIDUwNC40NzMwODMgQyAxNTguNjMzNTMgNTAyLjc5NTk5IDE2MC4wMDU0OTMgNTAwLjE1ODkwNSAxNjEuMTUwNTg5IDQ5OC42MTI4NTQgQyAxNjMuMjMyNjA1IDQ5NS44MDE4OCAxNjMuMjMyNjA1IDQ5NS44MDE4OCAxNTguNjA3NzQyIDQ3OS4wNzUwMTIgQyAxNTMuOTgyODY0IDQ2Mi4zNDgxNDUgMTUzLjk4Mjg2NCA0NjIuMzQ4MTQ1IDE0OS41NjgyMDcgNDYyLjMxNzQ0NCBDIDE0Ny4xNDAxNjcgNDYyLjMwMDY1OSAxNDMuMjIzMzQzIDQ2MS45NDYyODkgMTQwLjg2NDE4MiA0NjEuNTI5OTY4IEMgMTM4LjUwNDk5IDQ2MS4xMTM2NDcgMTM0LjU0MzkgNDYwLjA2NjU4OSAxMzIuMDYxNzM3IDQ1OS4yMDMwNjQgQyAxMjkuNTc5NTQ0IDQ1OC4zMzk1MzkgMTI1Ljg2NzA1IDQ1Ni41NzE2NTUgMTIzLjgxMTcxNCA0NTUuMjc0MjkyIEMgMTIxLjc1NjM0OCA0NTMuOTc2OTkgMTE4LjI0MjMxNyA0NTEuMTMyMjAyIDExNi4wMDI3MzEgNDQ4Ljk1MjYzNyBDIDExMy43NjMxNDUgNDQ2Ljc3MzA3MSAxMTAuODAzODAyIDQ0My4yODM2OTEgMTA5LjQyNjQyMiA0NDEuMTk4NDg2IEMgMTA4LjA0OTA0MiA0MzkuMTEzMjgxIDEwNi4xOTM3MzMgNDM1LjY2MjM1NCAxMDUuMzAzNDkgNDMzLjUyOTY2MyBDIDEwNC40MTMyNDYgNDMxLjM5NzAzNCAxMDMuMjQ1OTExIDQyNy4zOTQ3MTQgMTAyLjcwOTQwNCA0MjQuNjM1NjIgQyAxMDIuMTcyOTA1IDQyMS44NzY0NjUgMTAxLjc4MDUxIDQxNy40MjU3MiAxMDEuODM3Mzg3IDQxNC43NDQ5OTUgQyAxMDEuODk0Mjk1IDQxMi4wNjQzMzEgMTAyLjQ0NDQwNSA0MDcuNjg5ODE5IDEwMy4wNTk4OTggNDA1LjAyMzkyNiBDIDEwMy42NzUzNjkgNDAyLjM1ODAzMiAxMDUuMjc5MDk5IDM5Ny45MDM3NDggMTA2LjYyMzczNCAzOTUuMTI1NjEgQyAxMDguMDI2NjM0IDM5Mi4yMjcwNTEgMTEwLjYyNTU5NSAzODguMjAwMTM0IDExMi43MjIxMTUgMzg1LjY3NjU3NSBDIDExNS4yNjA2NTEgMzgyLjYyMTAzMyAxMTcuODA5MjI3IDM4MC4yNTg0ODQgMTIxLjA3MjY3IDM3Ny45MzU0ODYgQyAxMjQuMDkzMTAyIDM3NS43ODU0NjEgMTI4LjEyOTk5IDM3My43MDcwMzEgMTMyLjM4MjU2OCAzNzIuMTEyMzY2IEMgMTM3Ljg5OTMyMyAzNzAuMDQzNzAxIDE0MC4zNDQyMDggMzY5LjU5NTg4NiAxNDcuMTMxMzkzIDM2OS40MTA2NDUgQyAxNTMuOTg3NDg4IDM2OS4yMjM1NzIgMTU2LjMyMjgxNSAzNjkuNTI3MTYxIDE2MS45NzgxMDQgMzcxLjM0MDU3NiBDIDE2NS42NjkwODMgMzcyLjUyNDEwOSAxNzAuMzc2Nzg1IDM3NC41NTA0NzYgMTcyLjQzOTY1MSAzNzUuODQzNTA2IEMgMTc0LjUwMjUzMyAzNzcuMTM2NTM2IDE3Ny44Mjg5MzQgMzc5Ljc0ODY1NyAxNzkuODMxNjY1IDM4MS42NDgxOTMgQyAxODEuODM0Mzk2IDM4My41NDc3OTEgMTg0LjQ2NTM2MyAzODYuNTk3MTA3IDE4NS42NzgyNTMgMzg4LjQyNDUgQyAxODYuODkxMTI5IDM5MC4yNTE4OTIgMTg3LjcxNTgwNSAzOTIuMTUxOTc4IDE4Ny41MTA4OTUgMzkyLjY0Njk3MyBDIDE4Ny4zMDU5NTQgMzkzLjE0MTkwNyAxODUuNjQ1NjQ1IDM5NC40MzU3OTEgMTgzLjgyMTM1IDM5NS41MjIyNzggQyAxODEuOTk3MDQgMzk2LjYwODc2NSAxNzkuMDk3MDE1IDM5OC4zMzY5MTQgMTc3LjM3Njg0NiAzOTkuMzYyNTQ5IEMgMTc0LjI0OTMxMyA0MDEuMjI3NDc4IDE3NC4yNDkzMTMgNDAxLjIyNzQ3OCAxNjguOTIzNDYyIDM5Ni4xNzYwMjUgQyAxNjQuOTczMzU4IDM5Mi40Mjk0NDMgMTYyLjcxMDU4NyAzOTAuNzI2Njg1IDE2MC4xNjM4MDMgMzg5LjU4NDE2NyBDIDE1OC4yNzUyMzggMzg4LjczNjkzOCAxNTQuNTEwMTMyIDM4Ny43MjcxNzMgMTUxLjc5NjkwNiAzODcuMzQwMzMyIEMgMTQ4Ljk5MTQ0IDM4Ni45NDAzMDggMTQ1LjA1NjEwNyAzODcuMDM2ODY1IDE0Mi42NzI1NjIgMzg3LjU2NDE0OCBDIDE0MC4zNjc0MDEgMzg4LjA3NDE1OCAxMzYuOTg1MDYyIDM4OS4yNzA4MTMgMTM1LjE1NjIxOSAzOTAuMjIzMzI4IEMgMTMyLjgyOTA0MSAzOTEuNDM1NDg2IDEzMC40OTI0NDcgMzkzLjM2NjYzOCAxMjcuMzcwNzY2IDM5Ni42NTc4OTggQyAxMjMuMzI1MDY2IDQwMC45MjM0MDEgMTIyLjc2ODcxNSA0MDEuNzkzMzM1IDEyMS4zODU3MTkgNDA2LjAxNjIzNSBDIDEyMC41NDcxMjcgNDA4LjU3Njg0MyAxMTkuODE0NTIyIDQxMi40MDg4NzUgMTE5Ljc1NzY4MyA0MTQuNTMxNzk5IEMgMTE5LjcwMDg3NCA0MTYuNjU0Nzg1IDEyMC4xNDM0NzggNDIwLjQyMjMwMiAxMjAuNzQxMjk1IDQyMi45MDQxMTQgQyAxMjEuNDYyNjY5IDQyNS44OTg4NjUgMTIyLjgwMDIwOSA0MjguODU5MDA5IDEyNC43MTgzMzggNDMxLjcwNTgxMSBDIDEyNi42ODQ1NjMgNDM0LjYyMzkwMSAxMjguNjQ5OTAyIDQzNi43OTc3MjkgMTMwLjg2NjI4NyA0MzguNTA1OTgxIEMgMTMyLjg2ODk4OCA0NDAuMDQ5NSAxMzUuODU2ODEyIDQ0MS41NTkwMjEgMTM4LjYyMTUyMSA0NDIuNDI0MDcyIEMgMTQxLjA5NjU3MyA0NDMuMTk4NDg2IDE0NS4zNTY4ODggNDQzLjc3MjE1NiAxNDguMDk1ODEgNDQzLjY5OTcwNyBDIDE1MC44MzMwOTkgNDQzLjYyNzMxOSAxNTUuNzA4ODYyIDQ0Mi44ODIzODUgMTU4LjkzMDc4NiA0NDIuMDQ0MzEyIEMgMTYyLjI4NzgxMSA0NDEuMTcxMDgyIDE2NC45NDkyMTkgNDQwLjg1NjQ0NSAxNjUuMTY0NDkgNDQxLjMwNzMxMiBDIDE2NS4zNzEwNjMgNDQxLjc0MDA1MSAxNjYuODM0NjcxIDQ0Ni42ODU5NzQgMTY4LjQxNjk0NiA0NTIuMjk4MzQgQyAxNjkuOTk5MTc2IDQ1Ny45MTA3MDYgMTcyLjQ5NjI0NiA0NjYuODE0ODE5IDE3My45NjU5NzMgNDcyLjA4NTMyNyBDIDE3NS40MzU2ODQgNDc3LjM1NTgzNSAxNzcuMTQ5MDYzIDQ4My4zMTQ4OCAxNzcuNzczNDM4IDQ4NS4zMjc2OTggQyAxNzguMzk3ODEyIDQ4Ny4zNDA0NTQgMTc5LjUyNjA2MiA0ODkuNTgwMzgzIDE4MC4yODA2MDkgNDkwLjMwNTIzNyBDIDE4MS4wMzUxODcgNDkxLjAzMDEyMSAxODMuMTkyODU2IDQ5Mi40MTczNTggMTg1LjA3NTQ1NSA0OTMuMzg4MDMxIEMgMTg3LjIyMjkxNiA0OTQuNDk1MjcgMTg5LjUzMzYgNDk2LjI3Njc5NCAxOTEuMjc2Nzk0IDQ5OC4xNjkyODEgQyAxOTIuODA0OTYyIDQ5OS44MjgyNzggMTk0LjUzMDM4IDUwMi40MzMxMzYgMTk1LjExMTA1MyA1MDMuOTU3Nzk0IEMgMTk1LjY5MTcxMSA1MDUuNDgyNDgzIDE5Ni4xOTA2MTMgNTA4LjUzNTc5NyAxOTYuMjE5Njk2IDUxMC43NDI5NSBDIDE5Ni4yNTAzNTEgNTEzLjA2OTg4NSAxOTUuNjI3OTc1IDUxNi4yNzY3MzMgMTk0LjczODI5NyA1MTguMzc1NDg4IEMgMTkzLjc5ODc4MiA1MjAuNTkxODU4IDE5Mi4xNzA1NDcgNTIzLjA1NDg3MSAxOTAuNTM4MDU1IDUyNC43MjkxMjYgWiIvPgogICAgICAgIDxwYXRoIGlkPSJwYXRoNyIgZmlsbD0iI2ZmZGViMiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNIDE4OS45OTc1NTkgNTM1Ljc5MzA5MSBDIDE4NS40MzQ0MTggNTM2LjEzNDMzOCAxODQuMTg1MDU5IDUzNS44NjE5MzggMTgyLjY3ODg3OSA1MzQuMTk3NjMyIEMgMTgxLjY3OTk0NyA1MzMuMDkzODcyIDE4MC42Mjc0MTEgNTMxLjI5MTE5OSAxODAuMzM5OTA1IDUzMC4xOTE3NzIgQyAxNzkuOTc2MjU3IDUyOC44MDExNDcgMTgwLjQxMzUyOCA1MjguMDAzNTQgMTgxLjc3NjY4OCA1MjcuNTcwODYyIEMgMTgyLjg1NDQ0NiA1MjcuMjI4ODIxIDE4NC41NDk5NDIgNTI2LjA0OTgwNSAxODUuNTQ0NDk1IDUyNC45NTA4MDYgQyAxODYuODM3ODMgNTIzLjUyMTcyOSAxODcuMDQ1NjA5IDUyMi42NDU2MyAxODYuMjc0MTM5IDUyMS44NzQxNDYgQyAxODUuNTAyNjg2IDUyMS4xMDI2NjEgMTg0LjM0MDUxNSA1MjEuNDI3NzM0IDE4Mi4xOTI4NDEgNTIzLjAxNTUwMyBDIDE4MC41NDEzNTEgNTI0LjIzNjU3MiAxNzguNjk5NjE1IDUyNC45MzIzNzMgMTc4LjEwMDA4MiA1MjQuNTYxODkgQyAxNzcuNTAwNTY1IDUyNC4xOTEyODQgMTc2Ljc2MDkyNSA1MjIuODk1NjMgMTc2LjQ1NjQzNiA1MjEuNjgyNDk1IEMgMTc2LjE1MTk2MiA1MjAuNDY5MzYgMTc2LjU4ODA0MyA1MTcuODM2OTE0IDE3Ny40MjU0OTEgNTE1LjgzMjUyIEMgMTc4LjI2Mjk1NSA1MTMuODI4MjQ3IDE4MC41OTYyMjIgNTEwLjgyOTg2NSAxODIuNjEwNTM1IDUwOS4xNjk0OTUgQyAxODQuNjI0ODQ3IDUwNy41MDkxMjUgMTg4Ljc5OTAyNiA1MDUuMDIzMTMyIDE5MS44ODY0NTkgNTAzLjY0NTA1IEMgMTk0Ljk3MzkwNyA1MDIuMjY2OTk4IDE5OC42NjcyNjcgNTAwLjg1MTkyOSAyMDAuMDkzOTQ4IDUwMC41MDA0ODggQyAyMDIuNjg3ODgxIDQ5OS44NjE1MTEgMjAyLjY4Nzg4MSA0OTkuODYxNTExIDIwMS4yNTE0MTkgNTA2LjY4MDc1NiBDIDIwMC4zMTk1NSA1MTEuMTA0NjE0IDIwMC4wMzEzNTcgNTE1Ljk1ODg2MiAyMDAuNDMwOTg0IDUyMC41IEMgMjAwLjc2OTgwNiA1MjQuMzQ5OTc2IDIwMS4xNDg5NDEgNTI4LjYwOTYxOSAyMDEuMjczNTE0IDUyOS45NjU4MiBDIDIwMS40NDQzNjYgNTMxLjgyNTkyOCAyMDAuNzYzMTIzIDUzMi43OTM5NDUgMTk4LjUgNTMzLjkwNjYxNiBDIDE5Ni44NTAwMDYgNTM0LjcxNzg5NiAxOTMuMDIzODk1IDUzNS41NjY3NzIgMTg5Ljk5NzU1OSA1MzUuNzkzMDkxIFoiLz4KICAgICAgICA8cGF0aCBpZD0iU2hhcGUtY29weSIgZmlsbD0iI2ZmZGViMiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNIDY0MC41Nzc1MTUgNTM2Ljc5MzA5MSBDIDY0NS4xNDA2MjUgNTM3LjEzNDMzOCA2NDYuMzkwMDE1IDUzNi44NjE5MzggNjQ3Ljg5NjE3OSA1MzUuMTk3NjMyIEMgNjQ4Ljg5NTE0MiA1MzQuMDkzODcyIDY0OS45NDc2MzIgNTMyLjI5MTE5OSA2NTAuMjM1MTY4IDUzMS4xOTE3NzIgQyA2NTAuNTk4ODE2IDUyOS44MDExNDcgNjUwLjE2MTU2IDUyOS4wMDM1NCA2NDguNzk4NDAxIDUyOC41NzA4NjIgQyA2NDcuNzIwNjQyIDUyOC4yMjg4MjEgNjQ2LjAyNTE0NiA1MjcuMDQ5ODA1IDY0NS4wMzA1NzkgNTI1Ljk1MDgwNiBDIDY0My43MzcyNDQgNTI0LjUyMTcyOSA2NDMuNTI5NDggNTIzLjY0NTYzIDY0NC4zMDA5MDMgNTIyLjg3NDE0NiBDIDY0NS4wNzIzODggNTIyLjEwMjY2MSA2NDYuMjM0NTU4IDUyMi40Mjc3MzQgNjQ4LjM4MjIwMiA1MjQuMDE1NTAzIEMgNjUwLjAzMzY5MSA1MjUuMjM2NTcyIDY1MS44NzU0MjcgNTI1LjkzMjM3MyA2NTIuNDc0OTc2IDUyNS41NjE4OSBDIDY1My4wNzQ1MjQgNTI1LjE5MTI4NCA2NTMuODE0MTQ4IDUyMy44OTU2MyA2NTQuMTE4NjUyIDUyMi42ODI0OTUgQyA2NTQuNDIzMDk2IDUyMS40NjkzNiA2NTMuOTg3IDUxOC44MzY5MTQgNjUzLjE0OTU5NyA1MTYuODMyNTIgQyA2NTIuMzEyMTM0IDUxNC44MjgyNDcgNjQ5Ljk3ODgyMSA1MTEuODI5ODY1IDY0Ny45NjQ1MzkgNTEwLjE2OTQ5NSBDIDY0NS45NTAxOTUgNTA4LjUwOTEyNSA2NDEuNzc2MDYyIDUwNi4wMjMxMzIgNjM4LjY4ODU5OSA1MDQuNjQ1MDUgQyA2MzUuNjAxMTM1IDUwMy4yNjY5OTggNjMxLjkwNzc3NiA1MDEuODUxOTI5IDYzMC40ODExNCA1MDEuNTAwNDg4IEMgNjI3Ljg4NzIwNyA1MDAuODYxNTExIDYyNy4yODE5MjEgNDk5LjIwNzczMyA2MjkgNTA2IEMgNjMwLjIyODIxIDUxMC44NTU2ODIgNjMwLjM5OTU5NyA1MjAuNDU4ODYyIDYzMCA1MjUgQyA2MjkuNjYxMTMzIDUyOC44NDk5NzYgNjI5LjQyNjE0NyA1MjkuNjA5NjE5IDYyOS4zMDE1NzUgNTMwLjk2NTgyIEMgNjI5LjEzMDY3NiA1MzIuODI1OTI4IDYyOS44MTE5NTEgNTMzLjc5Mzk0NSA2MzIuMDc1MDczIDUzNC45MDY2MTYgQyA2MzMuNzI1MDM3IDUzNS43MTc4OTYgNjM3LjU1MTE0NyA1MzYuNTY2NzcyIDY0MC41Nzc1MTUgNTM2Ljc5MzA5MSBaIi8+CiAgICA8L2c+CiAgICA8ZyBpZD0iZzMiPgogICAgICAgIDxwYXRoIGlkPSJwYXRoOCIgZmlsbD0iIzg0ZDZlNCIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNIDQwNi41IDQ4Mi44MjQ4OSBDIDM5Ny4xNDk5OTQgNDgyLjc1Mjk5MSAzODIuNzUgNDgyLjM1ODUyMSAzNzQuNSA0ODEuOTQ4MzAzIEMgMzY2LjI1IDQ4MS41MzgwODYgMzUxLjE3NDk4OCA0ODAuMjM1MjI5IDM0MSA0NzkuMDUyOTc5IEMgMzMwLjgyNTAxMiA0NzcuODcwNzg5IDMxNS43NSA0NzUuNzk2NjMxIDMwNy41IDQ3NC40NDM3MjYgQyAyOTkuMjUgNDczLjA5MDg4MSAyODUuNTI5OTM4IDQ3MC41ODkzNTUgMjc3LjAxMDk4NiA0NjguODg0ODI3IEMgMjY4LjQ5MjAzNSA0NjcuMTgwMjk4IDI1NS4yMTcwNDEgNDY0LjI0MDkwNiAyNDcuNTExMDAyIDQ2Mi4zNTI5MDUgQyAyMzkuODA0OTQ3IDQ2MC40NjQ5MDUgMjMwLjQ2MjQ5NCA0NTguMDE5MTA0IDIyNi43NSA0NTYuOTE3NzI1IEMgMjIxLjE1NzQ4NiA0NTUuMjU4NjY3IDIyMCA0NTQuNTUwMjMyIDIyMCA0NTIuNzg2Mzc3IEMgMjIwIDQ1MS42MTU0NzkgMjE5LjM2MTU0MiA0NDkuOTQ3MDIxIDIxOC41ODExOTIgNDQ5LjA3ODczNSBDIDIxNy41Nzk4MzQgNDQ3Ljk2NDQ3OCAyMTYuNjIzNjExIDQ0MC44ODAwNjYgMjE1LjMzMTE5MiA0MjUgQyAyMTQuMDk2OTU0IDQwOS44MzQ5IDIxMy41IDM5Mi43MjAxNTQgMjEzLjUgMzcyLjUgQyAyMTMuNSAzNTQuNTAxMTYgMjE0LjAxODc2OCAzMzcuODk5NTM2IDIxNC43OTY3OTkgMzMxIEMgMjE1LjUxMDA0IDMyNC42NzQ5ODggMjE3LjE5NDEwNyAzMTQuNjE3MzEgMjE4LjUzOTE1NCAzMDguNjQ5NTM2IEMgMjE5Ljg4NDE4NiAzMDIuNjgxNzYzIDIyMi41ODUwNTIgMjkzLjAxNjQxOCAyMjQuNTQxMDQ2IDI4Ny4xNzEwMjEgQyAyMjYuNDk3MDU1IDI4MS4zMjU1NjIgMjMwLjEzODM5NyAyNzIuMzc1MTIyIDIzMi42MzI5MDQgMjY3LjI4MTA2NyBDIDIzNS4xMjc0MjYgMjYyLjE4Njk1MSAyMzkuODczNzAzIDI1NC4yMTU4ODEgMjQzLjE4MDIwNiAyNDkuNTY3NDQ0IEMgMjQ2LjQ4NjY5NCAyNDQuOTE5MDA2IDI1My41MzYzMDEgMjM2LjkwODM4NiAyNTguODQ2MDA4IDIzMS43NjYwNTIgQyAyNjQuMTU1NzAxIDIyNi42MjM3MTggMjcyLjEwMDAwNiAyMjAuMDQxMTM4IDI3Ni41IDIxNy4xMzgxMjMgQyAyODAuODk5OTk0IDIxNC4yMzUxMDcgMjg5IDIwOS42Njc4NDcgMjk0LjUgMjA2Ljk4ODU4NiBDIDMwMCAyMDQuMzA5Mzg3IDMwOS4wMjM3MTIgMjAwLjU2MTk1MSAzMTQuNTUyNzA0IDE5OC42NjEwMTEgQyAzMjAuMDgxNjk2IDE5Ni43NjAwNzEgMzI5LjMwNjY3MSAxOTQuMDMyNjU0IDMzNS4wNTI3MDQgMTkyLjYwMDE1OSBDIDM0MC43OTg3MDYgMTkxLjE2NzYwMyAzNTIuMDI0OTk0IDE4OC45MTU0MDUgMzYwIDE4Ny41OTUxNTQgQyAzNjcuOTc1MDA2IDE4Ni4yNzQ5NjMgMzgwLjU3NTAxMiAxODQuNTg4NDQgMzg4IDE4My44NDc0MTIgQyAzOTUuNDI0OTg4IDE4My4xMDYzMjMgNDA3LjkwNjYxNiAxODIuNTIyNTgzIDQxNS43MzY5MDggMTgyLjU1MDIzMiBDIDQyMy41NjcyIDE4Mi41Nzc4MiA0MzUuNzE3MTk0IDE4My4xNjExMzMgNDQyLjczNjkwOCAxODMuODQ2NDk3IEMgNDQ5Ljc1NjU5MiAxODQuNTMxNzk5IDQ2Mi40NzUwMDYgMTg2LjQ3Mzk5OSA0NzEgMTg4LjE2MjQ3NiBDIDQ3OS41MjQ5OTQgMTg5Ljg1MDg5MSA0OTEuNjYzNjM1IDE5Mi43ODcyOTIgNDk3Ljk3NDc2MiAxOTQuNjg3NzQ0IEMgNTA0LjI4NTg4OSAxOTYuNTg4MTk2IDUxMy43NDU0ODMgMjAwLjM0OTczMSA1MTguOTk2MDMzIDIwMy4wNDY4MTQgQyA1MjQuMjQ2NjQzIDIwNS43NDM4MzUgNTMxLjkwODAyIDIxMC4yOTk4MDUgNTM2LjAyMTMwMSAyMTMuMTcxMTQzIEMgNTQwLjEzNDU4MyAyMTYuMDQyNDggNTQ3LjYxNjY5OSAyMjIuNTUzMTAxIDU1Mi42NDgxOTMgMjI3LjYzOTE2IEMgNTU3LjY3OTc0OSAyMzIuNzI1MjIgNTY0LjUxMTEwOCAyNDAuOTQ1MDY4IDU2Ny44MjkxMDIgMjQ1LjkwNTQ1NyBDIDU3MS4xNDcwMzQgMjUwLjg2NTg0NSA1NzUuMTk5MTU4IDI1Ny43NTM5MDYgNTc2LjgzMzgwMSAyNjEuMjEyMTU4IEMgNTc4LjQ2ODUwNiAyNjQuNjcwNDcxIDU4MS42NDAxOTggMjczLjEyNSA1ODMuODgyMTQxIDI4MCBDIDU4Ni4xMjQwODQgMjg2Ljg3NSA1ODkuMDU4MDQ0IDI5Ny4yMjQ5NzYgNTkwLjQwMjAzOSAzMDMgQyA1OTEuNzQ2MDk0IDMwOC43NzUwMjQgNTkzLjc4NzU5OCAzMTkuMzQ5OTc2IDU5NC45Mzg3ODIgMzI2LjUgQyA1OTYuMDg5OTA1IDMzMy42NTAwMjQgNTk3LjcxMjc2OSAzNDYuMjUgNTk4LjU0NTEwNSAzNTQuNSBDIDU5OS40NTc3NjQgMzYzLjU0NjA4MiA2MDAuMzAxMzMxIDM4NS45MDUzMzQgNjAwLjY3MDQ3MSA0MTAuODMwOTMzIEMgNjAxLjI1NzgxMyA0NTAuNDkzMzQ3IDYwMS4yMDYxNzcgNDUyLjIzNjA4NCA1OTkuMzkxMjk2IDQ1My45OTk4NzggQyA1OTguMjcwMDIgNDU1LjA4OTUzOSA1OTIuNDEwODg5IDQ1Ny4wNTc0MzQgNTg1IDQ1OC44MzM0OTYgQyA1NzguMTI1IDQ2MC40ODEwNzkgNTY2LjQyNDk4OCA0NjMuMTg1MzY0IDU1OSA0NjQuODQzMDE4IEMgNTUxLjU3NTAxMiA0NjYuNTAwNjEgNTM5LjY1MDAyNCA0NjkuMDAxMzQzIDUzMi41IDQ3MC40MDAxNDYgQyA1MjUuMzQ5OTc2IDQ3MS43OTg5NSA1MTQuMDk5OTc2IDQ3My44Mzk0NzggNTA3LjUgNDc0LjkzNDY5MiBDIDUwMC44OTk5OTQgNDc2LjAyOTkwNyA0ODguMjk5OTg4IDQ3Ny44NTc2MDUgNDc5LjUgNDc4Ljk5NjI3NyBDIDQ3MC43MDAwMTIgNDgwLjEzNDg4OCA0NTQuNSA0ODEuNDkxNTc3IDQ0My41IDQ4Mi4wMTExMDggQyA0MzIuNSA0ODIuNTMwNTc5IDQxNS44NTAwMDYgNDgyLjg5Njc5IDQwNi41IDQ4Mi44MjQ4OSBaIi8+CiAgICAgICAgPGcgaWQ9Imc0Ij4KICAgICAgICAgICAgPHBhdGggaWQ9InBhdGg5IiBmaWxsPSIjODRkNmU0IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0gNTkwLjkyMDIyNyAyOTEuMzk4MjU0IEMgNTg3LjM0MDQ1NCAyOTIuODg0NTgzIDU4Ny4zNDA0NTQgMjkyLjg4NDU4MyA1ODIuNTc3NjM3IDI3OC40NzY3NDYgQyA1NzcuODE0NzU4IDI2NC4wNjg5MDkgNTc3LjgxNDc1OCAyNjQuMDY4OTA5IDU4MC4wMDg3ODkgMjYwLjk4NzYxIEMgNTgxLjIxNTUxNSAyNTkuMjkyOTA4IDU4Mi40MzEwMyAyNTYuMjA1MiA1ODIuNzA5OSAyNTQuMTI1OTc3IEMgNTgzLjA2MTUyMyAyNTEuNTA0NyA1ODIuNjAwMzQyIDI0OS4xNDI5NDQgNTgxLjIwNTgxMSAyNDYuNDIyNzkxIEMgNTgwLjA5OTY3IDI0NC4yNjUyNTkgNTc3Ljk4ODgzMSAyNDEuMzc1IDU3Ni41MTUwNzYgMjQwIEMgNTc0LjI0MDcyMyAyMzcuODc4MDUyIDU3Mi44NzY5NTMgMjM3LjUgNTY3LjQ5NjE1NSAyMzcuNSBDIDU2MS4xNTY3OTkgMjM3LjUgNTYxLjE1Njc5OSAyMzcuNSA1NTMuNTM3ODQyIDIyOS4yOTk2MjIgQyA1NDUuOTE4ODg0IDIyMS4wOTkyNDMgNTQ1LjkxODg4NCAyMjEuMDk5MjQzIDU0OC4yMDk0NzMgMjE5LjYwMTQ0IEMgNTQ5LjQ2OTIzOCAyMTguNzc3NjQ5IDU1Mi43MTMxMzUgMjE3LjEyNTc5MyA1NTUuNDE4MDkxIDIxNS45MzA2NjQgQyA1NTguNTkyMDQxIDIxNC41MjgzMiA1NjMuMjQ4ODQgMjEzLjU3NTk4OSA1NjguNTQ5MTMzIDIxMy4yNDUzIEMgNTc1LjEyMjE5MiAyMTIuODM1MjY2IDU3OC4xNTk0MjQgMjEzLjE1NzM0OSA1ODMuNzYwMzE1IDIxNC44NTg1ODIgQyA1ODguMDUyNjEyIDIxNi4xNjIzNTQgNTkzLjA2MTIxOCAyMTguNjc5MzgyIDU5Ni43MTM4MDYgMjIxLjM2ODIyNSBDIDYwMC4yOTkzNzcgMjI0LjAwNzc1MSA2MDQuMzMwODcyIDIyOC4yNDA3ODQgNjA2Ljg0NTIxNSAyMzIuMDA2MTA0IEMgNjA5LjE0MjA5IDIzNS40NDU2NzkgNjExLjk3Mzg3NyAyNDEuMzk1NzUyIDYxMy4xMzggMjQ1LjIyODQ1NSBDIDYxNC43MzI1NDQgMjUwLjQ3ODAyNyA2MTUuMTM1NTU5IDI1My44NjA5NjIgNjE0Ljc3MTk3MyAyNTguOTQyNjI3IEMgNjE0LjQ3MDAzMiAyNjMuMTYzMDI1IDYxMy4zNDIzNDYgMjY3Ljc1NjgzNiA2MTEuNzU5NTIxIDI3MS4yMTQxMTEgQyA2MTAuMzY4MTAzIDI3NC4yNTMzNTcgNjA3LjQ5MDQ3OSAyNzguNjY2MDE2IDYwNS4zNjQ4MDcgMjgxLjAxOTk1OCBDIDYwMy4yMzkxOTcgMjgzLjM3MzkwMSA1OTkuOTI0OTg4IDI4Ni4zMzc1ODUgNTk4IDI4Ny42MDU4OTYgQyA1OTYuMDc1MDEyIDI4OC44NzQyMDcgNTkyLjg4OTA5OSAyOTAuNTgwNzUgNTkwLjkyMDIyNyAyOTEuMzk4MjU0IFoiLz4KICAgICAgICAgICAgPHBhdGggaWQ9InBhdGgxMCIgZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9Im5vbmUiIGQ9Ik0gNTgwLjAxNTM4MSAyNjAuMjg1NzA2IEMgNTc4LjM2NzMxIDI2MC43MTY3MzYgNTc3LjM1NDQzMSAyNTkuNjcwNTMyIDU3NC41Mjk5NjggMjU0LjYxOTk5NSBDIDU3Mi42MjQ3NTYgMjUxLjIxMzA3NCA1NjkuMjg5NTUxIDI0NS44ODk4MzIgNTY3LjExODQwOCAyNDIuNzkwNDY2IEMgNTYzLjE4NDIwNCAyMzcuMTc0MTMzIDU2My4xNzc3MzQgMjM3LjE0OTEwOSA1NjUuMTkwNDkxIDIzNS4zMjc2MzcgQyA1NjYuNjEzMjIgMjM0LjA0MDAzOSA1NjguNzgwMzk2IDIzMy41IDU3Mi41MjQ0MTQgMjMzLjUgQyA1NzYuODEyMzc4IDIzMy41IDU3OC4zNTYwNzkgMjMzLjk4Mjg0OSA1ODAuNTE2NzI0IDIzNiBDIDU4MS45ODk1NjMgMjM3LjM3NSA1ODQuMDk5NjcgMjQwLjI2NTI1OSA1ODUuMjA1ODExIDI0Mi40MjI3OTEgQyA1ODYuNjAwMzQyIDI0NS4xNDI5NDQgNTg3LjA2MTUyMyAyNDcuNTA0NyA1ODYuNzA5OSAyNTAuMTI1OTc3IEMgNTg2LjQzMTAzIDI1Mi4yMDUyIDU4NS4yNjU1MDMgMjU1LjIyMjc3OCA1ODQuMTE5ODEyIDI1Ni44MzE3MjYgQyA1ODIuOTc0MTIxIDI1OC40NDA2NzQgNTgxLjEyNzEzNiAyNTkuOTk0OTk1IDU4MC4wMTUzODEgMjYwLjI4NTcwNiBaIi8+CiAgICAgICAgPC9nPgogICAgICAgIDxnIGlkPSJnNSI+CiAgICAgICAgICAgIDxwYXRoIGlkPSJwYXRoMTEiIGZpbGw9IiM4NGQ2ZTQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTSAyMjAuNDU1NDYgMjk5LjY1MzI1OSBDIDIxOS45Mjk5NjIgMjk5LjgxMjkyNyAyMTYuODAwMDAzIDI5OC40OTk2MzQgMjEzLjUgMjk2LjczNDkyNCBDIDIxMC4xOTk5OTcgMjk0Ljk3MDIxNSAyMDUuMTc3NzE5IDI5MS4xNzkwMTYgMjAyLjMzOTM3MSAyODguMzA5OTk4IEMgMTk4LjkyNDA3MiAyODQuODU3Nzg4IDE5Ni40NzIwOTIgMjgxLjIwNTAxNyAxOTUuMDg5MzcxIDI3Ny41MDkyNzcgQyAxOTMuNzc0OTQ4IDI3My45OTYyMTYgMTkzIDI2OS41NjcxMzkgMTkzIDI2NS41Njc4MSBDIDE5MyAyNjIuMDcxNDExIDE5My44ODM4NSAyNTYuMzUwNzY5IDE5NC45NjQxMjcgMjUyLjg1NTM0NyBDIDE5Ni4wNDQ0MDMgMjQ5LjM1OTkyNCAxOTguMjIxNTEyIDI0NC40NzQ5NzYgMTk5LjgwMjE3IDI0MiBDIDIwMS4zODI4MjggMjM5LjUyNTAyNCAyMDQuNjg5ODY1IDIzNS42NTU3NjIgMjA3LjE1MTEzOCAyMzMuNDAxNjcyIEMgMjA5LjYxMjQyNyAyMzEuMTQ3NjQ0IDIxMy42MzM4OTYgMjI4LjEyNjc3IDIxNi4wODc3NTMgMjI2LjY4ODcyMSBDIDIxOC41NDE2MTEgMjI1LjI1MDY3MSAyMjMuNDUxNDMxIDIyMy4zMzA1NjYgMjI2Ljk5ODQ4OSAyMjIuNDIxODc1IEMgMjMxLjUyMDc5OCAyMjEuMjYzMzA2IDIzNS4zMTYwNTUgMjIwLjk2MTEyMSAyMzkuNzAxMTI2IDIyMS40MTAzMzkgQyAyNDMuMTQwNTQ5IDIyMS43NjI3NTYgMjQ4Ljc4MzcyMiAyMjIuOTI0ODY2IDI1Mi4yNDE1MzEgMjIzLjk5Mjg1OSBDIDI1NS42OTkzNDEgMjI1LjA2MDkxMyAyNTkuNDE5OTIyIDIyNi41ODY1NDggMjYwLjUwOTQ2IDIyNy4zODMyNCBDIDI2Mi40MTQwOTMgMjI4Ljc3NTk0IDI2Mi4yMzkxNjYgMjI5LjA5NTM5OCAyNTUuOTczODE2IDIzNS42NjU4OTQgQyAyNTIuMzg5NjQ4IDIzOS40MjQ2ODMgMjQ4LjA3MzEzNSAyNDQuMjYzOTE2IDI0Ni4zODE1NjEgMjQ2LjQxOTggQyAyNDMuMzA1OTY5IDI1MC4zMzk2IDI0My4zMDU5NjkgMjUwLjMzOTYgMjM5LjEzMjc1MSAyNDguNjY5OCBDIDIzNi44Mzc0NzkgMjQ3Ljc1MTQwNCAyMzIuOTM3MDI3IDI0NyAyMzAuNDY1MDczIDI0NyBDIDIyNi43ODQ0MzkgMjQ3IDIyNS4zMzIxMDggMjQ3LjU4ODUwMSAyMjIuNDQ0MjYgMjUwLjI1IEMgMjIwLjUwNDc2MSAyNTIuMDM3NDc2IDIxOC4yNjkzMDIgMjU1LjM5NTkzNSAyMTcuNDc2NTc4IDI1Ny43MTMxMzUgQyAyMTYuNjU1MTM2IDI2MC4xMTQyNTggMjE2LjMwMzE2MiAyNjMuMjY1ODA4IDIxNi42NTgxODggMjY1LjA0MDk1NSBDIDIxNy4wMDA4MDkgMjY2Ljc1NDA4OSAyMTguNjgwMzc0IDI2OS41OTU3MDMgMjIwLjM5MDU2NCAyNzEuMzU1NjUyIEMgMjIyLjEwMDc1NCAyNzMuMTE1NjYyIDIyNC42MjUgMjc1LjI3NDM1MyAyMjYgMjc2LjE1Mjc3MSBDIDIyOC41IDI3Ny43NDk5MzkgMjI4LjUgMjc3Ljc0OTkzOSAyMjQuOTU1NDYgMjg4LjU1NjUxOSBDIDIyMy4wMDU5NjYgMjk0LjUwMDA2MSAyMjAuOTgwOTcyIDI5OS40OTM2NTIgMjIwLjQ1NTQ2IDI5OS42NTMyNTkgWiIvPgogICAgICAgICAgICA8cGF0aCBpZD0icGF0aDEyIiBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0ibm9uZSIgZD0iTSAyMjcuMTg4OTM0IDI3NSBDIDIyNi43OTUzMzQgMjc1IDIyNC4xOTU0MTkgMjczLjQ2NjAwMyAyMjEuNDExMzMxIDI3MS41OTEwNjQgQyAyMTguNjI3MjQzIDI2OS43MTYxODcgMjE1LjY2Njk0NiAyNjcuMTI4NjYyIDIxNC44MzI4NyAyNjUuODQxMDY0IEMgMjEzLjk5ODc5NSAyNjQuNTUzNDY3IDIxMy4wMTYxNTkgMjYyLjI4MDY0IDIxMi42NDkyNDYgMjYwLjc5MDI4MyBDIDIxMi4yNjY5NjggMjU5LjIzNzU0OSAyMTIuNjA4ODg3IDI1Ni4yNDg1OTYgMjEzLjQ0OTk5NyAyNTMuNzkwMjgzIEMgMjE0LjI1NzM1NSAyNTEuNDMwNjAzIDIxNi41MDQ3NjEgMjQ4LjAzNzQ3NiAyMTguNDQ0MjYgMjQ2LjI1IEMgMjIxLjI4MjYyMyAyNDMuNjM0MDk0IDIyMi44MDk0NDggMjQzIDIyNi4yNjk5NzQgMjQzIEMgMjI4LjYzNDYxMyAyNDMgMjMzLjI1MzcyMyAyNDMuOTQxMzQ1IDIzNi41MzQ2NTMgMjQ1LjA5MTg1OCBDIDIzOS44MTU1OTggMjQ2LjI0MjM3MSAyNDIuNjI0NDgxIDI0Ny4zMDQzODIgMjQyLjc3NjYyNyAyNDcuNDUxNzgyIEMgMjQyLjkyODc1NyAyNDcuNTk5MjQzIDI0MS41NTgwMjkgMjQ5Ljk0MTc3MiAyMzkuNzMwNTMgMjUyLjY1NzQxIEMgMjM3LjkwMzA0NiAyNTUuMzczMDQ3IDIzNC40OTQ1OTggMjYxLjUxMTEwOCAyMzIuMTU2MTg5IDI2Ni4yOTc0ODUgQyAyMjkuODE3Nzk1IDI3MS4wODM4NjIgMjI3LjU4MjUzNSAyNzUgMjI3LjE4ODkzNCAyNzUgWiIvPgogICAgICAgIDwvZz4KICAgICAgICA8ZyBpZD0iZzYiPgogICAgICAgICAgICA8cGF0aCBpZD0icGF0aDEzIiBmaWxsPSIjZmZmZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0gMzI0IDMzMi41MjMwNzEgQyAzMTkuNDEzMDI1IDMzMi43OTc0MjQgMzEzLjk3NTM3MiAzMzIuNDA0NjYzIDMxMCAzMzEuNTExNzE5IEMgMzA2LjQyNDk4OCAzMzAuNzA4NzQgMzAwLjE4OTMwMSAzMjguMzc5MDI4IDI5Ni4xNDI4NTMgMzI2LjMzNDQ3MyBDIDI5MS43MzE4NDIgMzI0LjEwNTc3NCAyODYuNDQ3ODc2IDMyMC4zMTUzNjkgMjgyLjk0NzYwMSAzMTYuODY5MDE5IEMgMjc5LjczNjYzMyAzMTMuNzA3NTIgMjc1LjcyNzYzMSAzMDguNzMxMTQgMjc0LjAzODcyNyAzMDUuODEwNDI1IEMgMjcyLjM0OTgyMyAzMDIuODg5NzA5IDI3MC4wMzAyMTIgMjk3LjQ1ODY3OSAyNjguODg0MDAzIDI5My43NDE0NTUgQyAyNjcuNDc0NDg3IDI4OS4xNzAzNDkgMjY2Ljc5OTk4OCAyODQuMjY2OTA3IDI2Ni43OTk5ODggMjc4LjU5MTM3IEMgMjY2Ljc5OTk4OCAyNzMuNjc2MzMxIDI2Ny40OTk0MiAyNjcuNzkzOTQ1IDI2OC40ODgxOSAyNjQuMzkyNjM5IEMgMjY5LjQxNjcxOCAyNjEuMTk4NjY5IDI3MS4zMTM5OTUgMjU2LjM0MDQ1NCAyNzIuNzA0Mzc2IDI1My41OTY2OCBDIDI3NC4wOTQ3ODggMjUwLjg1Mjg0NCAyNzcuNzQ0MDggMjQ1Ljk3NDY3IDI4MC44MTM5MzQgMjQyLjc1NjIyNiBDIDI4My44ODM3NTkgMjM5LjUzNzg0MiAyODguODkzOTgyIDIzNS40MDA5NCAyOTEuOTQ3NzIzIDIzMy41NjMxMSBDIDI5NS4wMDE0NjUgMjMxLjcyNTM0MiAzMDAuODc1IDIyOC45ODU2NTcgMzA1IDIyNy40NzUwMzcgQyAzMTAuOTUwMzQ4IDIyNS4yOTU5NTkgMzE0LjgxMDkxMyAyMjQuNjI3NzQ3IDMyMy42ODQzNTcgMjI0LjI0MDkwNiBDIDMzMS44NjYxOCAyMjMuODg0MjE2IDMzNi43OTA1NTggMjI0LjE4NzM3OCAzNDIuMDI3Mzc0IDIyNS4zNjk5OTUgQyAzNDUuOTY0NiAyMjYuMjU5MDk0IDM1Mi4xODE2NDEgMjI4LjQwODA4MSAzNTUuODQyOTg3IDIzMC4xNDU0NDcgQyAzNjAuMzgzODgxIDIzMi4zMDAxNzEgMzY0LjU2NjE5MyAyMzUuNDA1NDU3IDM2OSAyMzkuOTE0MjQ2IEMgMzcyLjczMDMxNiAyNDMuNzA3NjQyIDM3Ni42OTI1MDUgMjQ4Ljk4NDYxOSAzNzguMjk4NjQ1IDI1Mi4yOTg0NjIgQyAzNzkuODM3ODkxIDI1NS40NzQzMDQgMzgxLjgxMjI4NiAyNjAuOTcwMjE1IDM4Mi42ODYxODggMjY0LjUxMTUzNiBDIDM4My44MjE0NzIgMjY5LjExMiAzODQuMTI2ODYyIDI3My41OTgyNjcgMzgzLjc1NTg1OSAyODAuMjI1MTU5IEMgMzgzLjQxODI3NCAyODYuMjU0NzYxIDM4Mi40NzIxNjggMjkxLjUwNjgzNiAzODEuMDUxODQ5IDI5NS4yMzU1MzUgQyAzNzkuODUwMjUgMjk4LjM5MDA3NiAzNzcuMDY5NjExIDMwMy42NjI4NDIgMzc0Ljg3MjY1IDMwNi45NTI4MiBDIDM3Mi42NzU2OSAzMTAuMjQyNzk4IDM2OC4zMTgxMTUgMzE0Ljk2Njg1OCAzNjUuMTg5MDg3IDMxNy40NTA4MDYgQyAzNjIuMDYwMDg5IDMxOS45MzQ2OTIgMzU2LjcyODg4MiAzMjMuMzMyMjE0IDM1My4zNDE5NDkgMzI1LjAwMDg1NCBDIDM0OS45NTUwMTcgMzI2LjY2OTU1NiAzNDMuNjU1MDI5IDMyOC45NDM3MjYgMzM5LjM0MTk0OSAzMzAuMDU0NTY1IEMgMzM1LjAyODg3IDMzMS4xNjU0NjYgMzI4LjEyNSAzMzIuMjc2MzA2IDMyNCAzMzIuNTIzMDcxIFoiLz4KICAgICAgICAgICAgPHBhdGggaWQ9InBhdGgxNCIgZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9Im5vbmUiIGQ9Ik0gMjk2Ljg3OTc5MSAyOTkuNTM0MTE5IEMgMjkzLjc2MDI4NCAyOTkuOTEyNjU5IDI5MS4zMTU1ODIgMjk5LjUxMTk2MyAyODguMzgzOTExIDI5OC4xNDE2NjMgQyAyODYuMTIwMDU2IDI5Ny4wODM0OTYgMjgzLjEyNDA1NCAyOTQuNzA2MjM4IDI4MS43MjYxMDUgMjkyLjg1ODgyNiBDIDI4MC4zMjgxMjUgMjkxLjAxMTQ3NSAyNzguNjczNzM3IDI4Ny41ODA4MTEgMjc4LjA0OTY1MiAyODUuMjM1MTY4IEMgMjc3LjQyNTU2OCAyODIuODg5NTI2IDI3Ny4yMTkyMDggMjc5LjI4OTU1MSAyNzcuNTkxMTI1IDI3Ny4yMzUxNjggQyAyNzcuOTYzMDEzIDI3NS4xODA4NDcgMjc4Ljg0MTk4IDI3Mi4zNzUgMjc5LjU0NDM3MyAyNzEgQyAyODAuMjQ2NzY1IDI2OS42MjUgMjgyLjA5OTEyMSAyNjcuMjkxMTM4IDI4My42NjA3MzYgMjY1LjgxMzU5OSBDIDI4NS4yMjIzMjEgMjY0LjMzNjEyMSAyODcuNzY2Nzg1IDI2Mi42NDg2MjEgMjg5LjMxNTA5NCAyNjIuMDYzNTk5IEMgMjkwLjg2MzQwMyAyNjEuNDc4NjM4IDI5My42OTM4MTcgMjYxIDI5NS42MDQ5NSAyNjEgQyAyOTcuNTE2MDUyIDI2MSAzMDAuODYxMjM3IDI2MS45MDg4NzUgMzAzLjAzODcyNyAyNjMuMDE5Nzc1IEMgMzA1LjIxNjE4NyAyNjQuMTMwNjE1IDMwOC4yMzU3NzkgMjY2LjkxMDI3OCAzMDkuNzQ4ODcxIDI2OS4xOTY3MTYgQyAzMTIuMTA1ODk2IDI3Mi43NTg0MjMgMzEyLjUgMjc0LjM3NzYyNSAzMTIuNSAyODAuNTAwMjQ0IEMgMzEyLjUgMjg2LjQ2NDY2MSAzMTIuMDg2NTQ4IDI4OC4yNjE1MzYgMzEwIDI5MS4zNjUyMzQgQyAzMDguNjI1IDI5My40MTA1MjIgMzA2LjA5NTkxNyAyOTUuOTY1NjM3IDMwNC4zNzk3OTEgMjk3LjA0MzI3NCBDIDMwMi42NjM2OTYgMjk4LjEyMDk3MiAyOTkuMjg4Njk2IDI5OS4yNDE4MjEgMjk2Ljg3OTc5MSAyOTkuNTM0MTE5IFoiLz4KICAgICAgICAgICAgPHBhdGggaWQ9InBhdGgxNSIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9Im5vbmUiIGQ9Ik0gMzA0IDI5MCBDIDMwMy4yNzI5MTkgMjkwIDMwMS45NzU0MzMgMjkwLjA3NzgyIDMwMSAyODkgQyAyOTkuNzgwNTQ4IDI4Ny42NTI1MjcgMjk4Ljk2NTQ4NSAyODUuMjczNjIxIDI5OS40MTEyODUgMjgzLjQ5NzQ5OCBDIDI5OS43Njc4NTMgMjgyLjA3Njc4MiAzMDAuNjk1NzcgMjgwLjY3MDIyNyAzMDEuNDczMzI4IDI4MC4zNzE4ODcgQyAzMDIuMjUwODU0IDI4MC4wNzM0ODYgMzAzLjc2Mzg1NSAyODAuMTA3NjY2IDMwNC44MzU1NDEgMjgwLjQ0NzgxNSBDIDMwNS45MDcyMjcgMjgwLjc4Nzk2NCAzMDcuMDQyMjk3IDI4Mi4wNTM3NzIgMzA3LjM1NzkxIDI4My4yNjA2ODEgQyAzMDcuNjczNTUzIDI4NC40Njc2NTEgMzA3LjgxODkwOSAyODYuNzUwMTIyIDMwNyAyODggQyAzMDYuMTgxMDkxIDI4OS4yNDk4MTcgMzA0LjcyNzA4MSAyOTAgMzA0IDI5MCBaIi8+CiAgICAgICAgPC9nPgogICAgICAgIDxnIGlkPSJnNyI+CiAgICAgICAgICAgIDxwYXRoIGlkPSJwYXRoMTYiIGZpbGw9IiNmZmZmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTSA0NzcgMzI0LjU3ODkxOCBDIDQ2OS4yNzM0OTkgMzI0Ljg0MTg1OCA0NjMuNDIyMTggMzI0LjQ5ODEwOCA0NTkuMTY3NzU1IDMyMy41MzExODkgQyA0NTUuNjg0OTk4IDMyMi43Mzk2ODUgNDQ5LjQ2MjY3NyAzMjAuNDI1NTM3IDQ0NS4zNDAzNjMgMzE4LjM4ODYxMSBDIDQ0MC40ODE1MzcgMzE1Ljk4Nzg1NCA0MzUuNzY4MTU4IDMxMi42MDgxNTQgNDMxLjk0MDAzMyAzMDguNzgwMDI5IEMgNDI3Ljg5MTYwMiAzMDQuNzMxNjI4IDQyNC43MTk2MDQgMzAwLjIyMDU4MSA0MjEuODUxODA3IDI5NC40MzMxMDUgQyA0MTguMjMwNDA4IDI4Ny4xMjQ3NTYgNDE3LjYwNDMwOSAyODQuODg0MjE2IDQxNy4xODg3MjEgMjc3Ljc0NTY2NyBDIDQxNi45MTk3MzkgMjczLjEyNSA0MTcuMjQ0MTcxIDI2Ni44NjIyNDQgNDE3LjkyNjY5NyAyNjMuNSBDIDQxOC41OTY1NTggMjYwLjIwMDAxMiA0MjAuNjk2NjI1IDI1NC4yNTI4NjkgNDIyLjU5MzQ3NSAyNTAuMjg0MTggQyA0MjQuNTg1NTEgMjQ2LjExNjI3MiA0MjguNDYyMTg5IDI0MC40NDY5NiA0MzEuNzcxMTQ5IDIzNi44NjI0ODggQyA0MzQuOTIyMDI4IDIzMy40NDkzNDEgNDQwLjEzNDM2OSAyMjguOTQ4NzMgNDQzLjM1NDE4NyAyMjYuODYxMjA2IEMgNDQ2LjU3Mzk3NSAyMjQuNzczNjgyIDQ1MS43MTA3ODUgMjIyLjEyOTQ1NiA0NTQuNzY5Mjg3IDIyMC45ODUxMDcgQyA0NTcuODI3ODIgMjE5Ljg0MDgyIDQ2NC44NjUxNDMgMjE4LjI2ODEyNyA0NzAuNDA3ODA2IDIxNy40OTAyOTUgQyA0NzcuNzUzMDgyIDIxNi40NTk0NzMgNDgyLjI5Njg0NCAyMTYuMzMyOTQ3IDQ4Ny4xNjY3MTggMjE3LjAyMzYyMSBDIDQ5MC44NDE0NjEgMjE3LjU0NDggNDk2LjM1MDc2OSAyMTguOTA3NTkzIDQ5OS40MDk1NzYgMjIwLjA1MjA2MyBDIDUwMi40Njg0MTQgMjIxLjE5NjUzMyA1MDcuNjcwMTY2IDIyMy45MzUyNDIgNTEwLjk2OTA1NSAyMjYuMTM4MTg0IEMgNTE0LjI2Nzk0NCAyMjguMzQxMDY0IDUxOC43ODU3MDYgMjMyLjI0ODY1NyA1MjEuMDA4NTQ1IDIzNC44MjE3MTYgQyA1MjMuMjMxNDQ1IDIzNy4zOTQ3NzUgNTI2LjU4Mjc2NCAyNDIuNTM1ODg5IDUyOC40NTYwNTUgMjQ2LjI0NjM5OSBDIDUzMC4zMjkyODUgMjQ5Ljk1Njk3IDUzMi42Mjc5OTEgMjU2LjQzNTc5MSA1MzMuNTY0MjA5IDI2MC42NDM4NiBDIDUzNC43MTg4NzIgMjY1LjgzNDA0NSA1MzUuMDkzNTY3IDI3MC41ODAwNzggNTM0LjcyOTA2NSAyNzUuMzk5NzE5IEMgNTM0LjQzMzQ3MiAyNzkuMzA3MzczIDUzMy4yNjcwOSAyODUuMTM1MzE1IDUzMi4xMzY5NjMgMjg4LjM1MDY0NyBDIDUzMS4wMDY4MzYgMjkxLjU2NjA0IDUyOC42NzAzNDkgMjk2LjM5NzAzNCA1MjYuOTQ0NzAyIDI5OS4wODYxMjEgQyA1MjUuMjE5MTE2IDMwMS43NzUyNjkgNTIxLjQ1MzE4NiAzMDYuMTI2OTUzIDUxOC41NzU5ODkgMzA4Ljc1NjUzMSBDIDUxNS42OTg4NTMgMzExLjM4NjEwOCA1MTAuNjc5NzE4IDMxNC45NTA1IDUwNy40MjIzOTQgMzE2LjY3NzMwNyBDIDUwNC4xNjUwNyAzMTguNDA0MTc1IDQ5OC41NzUwMTIgMzIwLjgwMDQxNSA0OTUgMzIyLjAwMjMxOSBDIDQ5MC4yODExODkgMzIzLjU4ODY4NCA0ODUuMzQ4NjYzIDMyNC4yOTQ3MzkgNDc3IDMyNC41Nzg5MTggWiIvPgogICAgICAgICAgICA8cGF0aCBpZD0icGF0aDE3IiBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0ibm9uZSIgZD0iTSA0NDUuMjgyMTA0IDI5NC45OTkyMDcgQyA0NDMuNzUxOTUzIDI5NC45OTg3NzkgNDQwLjU3NTQwOSAyOTQuMDQ1Nzc2IDQzOC4yMjMxMTQgMjkyLjg4MTQwOSBDIDQzNS4zNjIwNjEgMjkxLjQ2NTIxIDQzMy4wODQ2NTYgMjg5LjI5NDI1IDQzMS4zNDM2NTggMjg2LjMyMzQyNSBDIDQyOS45MTIyMzEgMjgzLjg4MDkyIDQyOC41MTUyMjggMjc5Ljg3ODYwMSA0MjguMjM5MTY2IDI3Ny40Mjk1MDQgQyA0MjcuOTE1NTU4IDI3NC41NTgzNSA0MjguMzM3NTI0IDI3MS40MDQ3MjQgNDI5LjQyNzA2MyAyNjguNTUxODE5IEMgNDMwLjM1NjQ0NSAyNjYuMTE4Mjg2IDQzMi44NjM3MDggMjYyLjU0ODk1IDQzNC45OTg3NDkgMjYwLjYyMDA1NiBDIDQzNy4xODY0NjIgMjU4LjY0MzYxNiA0NDAuNDc2MzQ5IDI1Ni44MTM2NiA0NDIuNTM2ODA0IDI1Ni40MjcxMjQgQyA0NDQuNTc5OTg3IDI1Ni4wNDM4MjMgNDQ3Ljg5NTE0MiAyNTYuMjUxMjIxIDQ1MC4wNTEzOTIgMjU2Ljg5NzI3OCBDIDQ1Mi4xNzM1NTMgMjU3LjUzMzA4MSA0NTUuMjMwNjIxIDI1OS4xNjQ2MTIgNDU2Ljg0NDg3OSAyNjAuNTIyODg4IEMgNDU4LjQ1OTEwNiAyNjEuODgxMjI2IDQ2MC41MDQzOTUgMjY0LjgwMzM0NSA0NjEuMzg5OTIzIDI2Ny4wMTY1NDEgQyA0NjIuMjc1NDgyIDI2OS4yMjk2NzUgNDYzIDI3My4wNDcyNDEgNDYzIDI3NS41IEMgNDYzIDI3Ny45NTI3NTkgNDYyLjI5Njk5NyAyODEuNzE2NDkyIDQ2MS40Mzc3NzUgMjgzLjg2Mzg5MiBDIDQ2MC41Nzg1NTIgMjg2LjAxMTI5MiA0NTguODg0OTE4IDI4OC42OTg5MTQgNDU3LjY3NDEzMyAyODkuODM2NDI2IEMgNDU2LjQ2MzM0OCAyOTAuOTczODc3IDQ1My44MDU3ODYgMjkyLjYwMTAxMyA0NTEuNzY4NDYzIDI5My40NTIyNzEgQyA0NDkuNzMxMTQgMjk0LjMwMzUyOCA0NDYuODEyMjg2IDI5NC45OTk2MzQgNDQ1LjI4MjEwNCAyOTQuOTk5MjA3IFoiLz4KICAgICAgICAgICAgPHBhdGggaWQ9InBhdGgxOCIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9Im5vbmUiIGQ9Ik0gNDUzLjQ1MDAxMiAyODQuOTg0NjggQyA0NTIuODcyNDk4IDI4NC45OTMxMDMgNDUxLjg1OTk4NSAyODQuNDYwMDIyIDQ1MS4yMDAwMTIgMjgzLjc5OTk4OCBDIDQ1MC41NDAwMDkgMjgzLjE0MDAxNSA0NTAgMjgxLjM5NTA4MSA0NTAgMjc5LjkyMjQyNCBDIDQ1MCAyNzguNDQ5NzY4IDQ1MC42NTM0MTIgMjc2LjcwMjYzNyA0NTEuNDUyMDI2IDI3Ni4wMzk4NTYgQyA0NTIuMjUwNjEgMjc1LjM3NzAxNCA0NTMuODAyNjEyIDI3NS4xMTk5MzQgNDU0LjkwMDg0OCAyNzUuNDY4NTA2IEMgNDU1Ljk5OTExNSAyNzUuODE3MDc4IDQ1Ny4xODQxMTMgMjc3LjAwNDcgNDU3LjUzNDE0OSAyNzguMTA3NjA1IEMgNDU3Ljg4NDIxNiAyNzkuMjEwNTcxIDQ1Ny44ODI1MDcgMjgwLjg2Mzc3IDQ1Ny41MzAzOTYgMjgxLjc4MTQzMyBDIDQ1Ny4xNzgyNTMgMjgyLjY5OTAzNiA0NTYuMzUyMzU2IDI4My43OTE3NDggNDU1LjY5NTA2OCAyODQuMjA5NTk1IEMgNDU1LjAzNzc4MSAyODQuNjI3NTAyIDQ1NC4wMjc0OTYgMjg0Ljk3NjI1NyA0NTMuNDUwMDEyIDI4NC45ODQ2OCBaIi8+CiAgICAgICAgPC9nPgogICAgICAgIDxnIGlkPSJnOCI+CiAgICAgICAgICAgIDxwYXRoIGlkPSJwYXRoMTkiIGZpbGw9IiNmZmRlYjIiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTSA0NDAuODExNjE1IDM3Mi43Nzc3MSBDIDQzOC41MDY1OTIgMzcyLjc1NjM0OCA0MzIuMzc3MzE5IDM3MS4wMzkxMjQgNDI3LjE5MDk3OSAzNjguOTYxNjcgQyA0MjAuMjQxOTQzIDM2Ni4xNzgxMDEgNDE1LjY5NDA2MSAzNjUuMDYwMTgxIDQwOS45MDMxOTggMzY0LjcxMTg1MyBDIDQwMy4wOTQ4NDkgMzY0LjMwMjM2OCA0MDAuNzE1NTE1IDM2NC42ODUwNTkgMzkyLjA5MTU4MyAzNjcuNTc2ODQzIEMgMzg2LjYxNzEyNiAzNjkuNDEyNDc2IDM3OS43NDk1NDIgMzcxLjE2NTQ2NiAzNzYuODMwMjkyIDM3MS40NzIyMjkgQyAzNzMuMDMyOTI4IDM3MS44NzEyNzcgMzcwLjU2MDA1OSAzNzEuNTMyMjI3IDM2OC4xNDAwNzYgMzcwLjI4MDc2MiBDIDM2Ni4yNzk3MjQgMzY5LjMxODc4NyAzNjMuODc3NTAyIDM2Ny4wODQ0NzMgMzYyLjgwMTg4IDM2NS4zMTU3MzUgQyAzNjEuNzI2MjI3IDM2My41NDY5MzYgMzYwLjU0ODMwOSAzNjAuNTEyMTQ2IDM2MC4xODQyNjUgMzU4LjU3MTc3NyBDIDM1OS44MjAyNTEgMzU2LjYzMTM0OCAzNjAuMDEyNTczIDM1My4yMjM1MTEgMzYwLjYxMTYwMyAzNTAuOTk4Nzc5IEMgMzYxLjIxMDY5MyAzNDguNzczOTg3IDM2My4wNzQzMSAzNDUuMDU3Njc4IDM2NC43NTMwMjEgMzQyLjc0MDI5NSBDIDM2Ni40OTE0ODYgMzQwLjM0MDQ1NCAzNjkuODc5NzkxIDMzNy41MjI2NDQgMzcyLjYyNTI0NCAzMzYuMTkzNjA0IEMgMzc3LjQ0NTMxMyAzMzMuODYwMjI5IDM3Ny40NDUzMTMgMzMzLjg2MDIyOSAzODEuMDgzOTg0IDMzNy4wNTUwNTQgQyAzODMuMDg1MjM2IDMzOC44MTIxOTUgMzg2LjczNDI1MyAzNDAuODYwNDEzIDM4OS4xOTI5MzIgMzQxLjYwNjc1IEMgMzkxLjY1MTU4MSAzNDIuMzUzMDI3IDM5Ny43MjAwNjIgMzQyLjk1MzYxMyA0MDIuNjc4NDM2IDM0Mi45NDExNjIgQyA0MDguMjYxMTA4IDM0Mi45MjcyNDYgNDEzLjg4OTcwOSAzNDIuMjI2NDQgNDE3LjQ2MTMzNCAzNDEuMTAwNTI1IEMgNDIwLjYzMzUxNCAzNDAuMTAwNjQ3IDQyNS4yNTE0OTUgMzM3LjgxNzM4MyA0MjcuNzIzNDUgMzM2LjAyNjY3MiBDIDQzMi4wMzEwOTcgMzMyLjkwNjE4OSA0MzIuMzUzMDI3IDMzMi44MzU2OTMgNDM1LjQ2NzA0MSAzMzQuMzMwMzgzIEMgNDM3LjI1NDAyOCAzMzUuMTg4MTEgNDQxLjU1MTQ4MyAzMzguMDI2OTc4IDQ0NS4wMTY5MDcgMzQwLjYzOTA5OSBDIDQ0OC40ODIzIDM0My4yNTEyMjEgNDUyLjM3MjA0IDM0Ny4yNjQ0MDQgNDUzLjY2MDc2NyAzNDkuNTU3NDM0IEMgNDU0Ljk2NjY0NCAzNTEuODgwODU5IDQ1Ni4wMDIxNjcgMzU1LjUxODQ5NCA0NTYgMzU3Ljc3NDc4IEMgNDU1Ljk5NzgzMyAzNjAuMDAxMzQzIDQ1NS4wNTkxNzQgMzYzLjM1OTY4IDQ1My45MTQwNjMgMzY1LjIzNzc5MyBDIDQ1Mi43Njg5ODIgMzY3LjExNTk2NyA0NTAuMjk1NDQxIDM2OS41ODk0MTcgNDQ4LjQxNzM1OCAzNzAuNzM0NTU4IEMgNDQ2LjQ2MjQwMiAzNzEuOTI2NDUzIDQ0My4yMTA5NjggMzcyLjc5OTkyNyA0NDAuODExNjE1IDM3Mi43Nzc3MSBaIi8+CiAgICAgICAgICAgIDxwYXRoIGlkPSJwYXRoMjAiIGZpbGw9IiNmZmZmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTSA0MTYuNDE4NzkzIDQwNS41NDMyNzQgQyA0MTIuNzc3MzQ0IDQwNi4wMzE3MzggNDExLjk4MjYwNSA0MDUuNjcxNjMxIDQwOC4wNzE4NjkgNDAxLjc2MDg2NCBDIDQwMy43NDk2MzQgMzk3LjQzODY2IDQwMy43NDk2MzQgMzk3LjQzODY2IDQwNC4xODM4NjggMzgxLjI3NzY0OSBDIDQwNC40MjI2OTkgMzcyLjM4OTA5OSA0MDQuOTQxNjgxIDM2NC43OTMwOTEgNDA1LjMzNzE4OSAzNjQuMzk3NTIyIEMgNDA1LjczMjcyNyAzNjQuMDAyMDE0IDQwOS4xOTYzNSAzNjQuNDUzMzA4IDQxMy4wMzQyNDEgMzY1LjQwMDQ1MiBDIDQxNi44NzIwNyAzNjYuMzQ3NDczIDQyMS40NjgyMDEgMzY3Ljk3MTg2MyA0MjMuMjQ3ODAzIDM2OS4wMTAwMSBDIDQyNi40ODM0NTkgMzcwLjg5NzcwNSA0MjYuNDgzNDU5IDM3MC44OTc3MDUgNDI2Ljc4NTY3NSAzODMuOTEwODI4IEMgNDI2Ljk1MTg3NCAzOTEuMDY4MDU0IDQyNi44Mzk3ODMgMzk3LjkyNDgwNSA0MjYuNTM2NTYgMzk5LjE0ODEzMiBDIDQyNi4yMzMzMzcgNDAwLjM3MTQ2IDQyNC43MzgzNDIgNDAyLjE4OTMzMSA0MjMuMjE0Mzg2IDQwMy4xODc5MjcgQyA0MjEuNjkwMzY5IDQwNC4xODY0NjIgNDE4LjYzMjM4NSA0MDUuMjQ2Mzk5IDQxNi40MTg3OTMgNDA1LjU0MzI3NCBaIi8+CiAgICAgICAgICAgIDxwYXRoIGlkPSJwYXRoMjEiIGZpbGw9IiNmZmZmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTSAzOTEuOTgwOTU3IDQwNCBDIDM5MC4wNDU3NDYgNDA0IDM4Ny40OTcwMDkgNDAzLjE5MTcxMSAzODYuMzE3MDc4IDQwMi4yMDM3MzUgQyAzODUuMTM3MTE1IDQwMS4yMTU3NTkgMzgzLjIzNTc3OSAzOTguMjU2NDcgMzgyLjA5MTg1OCAzOTUuNjI3NTAyIEMgMzgwLjk0NzkwNiAzOTIuOTk4NDc0IDM3OS43MjI5NjEgMzg4LjA4MjMzNiAzNzkuMzY5NzIgMzg0LjcwMjc1OSBDIDM3OS4wMTY0NzkgMzgxLjMyMzE4MSAzNzkuMDI4OTYxIDM3Ni45NTA5ODkgMzc5LjM5NzQzIDM3NC45ODY3NTUgQyAzNzkuOTY3MDQxIDM3MS45NTA0MzkgMzgwLjU2MzkzNCAzNzEuMzMzOTIzIDM4My4zODEzNzggMzcwLjg3MTU4MiBDIDM4NS4yMDQwNDEgMzcwLjU3MjQ0OSAzODkuMjM1NzQ4IDM2OS4zMzM5MjMgMzkyLjM0MDcyOSAzNjguMTE5MjYzIEMgMzk1LjQ0NTcwOSAzNjYuOTA0NjYzIDM5OS40MTc1NzIgMzY1LjY1NTc2MiA0MDEuMTY3MDg0IDM2NS4zNDM5MzMgQyA0MDQuMzQ4MDUzIDM2NC43NzY5NzggNDA0LjM0ODA1MyAzNjQuNzc2OTc4IDQwMy45MDgyNjQgMzgwLjUzOTM2OCBDIDQwMy40Njg0NDUgMzk2LjMwMTY5NyA0MDMuNDY4NDQ1IDM5Ni4zMDE2OTcgMzk5LjQ4Mzk3OCA0MDAuMTUwODc5IEMgMzk2LjQ1Njc1NyA0MDMuMDc1MzE3IDM5NC42NTQyMzYgNDA0IDM5MS45ODA5NTcgNDA0IFoiLz4KICAgICAgICAgICAgPHBhdGggaWQ9InBhdGgyMiIgZmlsbD0iIzAwMDAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9Im5vbmUiIGQ9Ik0gNDA1IDM0My41MDA5MTYgQyA0MDAuODc1IDM0My43MzY4MTYgMzk1LjcwMDAxMiAzNDMuNDkwNzIzIDM5My41IDM0Mi45NTQwNDEgQyAzOTEuMjk5OTg4IDM0Mi40MTc0MTkgMzg4LjMxNTM2OSAzNDEuNTAwNDg4IDM4Ni44Njc0OTMgMzQwLjkxNjUwNCBDIDM4NS40MTk1ODYgMzQwLjMzMjUyIDM4Mi45OTU4OCAzMzguNTYxMzQgMzgxLjQ4MTQxNSAzMzYuOTgwNTkxIEMgMzc5LjA2NDYzNiAzMzQuNDU4MDA4IDM3OC43OTE2ODcgMzMzLjU0MDU4OCAzNzkuMjQ5NTEyIDMyOS40Nzg1NzcgQyAzNzkuNTkxNDkyIDMyNi40NDQ3MDIgMzgwLjc3Mjc5NyAzMjMuNTg0NjU2IDM4Mi42NzkwMTYgMzIxLjE3NTI5MyBDIDM4NC4yNzgzNTEgMzE5LjE1Mzg3IDM4OC4xODE5NzYgMzE2LjE5MzE3NiAzOTEuMzUzNzkgMzE0LjU5NTk0NyBDIDM5NS42MTg1NjEgMzEyLjQ0ODMwMyAzOTkuMDE0MTMgMzExLjU3MDM3NCA0MDQuMzg5NzQgMzExLjIyNTQwMyBDIDQwOS40MDE4MjUgMzEwLjkwMzc0OCA0MTMuNDE4MDMgMzExLjI3MDMyNSA0MTcuMzI0OTIxIDMxMi40MDYwNjcgQyA0MjAuNDQxMzE1IDMxMy4zMTIwMTIgNDI0LjUxMjYzNCAzMTUuMzg5MjIxIDQyNi4zNzIzMTQgMzE3LjAyMjAzNCBDIDQyOC4yMzE5OTUgMzE4LjY1NDg0NiA0MzAuMjg5NjEyIDMyMS4yODQ5NzMgNDMwLjk0NDgyNCAzMjIuODY2NzYgQyA0MzEuNjAwMDA2IDMyNC40NDg1NDcgNDMxLjk5Mjk1IDMyNy40Njg5OTQgNDMxLjgxODAyNCAzMjkuNTc4ODU3IEMgNDMxLjU1NDkzMiAzMzIuNzUyNTAyIDQzMC43NTgzOTIgMzMzLjk3OTI0OCA0MjcuMjA1ODcyIDMzNi42ODE4ODUgQyA0MjQuODQ0MTE2IDMzOC40Nzg2MzggNDIwLjU2OTA5MiAzNDAuNjUxNDg5IDQxNy43MDU4NzIgMzQxLjUxMDQzNyBDIDQxNC44NDI2NTEgMzQyLjM2OTMyNCA0MDkuMTI1IDM0My4yNjUwNzYgNDA1IDM0My41MDA5MTYgWiIvPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg== + mediatype: image/svg+xml + install: + spec: + clusterPermissions: + - rules: + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - update + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + resources: + - deployments + - replicasets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - cert-manager.io + resources: + - certificates + - issuers + verbs: + - create + - delete + - get + - list + - update + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - overcommit.inditex.dev + resources: + - overcommitclasses + - overcommits + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - overcommit.inditex.dev + resources: + - overcommitclasses/finalizers + - overcommits/finalizers + verbs: + - update + - apiGroups: + - overcommit.inditex.dev + resources: + - overcommitclasses/status + - overcommits/status + verbs: + - get + - patch + - update + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + serviceAccountName: k8s-overcommit-controller-manager + deployments: + - label: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: k8s-overcommit + control-plane: controller-manager + name: k8s-overcommit-operator + spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + strategy: {} + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + containers: + - args: + - -metrics-secure=false + - --metrics-bind-address=:8080 + command: + - /manager + env: + - name: ENABLE_OVERCOMMIT_CONTROLLER + value: "true" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/inditextech/k8s-overcommit-operator:1.1.1 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 8080 + name: metrics + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + securityContext: + runAsNonRoot: true + serviceAccountName: k8s-overcommit-controller-manager + terminationGracePeriodSeconds: 10 + permissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + serviceAccountName: k8s-overcommit-controller-manager + strategy: deployment + installModes: + - supported: false + type: OwnNamespace + - supported: false + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - ocp + - k8s + - overcommit + links: + - name: K8s Overcommit + url: https://k8s-overcommit.domain + maintainers: + - email: enriqueavi@inditex.com + name: enriqueAndresVillar + maturity: alpha + minKubeVersion: 1.22.0 + provider: + name: inditexTech + version: 1.1.1 diff --git a/deploy/olm/1.1.1/overcommit.inditex.dev_overcommitclasses.yaml b/deploy/olm/1.1.1/overcommit.inditex.dev_overcommitclasses.yaml new file mode 100644 index 0000000..2641c47 --- /dev/null +++ b/deploy/olm/1.1.1/overcommit.inditex.dev_overcommitclasses.yaml @@ -0,0 +1,210 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + creationTimestamp: null + name: overcommitclasses.overcommit.inditex.dev +spec: + group: overcommit.inditex.dev + names: + kind: OvercommitClass + listKind: OvercommitClassList + plural: overcommitclasses + shortNames: + - oc + - ocs + singular: overcommitclass + scope: Cluster + versions: + - additionalPrinterColumns: + - description: CPU overcommit ratio + jsonPath: .spec.cpuOvercommit + name: CPU + type: number + - description: Memory overcommit ratio + jsonPath: .spec.memoryOvercommit + name: Memory + type: number + - description: Is default overcommit class + jsonPath: .spec.isDefault + name: Default + type: boolean + name: v1alphav1 + schema: + openAPIV3Schema: + description: OvercommitClass is the Schema for the overcommitclasses API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: OvercommitClassSpec defines the desired state of OvercommitClass + properties: + annotations: + additionalProperties: + type: string + type: object + cpuOvercommit: + maximum: 1 + minimum: 0.0001 + type: number + excludedNamespaces: + type: string + isDefault: + default: false + type: boolean + labels: + additionalProperties: + type: string + type: object + memoryOvercommit: + maximum: 1 + minimum: 0.0001 + type: number + nodeSelector: + additionalProperties: + type: string + type: object + tolerations: + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + required: + - cpuOvercommit + - excludedNamespaces + - memoryOvercommit + type: object + status: + description: OvercommitClassStatus defines the observed state of OvercommitClass + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + resources: + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file + items: + properties: + name: + type: string + ready: + type: boolean + required: + - ready + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm/1.1.1/overcommit.inditex.dev_overcommits.yaml b/deploy/olm/1.1.1/overcommit.inditex.dev_overcommits.yaml new file mode 100644 index 0000000..b9833e0 --- /dev/null +++ b/deploy/olm/1.1.1/overcommit.inditex.dev_overcommits.yaml @@ -0,0 +1,187 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + creationTimestamp: null + name: overcommits.overcommit.inditex.dev +spec: + group: overcommit.inditex.dev + names: + kind: Overcommit + listKind: OvercommitList + plural: overcommits + singular: overcommit + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Label to apply to the pods to make overcommit + jsonPath: .spec.overcommitLabel + name: Target Label + type: string + name: v1alphav1 + schema: + openAPIV3Schema: + description: Overcommit is the Schema for the overcommits API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: OvercommitSpec defines the desired state of Overcommit + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + nodeSelector: + additionalProperties: + type: string + type: object + overcommitLabel: + minLength: 1 + type: string + tolerations: + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + required: + - overcommitLabel + type: object + status: + description: OvercommitStatus defines the observed state of Overcommit + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + resources: + items: + properties: + name: + type: string + ready: + type: boolean + required: + - ready + type: object + type: array + type: object + type: object + x-kubernetes-validations: + - message: overcommit is a singleton, .metadata.name must be 'cluster' + rule: self.metadata.name == 'cluster' + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null